/* Tokens (docs/ISTRENA_DESIGN.md §2, look version 3 «Стол»). :root is the
   evening theme, body.theme-light the day theme. Sheet surfaces, lowest
   first: --bg (the sheet), --panel (toolbars, stat cells), --bg-1 (panels
   and cards), --bg-2 (raised: hover, popover groups), --control (inputs);
   --chip carries counts and round buttons. The top (--top, --top-2) is navy
   in both themes. Soft and line variants are fixed values, never opacity
   over a surface. tests/test_web_css.py checks every text token against
   every surface, in both themes, so keep the two blocks in step. */
:root{
  --bg: #0b1526;
  --panel: #16263f;
  --bg-1: #111e34;
  --bg-2: #16263f;
  --control: #0e1a2d;
  --chip: #1d2e4b;
  --rule: #1f3049;
  --rule-strong: #34496b;
  --control-line: #5d7699;

  --ink: #edf2f9;
  --ink-soft: #b5c1d4;
  --ink-faint: #8d9ab0;

  /* The top bar and the hero: navy in both themes, text checked on both. */
  --top: #091a33;
  --top-2: #122a4d;
  --top-rule: #24406a;
  --top-ink: #ffffff;
  --top-soft: #a9bfdf;
  --top-acc: #ff7a2e;
  --top-ok: #5cd197;
  --top-bad: #ff8b80;
  --top-wait: #9ec3ff;
  --table: #1b4b8d;
  --mesh: #3d5579;
  --post: #4a6288;
  --glow: rgba(255,196,130,.08);
  --vignette: rgba(2,8,18,.35);
  --lamp: #ffd79a;
  --lamp-a: .32;
  --chart-a: .09;

  --ok: #5cd197;
  --ok-soft: #16362a;
  --ok-line: #2f7a57;
  --bad: #ff8b80;
  --bad-soft: #3e2024;
  --bad-line: #9a4f4a;
  --ball: #ff9d62;
  --ball-soft: #3b2414;
  --ball-line: #a2552a;
  --blue: #91b9f3;
  --blue-soft: #1a2d4e;
  --blue-line: #4f73a8;
  --neutral: #9aa6ba;
  --neutral-soft: #1a2940;
  --neutral-line: #4a6288;

  --focus: #91b9f3;
  /* Panels and cards take --lift and nothing else; floating things take
     --shadow-float. */
  --lift: 0 1px 0 rgba(255,255,255,.03) inset;
  --shadow-float: 0 18px 44px rgba(0,0,0,.55);

  /* The ball as a fill: the primary button, the live ball, count badges.
     Orange text uses --ball, the text-safe shade. */
  --brand: #ff7a2e;
  --brand-fg: #1f0e02;

  --font-text: 'Onest', -apple-system, 'Segoe UI', sans-serif;
  --font-fig: 'Fira Sans Extra Condensed', 'Arial Narrow', sans-serif;

  --r-sheet: 32px;
  --r-card: 24px;
  --r-band: 18px;
  --r-ctl: 14px;
  --r-badge: 13px;
}
body.theme-light{
  --bg: #eceff4;
  --panel: #f4f6f9;
  --bg-1: #ffffff;
  --bg-2: #f4f6f9;
  --control: #ffffff;
  --chip: #e8edf3;
  --rule: #e1e6ed;
  --rule-strong: #c3ccd8;
  --control-line: #7d8999;

  --ink: #0f1b2d;
  --ink-soft: #415069;
  --ink-faint: #5f6c81;

  --top: #0f2a4f;
  --top-2: #173763;
  --top-rule: #2a4a78;
  --top-soft: #b7cbe8;
  --table: #1d5096;
  --mesh: #b3bfcd;
  --post: #c3ccd8;
  --glow: rgba(170,200,255,.07);
  --vignette: rgba(0,0,0,0);
  --lamp: #ffffff;
  --lamp-a: .16;
  --chart-a: .16;

  --ok: #157a4a;
  --ok-soft: #e1f3e9;
  --ok-line: #7fb99a;
  --bad: #bf342a;
  --bad-soft: #fbe6e3;
  --bad-line: #e0a09a;
  --ball: #b8470b;
  --ball-soft: #ffe9dc;
  --ball-line: #f0b48f;
  --blue: #2a64b8;
  --blue-soft: #e5eefb;
  --blue-line: #9db8e0;
  --neutral: #5f6c81;
  --neutral-soft: #edf0f4;
  --neutral-line: #b3bfcd;

  --focus: #2a64b8;
  --lift: 0 1px 2px rgba(15,27,45,.05), 0 8px 24px rgba(15,27,45,.06);
  --shadow-float: 0 18px 44px rgba(15,27,45,.22);
  --brand: #ff6b1a;
}
/* Older names, kept for the pages not yet on the v2 look. Declared on
   body as well, so each resolves against the theme's own tokens. */
:root, body{
  --accent: var(--brand);
  --accent-fg: var(--brand-fg);
  --accent-soft: var(--ball-soft);
  --accent-line: var(--ball-line);
  --accent-ink: var(--ball);
  --warn: var(--blue);
  --warn-soft: var(--blue-soft);
  --warn-line: var(--blue-line);
  --warn-ink: var(--blue);
  --bg-3: var(--bg-2);
  --bg-4: var(--rule);
  --rule-2: var(--rule-strong);
  --rule-3: var(--control-line);
  --ink-mute: var(--ink-faint);

}

*{box-sizing:border-box}
html,body{margin:0;padding:0;color:var(--ink);
  font-family:var(--font-text);
  font-size:15px;line-height:22px;-webkit-font-smoothing:antialiased;
}
/* Only body is painted: the theme class lives on body, and with html left
   transparent the browser spreads body's ground over the whole canvas. */
body{min-height:100vh;background:var(--bg)}

h1,h2,h3,h4{margin:0;font-weight:600;letter-spacing:-0.01em;}
h1{font-size:30px;line-height:38px}
h2{font-size:19px;line-height:24px}
h3{font-size:19px;line-height:24px}
h4{font-size:15px;line-height:22px;font-weight:600}
/* Every figure: Fira Sans Extra Condensed with tabular digits (§3). */
.mono{font-family:var(--font-fig);font-variant-numeric:tabular-nums;font-size:15px;letter-spacing:0;}
.num{font-family:var(--font-fig);font-variant-numeric:tabular-nums;}

.ink{color:var(--ink)}
.ink-soft{color:var(--ink-soft)}
.ink-faint{color:var(--ink-faint)}
.ink-mute{color:var(--ink-faint)}
.accent{color:var(--ball)}
.warn{color:var(--blue)}
.ok-c{color:var(--ok)}
.bad-c{color:var(--bad)}

button{font-family:inherit;font-size:inherit;color:inherit;background:transparent;border:0;cursor:pointer}
a{color:inherit;text-decoration:none}

/* ── The shell (docs/ISTRENA_DESIGN.md §6): the navy top bar, the hero and
   the sheet that overlaps it. The top's light is one radial glow; in the
   evening a vignette darkens its edges. ── */
.app{
  /* One content edge for the top bar, the hero and the sheet
     (istrena-wide-rail D2): 32 px, and from a 2448 px window 2384 px of
     content centred. The percentage resolves where the property is used,
     against the app's width, so the three share their edges exactly. */
  --edge:max(32px, calc((100% - 2384px) / 2));
  min-height:100vh;
  display:flex; flex-direction:column;
  background:
    radial-gradient(ellipse 1150px 560px at 62% 30px, var(--glow), transparent 72%),
    radial-gradient(ellipse 1400px 620px at 52% 180px, transparent 50%, var(--vignette)),
    var(--top);
  background-repeat:no-repeat;
}
.topbar{
  height:72px; flex:0 0 auto;
  display:flex; align-items:center; gap:36px;
  padding:0 var(--edge);
  color:var(--top-ink);
  position:relative; z-index:40;
}
.brand{ display:flex; align-items:center; gap:10px; flex:0 0 auto; color:var(--top-ink) }
.brand-mark{ width:15px; flex:0 0 auto; color:var(--top-ink); display:grid; place-items:center }
.brand-mark svg{ display:block; width:100%; height:auto }
.brand-name{ display:block; color:var(--top-ink); line-height:0 }
.brand-name svg{ display:block; height:17px; width:auto }

/* The pill nav: the open tab is filled and its icon's ball turns orange. */
.tabs{
  display:flex; align-items:center; gap:2px; min-width:0;
  padding:4px; border-radius:22px; background:var(--top-2);
  overflow-x:auto; scrollbar-width:none;
}
.nav-item{
  height:36px; flex:0 0 auto;
  display:flex; align-items:center; gap:8px;
  padding:0 16px 0 12px; border-radius:18px;
  font-size:15px; font-weight:500; color:var(--top-soft); white-space:nowrap;
  transition:background .12s, color .12s;
}
.nav-item .ic{ display:inline-grid; place-items:center; flex:0 0 auto }
.nav-item .ic .ball{ fill:currentColor; stroke:none }
.nav-item:hover{ color:var(--top-ink); background:rgba(255,255,255,.07) }
.nav-item.active{ background:rgba(255,255,255,.14); color:var(--top-ink); font-weight:600 }
.nav-item.active .ic .ball{ fill:var(--brand) }
.topbar :focus-visible{ outline:2px solid var(--top-wait); outline-offset:2px }
.nav-badge{
  min-width:22px; height:22px; padding:0 6px; margin-left:2px;
  border-radius:11px; background:var(--brand); color:var(--brand-fg);
  font-size:14px; font-weight:600;
  display:inline-flex; align-items:center; justify-content:center;
}

.top-right{ margin-left:auto; display:flex; align-items:center; gap:12px; flex:0 0 auto }
.top-pill{
  height:44px; padding:0 18px; border-radius:22px;
  background:var(--top-2); color:var(--top-ink);
  display:flex; align-items:center; gap:10px; white-space:nowrap;
}
.bot-pill{ padding:0 18px 0 14px }
.bot-dot{ width:10px; height:10px; flex:0 0 auto; border-radius:50%; background:var(--top-ok); box-shadow:0 0 0 4px rgba(92,209,151,.18) }
.bot-pill.silent .bot-dot{ background:var(--top-bad); box-shadow:0 0 0 4px rgba(255,139,128,.18) }
.bot-pill.unknown .bot-dot{ background:var(--top-soft); box-shadow:none }
.bot-text{ display:flex; flex-direction:column }
.bot-label{ font-size:14px; line-height:18px; font-weight:500 }
.bot-detail{ font-size:13px; line-height:16px; color:var(--top-soft) }
.top-clock{ align-items:baseline; gap:6px; padding-top:8px }
.top-clock .num{ font-size:24px; line-height:28px; font-weight:600 }
.top-unit{ font-size:13px; color:var(--top-soft) }
.topbar .icon-btn{ width:44px; height:44px; border:0; border-radius:50%; background:var(--top-2); color:var(--top-ink) }
.topbar .icon-btn:hover{ background:var(--top-rule); color:var(--top-ink); border-color:transparent }
.account-btn{
  width:44px; height:44px; border-radius:50%;
  background:var(--table); color:var(--top-ink);
  font-size:16px; font-weight:600;
}
.account-menu{ top:76px; right:32px; width:280px; display:none; flex-direction:column; gap:10px }
.account-menu:popover-open{ display:flex }
.account-login{ font-weight:600 }
.account-link{ color:var(--ink-soft); font-size:14px }
.account-link:hover{ color:var(--ink); text-decoration:underline }
.account-menu .signout .btn{ width:100% }

/* The sheet: the pages' content, on a rounded paper that overlaps the hero.
   `.paper`, because `.sheet` is the bet breakdown's drawer further down. */
.paper{
  flex:1 0 auto;
  display:flex; flex-direction:column; min-width:0;
  background:var(--bg);
  border-radius:var(--r-sheet) var(--r-sheet) 0 0;
  position:relative; z-index:1;
}
.hero + .paper{ margin-top:-24px }
.cmdk{
  display:flex; align-items:center; gap:8px;
  padding:6px 10px; border:1px solid var(--rule); border-radius:7px;
  background:var(--bg-1); color:var(--ink-faint);
  font-size:13px; min-width:260px; cursor:pointer;
}
.cmdk:hover{ color:var(--ink-soft); border-color:var(--rule-2)}
.cmdk .kbd{
  margin-left:auto;
  font-family:var(--font-fig); font-size:13px;
  padding:1px 5px; border:1px solid var(--rule-2); border-radius:4px;
}

.icon-btn{
  width:36px; height:36px; border-radius:var(--r-ctl);
  border:1px solid var(--rule);
  background:var(--control);
  color:var(--ink-soft);
  display:grid; place-items:center;
  transition:background .12s, border-color .12s, color .12s;
}
.icon-btn:hover{ color:var(--ink); border-color:var(--rule-strong); background:var(--bg-2)}
.avatar{
  width:28px; height:28px; border-radius:50%;
  background:linear-gradient(135deg, var(--bg-3), var(--bg-4));
  border:1px solid var(--rule-2);
  overflow:hidden; flex:0 0 auto;
}
.avatar svg{ width:100%; height:100%; }

main{ display:flex; flex-direction:column; min-width:0; }
/* Content edge 32 px from the window at 1920, 24 px at 1280; above 2448
   px the content stops at 2384 px, centred (--edge). */
.canvas{ padding:32px var(--edge) 48px; width:100%; margin:0;}
/* The bar needs 1601 px with every label (1616 with a scrollbar). Under
   1920 its gaps close to 24 px, which holds down to 1600 (the rule comes
   first, so the 20 px under 1600 wins). Under 1600 a closed tab shows its
   icon only: the label stays for screen readers and in the tooltip, and
   the open tab keeps its label. */
@media (max-width:1919px){ .topbar{ gap:24px } }
@media (max-width:1599px){ .canvas{ padding:32px 24px 48px } .topbar{ padding:0 24px; gap:20px } }
@media (max-width:1599px){
  .nav-item:not(.active){ gap:0; min-width:36px; padding:0 9px; justify-content:center }
  .nav-item:not(.active) .nav-lbl{ position:absolute; width:1px; height:1px; margin:-1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap }
}
.page{display:block}

.page-head{
  display:flex; align-items:flex-end; justify-content:space-between;
  gap:24px; margin-bottom:24px;
}
.page-head .title-row{ display:flex; align-items:flex-end; gap:14px}
.page-head h1{ font-weight:600 }
.page-head .kicker{
  font-size:13px; font-weight:600; letter-spacing:0;
  color:var(--ink-faint); margin-bottom:4px;
}
.page-head .meta{ color:var(--ink-soft); font-size:15px; line-height:22px; margin-top:6px; max-width:80ch}

/* A panel: a rounded sheet with one soft lift and no visible border. The
   transparent border keeps the state variants' geometry. */
.card{
  background:var(--bg-1);
  border:1px solid transparent;
  border-radius:var(--r-card);
  box-shadow:var(--lift);
  padding:20px;
  transition:border-color .15s, background .15s;
}
.card.hover:hover{ border-color:var(--rule-strong)}
.card.flat{ background:transparent; border:1px dashed var(--rule-2)}
.card.tag-accent{ border-color:var(--ball-line); background:var(--ball-soft) }
.card-h{
  display:flex; align-items:center; justify-content:space-between;
  gap:12px; margin-bottom:12px;
}
.card-h h3{font-weight:600}
.label{
  font-size:13px; font-weight:500; letter-spacing:0;
  color:var(--ink-faint);
}

.stat-num{font-size:36px; font-weight:600; line-height:1; letter-spacing:-.025em;
  font-family:var(--font-fig); font-variant-numeric:tabular-nums;}
.stat-num.lg{ font-size:44px }
.stat-num.sm{ font-size:26px }
.stat-num.acc{ color:var(--ball)}
.stat-num.bad{ color:var(--bad)}
.stat-sub{ font-size:13px; color:var(--ink-soft); margin-top:6px}
.stat-delta{
  display:inline-flex; align-items:center; gap:4px;
  font-family:var(--font-fig); font-size:13px;
  padding:1px 6px; border-radius:4px;
}
.stat-delta.up{ background:var(--ball-soft); color:var(--ball)}
.stat-delta.down{ background:var(--warn-soft); color:var(--warn)}

.grid{display:grid; gap:14px}
.g-2{grid-template-columns:repeat(2,1fr)}
.g-3{grid-template-columns:repeat(3,1fr)}
.g-4{grid-template-columns:repeat(4,1fr)}
.g-5{grid-template-columns:repeat(5,1fr)}
.g-6{grid-template-columns:repeat(6,1fr)}
.g-12{grid-template-columns:repeat(12,1fr)}
.row{display:flex; gap:14px}
.row.wrap{flex-wrap:wrap}
.row.tight{gap:8px}
.row.between{justify-content:space-between; align-items:center}
.row.center{align-items:center}
.row.baseline{align-items:baseline}
.col{display:flex; flex-direction:column; gap:14px}
.grow{flex:1; min-width:0}
.mt{margin-top:14px} .mt-s{margin-top:8px} .mt-l{margin-top:22px}
.mb{margin-bottom:14px} .mb-s{margin-bottom:8px} .mb-l{margin-bottom:22px}

.chips{display:flex; gap:6px; flex-wrap:wrap}
.chip{
  display:inline-flex; align-items:center; gap:6px;
  min-height:32px; padding:0 12px; border:1px solid var(--rule); border-radius:var(--r-ctl);
  background:var(--control);
  color:var(--ink-soft); font-size:14px; font-weight:500;
  cursor:pointer; transition:background .12s, border-color .12s, color .12s;
  line-height:20px;
}
.chip:hover{ color:var(--ink); border-color:var(--rule-strong)}
.chip.on{
  background:var(--ball-soft); color:var(--ink);
  border-color:var(--ball-line);
}
.chip.mute.on{
  background:var(--bg-3); color:var(--ink); border-color:var(--rule-3);
}
.chip .dot{ width:6px; height:6px; border-radius:50%; background:currentColor; opacity:.7}
/* Segmented control: a --chip track of 36 px segments; the selected one is
   the sheet's white with --ink. */
.seg{
  display:inline-flex; height:44px; padding:4px; gap:2px;
  background:var(--chip); border-radius:22px;
}
.seg button, .seg a, .seg label{
  height:36px; min-width:64px; padding:0 16px; border-radius:18px; color:var(--ink-soft);
  font-size:14px; font-weight:500; display:inline-flex; align-items:center; justify-content:center; gap:6px;
  text-decoration:none;
}
.seg button.on, .seg a.on, .seg [aria-pressed="true"], .seg [aria-selected="true"], .seg label:has(input:checked){ background:var(--bg-1); color:var(--ink); font-weight:600 }
/* Over native radios (a mode that is a form field): the radio covers its
   segment, so the arrows switch it and a press anywhere picks. */
fieldset.seg{ position:relative; margin:0; border:0; min-width:0 }
.seg label{ position:relative; cursor:pointer }
.seg input{ position:absolute; inset:0; width:100%; height:100%; margin:0; opacity:0; cursor:pointer }
.seg label:not(:has(input:checked)):hover{ color:var(--ink) }
.seg label:has(input:focus-visible){ outline:2px solid var(--focus); outline-offset:2px }

/* Badge: 26 px, radius 13, 11 px padding, 13 px 600, its state's colour on
   its soft fill. */
.tag, .pill{
  display:inline-flex; align-items:center; gap:5px;
  height:26px; padding:0 11px; border-radius:var(--r-badge);
  background:var(--neutral-soft); border:0;
  font-size:13px; font-weight:600; line-height:18px;
  color:var(--neutral);
  letter-spacing:0; white-space:nowrap; vertical-align:middle;
}
.tag .st-ic, .pill .st-ic{ flex-basis:14px; width:14px; height:14px }
.tag .st-ic svg, .pill .st-ic svg{ width:14px; height:14px }
.tag.acc, .pill.acc{ background:var(--ball-soft); color:var(--ball)}
.tag.warn, .pill.warn{ background:var(--blue-soft); color:var(--blue)}
.tag.ok, .pill.ok{ background:var(--ok-soft); color:var(--ok)}
.tag.bad, .pill.bad{ background:var(--bad-soft); color:var(--bad)}
.pill.mute{ background:transparent; box-shadow:inset 0 0 0 1px var(--rule-strong); color:var(--ink-faint)}

table.tf{ width:100%; border-collapse:collapse; font-size:14px; line-height:20px}
table.tf th, table.tf td{
  padding:10px 12px; text-align:left;
  border-bottom:1px solid var(--rule);
  font-variant-numeric:tabular-nums;
}
table.tf thead th{
  font-size:13px; line-height:18px; font-weight:500; letter-spacing:0;
  color:var(--ink-faint);
  background:var(--bg-1);
  position:sticky; top:0;
}
table.tf tbody tr{ transition:background .1s}
table.tf tbody tr:hover{ background:var(--bg-2)}
table.tf tbody tr.sel, table.tf tbody tr[aria-selected="true"]{ background:var(--blue-soft)}
table.tf td.r, table.tf th.r{text-align:right}
table.tf td.c, table.tf th.c{text-align:center}
table.tf .mono{font-size:14px}
/* A scroll box for a long table. The `.tf thead th` header is already
   sticky and only needs a scrolling parent, so a long grid neither
   stretches the page nor pushes the other cards off screen. */
.tbl-scroll{ max-height:min(52vh, 460px); overflow-y:auto}

.slider{
  height:38px; position:relative; padding:0 12px;
  display:flex; align-items:center;
  cursor:pointer; user-select:none;
}
.slider-track{
  width:100%; height:4px; border-radius:2px;
  background:var(--bg-3); position:relative;
}
.slider-fill{
  position:absolute; left:0; top:0; bottom:0; border-radius:2px;
  background:var(--accent);
}
.slider-thumb{
  position:absolute; top:50%; transform:translate(-50%,-50%);
  width:14px; height:14px; border-radius:50%;
  background:var(--accent); border:2px solid var(--bg);
  box-shadow:0 0 0 1px var(--accent);
  transition: transform .12s ease, box-shadow .15s ease;
}
.slider:hover .slider-thumb{ transform:translate(-50%,-50%) scale(1.12); box-shadow: 0 0 0 1px var(--accent), 0 0 0 6px var(--accent-soft); }
.slider.dragging .slider-thumb{ transform:translate(-50%,-50%) scale(1.18) }
.slider-axis{
  display:flex; justify-content:space-between;
  font-family:var(--font-fig); font-size:13px;
  color:var(--ink-faint); margin-top:6px;
}

.bar-row{display:grid; grid-template-columns: 90px 1fr 70px 70px; align-items:center; gap:10px; padding:6px 0}
.bar-track{
  height:6px; border-radius:3px; background:var(--bg-3); overflow:hidden;
}
.bar-fill{ height:100%; background:var(--accent); border-radius:3px}
.bar-fill.warn{ background:var(--warn)}

svg .grid-l{stroke:var(--rule); stroke-width:1; stroke-dasharray:2 4}
svg .axis{stroke:var(--rule-2); stroke-width:1}
svg .axis-l{fill:var(--ink-faint); font-family:var(--font-fig); font-size:13px}
svg .ideal{stroke:var(--ink-mute); stroke-width:1; stroke-dasharray:3 3}
svg .lineA{stroke:var(--accent); stroke-width:1.8; fill:none; stroke-linejoin:round}
svg .lineA.gap{stroke:var(--ink-mute); stroke-width:1.2}
svg .lineA-fill{fill:var(--accent-soft); stroke:none}
svg .lineB{stroke:var(--warn); stroke-width:1.4; fill:none; stroke-dasharray:4 3; stroke-linecap:round}
svg .dot{fill:var(--accent); stroke:var(--bg); stroke-width:1.5}
svg .dot-w{fill:var(--warn); stroke:var(--bg); stroke-width:1.5}
svg .bar{fill:var(--accent); opacity:.85}
svg .bar-w{fill:var(--warn); opacity:.85}
svg .cursor{stroke:var(--accent); stroke-width:1; stroke-dasharray:2 3}
svg .lbl{fill:var(--ink-soft); font-family:var(--font-text); font-size:13px}
svg .lbl-mono{fill:var(--ink-soft); font-family:var(--font-fig); font-size:13px}
/* Individual-total scatter: per-match dots + dashed average baselines. */
svg .ind-pt{stroke:var(--bg); stroke-width:1.2}
svg .ind-pt.win{fill:var(--accent)}
svg .ind-pt.loss{fill:var(--warn)}
svg .ind-avg{stroke-width:1.2; stroke-dasharray:4 3}
svg .ind-avg.all{stroke:var(--accent); opacity:.7}
svg .ind-avg.loss{stroke:var(--warn); opacity:.7}
/* Average-baseline value labels (left end) + per-dot total labels. */
svg .ind-avg-lbl{font-family:var(--font-fig); font-size:13px; font-weight:600}
svg .ind-avg-lbl.all{fill:var(--accent)}
svg .ind-avg-lbl.loss{fill:var(--warn)}
svg .ind-pt-lbl{font-family:var(--font-fig); font-size:13px; fill:var(--ink-soft)}
/* Inline dot legend in chart captions. */
.dot-legend{font-size:13px; vertical-align:middle; margin:0 1px 0 6px}
.dot-legend.win{color:var(--accent)}
.dot-legend.loss{color:var(--warn)}
/* Hover of server-drawn charts (static/widgets.js, web/charts.py). */
svg[data-hover]{ touch-action:pan-y; cursor:crosshair; outline:none }
svg[data-hover]:focus-visible{ outline:1px solid var(--accent-line); outline-offset:2px; border-radius:4px }
svg .even{ vector-effect:non-scaling-stroke }
svg .hv{ pointer-events:none }
svg .hv-guide{ stroke:var(--ink-faint); stroke-width:1; stroke-dasharray:3 3; vector-effect:non-scaling-stroke }
svg .hv-dot{ fill:var(--bg); stroke:var(--accent); stroke-width:2; vector-effect:non-scaling-stroke }
svg .hv-dot.mute{ stroke:var(--ink-soft) }
svg .hv-dot.warn{ stroke:var(--warn) }
svg .hv-dot.ok{ stroke:var(--ok) }
svg .hv-dot.bad{ stroke:var(--bad) }
.hv-sw{ display:inline-block; width:8px; height:8px; border-radius:2px; margin-right:6px; vertical-align:0; background:var(--accent) }
.hv-sw.mute{ background:var(--ink-soft) }
.hv-sw.warn{ background:var(--warn) }
.hv-sw.ok{ background:var(--ok) }
.hv-sw.bad{ background:var(--bad) }
.chart-legend{ display:flex; flex-wrap:wrap; justify-content:center; align-items:center; gap:4px 14px; font-size:13px; color:var(--ink-soft); margin:6px 0 8px }
.chart-legend .hv-sw{ margin-right:5px }

.work{
  display:grid; gap:18px;
  grid-template-columns: 240px 1fr;
  align-items:flex-start;
}
.work-3{
  display:grid; gap:18px;
  grid-template-columns: 240px 1fr 320px;
  align-items:flex-start;
}
.rail{
  background:var(--panel);
  border:1px solid var(--rule);
  border-radius:10px;
  padding:16px;
  position:sticky; top:74px;
  max-height: calc(100vh - 90px);
  overflow:auto;
}
.rail h3{ font-size:14px; margin-bottom:4px}
.rail .group{ padding:14px 0; border-top:1px solid var(--rule)}
.rail .group:first-of-type{ border-top:0; padding-top:8px}
.rail .group .label{ margin-bottom:8px; display:block}

.drill{
  background:var(--bg-1);
  border:1px solid var(--accent-line);
  border-radius:10px;
  padding:16px;
  position:sticky; top:74px;
}
.drill::before{
  content:'подробно · Esc закрывает';
  display:block;
  font-family:var(--font-fig); font-size:13px;
  color:var(--ball); margin-bottom:10px;
}

.tabbar{
  display:flex; gap:2px; padding:2px; height:36px;
  background:var(--control); border:1px solid var(--rule); border-radius:var(--r-ctl);
  width:fit-content;
}
.tabbar button{
  min-width:64px; padding:0 14px; border-radius:4px;
  color:var(--ink-soft); font-size:14px; font-weight:500;
  transition:background .12s, color .12s;
}
.tabbar button:hover{ color:var(--ink) }
.tabbar button.on{ background:var(--ball-soft); color:var(--ink)}

.pred-card{
  background:var(--bg-1); border:1px solid var(--rule);
  border-radius:10px; padding:14px;
  display:flex; flex-direction:column; gap:10px;
  transition:border-color .12s;
}
.pred-card.win{ border-left:3px solid var(--accent)}
.pred-card.loss{ border-left:3px solid var(--warn)}
.pred-card:hover{border-color:var(--rule-2)}
.pred-head{ display:flex; justify-content:space-between; gap:10px; align-items:flex-start}
.pred-conf{font-size:26px; font-weight:600; line-height:1; font-family:var(--font-fig)}
.confbar{height:4px; border-radius:2px; background:var(--bg-3); overflow:hidden; width:80px; margin-top:4px}
.confbar-fill{height:100%; background:var(--accent); border-radius:2px}

/* Predictions card · finished-match result strip. Three-cell footer that
   sits flush against the card's bottom edge. */
.result-strip{
  display:grid; grid-template-columns:1fr 1fr 1fr; gap:0;
  background:var(--bg-2); border:1px solid var(--rule);
  border-radius:8px; overflow:hidden;
  margin-top:2px;
}
.result-strip.is-hit{ border-color:color-mix(in srgb, var(--ok) 35%, transparent); background:color-mix(in srgb, var(--ok) 5%, transparent)}
.result-strip.is-miss{ border-color:color-mix(in srgb, var(--bad) 35%, transparent); background:color-mix(in srgb, var(--bad) 5%, transparent)}
.result-strip .rs-cell{ padding:10px 12px; min-width:0}
.result-strip .rs-cell + .rs-cell{ border-left:1px solid var(--rule)}
.result-strip .rs-mid{ text-align:center}
.result-strip .rs-right{ text-align:right}
.result-strip .rs-val{ margin-top:4px; font-size:14px; display:flex; align-items:center; gap:6px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.result-strip .rs-mid .rs-val{ justify-content:center}
.result-strip .rs-right .rs-val{ justify-content:flex-end}

.banner{
  display:flex; align-items:center; gap:12px;
  background:var(--bg-1); border:1px solid var(--rule); border-radius:var(--r-card);
  padding:12px 20px;
}
.banner .dot{ width:8px; height:8px; flex:0 0 auto; border-radius:50%; background:var(--ball)}
.banner.warn{ border-color:var(--blue-line); background:var(--blue-soft)}
.banner.warn .dot{ background:var(--blue)}

/* Fields: 40 px, radius 14, 16 px side padding, a 1.5 px line that turns
   --brand on focus; the label 8 px above. */
.input{
  width:100%; height:40px; padding:0 16px;
  background:var(--control); border:1.5px solid var(--control-line); border-radius:var(--r-ctl);
  color:var(--ink); font-family:inherit; font-size:15px; line-height:22px;
  transition:border-color .12s;
}
select.input{ padding-right:32px }
.input:focus{ border-color:var(--brand); outline:2px solid var(--focus); outline-offset:1px}
.input::placeholder{ color:var(--ink-faint)}
.field{display:flex; flex-direction:column; gap:8px}
.field .label{display:block; font-size:14px; line-height:20px; font-weight:600; color:var(--ink-soft)}
.field .hint{font-size:13px; line-height:18px; color:var(--ink-faint)}
/* Buttons: 40 px pills, one baseline with the fields beside them. Primary
   is --brand; secondary a --chip; ghost is text only. */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:6px;
  height:40px; padding:0 18px; border-radius:20px;
  font-size:15px; line-height:22px; font-weight:600; white-space:nowrap;
  background:var(--chip); color:var(--ink);
  border:0;
  transition:background .12s, filter .12s;
}
.btn:hover{ background:var(--rule-strong)}
.btn.primary{ background:var(--brand); color:var(--brand-fg)}
.btn.primary:hover{ filter:brightness(1.06)}
.btn.ghost{ background:transparent; color:var(--ink-soft)}
.btn.ghost:hover{ background:var(--bg-2); color:var(--ink)}
.btn.sm{ height:32px; padding:0 14px; border-radius:16px; font-size:14px }
.btn:disabled{ opacity:.45; cursor:default }

.link{ color:var(--ball); text-decoration:none}
.link:hover{ text-decoration:underline }

body.theme-light svg .ideal{stroke:var(--rule-3)}

.anno{
  background:var(--ball-soft); border-left:2px solid var(--ball-line);
  color:var(--ink-soft);
  padding:8px 12px; border-radius:0 6px 6px 0;
  font-size:13px; line-height:1.5;
}
.anno b{color:var(--ink)}

.ic svg{width:14px; height:14px}

::-webkit-scrollbar{width:10px; height:10px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:var(--rule-2); border-radius:5px; border:2px solid var(--bg)}
::-webkit-scrollbar-thumb:hover{background:var(--rule-3)}

.card.hover, table.tf tbody tr{ transition: background .15s ease, border-color .15s ease}

.draw-in{
  stroke-dasharray: var(--len, 2000);
  stroke-dashoffset: var(--len, 2000);
  animation: drawIn 1.1s cubic-bezier(.2,.7,.2,1) .15s forwards;
}
@keyframes drawIn{ to{ stroke-dashoffset:0 } }

.fade-in{ opacity:0; animation: fadeIn .6s ease .25s forwards }
@keyframes fadeIn{ to{ opacity:1 } }


.tt{
  position:fixed; z-index:200; pointer-events:none;
  background:var(--bg-2); border:1px solid var(--rule-strong);
  padding:10px 12px; border-radius:var(--r-ctl);
  min-width:160px;
  box-shadow:var(--shadow-float);
  font-size:13px; line-height:18px;
  opacity:0; transform: translateY(2px); transition: opacity .14s, transform .14s;
}
.tt.show{ opacity:1; transform:none }
.tt .tt-h{ font-weight:600; color:var(--ink); margin-bottom:4px; font-family:var(--font-fig); font-size:13px}
.tt .tt-row{ display:flex; justify-content:space-between; gap:14px; color:var(--ink-soft)}
.tt .tt-row b{ color:var(--ink); font-family:var(--font-fig); font-variant-numeric:tabular-nums}
.tt .tt-body{ color:var(--ink-soft); max-width:280px; line-height:1.45; white-space:normal; }
.tt-arrow{
  position:absolute; bottom:-5px; left:50%; transform:translateX(-50%) rotate(45deg);
  width:8px; height:8px; background:var(--bg-2); border-right:1px solid var(--rule-strong); border-bottom:1px solid var(--rule-strong);
}

.roi-hit{ fill:transparent; cursor:crosshair }
.roi-cursor-group{ pointer-events:none; transition: transform .12s cubic-bezier(.2,.7,.2,1)}

.dot, .dot-w{ cursor:pointer; transition: r .12s ease, filter .12s ease }
.dot:hover, .dot-w:hover{ filter: drop-shadow(0 0 6px currentColor) }

table.tf tbody tr.row-active{ background:var(--blue-soft) }
table.tf tbody tr.row-hover{ background: var(--bg-2); cursor:pointer }

.swipe{ position:relative; transition: transform .25s cubic-bezier(.2,.7,.2,1), opacity .25s ease}
.swipe.leaving-left{ transform:translateX(-12px); opacity:0 }
.swipe.leaving-right{ transform:translateX(12px); opacity:0 }
.swipe.entering{ animation: swipeIn .3s cubic-bezier(.2,.7,.2,1) }
@keyframes swipeIn{ from{ opacity:0; transform:translateX(12px) } to{ opacity:1; transform:none } }

.chip{ transition: all .14s cubic-bezier(.2,.7,.2,1)}
.chip:active{ transform: translateY(1px) scale(.97) }


.roi-cursor-label{ pointer-events:none; }
.roi-cursor-label rect{ fill:var(--bg-1); stroke:var(--accent-line); }
.roi-cursor-label text{ fill:var(--accent); font-family:var(--font-fig); font-size:13px; }

button:focus-visible, .input:focus-visible, .chip:focus-visible{
  outline: 2px solid var(--focus); outline-offset:2px;
}

.scrub{ transition: color .2s ease }
.live-dot{ display:inline-block; width:6px; height:6px; border-radius:50%; background:var(--ball)}

/* Log line entries */
.log-line{ padding:2px 0; font-family:var(--font-fig); font-size:13px; white-space:pre-wrap; word-break:break-word; }
.log-line.ok{ color:var(--ok) }
.log-line.warn{ color:var(--warn) }
.log-line.err{ color:var(--bad) }
.log-line.info{ color:var(--ink-soft) }
.log-stream{ background:var(--bg); padding:14px 18px; font-family:var(--font-fig); font-size:13px; max-height:300px; overflow:auto; }

/* ── Players feature components ── */
.search-wrap{ position:relative; }
.search-wrap .search-ic{
  position:absolute; left:14px; top:50%; transform:translateY(-50%);
  color:var(--ink-faint); pointer-events:none;
}
.search-input{
  width:100%; padding:13px 14px 13px 40px;
  background:var(--bg-1); border:1px solid var(--rule); border-radius:9px;
  color:var(--ink); font-family:inherit; font-size:15px;
  transition:border-color .12s, box-shadow .12s;
}
.search-input:focus{
  outline:0; border-color:var(--accent);
  box-shadow:0 0 0 3px var(--accent-soft);
}
.search-input::placeholder{ color:var(--ink-faint); }

.star-btn{
  display:grid; place-items:center;
  width:32px; height:32px; border-radius:8px;
  flex:0 0 auto; transition:background .12s;
}
.star-btn:hover{ background:var(--bg-2); }
.star-btn svg{ width:18px; height:18px; }
.star-btn svg path{
  fill:none; stroke:var(--ink-faint); stroke-width:1.6;
  stroke-linejoin:round; transition:fill .14s, stroke .14s;
}
.star-btn.on svg path{ fill:var(--accent); stroke:var(--accent); }
.star-btn.on{ filter:drop-shadow(0 0 6px var(--accent-soft)); }
.star-btn.lg{ width:40px; height:40px; }
.star-btn.lg svg{ width:24px; height:24px; }

.player-list{ display:grid; gap:10px; grid-template-columns:repeat(auto-fill, minmax(300px, 1fr)); }
.player-row{
  display:flex; align-items:center; gap:14px;
  background:var(--bg-1); border:1px solid var(--rule);
  border-radius:10px; padding:12px 14px;
  transition:border-color .12s, transform .15s, background .12s;
}
.player-row:hover{ border-color:var(--rule-2); transform:translateY(-1px); }
.player-row .pr-avatar{
  width:38px; height:38px; border-radius:50%;
  background:linear-gradient(135deg,var(--bg-3),var(--bg-4));
  border:1px solid var(--rule-2); overflow:hidden; flex:0 0 auto;
  display:grid; place-items:center;
  font-family:var(--font-fig); font-size:14px; color:var(--ink-soft);
}
.player-row .pr-id{ min-width:0; flex:1; }
.player-row .pr-name{
  font-weight:600; font-size:15px; color:var(--ink);
  display:flex; align-items:center; gap:8px;
}
.player-row .pr-sub{
  font-size:13px; color:var(--ink-soft); margin-top:2px;
  display:flex; align-items:center; gap:8px; flex-wrap:wrap;
}
.player-row .pr-metric{ text-align:right; flex:0 0 auto; }
.player-row .pr-metric .m-val{
  font-family:var(--font-fig); font-variant-numeric:tabular-nums;
  font-size:20px; font-weight:600; color:var(--ink);
}
.player-row .pr-metric .m-val.acc{ color:var(--accent); }
.player-row .pr-metric .m-lbl{
  font-size:13px; letter-spacing:0;
  color:var(--ink-faint); margin-top:2px;
}

/* Scanner — candidate row = a player-row head + an expandable loss list. */
.scan-row{
  background:var(--bg-1); border:1px solid var(--rule); border-radius:10px;
  overflow:hidden; transition:border-color .12s;
}
.scan-row:hover{ border-color:var(--rule-2); }
.scan-row .scan-head{
  background:transparent; border:0; border-radius:0;
  padding:12px 14px;
}
.scan-row .scan-head:hover{ transform:none; }
.scan-losses{ padding:0 14px 10px 14px; }
.scan-losses summary{
  cursor:pointer; list-style:none; padding:8px 0;
  font-size:13px; letter-spacing:0;
  color:var(--ink-faint);
}
.scan-losses summary::-webkit-details-marker{ display:none; }
.scan-losses summary::before{ content:'▸ '; }
.scan-losses[open] summary::before{ content:'▾ '; }
.scan-losses[open] summary{ color:var(--ink-soft); }

.streak{ display:inline-flex; gap:3px; }
.streak i{
  width:15px; height:15px; border-radius:4px;
  display:grid; place-items:center;
  font-family:var(--font-fig); font-size:13px; font-weight:600;
  font-style:normal;
}
.streak i.w{ background:color-mix(in srgb, var(--ok) 16%, transparent); color:var(--ok); }
.streak i.l{ background:var(--bad-soft); color:var(--bad); }

.flag{
  font-family:var(--font-fig); font-size:13px;
  color:var(--ink-faint); letter-spacing:.04em;
}

.pagination{
  display:flex; align-items:center; justify-content:center; gap:4px;
  margin-top:18px;
}
.pagination button, .pagination a{
  min-width:32px; height:32px; padding:0 8px;
  border-radius:7px; border:1px solid var(--rule);
  background:var(--bg-1); color:var(--ink-soft);
  font-size:14px; font-variant-numeric:tabular-nums;
  display:inline-flex; align-items:center; justify-content:center;
  transition:all .12s;
}
.pagination button:hover:not(:disabled), .pagination a:hover{
  color:var(--ink); border-color:var(--rule-2);
}
.pagination button.on, .pagination a.on{
  background:var(--accent); color:var(--accent-fg); border-color:var(--accent);
}
.pagination button:disabled{ opacity:.35; cursor:default; }
.pagination .pg-gap{ color:var(--ink-faint); padding:0 4px; }

.player-hero{ display:flex; align-items:flex-start; gap:18px; }
.player-hero .ph-avatar{
  width:64px; height:64px; border-radius:50%;
  background:linear-gradient(135deg,var(--bg-3),var(--bg-4));
  border:1px solid var(--rule-2); overflow:hidden; flex:0 0 auto;
  display:grid; place-items:center;
  font-family:var(--font-fig); font-size:20px; color:var(--ink-soft);
}
.player-hero .ph-meta{ color:var(--ink-soft); font-size:14px; margin-top:8px;
  display:flex; gap:8px; flex-wrap:wrap; align-items:center; }

/* Bio row (sex / age / nationality) under the player name. */
.ph-bio{ display:flex; gap:8px; flex-wrap:wrap; align-items:center; margin-top:6px; }
.ph-bio span{
  font-size:13px; font-weight:500; padding:2px 9px; border-radius:999px;
  display:inline-flex; align-items:center; gap:4px; line-height:1.6;
}
.ph-bio .bio-sex.w{ background:rgba(236,72,153,.16); color:#f9a8d4; }
.ph-bio .bio-sex.m{ background:rgba(59,130,246,.16); color:#93c5fd; }
.ph-bio .bio-age{ background:var(--bg-3); color:var(--ink-soft); }
.ph-bio .bio-nat{ background:var(--bg-3); color:var(--ink-faint);
  font-family:var(--font-fig); letter-spacing:.04em;
  padding-left:4px; }
.ph-bio .bio-flag{
  width:16px; height:16px; border-radius:50%;
  object-fit:cover; flex:0 0 auto;
  border:1px solid var(--rule-2);
}

/* Total-profile flag chips (under the bio row) + hover tooltip. */
.ph-flags{ display:flex; gap:6px; flex-wrap:wrap; align-items:center; margin-top:6px; }
.ph-flags-lbl{ font-size:13px; color:var(--ink-faint);
  letter-spacing:0; margin-right:2px; }
.flag-chip{
  position:relative; font-size:13px; font-weight:500; line-height:1.6;
  padding:2px 9px; border-radius:999px; cursor:default;
  background:var(--bg-3); color:var(--ink-soft); border:1px solid var(--rule-2);
}
.flag-chip.sev-2{ border-color:var(--warn-line); color:var(--ink); background:var(--warn-soft); }
.flag-chip.sev-3{ border-color:color-mix(in srgb, var(--bad) 45%, transparent); color:var(--bad); background:color-mix(in srgb, var(--bad) 12%, transparent); }
.flag-tip{
  position:absolute; left:0; top:calc(100% + 6px); z-index:60;
  width:max-content; max-width:280px; text-align:left;
  background:var(--bg-1); border:1px solid var(--rule-3); border-radius:8px;
  padding:8px 10px; box-shadow:var(--shadow-float);
  display:flex; flex-direction:column; gap:3px;
  opacity:0; visibility:hidden; transform:translateY(-3px);
  transition:opacity .12s, transform .12s; pointer-events:none;
}
.flag-chip:hover .flag-tip, .flag-chip:focus .flag-tip, .flag-chip:focus-within .flag-tip{
  opacity:1; visibility:visible; transform:none;
}
.flag-tip-name{ font-size:13px; color:var(--ink); }
.flag-tip-desc{ font-size:13px; color:var(--ink-soft); line-height:1.45; }
.flag-tip-ev{ font-size:13px; color:var(--ink-faint); font-style:italic; line-height:1.4; }

/* Next-match card. */
.next-match .nm-meta{ font-size:13px; margin-top:-4px; margin-bottom:12px; }
.nm-players{
  display:flex; align-items:center; gap:14px;
  padding:12px 14px; background:var(--bg-2); border-radius:8px;
  border:1px solid var(--rule);
}
.nm-side{ flex:1; display:flex; flex-direction:column; gap:3px; }
.nm-side:last-of-type{ text-align:right; align-items:flex-end; }
.nm-side .nm-name{ font-size:16px; font-weight:500; }
.nm-side.win .nm-name{ color:var(--accent); }
.nm-side .nm-pick{
  font-size:13px; letter-spacing:0;
  color:var(--accent); font-family:var(--font-fig);
}
.nm-vs{ font-size:13px; color:var(--ink-faint);
  font-family:var(--font-fig); flex:0 0 auto; }
.nm-totals{ margin-top:14px; }
.nm-total-chips{ display:flex; gap:6px; flex-wrap:wrap; margin-top:6px; }
.chip-stat{
  font-size:13px; font-family:var(--font-fig);
  padding:3px 9px; border-radius:6px;
  background:var(--bg-3); color:var(--ink-soft); border:1px solid var(--rule);
}
.chip-stat.accent{ color:var(--accent); border-color:var(--accent-line); }
.nm-decision{
  display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  margin-top:12px; padding:9px 12px; border-radius:8px;
}
.nm-decision.bet{ background:color-mix(in srgb, var(--ok) 10%, transparent); border:1px solid color-mix(in srgb, var(--ok) 30%, transparent); }
.nm-decision.skip{ background:var(--bg-2); border:1px solid var(--rule); }
.nm-dec-tag{
  font-size:13px; font-weight:600; letter-spacing:.07em;
  padding:2px 8px; border-radius:4px;
  background:var(--accent); color:var(--accent-fg);
}
.nm-dec-tag.skip{ background:var(--bg-4); color:var(--ink-soft); }
.nm-dec-line{ font-size:15px; font-weight:600;
  font-family:var(--font-fig); }
.nm-dec-meta{ font-size:13px; color:var(--ink-soft);
  font-family:var(--font-fig); }
.nm-actions{ margin-top:14px; }

.form-score{ display:flex; align-items:center; gap:16px; }
.form-score .fs-num{
  font-family:var(--font-fig); font-variant-numeric:tabular-nums;
  font-size:48px; font-weight:600; line-height:1; letter-spacing:-.03em;
}
.form-score .fs-num.hot{ color:var(--accent); }
.form-score .fs-num.cold{ color:var(--warn); }
.form-bar{
  height:8px; border-radius:4px; background:var(--bg-3); overflow:hidden;
  position:relative;
}
.form-bar > i{
  position:absolute; left:0; top:0; bottom:0; border-radius:4px;
  background:linear-gradient(90deg,var(--warn),var(--accent));
}

.donut-wrap{ display:flex; align-items:center; gap:18px; }
.donut{ position:relative; width:120px; height:120px; flex:0 0 auto; }
.donut .donut-center{
  /* Flex column keeps the two lines packed in the exact middle of the
     donut. With `display:grid; place-items:center` each child became
     its own grid row and they drifted to the top/bottom of the circle. */
  position:absolute; inset:0; display:flex; flex-direction:column;
  align-items:center; justify-content:center; text-align:center; gap:3px;
}
.donut .donut-center .dc-num{
  font-family:var(--font-fig); font-size:28px; font-weight:600;
  color:var(--ink); line-height:1;
}
.donut .donut-center .dc-lbl{
  font-size:13px; letter-spacing:0;
  color:var(--ink-faint);
}

/* Inline info-icon used next to card titles (e.g. Form score). */
.info-ic{
  display:inline-grid; place-items:center;
  width:14px; height:14px; border-radius:50%;
  background:var(--bg-3); color:var(--ink-soft);
  border:1px solid var(--rule-2);
  font-family:var(--font-fig); font-size:13px; font-weight:600;
  cursor:help; transition:color .12s, border-color .12s, background .12s;
}
.info-ic:hover, .info-ic:focus-visible{
  color:var(--accent); border-color:var(--accent-line);
  background:var(--accent-soft); outline:none;
}

.agg-row{
  display:grid; grid-template-columns:78px 1fr 56px;
  align-items:center; gap:12px; padding:9px 0;
}
.agg-row + .agg-row{ border-top:1px solid var(--rule); }
.agg-row .agg-lbl{ font-size:14px; color:var(--ink-soft); }
.agg-track{ height:8px; border-radius:4px; background:var(--bg-3); overflow:hidden; }
.agg-track > i{ display:block; height:100%; border-radius:4px; background:var(--accent); }
.agg-track > i.weak{ background:var(--ok); }
.agg-track > i.strong{ background:var(--warn); }
.agg-row .agg-val{
  text-align:right; font-family:var(--font-fig);
  font-variant-numeric:tabular-nums; font-size:16px; font-weight:600; color:var(--ink);
}
/* Two-value variant: match total + individual total side by side. */
.agg-row.two-val{ grid-template-columns:78px 1fr 56px 56px; }
.agg-head{
  display:grid; grid-template-columns:78px 1fr 56px 56px;
  gap:12px; padding:0 0 4px;
}
.agg-head span{
  font-size:13px; letter-spacing:0;
  color:var(--ink-faint); text-align:right;
}
.agg-row .agg-val.ind{ color:var(--ink-soft); font-weight:500; }

/* ── Totals profile ── individual total + blowout + opponent split on two
   matched windows (all-time / recent). Columns: label · all-time · recent ·
   trend. The trend arrow is direction-only and never good/bad coloured. */
.tp-head, .tp-row{
  display:grid; grid-template-columns:1fr 78px 78px 26px;
  align-items:center; gap:10px;
}
.tp-head{ padding:0 0 5px; }
.tp-head span{
  font-size:13px; letter-spacing:0;
  color:var(--ink-faint); text-align:right;
}
.tp-head span.lbl{ text-align:left; }
.tp-row{ padding:8px 0; }
.tp-row + .tp-row{ border-top:1px solid var(--rule); }
.tp-lbl{ font-size:14px; color:var(--ink-soft); }
.tp-lbl small{ color:var(--ink-faint); font-size:13px; }
/* Two-slot cell: value | (n). The count column has a fixed width so the
   value's right edge lines up across rows even when the count is absent
   (blowout row has no count). */
.tp-val{
  display:grid; grid-template-columns:1fr 34px; align-items:baseline; gap:2px;
  font-family:var(--font-fig); font-variant-numeric:tabular-nums;
  font-size:16px; font-weight:600; color:var(--ink);
}
.tp-val.recent{ color:var(--ink-soft); }
.tp-val .v{ text-align:right; }
.tp-val .n{ color:var(--ink-faint); font-weight:400; font-size:13px; text-align:left; }
.tp-trend{ text-align:center; font-size:13px; color:var(--ink-faint); }
/* Trend-arrow colouring by direction (up = accent, down = warn, flat/na faint). */
.tp-trend.trend-up{ color:var(--accent); }
.tp-trend.trend-down{ color:var(--warn); }
.tp-trend.trend-flat, .tp-trend.trend-na{ color:var(--ink-faint); }
.tp-sub-h{
  margin-top:14px; padding-top:12px; border-top:1px solid var(--rule);
  font-size:13px; letter-spacing:0; color:var(--ink-faint);
  margin-bottom:6px;
}

/* ── Player page tabs ── the tab row reuses .tabbar with links instead of
   buttons. Result-slice rows reuse the totals-profile grid with wider cells:
   average total on top, matches and W-L underneath. */
.player-tabs a{
  padding:6px 14px; border-radius:5px; border:1px solid transparent;
  color:var(--ink-soft); font-size:13px; font-weight:500; white-space:nowrap;
  text-decoration:none; transition:all .12s;
}
.player-tabs a:hover{ color:var(--ink) }
.player-tabs a.on{ background:var(--bg-3); color:var(--ink); border-color:var(--rule-2)}
.player-tabs a:focus-visible{ outline:1px solid var(--accent); outline-offset:1px }
.tp-head.sl, .tp-row.sl{ grid-template-columns:1fr 96px 96px; }
.sl-cell{
  display:flex; flex-direction:column; align-items:flex-end;
  font-family:var(--font-fig); font-variant-numeric:tabular-nums;
}
.sl-cell .v{ font-size:16px; font-weight:600; color:var(--ink); }
.sl-cell .wl{ font-size:13px; color:var(--ink-faint); }
.ph-scroll{ overflow-x:auto; }
svg .season-avg{ stroke:var(--ink-soft); stroke-width:1.6; fill:none; stroke-linejoin:round }

/* ── Compare page: Totals-profile grid ──
   Three columns — label · player-A two-window cell · player-B two-window
   cell — repeated per metric. Reuses .tp-val / .tp-lbl from the player
   page so the rows look like the same component. Deliberately neutral:
   no winner colour, because ind_total and blowout-% point in opposite
   directions for under bets. */
.ctp-grid{
  display:grid; grid-template-columns:1fr 2fr 2fr; gap:0 16px;
}
.ctp-h{
  padding:0 0 4px; font-size:13px; letter-spacing:0; color:var(--ink-faint);
}
.ctp-h.ctp-side{ text-align:center; font-weight:600; color:var(--ink-soft); }
.ctp-sub-h{
  display:grid; grid-template-columns:1fr 1fr; gap:12px;
  padding:0 0 6px; font-size:13px; letter-spacing:0; color:var(--ink-faint);
}
.ctp-sub-h span{ text-align:right; }
.ctp-row{
  padding:9px 0; border-top:1px solid var(--rule);
  display:flex; align-items:center;
}
.ctp-row.ctp-lbl{ justify-content:flex-start; }
.ctp-row.ctp-cells{
  display:grid; grid-template-columns:1fr 1fr; gap:12px;
}

.empty{
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  min-height:144px; padding:24px 20px; text-align:center;
  border:1px dashed var(--rule-strong); border-radius:var(--r-card);
  color:var(--ink-soft);
}
.empty .empty-ic{ width:40px; height:40px; margin:0 auto 12px; color:var(--ink-mute); }

/* ── Compare page ──────────────────────────────────────────────────────── */
.ph-avatar{
  width:64px; height:64px; border-radius:50%;
  background:linear-gradient(135deg,var(--bg-3),var(--bg-4));
  border:1px solid var(--rule-2); overflow:hidden; flex:0 0 auto;
  display:grid; place-items:center;
  font-family:var(--font-fig); font-size:20px; color:var(--ink-soft);
}
.ph-avatar.sm{ width:42px; height:42px; font-size:15px; }

/* Header — both players centred and flanking the VS chip. */
.cmp-versus{
  display:flex; align-items:center; justify-content:center; gap:22px;
  flex-wrap:wrap;
}
.cmp-head{ display:flex; align-items:center; gap:12px; min-width:0; }
.cmp-head.b{ flex-direction:row-reverse; text-align:right; }
.cmp-head-txt{ min-width:0; }
.cmp-name{ font-weight:600; font-size:17px; color:var(--ink); }
.cmp-head .ph-meta{ display:flex; gap:6px; flex-wrap:wrap; margin-top:5px; }
.cmp-head.b .ph-meta{ justify-content:flex-end; }
.cmp-vs{
  font-family:var(--font-fig); font-size:13px; font-weight:600;
  letter-spacing:.12em; color:var(--ink-faint);
  padding:6px 9px; border:1px solid var(--rule-2); border-radius:999px;
  flex:0 0 auto;
}

/* Metrics — mirrored comparison bars growing outward from the centre. */
.cmp-metric{ padding:9px 0; }
.cmp-metric + .cmp-metric{ border-top:1px solid var(--rule); }
.cmp-mlabel{
  text-align:center; font-size:13px; letter-spacing:0; color:var(--ink-faint); margin-bottom:7px;
}
.cmp-bars{ display:flex; align-items:center; }
.cmp-side{
  flex:1 1 0; min-width:0;
  display:flex; align-items:center; gap:9px;
}
.cmp-side.a{ justify-content:flex-end; }
.cmp-side.b{ justify-content:flex-start; }
.cmp-fill{
  height:9px; border-radius:5px; min-width:2px;
  background:var(--accent); transition:width .35s cubic-bezier(.2,.7,.2,1);
}
.cmp-fill.is-better{ background:var(--ok); }
.cmp-fill.is-worse{ background:var(--bad); }
.cmp-fill.is-form{ background:var(--accent); opacity:.7; }
.cmp-bval{
  flex:0 0 auto;
  font-family:var(--font-fig); font-variant-numeric:tabular-nums;
  font-size:16px; font-weight:600; color:var(--ink); white-space:nowrap;
}
.cmp-bval.is-better{ color:var(--ok); }
.cmp-bval.is-worse{ color:var(--bad); }

.cmp-sub{
  margin-top:10px; padding-top:12px; border-top:1px solid var(--rule);
  font-size:13px; letter-spacing:0;
  color:var(--ink-mute); text-align:center;
}
.cmp-sub + .cmp-metric{ border-top:0; }

.cmp-form{ font-size:22px; line-height:1; }
.form-arrow{ font-size:13px; line-height:1; }
.form-arrow.up{ color:var(--ok); }
.form-arrow.down{ color:var(--bad); }
.form-arrow.flat, .form-arrow.na{ color:var(--ink-mute); }

.cmp-charts{ display:grid; grid-template-columns:1fr 1fr; gap:18px; align-items:start; }
.cmp-chart-lbl{
  font-size:13px; font-weight:500; color:var(--ink-soft); margin-bottom:4px;
}
.cmp-chart-lbl.right{ text-align:right; }

/* Common-opponents — 2-column grid of compact cards. Each card names
   the opponent, then splits into A/B halves with the player's surname
   labelling whose record it is. */
.cmp-common{
  display:grid; grid-template-columns:1fr 1fr; gap:10px;
}
.co-card{
  background:var(--bg-2); border:1px solid var(--rule);
  border-radius:8px; padding:10px 12px;
}
.co-card .co-opp{
  display:block; font-size:14px; font-weight:500; margin-bottom:8px;
}
.co-split{
  display:grid; grid-template-columns:1fr 1fr; gap:8px;
}
.co-side{
  display:flex; flex-direction:column; gap:2px;
  padding:6px 8px; background:var(--bg-3); border-radius:6px;
}
.co-side.b{ text-align:right; align-items:flex-end; }
.co-who{
  font-size:13px; letter-spacing:0;
  color:var(--ink-faint); font-weight:600; margin-bottom:2px;
}
.co-rec{ font-size:14px; font-weight:500;
  font-family:var(--font-fig); }
.co-tot{ font-size:13px; color:var(--ink-faint);
  font-family:var(--font-fig); }
@media (max-width:680px){
  .cmp-common{ grid-template-columns:1fr; }
}

/* ── Match analysis ── */
.am-players{ align-items:start; }
.am-sec{ margin-top:18px; }
.am-sec h4{ font-size:13px; font-weight:600; color:var(--ink-soft); margin-bottom:8px; }
.am-note{ font-size:13px; color:var(--ink-faint); line-height:1.5; }
.am-note b{ color:var(--ink); font-weight:600; }
details > summary.am-note{ cursor:pointer; }
table.tf.am-win th, table.tf.am-win td{ padding:7px 8px; }
.am-chart{ display:block; width:100%; height:140px;
  background:var(--bg-2); border:1px solid var(--rule); border-radius:8px; }
.am-chart .am-mid{ stroke:var(--rule-2); stroke-width:1; stroke-dasharray:2 4; }
.am-chart .am-form{ fill:none; stroke:var(--accent-ink); stroke-width:2;
  stroke-linejoin:round; vector-effect:non-scaling-stroke; }
.am-chart .am-elo{ fill:none; stroke:var(--ink-faint); stroke-width:1.2;
  stroke-dasharray:5 4; vector-effect:non-scaling-stroke; }
.am-legend{ display:flex; justify-content:space-between; gap:10px; margin-top:6px;
  font-family:var(--font-fig); font-size:13px; color:var(--ink-faint); }
.am-key{ display:inline-block; width:14px; height:0; margin-right:5px; vertical-align:middle; }
.am-key.form{ border-top:2px solid var(--accent-ink); }
.am-key.elo{ border-top:1.5px dashed var(--ink-faint); }

/* ══ Back office: group billing ══════════════════════════════════════
   These screens are about money counted in flats. Hence the rules:
   numbers are monospaced and tabular, labels 10px uppercase, and colour
   carries exactly one meaning (--ok earned, --bad minus, --accent due).
   Nothing else is coloured. */

/* ── Switch. A bare checkbox was the one thing on these pages that
   broke the theme. ─────────────────────────────────────────────── */
.switch{ position:relative; display:inline-block; width:40px; height:24px; flex:0 0 auto }
.switch input{
  position:absolute; inset:0; width:100%; height:100%;
  margin:0; opacity:0; cursor:pointer; z-index:2;
}
.switch .track{
  position:absolute; inset:0; border-radius:12px;
  background:var(--chip); border:0;
  transition: background .15s ease;
}
.switch .knob{
  position:absolute; top:2px; left:2px; width:20px; height:20px;
  border-radius:50%; background:var(--bg-1); box-shadow:0 0 0 1px var(--rule-strong);
  transition: left .15s cubic-bezier(.2,.7,.2,1);
}
.switch input:checked ~ .track{ background:var(--brand) }
.switch input:checked ~ .knob{ left:18px; box-shadow:none }
.switch input:disabled{ cursor:not-allowed }
.switch input:disabled ~ .track,
.switch input:disabled ~ .knob{ opacity:.4 }
.switch input:focus-visible ~ .track{ outline:2px solid var(--focus); outline-offset:2px }

.switch-row{
  display:flex; align-items:center; gap:14px;
  padding:11px 0; border-bottom:1px solid var(--rule);
}
.switch-row:last-child{ border-bottom:0 }
.switch-row .sr-body{ flex:1; min-width:0 }
.switch-row .sr-name{ display:block; font-size:14px; color:var(--ink) }
.switch-row .sr-hint{ display:block; font-size:13px; color:var(--ink-faint); margin-top:2px }
.switch-row.off .sr-name{ color:var(--ink-soft) }

/* ── Days of the week switched off for a group. ─────────────────────
   Seven chips instead of seven switches. A checked chip means the day
   is OFF, so its active state is red, not the accent: it is a ban. */
.day-chips{ display:flex; flex-wrap:wrap; gap:6px; padding:11px 0 }
.day-chip{ position:relative; cursor:pointer; user-select:none }
.day-chip input{ position:absolute; opacity:0; width:0; height:0 }
.day-chip span{
  display:block; min-width:38px; text-align:center;
  padding:6px 8px; border:1px solid var(--rule); border-radius:8px;
  font-size:13px; color:var(--ink-soft); background:transparent;
}
.day-chip input:checked ~ span{
  border-color:var(--bad); color:var(--bad);
  background:color-mix(in srgb, var(--bad) 12%, transparent);
}
.day-chip input:focus-visible ~ span{ outline:2px solid var(--accent); outline-offset:2px }

/* ── Grids: two columns on a desktop, one on a phone. ───────────────
   auto-fit, not auto-fill: with fewer items than columns the empty
   tracks collapse and the content takes the full width. */
.grid-auto{ display:grid; gap:16px; grid-template-columns:repeat(auto-fit, minmax(340px, 1fr)) }
.grid-tiles{ display:grid; gap:12px; grid-template-columns:repeat(auto-fit, minmax(210px, 1fr)) }

/* ── Money tile: period, units, books. ────────────────────────────── */
.mtile{ padding:14px 16px }
.mtile .stat-num{ font-size:28px }
.mtile .stat-num.up{ color:var(--ok) }
.mtile .stat-num.down{ color:var(--bad) }
.mtile-sub{
  font-family:var(--font-fig); font-size:13px;
  color:var(--ink-soft); margin-top:6px; font-variant-numeric:tabular-nums;
}
.mtile-books{ margin-top:10px; padding-top:10px; border-top:1px solid var(--rule) }
.book-row{
  display:flex; align-items:baseline; justify-content:space-between; gap:8px;
  font-family:var(--font-fig); font-size:13px;
  color:var(--ink-faint); padding:2px 0; font-variant-numeric:tabular-nums;
}
.book-row b{ color:var(--ink-soft); font-weight:500 }

/* ── Row tile: label and number on one line, for secondary figures. */
.mtile.row-tile{ padding:12px 16px }
.mtile.row-tile .rt-head{
  display:flex; align-items:baseline; justify-content:space-between; gap:12px;
}
.mtile.row-tile .stat-num{ font-size:20px }
.mtile.row-tile .mtile-sub{ margin-top:6px }

/* ── Paging under a table. ───────────────────────────────────────── */
.pager{
  display:flex; align-items:center; justify-content:flex-end; gap:12px;
  margin-top:14px;
}
.pager-at{
  font-family:var(--font-fig); font-size:13px;
  color:var(--ink-faint); font-variant-numeric:tabular-nums;
}

/* ── Taken bets by day: the switcher, the summary, the bet row. ──── */
.bets-nav{ display:flex; align-items:center; gap:6px }
.bets-nav .input{ width:auto; min-width:170px; padding-top:5px; padding-bottom:5px }
.bets-nav .btn{ min-width:30px; text-align:center }
.bets-sum{
  display:flex; flex-wrap:wrap; gap:4px 16px; margin-top:12px;
  font-family:var(--font-fig); font-size:13px;
  color:var(--ink-soft); font-variant-numeric:tabular-nums;
}
/* An empty day has no summary, and no gap for one. */
.bets-sum:empty{ display:none }
.bets-sum .up{ color:var(--ok) }
.bets-sum .down{ color:var(--bad) }
.bet-pick, .bet-out{
  display:flex; flex-direction:column; align-items:flex-end; gap:2px;
  flex:0 0 auto; font-family:var(--font-fig);
  font-variant-numeric:tabular-nums;
}
.bet-pick{ min-width:74px }
.bet-out{ min-width:88px }
.bet-side{ font-size:14px; font-weight:600; color:var(--ink) }
.bet-odds, .bet-score{ font-size:13px; color:var(--ink-faint) }
.bet-profit{ font-size:14px; font-weight:600; color:var(--ink-soft) }
.bet-profit.up{ color:var(--ok) }
.bet-profit.down{ color:var(--bad) }
.bet-profit.mute{ font-size:13px; font-weight:400; color:var(--ink-mute) }


/* ── Period strip: the whole arithmetic on one line. ─────────────── */
.pstrip{ display:flex; align-items:flex-end; flex-wrap:wrap; gap:4px 10px; margin-top:16px }
.pstrip-cell{ display:flex; flex-direction:column; gap:4px; min-width:74px }
.pstrip-cell .label{ margin:0 }
.pstrip-val{
  font-family:var(--font-fig); font-variant-numeric:tabular-nums;
  font-size:16px; font-weight:600; color:var(--ink);
}
.pstrip-val.up{ color:var(--ok) }
.pstrip-val.down{ color:var(--bad) }
.pstrip-val.due{ color:var(--accent-ink) }
.pstrip-op{
  font-family:var(--font-fig); font-size:14px;
  color:var(--ink-mute); padding-bottom:2px;
}
.pstrip-bar{
  display:flex; width:100%; height:6px; border-radius:3px;
  background:var(--bg-3); overflow:hidden; margin-top:14px;
}
.pstrip-seg{ height:100% }
.pstrip-seg.paid{ background:var(--ok) }
.pstrip-seg.carried{ background:var(--ink-mute) }
.pstrip-seg.written{
  background:repeating-linear-gradient(45deg, var(--rule-3) 0 4px, var(--bg-3) 4px 8px);
}
.pstrip-seg.rest{ background:var(--accent) }
.pstrip-legend{
  display:flex; flex-wrap:wrap; gap:4px 14px; margin-top:8px;
  font-family:var(--font-fig); font-size:13px; color:var(--ink-faint);
  font-variant-numeric:tabular-nums;
}

/* ── List row: title, meta, action on the right. ─────────────────── */
.lrow{
  display:flex; align-items:center; gap:12px;
  padding:10px 12px; border:1px solid var(--rule); border-radius:8px;
  background:var(--bg-1); transition:border-color .12s ease;
}
.lrow:hover{ border-color:var(--rule-2) }
.lrow .lrow-body{ flex:1; min-width:0 }
.lrow .lrow-name{ font-size:14px; color:var(--ink) }
.lrow .lrow-meta{
  font-family:var(--font-fig); font-size:13px;
  color:var(--ink-faint); margin-top:2px;
}
.lrow .lrow-actions{ display:flex; gap:6px; flex:0 0 auto; align-items:center }

/* ── Notices bell. ───────────────────────────────────────────────── */
.bell{ position:relative; flex:0 0 auto }
.bell-dot{
  position:absolute; top:4px; right:4px; width:7px; height:7px;
  border-radius:50%; background:var(--accent);
  border:1.5px solid var(--bg-1); pointer-events:none;
}
/* fixed, not absolute, so no panel's overflow clips it. JS places it from
   the button; the values below are the fallback. */
.notif-pop{
  position:fixed; bottom:64px; left:12px; z-index:60;
  width:320px; max-height:60vh; overflow:auto;
  background:var(--bg-2); border:1px solid var(--rule-strong); border-radius:var(--r-card);
  box-shadow:var(--shadow-float); padding:6px;
}
.notif-pop[hidden]{ display:none }
.notif-head{
  display:flex; align-items:center; justify-content:space-between; gap:8px;
  padding:8px 8px 10px; border-bottom:1px solid var(--rule);
}
.notif-item{
  display:block; padding:10px 8px; border-radius:7px;
  border-bottom:1px solid var(--rule); color:inherit;
}
.notif-item:last-child{ border-bottom:0 }
.notif-item:hover{ background:var(--bg-3) }
.notif-item .ni-title{ font-size:13px; color:var(--ink-soft) }
.notif-item.unread .ni-title{ color:var(--ink); font-weight:500 }
.notif-item .ni-body{
  font-family:var(--font-fig); font-size:13px;
  color:var(--ink-faint); margin-top:3px; font-variant-numeric:tabular-nums;
}
.notif-item .ni-when{ font-size:13px; color:var(--ink-mute); margin-top:4px }
.notif-empty{ padding:20px 12px; text-align:center; font-size:13px; color:var(--ink-faint) }

/* ── Bet breakdown: a sheet sliding in from the right. ─────────────
   Not a centred modal: the breakdown is a long column of facts, and
   the row it was opened from should stay visible. */
.sheet-back{
  position:fixed; inset:0; z-index:120; background:rgba(0,0,0,.5);
  opacity:0; pointer-events:none; transition:opacity .18s ease;
}
.sheet-back.open{ opacity:1; pointer-events:auto }
.sheet{
  position:fixed; top:0; right:0; bottom:0; z-index:121; width:min(560px,100%);
  background:var(--bg-1); border-left:1px solid var(--rule-2);
  box-shadow:var(--shadow-float);
  display:flex; flex-direction:column;
  transform:translateX(100%); transition:transform .2s cubic-bezier(.2,.7,.2,1);
}
.sheet.open{ transform:none }
.sheet-head{
  display:flex; align-items:flex-start; justify-content:space-between; gap:12px;
  padding:16px 18px; border-bottom:1px solid var(--rule);
}
.sheet-title{ font-size:16px; color:var(--ink); line-height:1.35 }
.sheet-sub{
  font-family:var(--font-fig); font-size:13px;
  color:var(--ink-faint); margin-top:4px;
}
.sheet-body{ flex:1; overflow-y:auto; padding:18px; display:flex;
  flex-direction:column; gap:18px }
.sheet-x{
  flex:0 0 auto; width:28px; height:28px; border-radius:7px; line-height:1;
  border:1px solid var(--rule); background:var(--bg-2); color:var(--ink-soft);
  cursor:pointer;
}
.sheet-x:hover{ background:var(--bg-3); color:var(--ink) }

/* Metric-value pairs inside the breakdown. */
.facts{ display:grid; grid-template-columns:repeat(auto-fit,minmax(150px,1fr));
  gap:10px }
.fact{
  border:1px solid var(--rule); border-radius:8px; padding:9px 11px;
  background:var(--bg-2);
}
.fact .fact-k{ font-size:13px; letter-spacing:0;
  color:var(--ink-faint) }
.fact .fact-v{
  font-family:var(--font-fig); font-size:15px; color:var(--ink);
  margin-top:4px; font-variant-numeric:tabular-nums;
}
.fact .fact-v.up{ color:var(--ok) } .fact .fact-v.down{ color:var(--bad) }
.fact .fact-v.mute{ color:var(--ink-faint) }

/* ── Providers: the match and a column per book. ─────────────────── */
.pv-row{
  display:grid; grid-template-columns:minmax(220px,1.3fr) repeat(2,minmax(190px,1fr));
  gap:10px; align-items:stretch;
  padding:10px; border:1px solid var(--rule); border-radius:10px;
  background:var(--bg-1);
}
.pv-row:hover{ border-color:var(--rule-2) }
.pv-head{ min-width:0; display:flex; flex-direction:column; justify-content:center }
.pv-names{ font-size:14px; color:var(--ink); line-height:1.35 }
.pv-meta{
  font-family:var(--font-fig); font-size:13px; color:var(--ink-faint);
  margin-top:3px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.pv-cell{
  border:1px solid var(--rule); border-radius:8px; background:var(--bg-2);
  padding:8px 10px; display:flex; flex-direction:column; gap:6px; min-width:0;
}
.pv-cell.empty-cell{ background:transparent; border-style:dashed }
.pv-sig{
  width:100%; text-align:left; cursor:pointer; border:0; background:transparent;
  padding:3px 4px; border-radius:6px; color:inherit;
  display:flex; align-items:baseline; gap:8px; flex-wrap:wrap;
}
.pv-sig:hover{ background:var(--bg-3) }
.pv-side{
  font-size:13px; letter-spacing:0;
  color:var(--ink-faint);
}
.pv-side.bet{ color:var(--accent-ink) }
.pv-line{
  font-family:var(--font-fig); font-size:15px; color:var(--ink);
  font-variant-numeric:tabular-nums;
}
.pv-odds{ font-family:var(--font-fig); font-size:13px;
  color:var(--ink-soft) }
.pv-p{ font-family:var(--font-fig); font-size:13px;
  color:var(--ink-faint); margin-left:auto }
.pv-branch{
  font-size:13px; color:var(--ink-mute); letter-spacing:.03em;
}
.pv-taken{ display:flex; gap:5px; flex-wrap:wrap; margin-top:2px }
.pv-none{ font-size:13px; color:var(--ink-mute); padding:3px 4px }
.pv-cols{
  display:grid; grid-template-columns:minmax(220px,1.3fr) repeat(2,minmax(190px,1fr));
  gap:10px; padding:0 10px 4px;
}
.pv-cols span{
  font-size:13px; letter-spacing:0;
  color:var(--ink-faint);
}

/* A book's line ladder inside the breakdown. */
.ladder{ width:100%; border-collapse:collapse; font-size:13px }
.ladder th, .ladder td{
  padding:5px 8px; border-bottom:1px solid var(--rule); text-align:right;
  font-family:var(--font-fig); font-variant-numeric:tabular-nums;
}
.ladder th{
  text-align:right; font-family:inherit; font-size:13px; color:var(--ink-faint); letter-spacing:0;
}
.ladder th:first-child, .ladder td:first-child{ text-align:left }
.ladder tr.closed td{ color:var(--ink-mute) }
.ladder tr.hit td{ background:var(--accent-soft) }

/* ── Branch settings. ────────────────────────────────────────────── */
.bset{ display:flex; flex-direction:column; gap:2px }
.bset-row{
  display:flex; align-items:center; gap:12px; padding:9px 2px;
  border-bottom:1px solid var(--rule);
}
.bset-row:last-child{ border-bottom:0 }
.bset-row.off .bset-name{ color:var(--ink-faint) }
.bset-body{ flex:1; min-width:0 }
.bset-name{ font-size:14px; color:var(--ink) }
.bset-hint{ font-size:13px; color:var(--ink-faint); margin-top:2px;
  line-height:1.45 }
.bset-ctl{ flex:0 0 auto; display:flex; align-items:center; gap:8px }
.bset-ctl .input{ width:96px; text-align:right }
.bset-wide{ flex-direction:column; align-items:stretch; gap:8px }
.bset-wide .bset-ctl{ flex-wrap:wrap }
.bset-off{
  font-size:13px; color:var(--ink-mute); border:1px dashed var(--rule-2);
  border-radius:6px; padding:4px 8px;
}
.bset-shared{
  font-size:13px; letter-spacing:0;
  color:var(--ink-mute); border:1px solid var(--rule); border-radius:5px;
  padding:2px 5px;
}
.bset-card.shadow{ border-style:dashed }
.bset-note{ font-size:13px; color:var(--ink-faint); line-height:1.5 }
/* Line -> own threshold grid. An empty cell is the base threshold. */
.bset-grid{ display:flex; flex-wrap:wrap; gap:6px }
.bset-cell{ display:flex; flex-direction:column; gap:3px; width:64px }
.bset-cell span{ font-size:13px; color:var(--ink-mute); text-align:center }
.bset-ctl .bset-cell .input{ width:64px; text-align:center; padding:4px 2px }
.bset-cell .input.set{ border-color:var(--accent); color:var(--ink) }
/* A line outside the band stays visible while it has a threshold. */
.bset-cell.out span{ color:var(--ink-faint) }
.bset-cell.out .input{ border-style:dashed }

/* Change log: one row per version. */
.vlog-item{
  display:flex; gap:12px; padding:9px 2px; border-bottom:1px solid var(--rule);
}
.vlog-item:last-child{ border-bottom:0 }
.vlog-v{
  font-family:var(--font-fig); font-size:13px; color:var(--accent-ink);
  flex:0 0 auto; width:46px;
}
.vlog-body{ flex:1; min-width:0 }
.vlog-change{
  font-family:var(--font-fig); font-size:13px; color:var(--ink-soft);
  line-height:1.6;
}
.vlog-when{ font-size:13px; color:var(--ink-mute); margin-top:3px }
.vlog-arrow{ color:var(--ink-mute); margin:0 4px }

/* Toast with the result of an edit. */
.toast{
  position:fixed; left:50%; bottom:24px; transform:translateX(-50%) translateY(8px);
  z-index:300; background:var(--bg-3); border:1px solid var(--rule-2);
  border-radius:9px; padding:9px 14px; font-size:13px; color:var(--ink);
  box-shadow:var(--shadow-float); opacity:0; pointer-events:none;
  transition:opacity .16s ease, transform .16s ease;
}
.toast.on{ opacity:1; transform:translateX(-50%) }

/* Analytics · history tab. */
.hist-note{ font-size:13px; color:var(--ink-faint); max-width:72ch }
.hist-pane{ min-width:0 }
.hist-pane-h{ margin-bottom:8px }
.hist-empty{ font-size:14px; padding:18px 0 }
.hist-legend{ font-size:13px; color:var(--ink-soft); margin:6px 0 8px; text-align:center }
.hist-foot{ font-size:13px; color:var(--ink-faint); margin-top:6px; max-width:72ch }
.hist-scroll{ overflow-x:auto }
.hist-svg{ display:block }
.hist-stack{ display:block; min-width:80px; border-radius:2px }
table.tf.hist-tbl th, table.tf.hist-tbl td{ padding:6px 8px }
table.tf.hist-tbl tr.hist-sep td{ border-top:1px solid var(--rule-2) }
.hist-rate{ display:grid; grid-template-columns:minmax(50px,1fr) 38px; gap:8px; align-items:center }
.hist-rate .num{ text-align:right }
.hist-sw{ display:inline-block; width:9px; height:9px; border-radius:2px; margin:0 5px 0 10px; vertical-align:-1px }
.hist-sw:first-child{ margin-left:0 }
.hist-sw-avg, svg .hist-bar{ background:var(--bg-4); fill:var(--bg-4) }
.hist-sw-cur{ background:var(--accent) }
.hist-sw-blow, svg .hist-bar.blow{ background:var(--accent); fill:var(--accent) }
.surf-hard{ background:var(--ink-soft); fill:var(--ink-soft) }
.surf-clay{ background:var(--warn); fill:var(--warn) }
.surf-grass{ background:var(--ok); fill:var(--ok) }
.surf-carpet{ background:var(--ink-faint); fill:var(--ink-faint) }
.surf-other{ background:var(--ink-mute); fill:var(--ink-mute) }
.hist-more summary{ cursor:pointer; font-size:13px; color:var(--ink-faint); padding:6px 0 }
.hist-more[open] summary{ color:var(--ink-soft) }

/* Analytics · match page. */
.am-rank{ font-family:var(--font-fig); font-size:13px; font-weight:500;
  color:var(--ink-faint); white-space:nowrap; vertical-align:middle; }
h1 .am-rank{ font-size:14px; cursor:help; }
.am-opp-rank{ font-size:13px; white-space:nowrap; }
.am-co-h{ display:flex; align-items:baseline; justify-content:space-between; gap:8px; margin-bottom:8px; }
.am-co-h .co-opp{ margin-bottom:0; min-width:0; }
/* uniform chart scale: height from the viewBox, not fixed */
.am-chart{ height:auto; aspect-ratio:440 / 150; }
.am-chart:focus{ outline:none; }
.am-chart:focus-visible{ outline:1px solid var(--rule-2); }
.am-chart .am-elo-dot{ fill:var(--ink-faint); }
.am-chart .axis-l{ font-size:13px; }
.am-list .pagination{ margin-top:10px; }

/* Analytics · day cards. */
.ac-toolbar{ display:flex; flex-wrap:wrap; align-items:center; gap:8px 12px }
.ac-toolbar .input{ flex:1 1 260px }
.mc-linestrip.ac-linestrip{ grid-template-columns:1fr 1fr }
.mc-lc.ac-take.bet{ background:var(--accent-soft) }
.mc-lc.ac-take.bet .mc-lc-lbl,
.mc-lc.ac-take.bet .mc-lc-v{ color:var(--accent-ink) }
.mc-lc.ac-take:not(.bet) .mc-lc-v{ color:var(--ink-mute) }
.ac-form{ display:inline-flex; gap:3px; margin-left:10px; vertical-align:1px }
.ac-fd{ display:inline-block; width:7px; height:7px; border-radius:50%; cursor:default }
.ac-fd.w{ background:var(--ok) }
.ac-fd.l{ background:var(--bad) }
.ac-rookie{ margin-left:6px; vertical-align:1px }

/* Analytics · history tab: panel alignment and slices. */
/* The two panels are rows of one grid (subgrid), so their parts line up. */
.hist-grid{ display:grid; grid-template-columns:repeat(2, minmax(0, 1fr)); column-gap:24px; row-gap:0; align-items:start }
.hist-grid > .hist-pane{ display:grid; grid-row:span var(--hist-rows, 1); grid-template-rows:subgrid; align-content:start }
.hist-grid > .hist-pane > *{ min-width:0 }
.hist-sum{ color:var(--ink-faint) }
.hist-slices{ margin-top:16px; padding-top:14px; border-top:1px solid var(--rule) }
.hist-slices-h{ gap:12px; flex-wrap:wrap; margin-bottom:12px }
.hist-slice-h{ font-weight:600; margin-bottom:10px }
.hist-cell{ min-width:0 }
.hist-cell-h{ margin-bottom:6px }

/* Notices bell: the unread count on the bell (partials/bell.html). */
.bell .bell-count{
  position:absolute; top:-5px; right:-6px; min-width:18px; height:18px;
  padding:0 5px; border-radius:9px; background:var(--accent); color:var(--accent-fg);
  font:600 13px/18px var(--font-fig); text-align:center;
  border:1.5px solid var(--top); pointer-events:none;
}

/* Groups · group page: the ledger's weeks, forms and hints. */
.gp-hint{ font-size:13px; color:var(--ink-faint) }
.gp-form{ display:flex; flex-direction:column; gap:12px }
.gp-week{ padding:14px 16px; border:1px solid var(--rule); border-radius:8px; background:var(--bg-1) }
.gp-week-name{ font-size:15px; font-weight:600; letter-spacing:-.01em }
.gp-week .pstrip{ margin-top:12px }
.gp-more summary{ cursor:pointer; font-size:13px; color:var(--ink-soft) }
.gp-line{ font-size:13px; color:var(--ink-soft) }
.gp-cancelled .lrow-name{ color:var(--ink-faint); text-decoration:line-through }
.gp-acts{ display:flex; flex-wrap:wrap; gap:8px; align-items:flex-start }
.gp-act summary{ list-style:none; cursor:pointer; display:inline-block }
.gp-act summary::-webkit-details-marker{ display:none }
.gp-act[open]{ flex-basis:100%; padding:12px; border:1px dashed var(--rule-2); border-radius:8px }
.gp-act[open] summary{ margin-bottom:12px }
.gp-preview{ padding-top:14px; border-top:1px solid var(--rule) }
table.tf.gp-stats tr.gp-stats-group td{ font-weight:600; border-bottom:1px solid var(--rule-2) }
table.tf.gp-stats td.up{ color:var(--ok) }
table.tf.gp-stats td.down{ color:var(--bad) }

/* «Сегодня», «Ставки» and the bet page. */
.bj-scroll{ overflow-x:auto }
.bj-players .link{ white-space:nowrap }
.bj-vs{ color:var(--ink-faint) }
.bj-profit.up{ color:var(--ok) }
.bj-profit.down{ color:var(--bad) }
.bj-profit.mute{ color:var(--ink-faint) }
table.tf tr.bj-excluded td{ color:var(--ink-soft) }
table.tf tr.bj-reject td{ color:var(--ink-soft); border-bottom-style:dashed; font-style:italic }
table.tf tr.bj-reject .tag, table.tf tr.bj-reject .link{ font-style:normal }
.bj-reason{ color:var(--ink) }
.bj-edge{ color:var(--ink-faint); margin-left:6px }
.bj-sum .stat-num{ min-width:90px }
.td-sections{ width:100%; border-collapse:collapse; font-size:13px }
.td-sections td{ padding:3px 0 }
.td-sections td.r{ text-align:right; padding-left:10px }
.td-faint, .bp-faint{ color:var(--ink-soft) }
.td-upcoming{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:8px }
.td-upcoming li{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; font-size:14px; padding-bottom:8px; border-bottom:1px solid var(--rule) }
.td-upcoming li:last-child{ border-bottom:0; padding-bottom:0 }
.td-time{ min-width:44px }
.bp-kv{ display:grid; grid-template-columns:minmax(120px, max-content) minmax(0,1fr); gap:8px 16px; margin:0; font-size:14px; line-height:20px }
.bp-kv dt{ color:var(--ink-faint); white-space:nowrap }
.bp-kv dd{ margin:0; min-width:0 }
.bp-list{ margin:0; padding-left:18px; display:flex; flex-direction:column; gap:4px }
@media (max-width:760px){ .bp-kv{ grid-template-columns:1fr; gap:2px } .bp-kv dd{ margin-bottom:6px } }


/* ══ Istrena look v2 (docs/ISTRENA_DESIGN.md §4 to §6) ══════════════ */

/* ── The hero (docs/ISTRENA_DESIGN.md §6): the page's figures on the navy
   top, full width, in thin lines only. 20 px above, 56 px below, and the
   paper covers the last 24 px: 20 + 184 + 56 = 260. A 440 px text column
   beside the cells; under 1600 px the text stacks above them. ── */
.hero{
  position:relative; overflow:hidden;
  color:var(--top-ink); /* on .app's navy and glow, which run on under it */
  padding:20px var(--edge) 56px;
  display:grid; grid-template-columns:440px minmax(0, 1fr); gap:32px;
}
.hero-text{
  position:relative; z-index:1; min-width:0;
  display:flex; flex-direction:column; justify-content:flex-end;
  padding-bottom:4px;
}
.hero h1{ color:var(--top-ink) }
.hero-meta{ margin:8px 0 0; color:var(--top-soft); font-size:15px; line-height:22px }
.hero-meta .mono{ color:var(--top-ink) }
.hero-back{
  display:inline-flex; align-items:center; gap:6px; width:max-content;
  margin-bottom:10px; color:var(--top-soft); font-size:14px; line-height:20px;
}
.hero-back:hover{ color:var(--top-ink) }
.hero-back:focus-visible{ outline:2px solid var(--focus); outline-offset:2px; border-radius:6px }
.hero-figs{ position:relative; z-index:1; min-width:0 }
/* «Сегодня» only: the day of the month, outlined, behind the title. */
.hero-ghost{
  position:absolute; left:16px; top:-72px; z-index:0;
  font-family:var(--font-fig); font-size:420px; line-height:1; font-weight:600;
  color:transparent; -webkit-text-stroke:2px rgba(255,255,255,.075);
  pointer-events:none; user-select:none;
}
@media (max-width:1599px){
  .hero{ grid-template-columns:minmax(0, 1fr); gap:20px; padding:20px 24px 56px }
}

/* ── «Сегодня»'s hero (partials/today_hero.html): 380 px, the 440 px text
   column (the date, the day's profit, one line, three 64 px tiles) beside
   the day's running profit. The ghost «27» sits behind the figure. ── */
.hero.hero-today{
  height:380px; padding:20px var(--edge) 56px;
  grid-template-columns:440px minmax(0, 1fr); gap:32px;
}
.hero-today .hero-ghost{
  left:calc(var(--edge) + 178px); top:-34px; font-size:420px; line-height:420px; font-weight:700;
  letter-spacing:-.02em;
}
.ht-text{ position:relative; z-index:1; min-width:0; display:flex; flex-direction:column }
.hero-today h1{ margin:0; font-size:30px; line-height:38px; font-weight:600 }
.hero-today .hero-meta{ margin:4px 0 0; font-size:14px; line-height:20px }
.ht-figs{ flex:1 1 auto; min-height:0; display:flex; flex-direction:column }
.ht-day{ margin-top:20px; display:flex; align-items:baseline; gap:10px; white-space:nowrap }
.ht-fig{ font-size:104px; line-height:92px; font-weight:600; letter-spacing:-.01em; color:var(--top-ink) }
.ht-unit{ font-size:20px; line-height:24px; color:var(--top-soft) }
.ht-line{ margin:10px 0 0; font-size:15px; line-height:22px; color:var(--top-ink) }
.ht-tiles{ margin-top:auto; display:grid; grid-template-columns:repeat(3, minmax(0, 1fr)); gap:8px }
.ht-tile{
  height:64px; min-width:0; padding:9px 14px; border-radius:18px;
  background:var(--top-2); color:var(--top-ink); text-decoration:none;
  display:flex; flex-direction:column;
}
a.ht-tile{ transition:background .15s }
a.ht-tile:hover{ background:color-mix(in srgb, var(--top-2) 86%, #fff) }
a.ht-tile:focus-visible{ outline:2px solid var(--focus); outline-offset:2px }
.ht-cap{ flex:none; font-size:13px; line-height:18px; color:var(--top-soft); white-space:nowrap; overflow:hidden; text-overflow:ellipsis }
.ht-val{ flex:none; font-size:25px; line-height:30px; font-weight:600; white-space:nowrap }
/* line-height 0: the unit in the text face must not grow the figure's line. */
.ht-u{ font-family:var(--font-text); font-size:14px; line-height:0; font-weight:400; color:var(--top-soft) }
.ht-tile.hot [data-stuck-count]{ color:var(--top-acc) }
.ht-chart{ position:relative; z-index:1; min-width:0; display:flex; flex-direction:column }
/* No bets yet: the paddle tossing a ball beside the words, drawn in the
   navy's soft ink with the ball in --top-acc, no box. */
.ht-empty{
  margin:auto 0; padding-left:48px;
  display:grid; grid-template-columns:auto minmax(0, 1fr); column-gap:32px; align-items:center;
}
.ht-empty .art{ grid-row:1 / span 3; width:300px; color:var(--top-soft) }
.ht-empty .art .ball{ fill:var(--top-acc) }
.ht-empty .art .trail{ stroke:var(--top-acc) }
.ht-empty .art .soft{ fill:var(--top-rule) }
.ht-empty .art .floor, .ht-empty .art .mark{ stroke:var(--top-rule) }
.ht-empty-h{ margin:0; font-size:20px; line-height:28px; font-weight:600; align-self:end }
.ht-empty-s{ margin:6px 0 0; max-width:440px; font-size:15px; line-height:22px; color:var(--top-soft) }
.ht-empty-a{ margin-top:12px; justify-self:start; align-self:start; color:var(--top-ink); font-size:15px; font-weight:600; text-decoration:underline; text-decoration-color:var(--top-rule); text-underline-offset:4px }
.ht-empty-a:hover{ text-decoration-color:var(--top-ink) }
@media (max-width:760px){
  .ht-empty{ padding-left:0; grid-template-columns:minmax(0, 1fr) }
  .ht-empty .art{ grid-row:auto; width:220px; margin-bottom:12px }
}

/* The chart: the scale in a 48 px column, the plot, 24 px of air on the
   right; the «сейчас» pill in the 28 px row above, the hours in the 24 px
   row under it, the legend under all. */
.dy{ display:flex; flex-direction:column; gap:10px }
.dy-box{ display:grid; grid-template-columns:48px minmax(0, 1fr) 24px; grid-template-rows:28px 214px 24px }
.dy-y{ grid-column:1; grid-row:2; position:relative }
.dy-y span, .dy-x span{
  position:absolute; white-space:nowrap;
  font-family:var(--font-fig); font-variant-numeric:tabular-nums;
  font-size:13px; line-height:16px; color:var(--top-soft);
}
/* The digits share one left edge; a sign hangs in the gutter before it. */
.dy-y span{ left:10px; transform:translateY(-50%); opacity:.6 }
.dy-y .dy-sign{ position:absolute; right:100%; font-style:normal }
.dy-x{ grid-column:2; grid-row:3; position:relative }
.dy-x span{ top:8px; transform:translateX(-50%); opacity:.6 }
.dy-area{ grid-column:2; grid-row:1 / span 2; position:relative; padding-top:28px }
.dy-plot{ display:block; width:100%; height:214px; overflow:visible }
.dy-plot:focus-visible{ outline:2px solid var(--top-wait); outline-offset:4px; border-radius:4px }
.dy-plot path{ vector-effect:non-scaling-stroke }
.dy-grid{ fill:none; stroke:#fff; stroke-opacity:.1; stroke-width:1.5; stroke-dasharray:.1 7; stroke-linecap:round }
.dy-zero{ fill:none; stroke:#fff; stroke-opacity:.22; stroke-width:1 }
.dy-fill{ fill:url(#dyFill); stroke:none }
.dy-fill-top{ stop-color:#fff; stop-opacity:var(--chart-a) }
.dy-fill-end{ stop-color:#fff; stop-opacity:0 }
.dy-future{ fill:none; stroke:#fff; stroke-opacity:.22; stroke-width:1.5; stroke-dasharray:.1 6; stroke-linecap:round }
.dy-line{ fill:none; stroke:#fff; stroke-opacity:.92; stroke-width:2; stroke-linejoin:round; stroke-linecap:round }
/* Zero-length strokes: a round cap is a disc of the stroke's width. */
.dy-pt{ fill:none; stroke-linecap:round }
.dy-won{ stroke:#fff; stroke-width:7 }
.dy-ring-o{ stroke:#fff; stroke-opacity:.8; stroke-width:8.5 }
.dy-ring-i{ stroke:var(--top); stroke-width:5.5 }
.dy-void{ stroke:var(--top-soft); stroke-width:6; stroke-linecap:square }
.dy-wait-o{ stroke:var(--top-wait); stroke-width:8.5 }
.dy-halo{ stroke:var(--top-acc); stroke-opacity:.18; stroke-width:22 }
.dy-ball{ stroke:var(--top-acc); stroke-width:11 }
.dy-plot .hv-guide{ stroke:#fff; stroke-opacity:.45 }
.dy-plot .hv-dot{ fill:var(--top); stroke:#fff }
/* «сейчас»: the net at the current time, and its pill above the plot. */
.dy-now{ position:absolute; top:0; bottom:0; width:0; pointer-events:none }
.dy-now-pill{
  position:absolute; top:2px; left:0; transform:translateX(-50%);
  height:24px; padding:0 12px; border-radius:12px;
  background:rgba(255,255,255,.1); box-shadow:inset 0 0 0 1px rgba(255,255,255,.18);
  font-size:14px; line-height:24px; color:var(--top-ink); white-space:nowrap;
}
.dy-now.end .dy-now-pill{ transform:translateX(calc(-100% + 12px)) }
.dy-now.start .dy-now-pill{ transform:translateX(-12px) }
.dy-net{
  position:absolute; top:28px; bottom:0; left:-6px; width:12px; border-radius:6px;
  background:
    repeating-linear-gradient(45deg, rgba(255,255,255,.16) 0 .8px, transparent .8px 4.2px),
    repeating-linear-gradient(-45deg, rgba(255,255,255,.16) 0 .8px, transparent .8px 4.2px);
}
.dy-net::after{ content:""; position:absolute; left:5.5px; top:0; bottom:0; width:1px; background:rgba(255,255,255,.32) }
.dy-legend{
  display:flex; align-items:center; gap:22px; padding:0 6px 0 48px;
  font-size:13px; line-height:20px; color:var(--top-soft); white-space:nowrap; overflow:hidden;
}
.dy-legend span{ display:flex; align-items:center; gap:7px }
.dy-note{ margin-left:auto }
.dy-key{ flex:0 0 auto; width:7px; height:7px; border-radius:50% }
.dy-key.won{ background:#fff }
.dy-key.lost{ width:8.5px; height:8.5px; box-shadow:inset 0 0 0 1.5px #fff }
.dy-key.void{ width:6px; height:6px; border-radius:1.5px; background:var(--top-soft) }
.dy-key.wait{ width:8.5px; height:8.5px; box-shadow:inset 0 0 0 1.5px var(--top-wait) }
.dy-key.live{ width:10px; height:10px; background:var(--top-acc) }
@media (max-width:1599px){
  .hero.hero-today{ grid-template-columns:440px minmax(0, 1fr); padding:20px 32px 56px; gap:32px }
  .dy-legend .dy-note{ display:none }
}
@media (max-width:1099px){
  .hero.hero-today{ height:auto; grid-template-columns:minmax(0, 1fr); gap:20px; padding:20px 24px 56px }
  .ht-tiles{ margin-top:20px }
}
@media (max-width:760px){
  .hero.hero-today{ padding:16px 16px 44px; gap:16px }
  .ht-fig{ font-size:64px; line-height:60px }
  .ht-tile{ padding:9px 10px }
  .ht-val{ font-size:20px; line-height:26px }
  .dy-box{ grid-template-columns:40px minmax(0, 1fr) 12px }
  .dy-legend{ padding-left:40px; flex-wrap:wrap; gap:4px 16px }
}

/* The hero's text on navy: badges, links and the quiet inks re-tinted. */
.hero-tags{ display:flex; flex-wrap:wrap; gap:8px; margin-top:12px }
.hero .tag, .hero .pill{ background:var(--top-2); border-color:var(--top-rule); color:var(--top-ink) }
.hero .tag.ok, .hero .pill.ok{ color:var(--top-ok) }
.hero .tag.bad, .hero .pill.bad{ color:var(--top-bad) }
.hero .tag.acc, .hero .pill.acc{ color:var(--top-acc) }
.hero .tag.warn, .hero .pill.warn{ color:var(--top-wait) }
.hero .pill.mute{ background:transparent; color:var(--top-soft) }
.hero .link{ color:var(--top-ink); text-decoration:underline; text-decoration-color:var(--top-rule); text-underline-offset:3px }
.hero .link:hover{ text-decoration-color:currentColor }
.hero .ink-soft, .hero .ink-faint{ color:var(--top-soft) }

/* ── The hero cells: 3 to 5 tiles on --top-2, 184 px high. The label sits
   at the top; the figure (50 px) and its context line at the bottom. ── */
.board{
  display:grid; gap:12px;
  grid-template-columns:repeat(auto-fit, minmax(200px, 1fr));
}
.board-cell{
  background:var(--top-2);
  border-radius:var(--r-band);
  height:184px; padding:18px 22px;
  min-width:0;
  display:flex; flex-direction:column; gap:6px;
  container-type:inline-size; container-name:bcell;
}
.board-cap{
  font-size:14px; line-height:20px; color:var(--top-soft);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.board-sub{
  font-size:13px; line-height:18px; color:var(--top-soft);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.board-fig{
  display:flex; align-items:baseline; min-width:0; margin-top:auto;
  font-family:var(--font-fig); font-variant-numeric:tabular-nums;
  font-size:50px; line-height:54px; font-weight:500; letter-spacing:-.01em;
  color:var(--top-ink); white-space:nowrap;
}
.board-fig .u{
  font-family:var(--font-text);
  font-size:16px; line-height:22px; font-weight:400; letter-spacing:0;
  color:var(--top-soft); margin-left:8px;
}
.board-fig .win + .u{ margin:0 2px; font-family:var(--font-fig); font-size:50px; line-height:54px; color:var(--top-soft) }
.board-fig .win{ color:var(--top-ok) }
.board-fig .loss{ color:var(--top-bad) }
.board-fig.acc{ color:var(--top-acc) }
.board-fig.ok{ color:var(--top-ok) }
.board-fig.bad{ color:var(--top-bad) }
.board-fig.warn{ color:var(--top-wait) }
.board-fig.dim{ color:var(--top-soft) }
.board-sub b{ color:var(--top-ink); font-weight:500 }
/* The profit cell's 80 × 20 daily line: only with at least 1200 px of
   content and room beside the figure. */
.board-spark{ display:none; flex:0 0 auto; align-self:center; margin-left:auto; padding-left:12px; overflow:visible }
@media (min-width:1496px){
  @container bcell (min-width:300px){ .board-spark{ display:block } }
}
.board-spark-zero{ stroke:var(--top-rule); stroke-width:1 }
.board-spark-line{ fill:none; stroke:var(--top-soft); stroke-width:1.5; stroke-linejoin:round; vector-effect:non-scaling-stroke }
.board-spark.ok .board-spark-line{ stroke:var(--top-ok) }
.board-spark.bad .board-spark-line{ stroke:var(--top-bad) }
a.board-cell{ color:inherit; transition:background .15s }
a.board-cell:hover{ background:color-mix(in srgb, var(--top-2) 86%, #fff) }
a.board-cell:focus-visible{ outline:2px solid var(--focus); outline-offset:2px }
.board-sub .streak{ margin-top:0 }
.board .streak i.w{ background:color-mix(in srgb, var(--top-ok) 18%, transparent); color:var(--top-ok) }
.board .streak i.l{ background:color-mix(in srgb, var(--top-bad) 18%, transparent); color:var(--top-bad) }
.board .streak i{ width:17px; height:17px }
/* One line of provenance at the top of the paper, under the hero. */
.board-note{ margin:0 0 24px; font-size:13px; line-height:18px; color:var(--ink-soft) }
/* «Сегодня»: #today holds the hero and the paper, so it stands in for both
   in the shell's column. */
.today-frame{ flex:1 0 auto; display:flex; flex-direction:column; min-width:0 }
@media (max-width:760px){
  .hero{ padding:16px 16px 44px; gap:16px }
  .hero-ghost{ display:none }
  .board{ grid-template-columns:1fr 1fr; gap:8px }
  .board-cell{ height:auto; min-height:112px; padding:14px 16px }
  .board-cell:last-child:nth-child(odd){ grid-column:1 / -1 }
  .board-fig{ font-size:30px; line-height:36px }
  .board-fig .win + .u{ font-size:30px; line-height:36px }
}

/* ── State tones: one colour per state, for badges and card edges. ── */
.tone-ok{ --tone:var(--ok); --tone-soft:var(--ok-soft); --tone-line:var(--ok-line); --tone-ink:var(--ok) }
.tone-bad{ --tone:var(--bad); --tone-soft:var(--bad-soft); --tone-line:var(--bad-line); --tone-ink:var(--bad) }
.tone-warn{ --tone:var(--blue); --tone-soft:var(--blue-soft); --tone-line:var(--blue-line); --tone-ink:var(--blue) }
.tone-acc{ --tone:var(--ball); --tone-soft:var(--ball-soft); --tone-line:var(--ball-line); --tone-ink:var(--ball) }
.up{ color:var(--ok) }
.down{ color:var(--bad) }

/* ── Panels. A panel is a card with no padding of its own: a 60 px
   header, a body and a 60 px footer, each inset 24 px, on one soft lift
   with no visible border. ── */
.card-h{ margin-bottom:16px; display:flex; align-items:center; justify-content:space-between; gap:12px }
.card-h h3{ font-size:19px; line-height:24px }
.card-sub{ margin-top:2px; font-size:14px; line-height:20px; color:var(--ink-faint) }
.card-h .tag{ flex:0 0 auto }
.panel{ padding:0; display:flex; flex-direction:column; min-width:0; overflow:hidden }
.panel-h{
  flex:0 0 auto; height:60px; padding:4px 24px 0;
  display:flex; align-items:center; justify-content:space-between; gap:12px;
}
.panel-h h3, .panel-title{
  display:flex; align-items:center; gap:10px; min-width:0;
  font-size:19px; line-height:24px; font-weight:600;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
/* The count chip beside the title; `--brand` when it needs the owners. */
.panel-h .n{
  flex:0 0 auto; min-width:28px; height:24px; padding:0 8px;
  display:inline-flex; align-items:center; justify-content:center;
  border-radius:12px; background:var(--chip); color:var(--ink-soft);
  font-family:var(--font-fig); font-variant-numeric:tabular-nums;
  font-size:16px; line-height:24px; font-weight:600;
}
.panel-h .n.hot{ background:var(--brand); color:var(--brand-fg) }
.panel-h .acts{ display:flex; align-items:center; gap:8px; flex:0 0 auto }
/* An explanation of the contents sits next to the title; a hint about
   order or timing at the right end. */
.panel-h .near{ flex:1 1 auto; min-width:0; margin-left:-6px }
.panel-note{ padding:0 24px 12px; font-size:14px; line-height:20px; color:var(--ink-faint) }
.panel-note.end{ padding:12px 24px }
/* The day section keeps its own class for the HTMX swap; it is a panel. */
.card.gday{ padding:0; display:flex; flex-direction:column; min-width:0; overflow:hidden }
.panel-body{ padding:0 24px 24px; min-width:0 }
.panel-scroll{ overflow-x:auto; min-width:0 }
.panel-empty{
  flex:1; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:4px;
  min-height:144px; padding:24px; text-align:center; color:var(--ink-soft);
}
.panel-f{ margin-top:auto }
/* A pair is as tall as its taller panel. The shorter one's free space,
   between its rows and its pager, carries a centred note on what comes
   next. The fill adds no height of its own (size containment), and the
   note hides when the fill has no room for it. `.only` stands for the
   rows of an empty list and keeps the 144 px of an empty panel. */
.panel-fill{
  flex:1 1 0; min-height:0; container-type:size;
  display:grid; place-items:center; padding:0 24px;
}
.panel-fill.only{ flex-basis:auto; min-height:144px }
/* A short list in a stacked pair: one 48 px line under its rows, no free
   space around it. */
.panel-fill.line{ flex:none; min-height:48px; container-type:normal }
.fill-note{
  margin:0; max-width:80ch; text-align:center; text-wrap:balance;
  font-size:13px; line-height:18px; color:var(--ink-soft);
}
@container (max-height:59px){ .fill-note{ display:none } }
.stack > .pair{ margin-bottom:0 }
.panel-h .card-sub{ margin:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis }
/* Side by side only with `.side` (both lists at least 5 rows on the page,
   docs/ISTRENA_DESIGN.md §5): a pair without it always stacks, whatever the
   width, each panel at its own height. Side by side, the gap between the
   panels is the net (D12). */
.pair{ display:grid; gap:16px; align-items:stretch; margin-bottom:24px }
.pair > *{ min-width:0 }
.net{ display:none }
@media (min-width:1440px){
  .pair.side{ grid-template-columns:minmax(0,1.78fr) 28px minmax(0,1fr); column-gap:10px }
  .pair.side.even{ grid-template-columns:minmax(0,1fr) 28px minmax(0,1fr) }
  .pair.side > .net{ display:flex; flex-direction:column; align-items:center; padding:10px 0 }
}
.net-post{ flex:0 0 12px; width:12px; height:12px; border-radius:50%; background:var(--post) }
.net-mesh{
  flex:1 1 auto; width:14px; margin:5px 0; border-radius:7px;
  background:
    repeating-linear-gradient(45deg, var(--mesh) 0 1px, transparent 1px 6px),
    repeating-linear-gradient(-45deg, var(--mesh) 0 1px, transparent 1px 6px);
}
.stack{ display:flex; flex-direction:column; gap:24px; min-width:0 }
.stack > *{ min-width:0 }

/* ── The data table: fixed layout, 32 px heads, 48 px rows (64 px for
   bets and matches), cells 16 px apart, the rules inset 24 px from the
   panel's edge. `.dt` is opt-in; older auto tables keep `table.tf`. ── */
table.dt{
  width:calc(100% - 48px); margin:0 24px; table-layout:fixed;
  border-collapse:separate; border-spacing:0;
  font-size:15px; line-height:22px;
}
table.dt th, table.dt td{
  padding:0 8px; text-align:left; vertical-align:middle;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  font-variant-numeric:tabular-nums;
}
table.dt thead th{
  height:32px; font-size:13px; line-height:18px; font-weight:400;
  color:var(--ink-faint); background:var(--bg-1);
  border-bottom:1px solid var(--rule);
}
table.dt tbody td{ height:48px; border-bottom:1px solid var(--rule) }
table.dt.rows64 tbody td{ height:64px }
table.dt tbody tr:last-child td{ border-bottom:0 }
table.dt tbody tr{ transition:background .1s }
table.dt tbody tr:hover{ background:var(--bg-2) }
table.dt tbody tr[aria-selected="true"]{ background:var(--blue-soft) }
table.dt th:first-child, table.dt td:first-child{ padding-left:0 }
table.dt th:last-child, table.dt td:last-child{ padding-right:0 }
table.dt .r{ text-align:right }
table.dt .c{ text-align:center }
table.dt .mono{ font-size:15px }
table.dt td.num, table.dt .mono.strong{ font-weight:500 }
table.dt .link{ color:var(--ink) }
table.dt .link:hover{ color:var(--ball); text-decoration:none }
table.dt td.c-start .link, table.dt td.c-start{ color:var(--ink-soft) }
/* A cell that may not fit ends in an ellipsis; its title and the focus
   tip carry the full text. */
.ell{ white-space:nowrap; overflow:hidden; text-overflow:ellipsis }
table.dt tr.bj-excluded td{ color:var(--ink-soft) }
table.dt tr.bj-reject td{ color:var(--ink-soft); font-style:italic }
table.dt tr.bj-reject .tag, table.dt tr.bj-reject .link{ font-style:normal }
table.dt tr.gp-stats-group td{ font-weight:600; background:var(--bg-2) }
/* The bets columns at 1920 (a column's width includes its 8 px sides):
   start 72, the match the rest, the pick 150, price 60, state 140, profit
   76, «Взяли» 128. Below 976 px the table scrolls inside its panel. */
table.dt.bets{ min-width:976px }
col.w-start{ width:80px }
table.dt.by-day col.w-start{ width:128px }  /* «27.09 · TT Elite» under the time */
col.w-league{ width:88px }
col.w-pick{ width:166px }
col.w-price{ width:76px }
col.w-state{ width:176px }
col.w-profit{ width:92px }
col.w-takers{ width:136px }
col.w-takers.edge{ width:136px }
/* «Зависшие ставки»: the reason is what the owner reads, so it takes the
   rest. */
table.dt#stuck col.w-league{ width:96px }
col.w-stuck-players{ width:276px }
col.w-stuck-pick{ width:186px }
col.w-hours{ width:88px }
/* «Ближайшие матчи»: start 56, the match the rest, league 72, the
   decision 128. */
col.w-soon{ width:64px }
table.dt#upcoming col.w-league{ width:88px }
col.w-decision{ width:152px } /* «решает сейчас» is 141 px */
table.dt td.c-takers, table.dt th.c-takers{ text-align:center }

/* ── The 64 px bets row's cells: two lines each. ── */
.c2{ display:flex; flex-direction:column; min-width:0 }
.c2-time{ font-family:var(--font-fig); font-variant-numeric:tabular-nums; font-size:20px; line-height:24px; font-weight:600; color:var(--ink) }
table.dt td.c-start .c2-time .link, table.dt td.c-start .c2-time{ color:var(--ink) }
.c2-sub{ font-size:13px; line-height:18px; font-weight:400; font-style:normal; color:var(--ink-faint) }
table.dt td.c-league{ font-size:13px; color:var(--ink-soft) }
/* One player a line: the name, the match score in a disc and the sets. */
.pl-line{ display:flex; align-items:center; gap:6px; height:24px; min-width:0 }
.pl-line + .pl-line{ margin-top:3px }
.pl-name{ flex:1 1 auto; min-width:0; font-size:15px; line-height:22px }
.pl-name .link{ color:inherit }
.nm-w{ font-weight:600; color:var(--ink) }
.nm-l{ font-weight:400; color:var(--ink-soft) }
.nm-n{ font-weight:500; color:var(--ink) }
.ms{
  flex:0 0 24px; width:24px; height:24px; border-radius:50%;
  display:inline-grid; place-items:center;
  font-family:var(--font-fig); font-variant-numeric:tabular-nums;
  font-size:16px; line-height:24px; font-weight:700;
}
.ms-w{ background:var(--ink); color:var(--bg-1) }
.ms-l{ background:var(--chip); color:var(--ink-soft) }
.sets{ flex:0 0 auto; display:flex; gap:3px }
.set{
  width:26px; height:24px; border-radius:12px; text-align:center;
  font-family:var(--font-fig); font-variant-numeric:tabular-nums;
  font-size:17px; line-height:24px;
}
.set-w{ color:var(--ink); font-weight:600 }
.set-l{ color:var(--ink-faint); font-weight:400 }
/* The set a total turned in. */
.set-c{ background:var(--ball-soft); color:var(--ball); font-weight:700 }
.bj-players .link, .bj-players{ white-space:nowrap }
.bj-vs{ color:var(--ink-faint) }
.bj-pick{ white-space:nowrap; font-size:15px; line-height:22px; font-weight:600; color:var(--ink) }
.bj-pick .num, .bj-pick .mono{ font-weight:600 }
.bj-excl{ color:var(--blue) }
.bj-reason{ color:var(--ink) }
.bj-edge{ color:var(--ink-faint); margin-left:6px }
table.dt td.c-odds{ font-family:var(--font-fig); font-variant-numeric:tabular-nums; font-size:19px; font-weight:500; color:var(--ink) }
table.dt td.c-profit{ font-family:var(--font-fig); font-variant-numeric:tabular-nums; font-size:20px; font-weight:600 }
.bj-profit.up, td.up{ color:var(--ok); font-weight:500 }
.bj-profit.down, td.down{ color:var(--bad); font-weight:500 }
table.dt td.c-profit.up, table.dt td.c-profit.down{ font-weight:600 }
.bj-profit.mute{ color:var(--ink-faint) }
/* «Почему ждёт»: what holds the bet, and under it why no second book
   settled it. */
table.dt td.c-reason{ padding-left:12px; color:var(--ink) }
.c-reason .why, .c-reason .why-more{ display:block; white-space:nowrap; overflow:hidden; text-overflow:ellipsis }
.c-reason .why{ font-size:15px; line-height:22px; font-weight:600 }
.c-reason .why-more{ font-size:13px; line-height:18px; color:var(--ink-faint) }
/* How long a stuck bet has waited: a 28 px figure pill. */
.age{
  display:inline-flex; align-items:center; height:28px; padding:0 11px; border-radius:14px;
  background:var(--ball-soft); color:var(--ball);
  font-family:var(--font-fig); font-variant-numeric:tabular-nums; font-size:17px; font-weight:600;
}
/* «Ближайшие матчи»: «решает сейчас» is the ink chip (light in the
   evening, navy by day) with the orange ball, since text on the orange
   fill read poorly in both themes; under an hour «через 23 мин» on
   --ball-soft, later «в 08:40» in figures. */
.dc{ display:inline-flex; align-items:center; gap:6px; height:28px; padding:0 12px; border-radius:14px; font-size:14px; line-height:20px; font-weight:600; white-space:nowrap }
.dc-now{ padding-left:9px; background:var(--ink); color:var(--bg-1) }
.dc-now .st-due{ color:inherit; font-weight:inherit }
.dc-dot{ width:10px; height:10px; border-radius:50%; background:var(--brand) }
.dc-soon{ background:var(--ball-soft); color:var(--ball) }
.dc-later{ font-family:var(--font-fig); font-variant-numeric:tabular-nums; font-size:17px; color:var(--ink-soft) }
.st-due{ color:var(--ball); font-weight:500 }

/* ── State: a soft pill, 28 px, a 16 px icon and a 14 px word in its
   state's colour, and a 13 px line naming the detail under it. ── */
.st{
  display:inline-flex; align-items:center; gap:6px; max-width:100%; min-width:0;
  height:28px; padding:0 12px 0 8px; border-radius:14px;
  font-size:14px; line-height:20px; font-weight:600; font-style:normal; white-space:nowrap;
  background:var(--neutral-soft); color:var(--neutral);
}
.st-ic{ flex:0 0 16px; width:16px; height:16px; display:inline-grid; place-items:center }
.st-ic svg{ width:16px; height:16px; display:block }
.st-won{ background:var(--ok-soft); color:var(--ok) }
.st-lost{ background:var(--bad-soft); color:var(--bad) }
.st-live{ background:var(--ball-soft); color:var(--ball) }
.st-waiting, .st-stuck{ background:var(--blue-soft); color:var(--blue) }
.st-void{ background:var(--neutral-soft); color:var(--neutral) }
td.c-state .c2{ align-items:flex-start; gap:1px }
td.c-state .c2-sub{ max-width:100%; padding-left:8px; line-height:16px }

/* ── «Взяли»: one button its cell centres on both axes, holding up to
   three 30 px avatars that overlap by 8 px, then «+N». The left padding
   takes back the first avatar's overlap. ── */
.takers{
  display:inline-flex; align-items:center; vertical-align:middle;
  padding:3px 4px 3px 11px; border:0; border-radius:20px;
  background:none; color:var(--ink);
  transition:background .12s;
}
.takers:hover, .takers[aria-expanded="true"]{ background:var(--blue-soft) }
.av{
  flex:0 0 auto; width:30px; height:30px; margin-left:-8px;
  display:inline-flex; align-items:center; justify-content:center;
  border:2px solid var(--bg-1); border-radius:50%;
  background:var(--chip); color:var(--ink);
  font-size:13px; line-height:1; font-weight:600;
}
.av-more{
  background:var(--bg-1); border-color:var(--rule-strong); color:var(--ink-soft);
  font-family:var(--font-fig); font-variant-numeric:tabular-nums; font-size:14px;
}
.takers-none{ display:inline-flex; align-items:center; justify-content:center; vertical-align:middle; min-width:36px; height:28px; color:var(--ink-faint) }

/* ── Popovers: radius 24, 18 px padding, one hairline and the float. ── */
.pop{
  position:fixed; inset:auto; margin:0;
  width:min(392px, calc(100vw - 32px));
  max-height:min(70vh, 560px); overflow:auto;
  padding:18px;
  background:var(--bg-1); color:var(--ink);
  border:1px solid var(--rule); border-radius:var(--r-card);
  box-shadow:var(--shadow-float);
}
.pop:popover-open{ animation:pop-in .12s ease-out }
@keyframes pop-in{ from{ opacity:0; transform:translateY(-4px) } to{ opacity:1; transform:none } }
.pop-title{ font-size:16px; line-height:22px; font-weight:600 }
.pop-hint{ font-size:13px; line-height:18px; color:var(--ink-faint); margin-top:2px }
/* The takers panel (partials/bet_takers.html): as wide as its longest row
   and at least 392 px, one --bg-2 group per client group, rows of 44.
   Nothing in a row is cut; a long name wraps (owner, 2026-09-27). */
.takers-pop{ width:max-content; min-width:min(392px, calc(100vw - 32px)); max-width:min(640px, calc(100vw - 32px)); padding:18px 18px 12px }
.takers-group{ margin-top:12px; padding:6px; border-radius:16px; background:var(--bg-2) }
.takers-group-title{ margin:0; padding:4px 8px 2px; font-size:13px; line-height:18px; font-weight:600; color:var(--ink-soft); white-space:nowrap; overflow:hidden; text-overflow:ellipsis }
.takers-group[data-main] .takers-group-title, .takers-group[data-main] .takers-group-title a{ color:var(--ink) }
.takers-group-title a{ color:inherit; text-decoration:none }
.takers-group-title a:hover{ text-decoration:underline }
.takers-table{ width:100%; border-collapse:separate; border-spacing:0; font-size:14px; line-height:18px }
.takers-table td{ height:44px; padding:0 6px; vertical-align:middle; white-space:nowrap }
.takers-table td:first-child{ padding-left:8px }
.takers-table td:last-child{ padding-right:8px }
.takers-table td.takers-name{ font-weight:500; white-space:normal; overflow-wrap:anywhere }
.takers-book{ color:var(--ink-faint); font-size:13px }
.takers-line, .takers-odds{ font-family:var(--font-fig); font-variant-numeric:tabular-nums; font-size:18px; font-weight:600 }
.takers-time, .takers-source{ color:var(--ink-faint); font-size:13px }
.takers-empty{ margin:12px 0 4px; color:var(--ink-soft) }
.takers-pop .pgr{ margin:8px -18px -12px; padding:0 18px }
@media (max-width:760px){
  .takers-pop{ width:100vw; min-width:0; max-width:none; left:0 !important; right:0; top:auto !important; bottom:0; border-radius:var(--r-card) var(--r-card) 0 0 }
  /* Too narrow for six columns: the name on its own line, the rest under it. */
  .takers-table, .takers-table tbody{ display:block }
  .takers-table tr{ display:flex; flex-wrap:wrap; align-items:baseline; gap:2px 12px; padding:8px }
  .takers-table td, .takers-table td:first-child, .takers-table td:last-child{ height:auto; padding:0 }
  .takers-table td.takers-name{ flex-basis:100% }
}

/* ── The pager: the panel's 60 px footer, 34 px round steps. ── */
.pgr{
  height:60px; padding:0 24px 4px; flex:0 0 auto;
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  font-size:14px; line-height:20px; color:var(--ink-faint);
  font-variant-numeric:tabular-nums;
}
.pgr-ctl{ display:inline-flex; align-items:center; gap:10px }
.pgr-at{ min-width:48px; text-align:center; font-family:var(--font-fig); font-size:16px; color:var(--ink-soft) }
.pgr-btn{
  width:34px; height:34px; display:inline-grid; place-items:center;
  border:0; border-radius:50%;
  background:var(--chip); color:var(--ink);
}
a.pgr-btn:hover, button.pgr-btn:not(:disabled):hover{ background:var(--rule-strong) }
.pgr-btn:disabled{ background:var(--bg-2); color:var(--rule-strong); cursor:default }
/* A pager under a grid of cards gets a strip of its own. */
.pgr-strip{ margin-top:16px; background:var(--bg-1); border-radius:var(--r-card); box-shadow:var(--lift) }
.sr-only{ position:absolute; width:1px; height:1px; margin:-1px; padding:0; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0 }

/* ── Filter toolbar: full width above the results, a panel of its own;
   fields keep their labels and wrap whole. ── */
.toolbar{
  display:flex; flex-wrap:wrap; align-items:flex-end; gap:12px 16px;
  padding:18px 24px; margin-bottom:16px;
  background:var(--bg-1); border-radius:var(--r-card); box-shadow:var(--lift);
}
.toolbar .field{ flex:0 1 auto; min-width:0 }
.toolbar .field.grow{ flex:0 1 480px }
.toolbar .field .input{ width:auto; min-width:168px }
.toolbar .tb-toggle{ height:40px; display:inline-flex; align-items:center; gap:8px; font-size:15px; line-height:22px; cursor:pointer; white-space:nowrap }
.toolbar .tb-toggle .switch{ margin:0 }
.toolbar .tb-acts{ display:flex; align-items:center; gap:8px; margin-left:auto }
.toolbar.slim{ align-items:center; padding:12px 24px }
.fchips{ display:flex; flex-wrap:wrap; align-items:center; gap:8px; margin:-4px 0 16px }
.fchip{
  display:inline-flex; align-items:center; gap:6px; height:28px; padding:0 8px 0 12px;
  border-radius:14px; background:var(--ball-soft);
  color:var(--ink); font-size:13px; line-height:18px; font-weight:500; text-decoration:none;
}
.fchip svg{ color:var(--ink-soft) }
.fchip:hover svg{ color:var(--ink) }
.fchips-reset{ font-size:13px }
.list-note{ margin:0 0 16px; font-size:13px; line-height:18px; color:var(--ink-soft) }

/* ── League tiles: 168 px panels, four in a row (2 × 2 below 1440), only
   the profit coloured. The name and the unsettled count; the profit in 46 px
   with the seven day bars beside it; won:lost and ROI. ── */
.ltiles{ display:grid; gap:24px; grid-template-columns:repeat(4, minmax(0,1fr)) }
@media (max-width:1439px){ .ltiles{ grid-template-columns:repeat(2, minmax(0,1fr)); gap:16px } }
@media (max-width:760px){ .ltiles{ grid-template-columns:1fr } }
.ltile{
  height:168px; box-sizing:border-box; padding:20px 24px; min-width:0;
  display:grid; grid-template-columns:minmax(0, 1fr) auto; grid-template-rows:auto 1fr auto; column-gap:16px;
  background:var(--bg-1); border-radius:var(--r-card); box-shadow:var(--lift);
}
.ltile-k{ font-size:16px; line-height:22px; font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis }
.ltile-p{ font-size:13px; line-height:22px; color:var(--ink-faint); text-align:right; white-space:nowrap }
.ltile-v{ grid-column:1; align-self:center; font-family:var(--font-fig); font-variant-numeric:tabular-nums; font-size:46px; line-height:50px; font-weight:600; white-space:nowrap; color:var(--ink) }
.ltile-v.up{ color:var(--ok) }
.ltile-v.down{ color:var(--bad) }
.ltile-v .u{ font-family:var(--font-text); font-size:15px; font-weight:400; color:var(--ink-faint); margin-left:6px }
.ltile-bars{ grid-column:2; align-self:center; display:flex; gap:6px; height:56px }
.ltile-bars i{ display:grid; grid-template-rows:27px 2px 27px; justify-items:center; width:10px }
.ltile-bars b{ display:block; width:10px; border-radius:5px }
.ltile-bars .w{ align-self:end; background:var(--ok) }
.ltile-bars .t{ width:4px; height:2px; border-radius:1px; background:var(--rule-strong) }
.ltile-bars .l{ align-self:start; background:var(--bad) }
.ltile-meta{ grid-column:1 / 3; font-size:14px; line-height:22px; color:var(--ink-soft); white-space:nowrap; overflow:hidden; text-overflow:ellipsis }
.ltile-meta .num{ font-size:17px; font-weight:600; color:var(--ink) }
.ltile.empty-tile{ grid-column:1 / -1; height:auto; display:block; color:var(--ink-soft); font-size:14px }
.ltiles-top{ display:flex; align-items:baseline; gap:12px; margin:0 4px 12px; min-width:0 }
.ltiles-h{ margin:0; font-size:19px; line-height:24px; font-weight:600; white-space:nowrap }
.ltiles-note{ font-size:14px; line-height:20px; color:var(--ink-faint); white-space:nowrap; overflow:hidden; text-overflow:ellipsis }

/* ── The window (still `.drawer`, its old name): centred, as tall as its
   content up to the viewport less 48 px, a fixed header and footer and a
   scrolling body. Its width follows the content: 560 px, `.sm` 480 px for
   a confirmation, `.wide` 920 px for «Записать результат». ── */
dialog.drawer{
  --modal-w:560px;
  position:fixed; inset:0; margin:auto; padding:0;
  width:min(var(--modal-w), calc(100vw - 48px)); max-width:none;
  /* Not `auto`: between two zero insets it would fill the viewport. */
  height:fit-content; max-height:calc(100dvh - 48px);
  display:none; flex-direction:column;
  background:var(--bg-1); color:var(--ink);
  border:0; border-radius:var(--r-card);
  box-shadow:var(--shadow-float);
  /* A drawer may sit in a table cell: it takes none of the cell's text rules. */
  text-align:left; white-space:normal; font-size:15px; line-height:22px; font-weight:400;
}
dialog.drawer.sm{ --modal-w:480px }
dialog.drawer.wide{ --modal-w:920px }
dialog.drawer.wide:has(.settle-note, .settle-sent){ --modal-w:560px }
/* Only the window moves: a ::backdrop animation would escape the
   reduced-motion rule (§8). */
dialog.drawer[open]{ display:flex; animation:modal-in .14s ease-out }
/* The page dims into the arena's navy, as the hero sits over the table. */
dialog.drawer::backdrop{
  background:rgba(9,26,51,.55);
  background:color-mix(in srgb, var(--top) 55%, transparent);
}
/* The page behind holds still and does not shift when its scrollbar goes. */
html{ scrollbar-gutter:stable }
html:has(dialog.drawer[open]){ overflow:hidden }
.drawer-h, .drawer-f{ flex:0 0 64px; height:64px; padding:0 24px; display:flex; align-items:center; gap:12px }
.drawer-h{ justify-content:space-between; border-bottom:1px solid var(--rule) }
.drawer-f{ justify-content:flex-end; border-top:1px solid var(--rule) }
.drawer-title{ font-size:19px; line-height:24px; font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis }
.drawer-body{ flex:1 1 auto; min-height:0; overflow-y:auto; padding:24px }
@keyframes modal-in{ from{ opacity:0; transform:translateY(8px) } to{ opacity:1; transform:none } }
@keyframes sheet-in{ from{ opacity:0; transform:translateY(16px) } to{ opacity:1; transform:none } }
/* A phone: a sheet from the bottom edge, its footer above the home bar. */
@media (max-width:640px){
  dialog.drawer{
    margin:auto 0 0; width:100%; max-height:calc(100dvh - 24px);
    border-radius:var(--r-card) var(--r-card) 0 0;
  }
  dialog.drawer[open]{ animation-name:sheet-in }
  .drawer-f{
    flex-basis:calc(64px + env(safe-area-inset-bottom));
    height:calc(64px + env(safe-area-inset-bottom));
    padding-bottom:env(safe-area-inset-bottom);
  }
}

/* ── «Записать» (istrena-manual-settle, partials/settle*.html). The row's
   button keeps its width while it loads: the ball hops alone. The slot
   holds the swapped body and footer, which stay the dialog's own flex
   children. ── */
.settle-open{ min-width:104px }
.settle-open.htmx-request .btn-word{ position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap }
table.dt#stuck{ min-width:1096px }
col.w-act{ width:120px }
/* 4 px on the right keep the button's focus ring inside the cell, which
   clips its overflow. */
table.dt td.c-act, table.dt th.c-act{ text-align:right; padding-right:4px }
.bp-settle{ margin-top:12px }
.settle-slot{ display:contents }
.settle-form{ display:flex; flex-direction:column; gap:24px }
/* The body scrolls; its blocks never shrink into one another. */
.settle-form > *{ flex-shrink:0 }
/* What the owner types, and what it does: stacked, and from 1024 px side
   by side with the net between them (istrena-leagues-alerts-modal D7). */
.settle-panes{ display:flex; flex-direction:column; gap:24px; min-width:0 }
.settle-entry{ display:flex; flex-direction:column; gap:24px; min-width:0 }
/* «Результат» or «Не состоялся» (istrena-void-match D4): both modes' fields
   stay in the form and only the checked mode's show, so switching back
   finds the sets as they were typed. */
.settle-mode{ align-self:flex-start }
.settle-result{ display:flex; flex-direction:column; gap:24px; min-width:0 }
.field.settle-void{ display:none }
.settle-form:has([name=mode][value=void]:checked) .settle-result{ display:none }
.settle-form:has([name=mode][value=void]:checked) .settle-void{ display:flex }
@media (min-width:1024px){
  .settle-panes{ display:grid; grid-template-columns:minmax(0,1fr) 28px minmax(0,1fr); column-gap:10px; align-items:stretch }
  .settle-panes > .net{ display:flex; flex-direction:column; align-items:center; padding:10px 0 }
}
.settle-match{ display:flex; align-items:center; gap:12px; margin:0; min-width:0; font-size:14px; line-height:20px; color:var(--ink-soft) }
.settle-when{ white-space:nowrap }
.settle-match .link{ margin-left:auto; white-space:nowrap }
.settle-group{ margin:0; padding:0; border:0; min-width:0 }
.settle-legend{ float:left; width:100%; margin:0 0 8px; padding:0; font-size:14px; line-height:20px; font-weight:600; color:var(--ink-soft) }
.settle-legend + *{ clear:both }
.settle-hint{ margin:8px 0 0; font-size:13px; line-height:18px; color:var(--ink-faint) }

/* The winner: two 56 px toggles, one a player; the chosen one takes the
   selection's --blue. The radio covers its label, so a press anywhere on it
   picks. */
.win-picks{ display:grid; grid-template-columns:repeat(2, minmax(0, 1fr)); gap:12px }
.win-pick{
  position:relative; display:flex; align-items:center; gap:12px; min-width:0;
  height:56px; padding:0 16px; border-radius:16px; cursor:pointer;
  background:var(--bg-2); box-shadow:inset 0 0 0 1px var(--rule);
  transition:background .12s, box-shadow .12s;
}
.win-pick:hover{ box-shadow:inset 0 0 0 1px var(--rule-strong) }
.win-pick input{ position:absolute; inset:0; width:100%; height:100%; margin:0; opacity:0; cursor:pointer }
.win-pick:has(input:checked){ background:var(--blue-soft); box-shadow:inset 0 0 0 1.5px var(--blue) }
.win-pick:has(input:focus-visible){ outline:2px solid var(--focus); outline-offset:2px }
.win-mark{
  flex:0 0 20px; width:20px; height:20px; border-radius:50%; display:grid; place-items:center;
  box-shadow:inset 0 0 0 1.5px var(--control-line); color:transparent;
}
.win-mark svg{ width:14px; height:14px; display:block }
.win-pick:has(input:checked) .win-mark{ background:var(--blue); box-shadow:none; color:var(--bg-1) }
.win-text{ display:flex; flex-direction:column; min-width:0 }
.win-name{ font-size:15px; line-height:20px; font-weight:600; color:var(--ink) }
.win-sub{ font-size:13px; line-height:18px; color:var(--ink-faint) }

/* The sets: the number, player 1's points against the colon, player 2's,
   the names above their columns reading towards the middle. */
.set-grid{ display:grid; grid-template-columns:24px minmax(0, 1fr) 16px minmax(0, 1fr); align-items:center; row-gap:8px }
.set-head{ font-size:13px; line-height:18px; color:var(--ink-faint) }
.set-p1{ text-align:right }
.set-n, .set-colon{ font-family:var(--font-fig); font-variant-numeric:tabular-nums; font-size:17px; line-height:22px; color:var(--ink-faint) }
.set-colon{ text-align:center }
.input.set-in{
  width:72px; padding:0 8px; text-align:center;
  font-family:var(--font-fig); font-variant-numeric:tabular-nums; font-size:20px; font-weight:600;
}
.set-grid .set-in:nth-of-type(odd){ justify-self:end }
.set-grid .set-in:nth-of-type(even){ justify-self:start }

/* The score the sets make: the hero's condensed figures on navy, dim until
   a player has three sets; in the evening a step up from the card, ringed. */
.settle-check{ display:flex; flex-direction:column; gap:24px }
.settle-verdict{ display:flex; flex-direction:column; gap:12px }
.score-board{
  display:flex; align-items:center; gap:20px; min-height:96px; padding:16px 20px;
  border-radius:var(--r-band); background:var(--top); color:var(--top-ink);
}
body:not(.theme-light) .score-board{ background:var(--top-2); box-shadow:inset 0 0 0 1px var(--top-rule) }
.sb-fig{
  flex:0 0 auto; font-family:var(--font-fig); font-variant-numeric:tabular-nums;
  font-size:48px; line-height:52px; font-weight:600; color:var(--top-soft); white-space:nowrap;
}
.score-board.on .sb-fig{ color:var(--top-ink) }
.sb-colon{ padding:0 4px }
.sb-text{ display:flex; flex-direction:column; gap:4px; min-width:0 }
.sb-who{ font-size:14px; line-height:20px; font-weight:600; color:var(--top-ink) }
.score-board:not(.on) .sb-who{ font-weight:400; color:var(--top-soft) }
/* «Не состоялся»: the dash stays dim, the words are the verdict. */
.score-board.void .sb-who{ font-weight:600; color:var(--top-ink) }
.sb-note{ font-size:14px; line-height:20px; color:var(--top-soft) }
.sb-sets{ display:flex; flex-wrap:wrap; gap:4px 12px }
.sb-set{ font-family:var(--font-fig); font-variant-numeric:tabular-nums; font-size:17px; line-height:22px; color:var(--top-soft) }
/* One line on what comes next or what is wrong; two lines' room, so the
   plan below does not jump as it changes. */
.settle-msg{ display:flex; align-items:flex-start; gap:8px; min-height:40px; margin:0; font-size:14px; line-height:20px; font-weight:500; color:var(--ink-soft) }
.settle-msg .st-ic{ margin-top:2px }
.settle-msg.ok{ color:var(--ok) }
.settle-msg.error{ color:var(--bad) }
.settle-msg.settle-refused{ min-height:0 }

/* What the result makes of each pending bet of the match: 56 px rows. */
.settle-plan .settle-hint{ margin:0 0 4px }
.plan-list{ list-style:none; margin:0; padding:0 }
.plan-row{
  display:grid; grid-template-columns:minmax(0, 1fr) 44px 116px 64px; align-items:center; gap:12px;
  min-height:56px; border-bottom:1px solid var(--rule);
}
.plan-row:last-child{ border-bottom:0 }
.plan-pick{ display:flex; flex-direction:column; min-width:0 }
.plan-name{ font-size:15px; line-height:20px; font-weight:600; color:var(--ink); text-decoration:none }
.plan-name:hover{ color:var(--ball) }
.plan-sub{ font-size:13px; line-height:18px; color:var(--ink-faint) }
.plan-odds, .plan-profit{ text-align:right; font-family:var(--font-fig); font-variant-numeric:tabular-nums; font-size:17px; line-height:22px; white-space:nowrap }
.plan-odds{ color:var(--ink-soft) }
.plan-profit{ font-weight:600; color:var(--ink-faint) }
.plan-profit.up{ color:var(--ok) }
.plan-profit.down{ color:var(--bad) }
.plan-row .pill{ justify-self:start }
.plan-open{ font-size:15px; color:var(--ink-faint) }

/* After the send: what the bot did, and a note when nothing can be sent. */
.settle-send{ min-width:168px }
.settle-sent, .settle-note{ display:flex; flex-direction:column; align-items:flex-start; gap:12px }
.settle-sent-title{ margin:0; font-size:19px; line-height:24px; font-weight:600; color:var(--ink) }
.settle-reason{ margin:0; font-size:15px; line-height:22px; color:var(--bad) }
.settle-sent-score{ margin:0; font-size:15px; line-height:22px; color:var(--ink-soft) }
.settle-sent-score .num{ font-size:17px; color:var(--ink) }
.settle-sent .settle-hint{ margin:0 }
.settle-note-text{ margin:0; font-size:15px; line-height:22px; color:var(--ink) }
@media (max-width:480px){
  .plan-row{ grid-template-columns:44px minmax(0, 1fr) 64px; row-gap:4px; padding:10px 0 }
  .plan-pick{ grid-column:1 / -1 }
  .plan-odds{ text-align:left }
  .settle-match{ flex-wrap:wrap; row-gap:4px }
}

/* ── A live value that changed on the 30 s refresh: a 400 ms fade. ── */
.live-changed{ animation:live-fade .4s ease-out }
@keyframes live-fade{ from{ background-color:var(--ball-soft) } to{ background-color:transparent } }

/* ── The day's figure rolls each changed digit once, 300 ms in all: 220 ms
   a digit, left to right, the starts spread over 80 ms by workbench.js. It
   builds a two-line column per digit, old above new, one line (--lh) high,
   and puts the plain text back after the last. ── */
.dg{ display:inline-block; height:var(--lh); overflow:hidden; vertical-align:top }
.dg-col{ display:flex; flex-direction:column; animation:dg-roll .22s ease-out both }
.dg-col > span{ height:var(--lh) }
@keyframes dg-roll{ to{ transform:translateY(-50%) } }

/* ── A new «Взяли» mark: a ball drops onto the avatar the refresh added
   (--drop-x is its centre) and it appears ringed in orange, 400 ms; the
   ring fades after. The ball is the button's, since the avatar starts
   transparent. ── */
.takers.drop{ position:relative }
.takers.drop::after{
  content:""; position:absolute; left:var(--drop-x); top:50%;
  width:12px; height:12px; margin:-6px 0 0 -6px; border-radius:50%;
  background:var(--brand); pointer-events:none;
  animation:av-ball .4s ease-in forwards;
}
.av.av-drop{ position:relative; z-index:1; animation:av-land .4s ease-out, av-ring .8s ease-out .4s }
@keyframes av-ball{
  0%{ transform:translateY(-24px); opacity:1 }
  50%{ transform:translateY(0) scale(1.25,.75); opacity:1 }
  100%{ transform:translateY(0) scale(2.4); opacity:0 }
}
@keyframes av-land{
  0%, 45%{ transform:scale(.5); opacity:0 }
  100%{ transform:none; opacity:1; box-shadow:0 0 0 2px var(--brand); background:var(--ball-soft); color:var(--ball) }
}
@keyframes av-ring{
  from{ box-shadow:0 0 0 2px var(--brand); background:var(--ball-soft); color:var(--ball) }
  to{ box-shadow:0 0 0 2px transparent }
}

/* ── Page head controls. ── */
.page-head{ align-items:flex-end; margin-bottom:24px }
.head-chip{
  display:inline-flex; align-items:center; gap:8px;
  height:36px; padding:0 14px;
  border:1px solid var(--rule); border-radius:var(--r-ctl);
  background:var(--control); color:var(--ink);
  font-size:15px; line-height:22px; font-weight:500; white-space:nowrap;
}
.head-chip:hover, .head-chip[aria-expanded="true"]{ border-color:var(--ball-line); background:var(--ball-soft) }
.head-chip .num{ font-weight:500 }
.head-chip svg{ color:var(--ink-faint) }
.tb-count{ font-size:15px; line-height:22px; color:var(--ink-soft); white-space:nowrap }

/* ── «Группы»: the filter and the price chip in one toolbar line, then
   «Запросы доступа», the cards and «Неактивные группы», 24 px apart. ── */
.gr-toolbar{ flex-wrap:wrap; row-gap:12px }
.gr-seg{ max-width:100%; overflow-x:auto; scrollbar-width:none }
.gr-seg a{ white-space:nowrap }
.gr-seg .num{ font-size:16px; color:var(--ink-faint) }
.gr-requests{ margin-bottom:24px }
table.dt.gr-requests-tbl{ min-width:760px }
.gr-requests-tbl td{ height:56px }
.gr-req-name{ font-size:16px; font-weight:600 }
.gr-req-name .link{ color:var(--ink) }
col.w-gwho{ width:220px }
col.w-gwhen{ width:150px }

/* ── Group cards (§6): 248 px, the name and the badge, the chat and the
   league chips, three 32 px figures, the people who take bets, and a 42 px
   foot inset 10 px in the billing state's soft colour. Five across at
   1920, three at 1600, two at 1280. ── */
.gcards{ display:grid; gap:24px; grid-template-columns:repeat(5, minmax(0, 1fr)) }
@media (max-width:1760px){ .gcards{ grid-template-columns:repeat(3, minmax(0, 1fr)) } }
@media (max-width:1440px){ .gcards{ grid-template-columns:repeat(2, minmax(0, 1fr)) } }
@media (max-width:760px){ .gcards{ grid-template-columns:1fr } }
.card.gc{
  position:relative; height:248px; padding:20px 22px 0; overflow:hidden; color:inherit;
  display:flex; flex-direction:column; text-decoration:none;
}
.card.gc:hover{ border-color:var(--rule-strong) }
.card.gc:focus-visible{ outline:2px solid var(--focus); outline-offset:2px }
.gc-head{ display:flex; align-items:center; gap:10px; height:26px; min-width:0 }
.gc-name{ flex:1 1 auto; min-width:0; font-size:17px; line-height:24px; font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis }
.gc-head .tag{ flex:0 0 auto }
/* The main group's badge is --table with white text (§6). */
.gc[data-state="main"] .gc-head .tag, #gpState[data-state="main"]{ background:var(--table); color:#ffffff }
.gc-sub{ margin-top:6px; height:24px; display:flex; align-items:center; gap:6px; min-width:0; overflow:hidden; white-space:nowrap }
.gc-sub .mono{ flex:0 0 auto; margin-right:4px; font-family:var(--font-fig); font-variant-numeric:tabular-nums; font-size:16px; color:var(--ink-faint) }
.gc-chips{ display:flex; gap:6px; min-width:0; overflow:hidden }
.lg-chip{ flex:0 0 auto; height:24px; padding:0 10px; border-radius:12px; background:var(--bg-2); font-size:13px; line-height:24px; color:var(--ink-soft); white-space:nowrap }
.gc-none{ font-size:13px; line-height:24px; color:var(--ink-faint) }
.gc-figs{ margin-top:14px; display:grid; grid-template-columns:repeat(3, minmax(0, 1fr)); column-gap:12px }
.gc-fig{ min-width:0 }
.gc-fig .v{
  font-family:var(--font-fig); font-variant-numeric:tabular-nums;
  font-size:32px; line-height:34px; font-weight:600; white-space:nowrap;
}
.gc-fig .k{ font-size:13px; line-height:18px; color:var(--ink-faint); white-space:nowrap; overflow:hidden; text-overflow:ellipsis }
.gc-fig .v.up{ color:var(--ok) }
.gc-fig .v.down{ color:var(--bad) }
.gc-who{ margin-top:12px; height:30px; display:flex; align-items:center; gap:10px; min-width:0 }
.gc-avs{ display:flex; flex:0 0 auto; padding-left:8px }
.gc-people{ min-width:0; font-size:14px; line-height:20px; color:var(--ink-soft); white-space:nowrap; overflow:hidden; text-overflow:ellipsis }
.gc-foot{
  flex:0 0 42px; margin:auto -12px 10px; padding:0 14px; border-radius:16px;
  display:flex; align-items:center; justify-content:space-between; gap:12px; min-width:0;
  background:var(--bg-2); color:var(--ink);
}
.gc-foot.ft-main{ color:var(--ink-soft) }
.gc-foot.ft-bad{ background:var(--bad-soft); color:var(--bad) }
.gc-foot.ft-warn{ background:var(--blue-soft); color:var(--blue) }
.gc-foot.ft-ok{ background:var(--ok-soft); color:var(--ok) }
.gc-bill{ min-width:0; font-size:14px; line-height:20px; font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis }
.gc-last{ flex:0 0 auto; font-family:var(--font-fig); font-variant-numeric:tabular-nums; font-size:15px; line-height:20px; opacity:.85; white-space:nowrap }
/* Rejected groups and groups without the bot: a compact table under the
   cards, 5 a page. */
.gr-inactive{ margin-top:24px }
table.dt.gr-inactive-tbl{ min-width:760px }
col.w-gchat{ width:180px }
col.w-gstate{ width:144px }
col.w-gsince{ width:176px }

/* ── A group's page: full-width sections, 24 px apart. ── */
[data-page="group"] > section, [data-page="group"] > .gset{ margin-top:0; margin-bottom:24px }
/* The same inside the columns, at the lowest specificity, so the rail's
   reset (24 px gaps, no margins) wins from 2200 px. */
:where([data-page="group"]) :where(.lay-main, .lay-rail) > section{ margin-top:0; margin-bottom:24px }
/* «Настройки группы»: two full-width bars split by a 1 px rule. Each bar
   is its title, its items in one line (whole fields wrap), and its save
   button at the right end. In a bar of fields the title and the buttons
   sit on the fields' control line (label 18 + gap 6). */
.gset-bars{ display:flex; flex-direction:column }
.gbar{
  display:flex; align-items:center; gap:16px 24px; min-width:0;
  padding:16px 20px;
}
.gbar + .gbar{ border-top:1px solid var(--rule) }
.gbar-h{
  flex:0 0 136px; min-height:36px; margin:0;
  display:flex; align-items:center;
  font-size:15px; line-height:22px; font-weight:600;
}
.gbar-items{
  flex:1 1 0; min-width:0;
  display:flex; flex-wrap:wrap; align-items:center; gap:12px 24px;
}
/* The save button is a wrapped item of `.gbar-items`, not the row's own
   flex child: a wrap carries it onto the fields' last line, where it sits
   at the right end (`margin-left:auto`) and bottom-aligned with them
   (`align-self:flex-end`), instead of pinned to the row's first line. */
.gbar-act{
  flex:0 0 auto; display:flex; align-items:center; gap:12px;
  margin-left:auto; align-self:flex-end;
}
.gbar-toggle{
  height:36px; display:inline-flex; align-items:center; gap:8px;
  font-size:15px; line-height:22px; white-space:nowrap; cursor:pointer;
}
.gbar-name{ font-weight:500 }
.gbar-word{ min-width:40px; font-size:13px; line-height:18px; color:var(--ink-soft) }
.gbar-note{
  flex:1 1 240px; min-width:0; font-size:13px; line-height:18px; color:var(--ink-soft);
}
.gbar-fields{ align-items:flex-start }
.gbar-fields .gbar-h{ margin-top:24px }
.gbar-fields .gbar-items{ align-items:flex-start }
.gbar-fields .field{ flex:0 0 192px; width:192px; min-width:0 }
.gbar-fields .field .input{ width:100% }
.gbar-fields .field .label, .gbar-fields .field .hint{ white-space:nowrap; overflow:hidden; text-overflow:ellipsis }
.gbar-fields .gbar-fact{ flex-basis:auto; width:auto; max-width:240px }
@media (max-width:760px){
  .gbar{ flex-wrap:wrap }
  .gbar-h{ flex-basis:100% }
  .gbar-fields .gbar-h{ margin-top:0 }
  .gbar-fields .field{ flex-basis:100%; width:100% }
  .gbar-act{ margin-left:0 }
}
.gset-value{ height:36px; display:flex; align-items:center; font-size:15px; line-height:22px; color:var(--ink); white-space:nowrap }
.gset-value.mute{ color:var(--ink-soft) }
.gp-hint{ font-size:13px; line-height:18px; color:var(--ink-faint) }
.gp-form{ display:flex; flex-direction:column; gap:12px }
table.dt.gp-stats td.up, table.dt.gp-day td.up{ color:var(--ok) }
table.dt.gp-stats td.down, table.dt.gp-day td.down{ color:var(--bad) }
.lrow-list{ display:flex; flex-direction:column }
.lrow-list .lrow{ min-height:64px; padding:12px 20px; border:0; border-bottom:1px solid var(--rule); border-radius:0; background:transparent }
.lrow-list .lrow:last-child{ border-bottom:0 }
.lrow-list .lrow-name, .lrow-list .lrow-meta{ white-space:nowrap; overflow:hidden; text-overflow:ellipsis }

/* The payment strip: one 64 px line, the state's colour as a 3 px left
   edge, the one action on the right. */
.card.pay-strip{
  position:relative; overflow:hidden;
  display:flex; align-items:center; gap:16px;
  min-height:64px; padding:12px 20px;
}
.pay-strip::before{ content:''; position:absolute; left:0; top:0; bottom:0; width:3px; background:var(--tone) }
.ps-text{ flex:1 1 auto; min-width:0; display:flex; align-items:baseline; gap:12px; white-space:nowrap }
.ps-word{ flex:0 0 auto; font-size:15px; line-height:22px; font-weight:600; color:var(--tone-ink) }
.ps-line{ min-width:0; overflow:hidden; text-overflow:ellipsis; font-size:15px; line-height:22px; color:var(--ink-soft) }
.ps-line b{ font-weight:600; color:var(--ink) }
.ps-acts{ flex:0 0 auto; display:flex; align-items:center; gap:8px }

/* «Ставки по дням» on a group page. */
.gday-bar{ display:flex; flex-wrap:wrap; align-items:center; gap:12px; padding:12px 20px; border-bottom:1px solid var(--rule) }
.gday-switch{ display:flex; gap:8px; align-items:center; flex:1 1 420px; max-width:560px }
.gday-switch .pgr-btn{ flex:0 0 auto; cursor:pointer }
.gday-select{
  flex:1; min-width:0; height:36px; padding:0 12px;
  background:var(--control); border:1px solid var(--control-line); border-radius:var(--r-ctl);
  color:var(--ink); font-family:inherit; font-size:15px;
}
.gday-summary{
  display:grid; grid-template-columns:repeat(8, minmax(0,1fr)); gap:0;
  margin:0; border-bottom:1px solid var(--rule);
}
@media (max-width:1100px){ .gday-summary{ grid-template-columns:repeat(4, minmax(0,1fr)) } }
.gday-stat{ padding:10px 20px; min-width:0 }
.gday-stat + .gday-stat{ border-left:1px solid var(--rule) }
.gday-stat dt{ font-size:13px; line-height:18px; color:var(--ink-faint) }
.gday-stat dd{ margin:2px 0 0; font-family:var(--font-fig); font-size:18px; line-height:24px; font-weight:500; font-variant-numeric:tabular-nums }
.gday-stat dd.up{ color:var(--ok) }
.gday-stat dd.down{ color:var(--bad) }
.gday-people{ list-style:none; margin:0; padding:12px 20px; display:flex; flex-wrap:wrap; gap:8px; border-bottom:1px solid var(--rule) }
.gday-person{
  display:inline-flex; align-items:center; gap:10px; height:32px; padding:0 10px;
  background:var(--bg-2); border:1px solid var(--rule); border-radius:var(--r-ctl); font-size:14px;
}
.gday-person-name{ font-weight:500 }
.gday-person-count{ color:var(--ink-faint) }
.gday-person-profit{ font-weight:500 }
.gday-person-profit.up{ color:var(--ok) }
.gday-person-profit.down{ color:var(--bad) }
.gday-empty{ margin:0 }

/* The week of a group's bills. */
.gp-week{ padding:16px 20px; border-bottom:1px solid var(--rule) }
.gp-week:last-child{ border-bottom:0 }
.gp-week-name{ font-size:15px; line-height:22px; font-weight:600 }
.gp-week .pstrip{ margin-top:12px }
.gp-more summary{ cursor:pointer; font-size:13px; color:var(--ink-soft) }
.gp-line{ font-size:13px; color:var(--ink-soft) }
.gp-cancelled .lrow-name{ color:var(--ink-faint); text-decoration:line-through }
.gp-acts{ display:flex; flex-wrap:wrap; gap:8px; align-items:flex-start }
.gp-act summary{ list-style:none; cursor:pointer; display:inline-flex }
.gp-act summary::-webkit-details-marker{ display:none }
.gp-act[open]{ flex-basis:100%; padding:12px; border:1px dashed var(--rule-strong); border-radius:var(--r-ctl) }
.gp-act[open] summary{ margin-bottom:12px }
.gp-preview{ padding-top:16px; border-top:1px solid var(--rule) }

/* A card in a state shows it as a 3 px top edge, like the group cards. */
.card.edged{ position:relative; overflow:hidden }
.card.edged::before{ content:''; position:absolute; left:0; right:0; top:0; height:3px; background:var(--tone, transparent) }
.banner.bad{ border-color:var(--bad-line); background:var(--bad-soft) }
.banner.bad .dot{ background:var(--bad) }
.col-stack{ display:flex; flex-direction:column; gap:16px; min-width:0 }

:focus-visible{ outline:2px solid var(--focus); outline-offset:2px }

@media (prefers-reduced-motion: reduce){
  *, *::before, *::after{ animation:none !important; transition:none !important }
}

/* A bet's page: the bet, its result and the other books side by side on a
   wide window, stretched to one height; below them every block that grows
   with the chats stacks at full width. */
.bp-top{ display:grid; gap:16px; align-items:stretch; margin-bottom:24px }
.bp-top > *{ min-width:0 }
.bp-top > .card{ padding:0; display:flex; flex-direction:column; overflow:hidden }
@media (min-width:1100px){
  .bp-top{ grid-template-columns:repeat(2, minmax(0,1fr)) }
  .bp-top > .bp-span{ grid-column:1 / -1 }
}
@media (min-width:1600px){
  .bp-top{ grid-template-columns:minmax(0,4fr) minmax(0,4fr) minmax(0,5fr) }
  .bp-top > .bp-span{ grid-column:auto }
}
.bp-top .panel-h .acts, .panel-h .acts.bp-faint{ font-size:13px; line-height:18px; white-space:nowrap }
.bp-line{ margin:12px 0 0; font-size:14px; line-height:20px; color:var(--ink-soft) }
.be-chat{ padding:16px 20px }
.be-chat + .be-chat{ border-top:1px solid var(--rule) }
.be-chat .panel-scroll{ margin:0 -20px; border-top:1px solid var(--rule) }
.be-chat-h{ display:flex; align-items:baseline; justify-content:space-between; gap:12px; min-width:0; margin-bottom:12px }
.be-chat-h .who{ display:flex; align-items:baseline; gap:10px; min-width:0; font-size:15px; line-height:22px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis }
.be-chat-h .who strong{ font-weight:600 }
.be-chat-h .when{ flex:0 0 auto; font-size:13px; color:var(--ink-soft) }
.be-chat-title{ margin-bottom:12px; font-size:15px; line-height:22px; font-weight:600 }
.be-none{ margin:0; font-size:14px; line-height:20px; color:var(--ink-soft) }
.be-form{ display:flex; flex-wrap:wrap; gap:12px 16px; align-items:flex-end }
.be-form .field .input{ min-width:160px }
table.dt.be-marks, table.dt.be-req, table.dt.be-audit{ min-width:720px }
col.w-who{ width:18% }
col.w-chat{ width:16% }
col.w-what{ width:28% }
col.w-rstate{ width:24% }
col.w-src2{ width:22% }

/* «Статистика» (templates/stats.html, partials/stats_*): the band, the
   toolbar, then full-width panels. The chip radios stay in the tab order,
   unlike `hidden` ones. */
.st-form{ margin:0 }
.st-toolbar .chips{ gap:8px }
.st-toolbar .chip{ position:relative; min-height:36px; height:36px; font-size:14px }
.st-radio{ position:absolute; opacity:0; width:0; height:0; margin:0 }
.st-toolbar .chip:has(.st-radio:focus-visible){ outline:2px solid var(--focus); outline-offset:2px }
.st-none{ height:36px; display:flex; align-items:center; font-size:14px; color:var(--ink-soft) }
.st-panel-wrap{ position:relative; min-width:0 }
/* The ball rolls along the panel's top edge while a filter change loads;
   the old rows stay under it, dimmed. */
.st-loader{ position:absolute; z-index:2; left:24px; right:24px; top:-12px; pointer-events:none }
.st-loader.htmx-request + #statPanel{ opacity:.55 }
.st-loader .roll{ background:var(--rule-strong) }
#statPanel{ transition:opacity .12s ease }
#statPanel.htmx-swapping, #statPanel.htmx-settling{ opacity:.35 }
.panel-h .st-title{ min-width:0; font-size:18px; line-height:24px; font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis }
.st-span{ gap:12px; font-size:13px; line-height:18px; color:var(--ink-soft); white-space:nowrap }
.st-span .mono{ font-size:13px; color:var(--ink-faint) }
.st-soft{ color:var(--ink-soft) }
/* The chart (§6): 280 px, a 248 px plot and a 32 px row of dates. The plot
   stretches across the panel; its y is in pixels, so the HTML axis labels
   sit at the same heights, and its strokes do not stretch. */
.st-chart{ padding:16px 20px 8px }
.st-chart .chart-legend{ justify-content:flex-start; margin:0 0 12px 56px }
.st-chart-box{ position:relative; display:grid; grid-template-columns:56px minmax(0,1fr); grid-template-rows:248px 32px; height:280px }
.st-y{ position:relative }
.st-y span, .st-x span{ position:absolute; font-family:var(--font-fig); font-variant-numeric:tabular-nums; font-size:13px; line-height:18px; color:var(--ink-faint); white-space:nowrap }
.st-y span{ right:12px; transform:translateY(-50%) }
.st-x{ grid-column:2; position:relative }
.st-x span{ top:8px; transform:translateX(-50%) }
.st-plot{ display:block; width:100%; height:248px; overflow:visible }
.st-plot:focus{ outline:none }
.st-plot:focus-visible{ outline:2px solid var(--focus); outline-offset:4px }
svg.st-plot .grid-l, svg.st-plot .st-zero, svg.st-plot .st-line, svg.st-plot .st-end{ vector-effect:non-scaling-stroke }
svg .st-zero{ stroke:var(--rule-3); stroke-width:1 }
svg .st-line{ fill:none; stroke-width:2; stroke-linecap:round; stroke-linejoin:round }
svg .st-line.one, svg .st-end.one{ stroke:var(--ink) }
svg .st-fill{ fill:var(--ink); fill-opacity:.06; stroke:none }
svg .st-fill.ok{ fill:var(--ok); fill-opacity:.14 }
svg .st-fill.bad{ fill:var(--bad); fill-opacity:.14 }
svg .st-line.s0, svg .st-end.s0{ stroke:var(--accent) }
svg .st-line.s1, svg .st-end.s1{ stroke:var(--warn) }
svg .st-line.s2, svg .st-end.s2{ stroke:var(--ok) }
svg .st-line.s3, svg .st-end.s3{ stroke:var(--ink-soft) }
svg .st-end{ fill:none; stroke-width:8; stroke-linecap:round }
.hv-sw.acc{ background:var(--accent) }
/* The bucket tables: the label takes the rest, then fixed number columns. */
table.dt.st-table{ min-width:760px }
table.dt.st-takes{ min-width:976px }
col.w-n{ width:96px }
col.w-roi{ width:96px }
col.w-share{ width:128px }
col.w-book{ width:120px }
col.w-price-text{ width:22% }
table.dt.st-table tr.st-l0 td{ font-weight:600 }
table.dt.st-table tr.st-l1 td:first-child{ padding-left:40px }
table.dt.st-table tr.st-l2 td:first-child{ padding-left:60px; color:var(--ink-soft) }
table.dt td.ok-c{ color:var(--ok); font-weight:500 }
table.dt td.bad-c{ color:var(--bad); font-weight:500 }
.st-family + .st-family{ border-top:1px solid var(--rule) }
.st-family-h{ height:48px; padding:0 20px; display:flex; align-items:center; gap:8px; font-size:14px; line-height:20px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; border-bottom:1px solid var(--rule) }
@media (prefers-reduced-motion: reduce){ #statPanel{ transition:none } }

/* The hour heatmap (§7): the week on the table, white balls and lines. The
   board scales with the panel; the weekdays and hours are HTML beside it.
   Narrower than 960 px it keeps that width and scrolls inside the panel. */
.hm-panel .panel-h{ height:auto; min-height:60px; flex-wrap:wrap; row-gap:8px; padding-top:12px }
.hm-panel .panel-h .acts{ margin-left:auto }
.hm-legend{
  display:flex; align-items:center; gap:18px; height:40px; padding:0 18px;
  border-radius:20px; background:var(--table); color:#fff;
  font-size:14px; line-height:20px; white-space:nowrap;
}
.hm-legend > span{ display:flex; align-items:center; gap:8px }
.hm-legend .hm-sizes{ gap:4px }
.hm-legend .hm-sizes > span{ margin-right:6px; font-family:var(--font-fig); font-variant-numeric:tabular-nums }
.hm-legend svg{ display:block; flex:0 0 auto }
.hm-legend .f{ fill:#fff }
.hm-legend .o{ fill:none; stroke:#fff; stroke-width:2.2 }
.hm-legend .e{ fill:#fff; fill-opacity:.42 }
.hm-legend .d{ fill:#fff; fill-opacity:.5 }
.hm{
  display:grid; grid-template-columns:64px minmax(0,1fr); grid-template-rows:28px auto;
  min-width:960px; padding:8px 24px 28px;
}
.hm-hours{ grid-column:2; display:grid; grid-template-columns:repeat(24, minmax(0,1fr)); align-items:start }
.hm-hours span{ text-align:center; font-size:14px; line-height:18px; color:var(--ink-faint) }
.hm-days{ display:grid; grid-template-rows:repeat(7, minmax(0,1fr)); align-items:center }
.hm-days span{ display:flex; align-items:baseline; gap:6px; white-space:nowrap }
.hm-days b{ font-size:15px; line-height:20px; font-weight:600; color:var(--ink) }
.hm-days i{ font-style:normal; font-size:14px; line-height:20px; color:var(--ink-faint) }
svg.hm-board{ display:block; width:100%; height:auto; overflow:visible }
svg.hm-board .hm-table{ fill:var(--table) }
svg.hm-board .hm-grain{ clip-path:url(#hmClip); filter:url(#hmGrain); opacity:.45 }
svg.hm-board .hm-edge{ fill:none; stroke:#fff; stroke-opacity:.9; stroke-width:2 }
svg.hm-board .hm-mid{ stroke:#fff; stroke-opacity:.45; stroke-width:1.5 }
svg.hm-board #hmMesh path{ stroke:#fff; stroke-opacity:.55; stroke-width:.8 }
svg.hm-board .hm-mesh{ fill:url(#hmMesh) }
svg.hm-board .hm-net{ stroke:#fff; stroke-width:2.5; stroke-linecap:round }
svg.hm-board .hm-post{ fill:var(--ink-soft) }
svg.hm-board .hm-c{ outline:none }
svg.hm-board .hm-hit{ fill:transparent; stroke:none }
svg.hm-board .hm-c:hover .hm-hit{ fill:rgba(255,255,255,.08) }
svg.hm-board .hm-c:focus-visible .hm-hit{ stroke:#fff; stroke-width:2.5 }
svg.hm-board .hm-c circle{ fill:#fff }
svg.hm-board .hm-c.minus circle{ fill:none; stroke:#fff; stroke-width:2.4 }
svg.hm-board .hm-c.even circle{ fill-opacity:.42 }
svg.hm-board .hm-c.none circle{ fill-opacity:.28 }
@media (max-width:760px){
  .hm-panel .panel-h .acts{ flex:1 1 100%; min-width:0; margin-left:0 }
  .hm-panel .panel-h .card-sub{ flex-basis:100%; margin-left:0; white-space:normal }
  .hm-legend{ flex-wrap:wrap; height:auto; padding:8px 16px; row-gap:6px; column-gap:14px; border-radius:16px; white-space:normal }
}

/* «Игроки»: the search in a slim toolbar, the hits in a paged table. */
.toolbar .search-wrap{ display:block }
.toolbar .search-input{ height:36px; padding:0 12px 0 40px; border-radius:var(--r-ctl); background:var(--control); border-color:var(--control-line) }
.pl-empty .lead{ font-size:15px; line-height:22px; color:var(--ink) }
.pl-empty .hint{ max-width:72ch; font-size:13px; line-height:18px; color:var(--ink-faint) }
col.w-pname{ width:45% }
col.w-platin{ width:40% }
table.dt.players-tbl col.w-league{ width:15% }
table.dt.players-tbl{ min-width:560px }

/* A paged list keeps the frame of its ten rows on a short last page, so
   paging never moves what is under it. */
.panel-scroll.rows10{ min-height:calc(40px + 10 * 48px) }

/* A player's page. */
.pl-meta{ display:flex; flex-wrap:wrap; align-items:center; gap:8px 10px; margin-top:8px; font-size:15px }
[data-page="player"] > .banner{ margin-bottom:24px }

/* Finished matches (partials/player_macros.html). */
table.dt.played{ min-width:760px }
col.w-date{ width:156px }
col.w-opp{ width:40% }
col.w-sets{ width:36% }
col.w-src{ width:24% }
col.w-score{ width:80px }
table.dt .mr-time{ color:var(--ink-faint) }
table.dt .mr-res{ display:inline-grid; place-items:center; width:16px; height:16px; margin-right:6px; vertical-align:-3px }
table.dt .mr-res svg{ width:8px; height:8px }
table.dt .mr-res.win{ color:var(--ok) }
table.dt .mr-res.loss{ color:var(--bad) }
table.dt .mr-sets{ color:var(--ink-soft) }
table.dt .mr-src{ color:var(--ink-soft) }
table.dt .mr-score{ font-weight:600 }
table.dt.pl-bets{ min-width:820px }
table.dt.pl-bets.no-players{ min-width:640px }
table.dt.pl-bets.no-players col.w-pick{ width:100% }

/* A match's page: the players' form, one panel each, side by side and of
   one height under the band; they stack below 1600 px. The rest follows at
   full width. */
.fm-pair{ display:grid; gap:16px; align-items:stretch; margin-bottom:24px }
.fm-pair > *{ min-width:0 }
/* Side by side only where a panel holds the opponent and five sets on one
   line (~640 px a panel); below that the two stack. */
@media (min-width:1600px){ .fm-pair{ grid-template-columns:minmax(0,1fr) minmax(0,1fr) } }
.fm-panel .panel-h h3 .link{ color:var(--ink) }
.fm-panel .panel-h h3 .link:hover{ color:var(--ball) }
.fm-rec{ flex:0 0 auto; font-family:var(--font-fig); font-variant-numeric:tabular-nums; font-size:15px; line-height:22px; font-weight:600; white-space:nowrap }
.fm-rec .n{ font-family:var(--font-text); font-size:13px; font-weight:400; color:var(--ink-soft) }
table.dt.fm-tbl{ min-width:440px }
col.w-fm-opp{ width:36% }
.panel-scroll.rows5{ min-height:calc(40px + 5 * 48px) }
.panel-in{ display:flex; flex-direction:column; flex:1 1 auto; min-height:0 }
.mt-h2h-sum b{ color:var(--ink); font-weight:600 }
table.dt.mt-dec{ min-width:900px }
col.w-kind{ width:22% }
col.w-dec{ width:104px }
col.w-side{ width:18% }
col.w-num{ width:96px }
col.w-reason-rest{ width:30% }
col.w-time{ width:168px }
table.dt.mp-prices{ min-width:560px }
table.dt tr.sel td{ background:var(--ball-soft) }
.am-sec + .am-sec{ border-top:1px solid var(--rule) }
.am-sec-h{ height:48px; padding:0 20px; display:flex; align-items:center; gap:12px; min-width:0; border-bottom:1px solid var(--rule) }
.am-sec-h h4{ margin:0; font-size:15px; line-height:22px; font-weight:600; white-space:nowrap }
.am-sec-h .link{ font-size:13px; white-space:nowrap }
.am-sec-h .am-note{ min-width:0; font-size:13px; line-height:18px; color:var(--ink-faint) }
.am-empty{ padding:14px 20px; font-size:14px; color:var(--ink-soft) }

/* «Уведомления»: 48 px one-line rows, 10 to a page; a bill marked orange,
   an overdue one red, by a dot before the text. */
.notices-list{ display:flex; flex-direction:column }
.notices-list.rows10{ min-height:calc(10 * 48px) }
.notices-list .notif-item{
  height:48px; padding:0 20px;
  display:grid; grid-template-columns:8px minmax(0,1fr) minmax(140px, 260px) 150px; gap:12px;
  align-items:center; color:inherit; text-decoration:none;
  border-bottom:1px solid var(--rule); font-size:14px; line-height:20px;
}
.notices-list .notif-item:last-child{ border-bottom:0 }
.notices-list .notif-item:hover{ background:var(--bg-2) }
.ni-ic{ width:8px; height:8px; border-radius:50%; background:var(--tone, transparent) }
.notices-list .notif-item[data-kind="bill_issued"]{ --tone:var(--ball) }
.notices-list .notif-item[data-kind="bill_overdue"]{ --tone:var(--bad) }
.notices-list .ni-title, .notices-list .ni-body{ min-width:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis }
.notices-list .ni-title{ color:var(--ink-soft) }
.notices-list .notif-item.unread .ni-title{ color:var(--ink); font-weight:500 }
.notices-list .ni-title .pill{ height:22px; margin-right:6px; vertical-align:1px }
.notices-list .ni-body{ color:var(--ink-soft) }
.notices-list .ni-when{ text-align:right; font-family:var(--font-fig); font-variant-numeric:tabular-nums; font-size:13px; color:var(--ink-soft); white-space:nowrap }
@media (max-width:760px){
  .notices-list .notif-item{ grid-template-columns:8px minmax(0,1fr) auto }
  .notices-list .ni-body{ display:none }
}

/* «Доступы»: the accounts in a table, each account's forms in its drawer. */
table.dt.acc-tbl{ min-width:760px }
table.dt.acc-audit{ min-width:760px }
/* A log's two-line rows for the rail (design D7); its table serves
   everywhere else. */
.lrow-list.rail-rows{ display:none }
.stack .lay-main > :is(.bp-top, .fm-pair){ margin-bottom:0 }
col.w-login{ width:28% }
col.w-tg{ width:160px }
col.w-accstate{ width:152px }
col.w-act{ width:136px }
table.dt.acc-tbl .pill{ height:22px; margin-left:6px; vertical-align:1px }
.acc-forms{ display:flex; flex-direction:column; gap:24px; text-align:left; white-space:normal }
.acc-form{ display:flex; flex-direction:column; align-items:flex-start; gap:12px; padding-bottom:24px; border-bottom:1px solid var(--rule) }
.acc-form:last-child{ padding-bottom:0; border-bottom:0 }
.acc-form .field{ width:100% }
.acc-form .input{ width:100% }
.acc-forms .note{ font-size:14px; line-height:20px; color:var(--ink-soft) }
.btn.danger{ color:var(--bad); border-color:var(--bad-line) }
.acc-new{ display:flex; flex-wrap:wrap; gap:12px 16px; align-items:flex-end }
.acc-new .field .input{ min-width:240px }
.acc-hint{ margin:12px 0 0; font-size:13px; line-height:18px; color:var(--ink-soft) }

/* Sign-in (§9): no hero and no title. The page is --top with the glow and
   the vignette, a table in thin white lines behind a centred 460 px card. */
.signin{
  position:relative; min-height:100vh; display:grid; place-items:center; padding:24px 16px;
  overflow:hidden; color:var(--ink);
  background:
    radial-gradient(ellipse 1100px 640px at 50% 35%, var(--glow), transparent 72%),
    radial-gradient(ellipse 1500px 900px at 50% 50%, transparent 55%, var(--vignette)),
    var(--top);
}
.signin-table{ position:absolute; inset:0; width:100%; height:100%; pointer-events:none }
.signin-table #siMesh path{ stroke:#ffffff; stroke-opacity:.12; stroke-width:.9 }
.signin-table .si-edge{ fill:#ffffff; fill-opacity:.025; stroke:#ffffff; stroke-opacity:.16; stroke-width:2 }
.signin-table .si-mid{ stroke:#ffffff; stroke-opacity:.08; stroke-width:1.5 }
.signin-table .si-mesh{ fill:url(#siMesh) }
.signin-table .si-net{ stroke:#ffffff; stroke-opacity:.22; stroke-width:1.5 }
.signin-table .si-post{ fill:#ffffff; fill-opacity:.22 }
.signin-table .si-trail{ fill:none; stroke:var(--top-acc); stroke-opacity:.8; stroke-width:3; stroke-dasharray:.1 11; stroke-linecap:round }
.signin-table .si-ball{ fill:var(--top-acc) }
@media (max-width:760px){ .signin-table{ display:none } }
.signin-card{
  position:relative; width:min(460px, 100%); padding:40px 40px 32px;
  display:flex; flex-direction:column; gap:20px;
  background:var(--bg-1); border-radius:32px; box-shadow:var(--shadow-float);
}
@media (max-width:760px){ .signin-card{ padding:32px 24px 24px } }
.signin-brand{ display:flex; align-items:center; justify-content:center; gap:12px; padding-bottom:6px; color:var(--ink) }
.signin-brand .brand-mark{ width:20px; color:var(--ink) }
.signin-brand .brand-name{ color:var(--ink) }
.signin-brand .brand-name svg{ height:26px }
.signin-error{ border-radius:18px }
.signin-form{ display:flex; flex-direction:column; gap:20px }
.signin-form .input{ height:52px; padding:0 18px; font-size:16px; border-radius:18px; background:var(--bg-2); border-color:var(--rule) }
.signin-form .input:focus{ border-color:var(--brand) }
.signin-form .btn{ height:54px; margin-top:4px; border-radius:27px; font-size:16px; background:var(--top); color:#ffffff }
.signin-form .btn:hover{ background:var(--top-2); filter:none }
/* In the evening theme --top is darker than the card, so the one action on
   the page would sink into it; lift it a step and ring it. */
body:not(.theme-light) .signin-form .btn{ background:var(--top-2); box-shadow:inset 0 0 0 1px var(--rule-strong) }
body:not(.theme-light) .signin-form .btn:hover{ background:var(--chip) }
.signin-hint{ margin:4px 0 0; font-size:14px; line-height:21px; text-align:center; color:var(--ink-faint) }
.signin-tg{ display:flex; flex-direction:column; gap:20px; align-items:center }
.signin-divider{ display:flex; align-items:center; gap:14px; width:100%; font-size:14px; color:var(--ink-faint) }
.signin-divider::before, .signin-divider::after{ content:""; flex:1; height:1px; background:var(--rule) }

/* The error page (§9): no hero; one centred card on the sheet with the
   ball stopped by the net, what went wrong and the way back. */
.err-card{ width:min(560px, 100%); margin:24px auto 0; padding:16px 16px 28px }
.err-card .art-empty{ flex-direction:column; align-items:stretch; gap:12px; padding:0 }
.err-card .art-box{ width:auto }
.err-card .art-words{ flex:0 0 auto; padding:8px 16px 0 }

/* Drawings (§8, partials/art.html): thin currentColor lines, the ball in
   --brand, in a --bg-2 box beside the words (above them when narrow). */
.art{ display:block; max-width:100%; height:auto; color:var(--ink); fill:none; stroke:currentColor; stroke-width:2.2; stroke-linecap:round; stroke-linejoin:round }
.art .dot{ fill:currentColor; stroke:none }
.art .ball{ fill:var(--brand); stroke:none }
.art .soft{ fill:var(--ball-soft) }
.art .floor{ stroke:var(--rule-strong) }
.art .trail{ stroke:var(--brand); stroke-width:3; stroke-dasharray:.1 7.5 }
.art .trail.idle{ stroke:var(--rule-strong); stroke-width:2; stroke-dasharray:.1 6 }
.art .mark{ stroke:var(--ink-faint); stroke-width:2 }
.art .mark.hit{ stroke:var(--bad) }
.art-empty{ display:flex; align-items:center; gap:24px 32px; flex-wrap:wrap; padding:16px 24px 24px }
.art-box{ flex:0 0 auto; width:360px; max-width:100%; height:200px; border-radius:18px; background:var(--bg-2); display:flex; align-items:center; justify-content:center }
.art-words{ flex:1 1 320px; min-width:0; display:flex; flex-direction:column; align-items:flex-start; gap:10px }
.art-title{ margin:0; font-size:21px; line-height:28px; font-weight:600; color:var(--ink) }
.art-text{ margin:0; max-width:460px; font-size:15px; line-height:23px; color:var(--ink-soft) }
.art-btn{ margin-top:6px }
.art-badge .dot{ width:8px; height:8px; border-radius:50%; background:currentColor }

/* Loaders (§8, partials/loading.html). The track is --chip, the ball
   --brand; it rolls only while something loads, and the reduced-motion
   block stills it. */
.roll{ position:relative; display:block; height:4px; border-radius:2px; background:var(--chip) }
.roll-ball{ position:absolute; left:0; top:-5px; width:14px; height:14px; border-radius:50%; background:var(--brand); animation:roll 1.6s ease-in-out infinite alternate }
@keyframes roll{ to{ left:calc(100% - 14px) } }
.pop-load{ width:240px; padding:14px 4px }
.skel{ padding-bottom:12px }
.skel-h{ height:64px; padding:0 24px; display:flex; align-items:center; gap:14px }
.skel-title{ flex:none; font-size:18px; line-height:24px; font-weight:600; color:var(--ink) }
.skel-h .roll{ flex:1 1 auto }
.skel-word{ flex:none; font-size:14px; color:var(--ink-faint) }
.skel-row{
  height:64px; margin:0 24px; border-bottom:1px solid var(--rule);
  display:grid; grid-template-columns:72px minmax(0,1fr) 150px 60px 140px; align-items:center; gap:16px;
}
.skel-row i{ display:block; height:12px; border-radius:6px; background:var(--chip) }
.skel-row .s-two{ display:flex; flex-direction:column; gap:8px; min-width:0 }
.skel-row .s-two i{ max-width:100% }
.skel-row .s-sub{ height:10px; border-radius:5px; background:var(--bg-2) }
.skel-row .s-time{ width:44px }
.skel-row .s-pick{ width:110px }
.skel-row .s-odds{ width:40px }
.skel-row .s-pill{ width:92px; height:28px; border-radius:14px; background:var(--bg-2) }
@media (max-width:760px){
  .skel-row{ grid-template-columns:56px minmax(0,1fr) }
  .skel-row .s-pick, .skel-row .s-odds, .skel-row .s-pill{ display:none }
}
/* A button whose request is pending: navy, the ball hopping over a small
   net in 600 ms, and its busy words (workbench.js swaps .btn-word from
   data-busy and sets aria-busy; an HTMX button gets .htmx-request). */
.btn .hop{ display:none; flex:none }
.btn[aria-busy="true"], .btn.htmx-request{ background:var(--top); color:#ffffff; border-color:var(--top); padding-left:14px; pointer-events:none }
.btn[aria-busy="true"] .hop, .btn.htmx-request .hop{ display:block }
/* In the evening theme --top is darker than the card: a step up and a ring,
   as on the sign-in button. */
body:not(.theme-light) .btn[aria-busy="true"], body:not(.theme-light) .btn.htmx-request{ background:var(--top-2); border-color:var(--rule-strong) }
.hop path{ fill:none; stroke:currentColor; stroke-width:2; stroke-linecap:round }
.hop-ball{ fill:var(--top-acc); animation:hop .6s linear infinite alternate }
@keyframes hop{
  0%{ transform:translate(-11px, 10px) }
  25%{ transform:translate(-6px, 2.5px) }
  50%{ transform:translate(0, 0) }
  75%{ transform:translate(6px, 2.5px) }
  100%{ transform:translate(11px, 10px) }
}

/* ── The rail (istrena-wide-rail D1–D7, partials/layout.html). From a
   2200 px window: the main column and a 440 px rail, 24 px apart, both
   ending on one edge. Below it the wrappers step aside (`display:
   contents`), every block stands where it stood, and the Табло is not
   drawn, so its `intersect` trigger never fires. ── */
.lay, .lay-main, .lay-rail{ display:contents }
/* Under 2200 px the blocks are items of the page's own flex column
   (.stack), which the child rules there no longer reach. */
.lay-main > *, .lay-rail > *{ min-width:0 }
.stack .lay-main > .pair{ margin-bottom:0 }
.tablo-slot{ display:none }
@media (min-width:2200px){
  .lay{ display:grid; grid-template-columns:minmax(0, 1fr) 440px; gap:24px; align-items:stretch }
  .lay-main, .lay-rail{ display:flex; flex-direction:column; gap:24px; min-width:0 }
  .lay > :is(.lay-main, .lay-rail) > *{ margin-top:0; margin-bottom:0 }
  /* The shorter column's last block takes the free space; a panel carries
     it in its .panel-fill note. A wrapper passes it to its last panel. */
  .lay-main > :last-child, .lay-rail > :last-child{ flex:1 0 auto }
  .tablo-slot, .lay-pass{ display:flex; flex-direction:column; min-width:0 }
  .tablo-slot > .panel, .lay-pass > :last-child{ flex:1 0 auto }
  /* An empty list's drawing stands in the middle of a stretched panel. */
  .lay .panel > .art-empty:last-child{ flex:1 0 auto; align-content:center }

  /* League tiles in the rail: one panel, a tile per row at 168 px. */
  .lay-rail .ltiles-block{
    display:flex; flex-direction:column; min-width:0; overflow:hidden;
    background:var(--bg-1); border-radius:var(--r-card); box-shadow:var(--lift);
  }
  .lay-rail .ltiles-top{ flex:none; height:60px; margin:0; padding:4px 24px 0; align-items:center }
  .lay-rail .ltiles{ grid-template-columns:minmax(0, 1fr); gap:0 }
  .lay-rail .ltile{ background:none; box-shadow:none; border-radius:0; border-top:1px solid var(--rule) }
  /* At the rail's width the title keeps its words and count; the
     explanation beside it gives way. */
  .lay-rail .panel-h > h3{ flex:0 0 auto; max-width:100% }
  .lay-rail .panel-h > .acts.bp-faint{
    display:block; flex:0 1 auto; min-width:0;
    overflow:hidden; white-space:nowrap; text-overflow:ellipsis;
  }

  /* Compact tables in the rail (D7): a table keeps its label and main
     figures, and its `.c-x` cells are in the row's title. Without the
     colgroup the head row sets the widths. */
  .lay-rail table.dt{ min-width:0 }
  .lay-rail table.dt :is(colgroup, .c-x){ display:none }
  .lay-rail table.dt th.c-state{ width:148px }
  .lay-rail table.dt.st-table .c-wl{ display:table-cell; width:76px }
  .lay-rail table.dt.st-table :is(th.c-fl, th.c-roi){ width:80px }
  .lay-rail table.dt.st-table th.c-share{ width:104px }

  /* Forms stack their fields; a log reads as two-line rows. */
  .lay-rail :is(.acc-new, .be-form){ flex-direction:column; flex-wrap:nowrap; align-items:stretch }
  .lay-rail :is(.acc-new, .be-form) .field .input{ min-width:0; width:100% }
  .lay-rail :is(table.dt.acc-audit, table.dt.be-audit){ display:none }
  .lay-rail .lrow-list.rail-rows{ display:flex }
  .lay-rail table.dt.played th.c-date{ width:124px }
  .lay-rail table.dt.played th.c-score{ width:64px }

  /* The group cards count by the main column, not the window: five from
     1696 px (320 a card, as at a 1761 px window), four below. */
  .lay-main #grList{ container-type:inline-size }
  @container (max-width:1695px){ .gcards{ grid-template-columns:repeat(4, minmax(0, 1fr)) } }
}
table.dt.st-table .c-wl{ display:none }

/* ── The Табло (partials/tablo.html): the hero of «Сегодня» at the rail's
   scale. 60 px head and a 204 px body, the skeleton at the same height. ── */
.tablo-body{
  flex:none; height:204px; box-sizing:border-box; padding:0 24px 20px;
  display:flex; flex-direction:column; min-width:0;
}
.tablo-day{ display:flex; align-items:baseline; gap:10px; min-width:0; color:var(--ink); white-space:nowrap }
.tablo-fig{
  font-family:var(--font-fig); font-variant-numeric:tabular-nums;
  font-size:56px; line-height:60px; font-weight:600; color:var(--ink);
}
.tablo-fig.up{ color:var(--ok) }
.tablo-fig.down{ color:var(--bad) }
.tablo-unit{ font-size:16px; line-height:22px; color:var(--ink-faint) }
.tablo-line{
  margin-top:4px; font-size:14px; line-height:22px; color:var(--ink-soft);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.tablo-line .num{ font-size:17px; font-weight:600; color:var(--ink) }
.tablo-day:hover .tablo-unit, .tablo-line:hover{ color:var(--ink) }
.tablo-tiles{ margin-top:auto; display:grid; grid-template-columns:repeat(3, minmax(0, 1fr)); gap:8px }
.tablo-tile{
  height:64px; box-sizing:border-box; min-width:0; padding:9px 14px;
  border-radius:18px; background:var(--bg-2); color:var(--ink);
  display:flex; flex-direction:column;
}
a.tablo-tile:hover{ background:var(--chip) }
.tablo-cap{ font-size:13px; line-height:18px; color:var(--ink-soft); white-space:nowrap; overflow:hidden; text-overflow:ellipsis }
.tablo-val{ font-size:22px; line-height:28px; font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis }
.tablo-tile.hot{ background:var(--ball-soft) }
.tablo-tile.hot .tablo-val{ color:var(--ball) }
.tablo a:focus-visible{ outline:2px solid var(--focus); outline-offset:2px; border-radius:12px }
.tablo.skel{ padding-bottom:0 }
.tablo .panel-h .roll{ flex:1 1 auto }
.tablo-skel-fig{ display:block; width:184px; height:44px; margin-top:8px; border-radius:12px; background:var(--chip) }
.tablo-skel-line{ display:block; width:248px; height:12px; margin-top:18px; border-radius:6px; background:var(--bg-2) }
i.tablo-tile{ display:block }
.tablo-fail{ flex-direction:row; align-items:center; gap:16px; padding-top:4px }
.tablo-art{
  flex:none; width:128px; height:112px; border-radius:14px; background:var(--bg-2);
  display:grid; place-items:center; color:var(--ink-faint);
}
.tablo-art .art{ width:112px; height:56px }
.tablo-fail-words{ min-width:0 }
.tablo-fail-h{ margin:0; font-size:17px; line-height:24px; font-weight:600; color:var(--ink) }
.tablo-fail-s{ margin:4px 0 0; font-size:14px; line-height:20px; color:var(--ink-soft) }
