/* WUCC 2026 BEUltimate Tracker — extracted from wucc2026_map_mockup_v4.html
 * and extended with the tab shell, toolbar filters and standings tab.
 * Division colours and the BE gold are the validated values from the brief. */

:root{
  --bg:#0a0e12; --panel:#12181f; --panel-2:#171f28; --line:#26313b;
  --text:#eef2f5; --text-dim:#8fa0ac; --text-faint:#5d6d79;
  --gold:#e0b13e; --open:#4f8bf0; --mixed:#b06fe0; --womens:#ef5da8;
  --live:#2ec27e; --accent:#2c7a63;
  /* Cap deliberately does NOT reuse --gold: gold means "BEUltimate team" on
     every other surface, and a gold block on a game card would read as that.
     This is the same attention red as the offline status LED. */
  --cap:#e0553e;
  /* The qualifying cut on a pool table. See "the bracket cut" below for why this
     is neither gold nor green. */
  --cut:#6f8ba6; --cut-text:#93aec7;
}
*{box-sizing:border-box;}
html,body{height:100%;}
body{
  margin:0;background:var(--bg);color:var(--text);font-family:'Inter',sans-serif;
  -webkit-font-smoothing:antialiased;overflow:hidden;
}

.app{display:flex;flex-direction:column;height:100%;}

/* ---------------- header + tabs ---------------- */
header{
  display:flex;align-items:center;gap:10px;padding:10px 12px;
  border-bottom:1px solid var(--line);flex:none;z-index:20;background:var(--bg);
}
.crest{
  width:30px;height:30px;border-radius:7px;flex:none;
  background:conic-gradient(from 45deg,var(--gold),#8a6a1f,var(--gold));
  display:flex;align-items:center;justify-content:center;
  font-family:'Barlow Condensed';font-weight:700;font-size:9px;color:#0a0e12;
}
header h1{
  font-family:'Barlow Condensed';font-weight:700;font-size:14px;letter-spacing:.2px;
  margin:0;text-transform:uppercase;line-height:1.2;
}
header .sub{display:block;font-size:9.5px;color:var(--text-dim);margin-top:1px;}
header .spacer{flex:1;}
header .titles{min-width:0;}
header h1{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}

/* ---------------- info / disclaimer ---------------- */
.info-btn{
  flex:none;width:24px;height:24px;border-radius:50%;background:var(--panel);
  border:1px solid var(--line);color:var(--text-dim);font-family:'Barlow Condensed',serif;
  font-style:italic;font-weight:700;font-size:14px;line-height:1;cursor:pointer;
  display:flex;align-items:center;justify-content:center;
}
.info-btn:hover,.info-btn[aria-expanded="true"]{border-color:var(--gold);color:var(--gold);}
.info-panel{
  /* top is set from the header's measured height when it opens, since the
     header grows a little at the 640px breakpoint */
  position:fixed;top:52px;right:10px;z-index:80;width:min(320px,calc(100vw - 20px));
  background:var(--panel);border:1px solid var(--gold);border-radius:11px;
  padding:14px 16px 15px;box-shadow:0 16px 40px rgba(0,0,0,.6);
}
.info-panel[hidden]{display:none;}
.info-panel h2{
  font-family:'Barlow Condensed';font-weight:700;font-size:15px;margin:0 0 7px;
  text-transform:uppercase;letter-spacing:.3px;color:var(--gold);padding-right:18px;
}
.info-panel p{margin:0 0 8px;font-size:11.5px;line-height:1.55;color:var(--text-dim);}
.info-panel p:last-child{margin-bottom:0;}
.info-panel strong{color:var(--text);}
.info-panel a{color:var(--gold);font-weight:600;word-break:break-all;}
/* break-all above is for the bare WFDF URL, which has to be allowed to wrap
   anywhere. A name sitting inside a sentence must not: it would split as
   "Ra / yJ" whenever it landed at the end of a line. */
.info-panel a.inline-link{word-break:normal;white-space:nowrap;}
.info-panel .info-meta{
  border-top:1px dashed var(--line);padding-top:8px;margin-top:10px;
  font-size:10.5px;color:var(--text-faint);
}
.info-close{
  position:absolute;top:7px;right:9px;background:none;border:none;cursor:pointer;
  color:var(--text-dim);font-size:13px;font-family:inherit;padding:2px;line-height:1;
}
.status-chip{
  flex:none;display:flex;align-items:center;gap:5px;font-size:9.5px;color:var(--text-dim);
  border:1px solid var(--line);border-radius:7px;padding:4px 8px;background:var(--panel);
  white-space:nowrap;cursor:pointer;font-family:inherit;
}
.status-chip .led{width:7px;height:7px;border-radius:50%;background:var(--text-faint);flex:none;}
.status-chip.ok .led{background:var(--live);}
.status-chip.warn .led{background:var(--gold);}
.status-chip.err .led{background:#e0553e;}

/* Scrolls rather than wraps: "Power Rankings" is a wide label and three tabs
   run out of room on a narrow phone. Same treatment as .toolbar. */
.tabs{
  display:flex;gap:2px;padding:0 10px;border-bottom:1px solid var(--line);flex:none;
  background:var(--bg);z-index:20;overflow-x:auto;-webkit-overflow-scrolling:touch;
  scrollbar-width:none;
}
.tabs::-webkit-scrollbar{display:none;}
.tab{
  appearance:none;background:none;border:none;border-bottom:2px solid transparent;
  color:var(--text-dim);font-family:inherit;font-size:12.5px;font-weight:600;
  padding:9px 12px;cursor:pointer;flex:none;white-space:nowrap;
}
.tab.active{color:var(--text);border-bottom-color:var(--gold);}
.panel{flex:1;min-height:0;display:none;flex-direction:column;}
.panel.active{display:flex;}

/* ---------------- search ---------------- */
.search-bar{position:relative;padding:8px 10px 6px;flex:none;background:var(--bg);z-index:25;border-bottom:1px solid var(--line);}
#searchInput{
  width:100%;box-sizing:border-box;background:var(--panel);border:1px solid var(--line);border-radius:9px;
  color:var(--text);font-size:14px;padding:9px 34px 9px 32px;outline:none;font-family:inherit;
}
#searchInput:focus{border-color:var(--gold);}
.search-icon{position:absolute;left:20px;top:16px;color:var(--text-dim);font-size:15px;pointer-events:none;}
.search-clear{position:absolute;right:20px;top:15px;color:var(--text-dim);font-size:13px;cursor:pointer;display:none;padding:3px;}
.search-bar.has-text .search-clear{display:block;}
.search-results{
  position:absolute;left:10px;right:10px;top:calc(100% - 4px);
  background:var(--panel);border:1px solid var(--gold);border-top:none;border-radius:0 0 10px 10px;
  max-height:260px;overflow-y:auto;box-shadow:0 12px 24px rgba(0,0,0,.5);display:none;
}
.search-results.show{display:block;}
/* Two lines per result: identity on top, what they're doing underneath. One
   line couldn't fit team + division + opponent + field without ellipsising the
   part you were looking for. */
.search-result-item{
  display:block;padding:9px 14px;border-bottom:1px solid var(--line);cursor:pointer;
}
.search-result-item:last-child{border-bottom:none;}
.search-result-item:hover,.search-result-item:active{background:rgba(224,177,62,.12);}
.search-result-item .sr-main{display:flex;align-items:center;gap:7px;min-width:0;}
.search-result-item .sr-dot{width:8px;height:8px;border-radius:2px;flex:none;}
.search-result-item .sr-name{
  font-weight:700;font-size:13.5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.search-result-item .sr-div{
  font-size:9px;font-weight:700;letter-spacing:.4px;text-transform:uppercase;color:var(--text-faint);
  border:1px solid var(--line);border-radius:4px;padding:1px 4px;flex:none;
}
.search-result-item .sr-field{
  font-family:'JetBrains Mono';font-size:10.5px;color:var(--text-dim);flex:none;margin-left:auto;
  background:rgba(255,255,255,.06);padding:3px 7px;border-radius:6px;white-space:nowrap;
}
.search-result-item .sr-sub{
  font-size:11px;color:var(--text-dim);margin:3px 0 0 15px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.search-result-item .sr-live{color:var(--live);font-weight:700;}
/* names the other site when the game isn't on the map you're looking at */
.search-result-item .sr-at{color:var(--gold);font-weight:600;}
.search-result-item.be .sr-name{color:var(--gold);}
.search-result-item.be .sr-field{color:var(--gold);background:rgba(224,177,62,.15);}
.search-result-item.idle .sr-field{color:var(--text-faint);}
.search-result-item.idle .sr-sub{color:var(--text-faint);}
.search-empty{padding:14px;text-align:center;font-size:12.5px;color:var(--text-dim);}

/* ---------------- toolbar ---------------- */
.toolbar{
  display:flex;align-items:center;gap:6px;padding:7px 10px;border-bottom:1px solid var(--line);
  flex:none;overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none;
  background:var(--bg);z-index:20;
}
.toolbar::-webkit-scrollbar{display:none;}
.toolbar-label{
  flex:none;font-size:9px;font-weight:700;letter-spacing:.6px;text-transform:uppercase;
  color:var(--text-faint);padding-right:2px;
}
.pill{
  flex:none;padding:6px 12px;border-radius:8px;background:var(--panel);border:1px solid var(--line);
  font-size:12px;font-weight:600;color:var(--text-dim);white-space:nowrap;cursor:pointer;
  font-family:inherit;
}
.pill:disabled{opacity:.35;cursor:default;}
.pill.active{background:var(--accent);border-color:var(--accent);color:#fff;}
.pill .n{font-size:9.5px;opacity:.7;margin-left:4px;font-family:'JetBrains Mono';}
.pill.now{border-color:var(--live);color:var(--live);}
.pill.now.active{background:var(--live);border-color:var(--live);color:#08130d;}
.sep{width:1px;align-self:stretch;background:var(--line);flex:none;margin:0 2px;}
.legend-item{display:flex;align-items:center;gap:4px;font-size:10.5px;color:var(--text-dim);flex:none;}
.dot{width:8px;height:8px;border-radius:2px;flex:none;}
.dot.open{background:var(--open);} .dot.mixed{background:var(--mixed);} .dot.womens{background:var(--womens);}
.dot.live{background:var(--live);border-radius:50%;}
.be-chip{
  display:flex;align-items:center;gap:5px;background:var(--panel);border:1px solid var(--gold);
  padding:5px 10px;border-radius:8px;font-size:10.5px;font-weight:600;color:var(--gold);flex:none;
  font-family:inherit;cursor:pointer;
}
.be-chip .sw{width:9px;height:9px;border-radius:2px;border:2px solid var(--gold);}
/* filter engaged: gold fill, so it reads as "on" rather than just a legend */
.be-chip.active{background:var(--gold);color:#0a0e12;}
.be-chip.active .sw{border-color:#0a0e12;}

/* ---------------- map ---------------- */
.map-viewport{position:relative;flex:1;overflow:hidden;touch-action:none;background:#0d1a16;}
.map-canvas{position:absolute;top:0;left:0;transform-origin:0 0;will-change:transform;}
.map-canvas svg{display:block;}
/* One SVG per venue, stacked; only the active one is displayed. Both are kept
   up to date so switching sites is instant. */
.venue-svg{position:absolute;top:0;left:0;}
.pill.empty{opacity:.55;}

.field{cursor:pointer;}
.field polygon{transition:fill .12s,stroke-width .12s;}
/* Hover/selection target .field-shape specifically: a bare `polygon` selector
   would also repaint the BE halo behind it, since CSS beats the fill="none"
   presentation attribute. */
.field:hover .field-shape,.field:focus .field-shape{fill:rgba(20,180,150,.65);}
/* Selection is white, not gold. Gold now means BEUltimate and nothing else —
   with both in gold, a tapped field looked like a tracked one. */
.field.selected .field-shape{fill:rgba(255,255,255,.24);stroke:#fff;stroke-width:4.5;}

/* We draw no field numbers: the venue artwork already prints them, and a second
   set on top just fought with it. The number lives in a <title> instead. */

/* BEUltimate: a fat gold outline hugging the real field shape, plus a star
   badge in the middle. Nothing else on the map is gold. */
.be-halo{fill:none;stroke:var(--gold);stroke-width:11;stroke-opacity:.5;pointer-events:none;}
.field.selected .be-halo{stroke-opacity:.85;}
.be-badge{pointer-events:none;}
.be-badge circle{fill:var(--gold);stroke:#0a0e12;stroke-width:1.5;}
.be-badge text{font-size:11px;font-weight:700;fill:#0a0e12;text-anchor:middle;dominant-baseline:central;}
.live-pip{fill:var(--live);stroke:#0a0e12;stroke-width:1.5;animation:pulse 1.6s ease-in-out infinite;}
@keyframes pulse{0%,100%{opacity:1;}50%{opacity:.3;}}

.zoom-controls{position:absolute;right:12px;bottom:18px;display:flex;flex-direction:column;gap:6px;z-index:15;}
.zoom-btn{
  width:38px;height:38px;border-radius:10px;background:rgba(18,24,31,.92);border:1px solid var(--line);
  color:var(--text);font-size:18px;font-weight:700;display:flex;align-items:center;justify-content:center;
  -webkit-tap-highlight-color:transparent;cursor:pointer;font-family:inherit;
}
.hint{
  position:absolute;left:12px;bottom:18px;z-index:15;background:rgba(18,24,31,.88);
  border:1px solid var(--line);border-radius:9px;padding:7px 11px;font-size:10.5px;
  color:var(--text-dim);max-width:210px;line-height:1.4;
}
.offmap{
  position:absolute;left:12px;top:12px;z-index:14;background:rgba(18,24,31,.94);
  border:1px solid var(--line);border-radius:9px;padding:8px 10px;max-width:230px;
  font-size:10.5px;color:var(--text-dim);line-height:1.5;
}
.offmap b{color:var(--gold);font-size:10px;letter-spacing:.4px;text-transform:uppercase;display:block;margin-bottom:3px;}
.offmap .og{display:flex;justify-content:space-between;gap:8px;padding:2px 0;color:var(--text);font-size:11px;}
.offmap .og .f{font-family:'JetBrains Mono';color:var(--text-dim);flex:none;}
.offmap .og-more{font-size:10px;color:var(--text-faint);padding-top:2px;}
.offmap .og-filtered{color:var(--gold);opacity:.85;}
.offmap .og-group+.og-group{margin-top:8px;border-top:1px solid var(--line);padding-top:7px;}
.offmap .og-group.clickable{cursor:pointer;}
.offmap .og-group.clickable:hover b{color:#fff;}
.offmap.empty{display:none;}

/* ---------------- popover ---------------- */
.popover{
  position:absolute;z-index:30;background:var(--panel);border:1.5px solid var(--gold);
  border-radius:12px;padding:12px 14px;min-width:200px;max-width:280px;
  box-shadow:0 12px 30px rgba(0,0,0,.55);transform:translate(-50%,-100%);margin-top:-14px;
  opacity:0;pointer-events:none;transition:opacity .12s,transform .12s;
}
.popover.show{opacity:1;pointer-events:auto;}
.popover .pfield{font-family:'JetBrains Mono';font-size:10px;color:var(--text-dim);margin-bottom:6px;display:flex;justify-content:space-between;gap:10px;}
.popover .pdiv{height:3px;border-radius:2px;margin-bottom:8px;}
.popover .pteam{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:3px 0;}
.popover .pteam .n{font-size:14px;font-weight:700;}
/* Seed + our rank, under the team name on a game card. */
.popover .pteam .pmeta{
  display:block;font-family:'JetBrains Mono';font-size:9.5px;font-weight:500;
  color:var(--text-faint);letter-spacing:.2px;margin-top:2px;
}
.popover .pteam .n.tbd{font-weight:600;color:var(--text-dim);font-style:italic;font-size:12.5px;}
.popover .pteam .n .star{color:var(--gold);}
.popover .pteam .f{font-size:10.5px;color:var(--text-dim);font-family:'JetBrains Mono';flex:none;}
.popover .pteam .sc{font-family:'JetBrains Mono';font-size:15px;font-weight:600;flex:none;}
.popover .pvs{font-size:9px;color:var(--text-dim);letter-spacing:1.5px;text-align:center;margin:2px 0;}
.popover .pbe{margin-top:8px;padding-top:8px;border-top:1px dashed var(--line);font-size:10px;color:var(--gold);font-weight:600;display:flex;align-items:center;gap:5px;}
.popover .pnote{margin-top:7px;font-size:9.5px;color:var(--text-faint);line-height:1.45;}
.popover .plater{margin-top:8px;padding-top:7px;border-top:1px solid var(--line);font-size:10px;color:var(--text-dim);}
.popover .plater .row{display:flex;justify-content:space-between;gap:8px;padding:1px 0;}
.popover .plater .row .t{font-family:'JetBrains Mono';flex:none;color:var(--text-faint);}
.popover .plive{
  display:inline-flex;align-items:center;gap:4px;color:var(--live);font-size:9px;font-weight:700;
  letter-spacing:.6px;text-transform:uppercase;
}
.popover .plive::before{content:'';width:6px;height:6px;border-radius:50%;background:var(--live);animation:pulse 1.6s ease-in-out infinite;}
/* Cap is a state change a shooter needs to catch at a glance — the game is
   ending soon — so it gets a filled block rather than another quiet dim line. */
.popover .pcap{
  margin-top:8px;display:flex;align-items:center;gap:7px;
  background:rgba(224,85,62,.14);border:1px solid rgba(224,85,62,.45);
  border-radius:4px;padding:5px 7px;
}
.popover .pcap .tag{
  font-family:'JetBrains Mono';font-size:9.5px;font-weight:700;letter-spacing:1px;
  color:#fff;background:var(--cap);border-radius:2px;padding:2px 5px;flex:none;
}
.popover .pcap .det{font-size:10px;color:var(--cap);letter-spacing:.2px;}
.popover .close{position:absolute;top:6px;right:8px;color:var(--text-dim);font-size:14px;cursor:pointer;}
.popover .arrow{
  position:absolute;bottom:-7px;left:50%;transform:translateX(-50%);width:0;height:0;
  border-left:7px solid transparent;border-right:7px solid transparent;border-top:7px solid var(--gold);
}
.popover.flip{transform:translate(-50%,14px);margin-top:0;}
.popover.flip .arrow{bottom:auto;top:-7px;border-top:none;border-bottom:7px solid var(--gold);}
.popover.empty .pfield{margin-bottom:0;}

/* ---------------- standings ---------------- */
/* The scroll pane every tab panel uses. It has to carry flex:1 and min-height:0
   as well as overflow: .panel is a flex column of fixed height, so a child without
   these two grows to its content and the panel never scrolls at all. Named for the
   panel rather than the standings, which is where it started -- the Active Games
   list was added with a plain "scroll" class that matched no rule, and the tab
   shipped unscrollable. */
.pane-scroll{flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;padding:0 0 40px;}
.pool-block{border-bottom:1px solid var(--line);}
.pool-head{
  display:flex;align-items:baseline;gap:8px;padding:12px 12px 7px;position:sticky;top:0;
  background:linear-gradient(var(--bg) 70%,rgba(10,14,18,.85));z-index:2;
}
.pool-head h2{font-family:'Barlow Condensed';font-weight:700;font-size:16px;margin:0;text-transform:uppercase;letter-spacing:.3px;}
.pool-head .meta{font-size:10px;color:var(--text-faint);font-family:'JetBrains Mono';}
.pool-head .badge{
  margin-left:auto;flex:none;font-size:9px;font-weight:700;letter-spacing:.5px;text-transform:uppercase;
  border-radius:5px;padding:3px 6px;border:1px solid var(--line);color:var(--text-dim);
}
.pool-head .badge.official{border-color:var(--live);color:var(--live);}
.pool-head .badge.provisional{border-color:var(--gold);color:var(--gold);}
table.standings{width:100%;border-collapse:collapse;font-size:13px;}
table.standings th{
  text-align:right;font-size:9px;font-weight:700;letter-spacing:.5px;text-transform:uppercase;
  color:var(--text-faint);padding:4px 6px;border-bottom:1px solid var(--line);white-space:nowrap;
}
table.standings th.tl,table.standings td.tl{text-align:left;}
table.standings td{padding:7px 6px;border-bottom:1px solid rgba(38,49,59,.5);text-align:right;font-variant-numeric:tabular-nums;}
table.standings td.rank{color:var(--text-faint);font-family:'JetBrains Mono';font-size:11px;width:26px;padding-left:12px;}
table.standings td.team{text-align:left;font-weight:600;}
table.standings td.team .ctry{color:var(--text-faint);font-size:10.5px;font-family:'JetBrains Mono';margin-left:6px;}
table.standings td.team .seed{color:var(--text-faint);font-size:10px;margin-left:6px;}
/* Our computed rank, sat next to the seed so the pair reads as one thought. */
table.standings td.team .rankbadge{
  font-size:9.5px;font-family:'JetBrains Mono';color:var(--accent-text,#7fd8bd);
  border:1px solid rgba(44,122,99,.55);border-radius:3px;padding:1px 4px;margin-left:6px;
  white-space:nowrap;
}
table.standings td.team .rankbadge.thin{color:var(--text-faint);border-color:var(--line);border-style:dashed;}
/* A score must never break across lines. The separator is an en dash, which is a
   valid break opportunity, so "12–10" in a narrow column splits into "12–" and
   "10" on two lines — it reads as two separate numbers and it makes that one row
   taller than every other. Same reasoning for the numeric columns beside it.
   The headers already carry nowrap a few rules up. */
table.standings td.wl{font-family:'JetBrains Mono';font-size:12px;white-space:nowrap;}
table.standings td.num,
table.standings td.rank{white-space:nowrap;}
/* ---------------- active games ----------------
   Ordered by field number, because that is the order you walk past them. The
   field number is therefore the thing to find first, so it sits in its own column
   on the left at a size you can read at arm's length. */
.ag-head{
  display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;
  padding:11px 12px 9px;border-bottom:1px solid var(--line);
  position:sticky;top:0;background:var(--bg);z-index:5;
}
.ag-head h2{
  font-family:'Barlow Condensed',serif;font-weight:700;font-size:16px;margin:0;
  text-transform:uppercase;letter-spacing:.3px;
}
.ag-head .meta{font-size:10px;color:var(--text-faint);font-family:'JetBrains Mono';}
.ag-card{
  display:flex;gap:10px;align-items:stretch;cursor:pointer;
  padding:8px 12px;border-bottom:1px solid rgba(38,49,59,.6);
}
.ag-card:hover,.ag-card:focus-visible{background:var(--panel);outline:none;}
.ag-card:focus-visible{box-shadow:inset 2px 0 0 var(--gold);}
.ag-field{
  flex:none;width:46px;display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:1px;border-right:1px solid var(--line);padding-right:8px;
}
/* 21px, not 23: the F costs a character and "F31" has to fit the 46px column
   without wrapping or being clipped. */
.ag-fnum{font-family:'Barlow Condensed',serif;font-weight:700;font-size:21px;line-height:1;
  white-space:nowrap;}
.ag-venue{
  font-size:8px;text-transform:uppercase;letter-spacing:.4px;color:var(--text-faint);
  text-align:center;line-height:1.1;
}
.ag-body{flex:1;min-width:0;}
.ag-top{display:flex;align-items:center;gap:7px;margin-bottom:3px;}
.ag-type{
  font-size:9.5px;font-weight:700;text-transform:uppercase;letter-spacing:.5px;
  color:var(--text-dim);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  /* min-width:0 so it can actually shrink -- "17th place · Round of 16" is long,
     and without it a flex item refuses to go below its content width and pushes
     the division chip off the card instead of ellipsing. */
  flex:1;min-width:0;
}
/* Gold for a showcase game, unlike every other badge here, because gold already
   means "BEUltimate" on this site and a filmed game is exactly what that is about.
   An all-access game gets the same icon in faint ink -- the platform is carried by
   the icon's shape, so colour stays free to mean "showcase". */
.stream-badge{
  flex:none;display:inline-flex;align-items:center;gap:4px;
  font-size:8.5px;font-weight:700;text-transform:uppercase;letter-spacing:.4px;
  border-radius:4px;padding:1px 4px;text-decoration:none;
  color:var(--text-faint);border:1px solid transparent;
}
.stream-badge svg{display:block;flex:none;}
.stream-badge.showcase{color:var(--gold);border-color:rgba(224,177,62,.55);}
.stream-badge:hover,.stream-badge:focus-visible{border-color:currentColor;outline:none;}
.pstream{padding:4px 8px 0;}
.pstream .stream-badge{font-size:9px;}
.ag-div{
  flex:none;font-size:8.5px;font-weight:700;text-transform:uppercase;letter-spacing:.4px;
  border-radius:4px;padding:1px 5px;border:1px solid currentColor;opacity:.85;
}
.ag-div.open{color:var(--open);}
.ag-div.mixed{color:var(--mixed);}
.ag-div.womens{color:var(--womens);}
.ag-top .lvdot{margin-left:auto;flex:none;}
/* One grid for both sides so the scores line up as a column, which is what makes
   a glance down the list readable. */
.ag-side{display:flex;align-items:baseline;gap:6px;font-size:13px;padding:1px 0;}
.ag-name{
  flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  color:var(--text-dim);
}
.ag-side.lead .ag-name{color:var(--text);font-weight:600;}
.ag-ctry{
  flex:none;font-family:'JetBrains Mono';font-size:9.5px;color:var(--text-faint);
}
.ag-rank{
  flex:none;font-family:'JetBrains Mono';font-size:9.5px;color:var(--accent-text,#7fd8bd);
  min-width:26px;text-align:right;
}
.ag-rank.none{min-width:26px;}
.ag-score{
  flex:none;font-family:'JetBrains Mono';font-size:15px;width:26px;text-align:right;
  color:var(--text-dim);
}
.ag-side.lead .ag-score{color:var(--live);font-weight:600;}

/* ---------------- the bracket cut ----------------
   The line under the last pool placing that can still win the division.

   Deliberately not --gold: gold is reserved for BEUltimate teams here, and a gold
   rule cutting across a pool would read as being about those teams. Not --live
   either, which means a game is in progress. So a colour of its own, cool and
   desaturated enough that it sits behind the standings rather than competing with
   them, and clearly heavier than the 1px row rules so it does not just look like
   one of them. */
/* The last qualifying row drops its own rule, so the dashed line below it reads
   as one divider instead of two rules a pixel apart. */
table.standings tr.cut > td{border-bottom:0;}
table.standings tr.cutline > td{padding:0;border:0;}
table.standings tr.cutline .lbl{
  display:flex;align-items:center;gap:7px;
  font-family:'Barlow Condensed',serif;font-size:9px;font-weight:700;
  text-transform:uppercase;letter-spacing:.6px;color:var(--cut-text);
  padding:3px 6px 4px;
}
/* The rule is drawn either side of the label, so the label sits in the gap
   instead of on top of the line. */
table.standings tr.cutline .lbl::before,
table.standings tr.cutline .lbl::after{
  content:'';flex:1;height:0;border-top:2px dashed var(--cut);
}
.cut-note{
  margin:0;padding:9px 12px 8px;font-size:11px;line-height:1.45;
  color:var(--text-dim);border-bottom:1px solid var(--line);
  display:flex;align-items:baseline;gap:8px;
}
.cut-note b{color:var(--text);font-weight:600;}
.cut-note .dash{
  flex:none;width:16px;height:0;border-top:2px dashed var(--cut);
  transform:translateY(-3px);
}

/* ---------------- rankings ---------------- */
.rank-head{
  display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;
  padding:11px 12px 9px;border-bottom:1px solid var(--line);
}
.rank-head h2{font-family:'Barlow Condensed';font-weight:700;font-size:16px;margin:0;
  text-transform:uppercase;letter-spacing:.3px;}
.rank-head .meta{font-size:10px;color:var(--text-faint);font-family:'JetBrains Mono';}
.rank-head .rank-algo{
  margin-left:auto;font-size:10px;font-family:'JetBrains Mono';color:var(--gold);
  border:1px solid rgba(224,177,62,.45);border-radius:4px;padding:3px 7px;
  text-decoration:none;white-space:nowrap;
}
.rank-head .rank-algo:hover{background:rgba(224,177,62,.12);}
table.rankings td.rating{font-size:13px;font-weight:600;color:var(--text);}
table.rankings td.team .tag-seed{
  font-size:9px;letter-spacing:.4px;text-transform:uppercase;color:var(--text-faint);
  border:1px dashed var(--line);border-radius:3px;padding:1px 4px;margin-left:6px;
}
/* Rows still leaning on the seeding prior read dimmer, so a number resting on
   an assumption never looks as solid as one earned on the field. */
table.rankings tr.thin td.rating{color:var(--text-dim);font-weight:500;}
table.rankings tr.seed-only td{opacity:.55;}
.rank-note{padding:14px 12px 34px;border-top:1px solid var(--line);}
.rank-note p{font-size:11px;line-height:1.6;color:var(--text-dim);margin:0 0 9px;}
.rank-note p:last-child{margin-bottom:0;}
.rank-note strong{color:var(--text);font-weight:600;}
.rank-note em{color:var(--text-dim);font-style:italic;}
.rank-note a{color:var(--gold);}
table.standings tr.clickable{cursor:pointer;}
table.standings tr.clickable:hover td{background:rgba(255,255,255,.035);}
table.standings tr.clickable:focus-visible{outline:2px solid var(--gold);outline-offset:-2px;}

/* A team on a field right now. Shared by the rankings table and the team page. */
.lvdot{
  display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--live);
  flex:none;margin-right:5px;vertical-align:1px;animation:pulse 1.6s ease-in-out infinite;
}
.rank-live{
  display:inline-flex;align-items:center;font-size:10px;font-family:'JetBrains Mono';
  color:var(--live);border:1px solid rgba(46,194,126,.4);border-radius:3px;padding:2px 6px;
}
table.rankings tr.playing td.team{font-weight:600;}
table.rankings td.team .lvnow{
  display:block;font-size:9.5px;font-family:'JetBrains Mono';color:var(--live);margin-top:2px;
}
.team-live{
  display:flex;align-items:center;gap:8px;margin:0;padding:10px 12px;cursor:pointer;
  background:rgba(46,194,126,.1);border-bottom:1px solid rgba(46,194,126,.3);
}
.team-live:hover{background:rgba(46,194,126,.16);}
.team-live:focus-visible{outline:2px solid var(--live);outline-offset:-2px;}
.team-live b{font-family:'JetBrains Mono';font-size:15px;color:var(--live);}
.team-live span:last-child{font-size:11.5px;color:var(--text-dim);}

/* ---------------- one team's page ---------------- */
.team-head{padding:11px 12px 9px;border-bottom:1px solid var(--line);}
.team-back{
  appearance:none;background:none;border:1px solid var(--line);border-radius:5px;
  color:var(--text-dim);font-family:inherit;font-size:11px;padding:4px 9px;cursor:pointer;
}
.team-back:hover{color:var(--text);border-color:var(--text-faint);}
.team-id{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-top:9px;}
.team-dot{width:9px;height:9px;border-radius:50%;flex:none;}
.team-id h2{font-family:'Barlow Condensed';font-weight:700;font-size:20px;margin:0;
  text-transform:uppercase;letter-spacing:.3px;}
.team-sub{font-size:11px;color:var(--text-faint);font-family:'JetBrains Mono';}
.team-stats{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--line);}
.team-tile{background:var(--panel);padding:10px 8px;text-align:center;}
/* Proportional figures: these are standalone values, not a column to align. */
.team-tile b{display:block;font-size:19px;font-weight:600;line-height:1.1;white-space:nowrap;}
.team-tile span{display:block;font-size:9px;letter-spacing:.5px;text-transform:uppercase;
  color:var(--text-faint);margin-top:4px;line-height:1.3;}
.team-h3{font-family:'Barlow Condensed';font-weight:700;font-size:14px;text-transform:uppercase;
  letter-spacing:.4px;color:var(--text-dim);margin:0;padding:15px 12px 7px;}
.team-count{font-family:'JetBrains Mono';font-size:10px;color:var(--text-faint);font-weight:500;}
.team-note{font-size:11px;line-height:1.55;color:var(--text-faint);padding:2px 12px 8px;margin:0;}
.team-note.tap{padding-bottom:34px;}

.team-chart{margin:0;padding:2px 10px 4px;}
/* Capped, not fluid. .app has no max-width, so width:100% on a desktop-width
   panel would scale the viewBox ratio into a chart hundreds of pixels tall. */
.team-chart svg{width:100%;max-width:340px;height:auto;display:block;}
/* Hairline, solid, one step off the surface — recessive by design. */
.tp-grid{stroke:var(--line);stroke-width:1;}
.tp-line{fill:none;stroke-width:2;stroke-linejoin:round;stroke-linecap:round;}
/* 2px surface ring so a dot stays legible where it crosses the line. */
.tp-dot{stroke:var(--panel);stroke-width:2;}
.tp-tick,.tp-xlab{fill:var(--text-faint);font-size:9px;font-family:'JetBrains Mono';}
.tp-tick{text-anchor:end;}
.tp-lab{fill:var(--text-dim);font-size:10px;font-family:'JetBrains Mono';}
.tp-lab.strong{fill:var(--text);font-weight:600;}
.team-chart figcaption{font-size:10px;color:var(--text-faint);padding:2px 4px 0;line-height:1.5;}
/* The chart's table twin, so no value is reachable only by hovering. */
.team-table{display:flex;flex-wrap:wrap;gap:1px;background:var(--line);margin:8px 12px 0;}
.team-table div{flex:1 1 72px;background:var(--panel);padding:6px 8px;display:flex;
  flex-direction:column;gap:2px;}
.team-table span:first-child{font-size:9px;letter-spacing:.4px;text-transform:uppercase;color:var(--text-faint);}
.team-table span:last-child{font-size:11.5px;font-family:'JetBrains Mono';color:var(--text);}

.tg{
  display:flex;align-items:center;gap:9px;padding:9px 12px;cursor:pointer;
  border-bottom:1px solid rgba(38,49,59,.5);
}
.tg:hover{background:rgba(255,255,255,.035);}
.tg:focus-visible{outline:2px solid var(--gold);outline-offset:-2px;}
.tg-when{font-family:'JetBrains Mono';font-size:10px;color:var(--text-faint);width:52px;flex:none;}
.tg-when i{display:block;font-style:normal;color:var(--text-dim);}
.tg-res{font-family:'JetBrains Mono';font-size:11px;font-weight:600;width:14px;flex:none;
  text-align:center;color:var(--text-faint);}
.tg-res.w{color:var(--live);} .tg-res.l{color:var(--cap);}
.tg-livedot{display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--live);
  animation:pulse 1.6s ease-in-out infinite;}
.tg-opp{flex:1;min-width:0;font-size:13px;}
.tg-opp i{display:block;font-style:normal;font-size:9.5px;font-family:'JetBrains Mono';
  color:var(--text-faint);margin-top:1px;}
.tg-score{font-family:'JetBrains Mono';font-size:12.5px;flex:none;white-space:nowrap;}
.tg-field{font-family:'JetBrains Mono';font-size:10px;color:var(--text-faint);flex:none;width:30px;
  text-align:right;}

/* the map search's per-fixture rows */
.search-results .sr-next{border-top:1px solid rgba(38,49,59,.6);margin-top:5px;padding-top:3px;}
.search-results .sr-nextrow{display:flex;align-items:center;gap:8px;padding:3px 0;font-size:10.5px;}
.search-results .sr-nextrow:hover{background:rgba(255,255,255,.05);}
.search-results .sr-nextrow .t{font-family:'JetBrains Mono';color:var(--text-dim);width:74px;flex:none;}
.search-results .sr-nextrow .o{flex:1;min-width:0;color:var(--text-dim);overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap;}
.search-results .sr-nextrow .f{font-family:'JetBrains Mono';color:var(--text-faint);flex:none;}
.search-results .sr-nextmore{font-size:9.5px;color:var(--text-faint);padding:2px 0 1px;}
/* Names the person a player-name search matched, so the team it landed on
   doesn't look like a mis-hit. */
.search-results .sr-alias{
  display:inline-block;font-size:9.5px;font-family:'JetBrains Mono';color:var(--gold);
  border:1px solid rgba(224,177,62,.4);border-radius:3px;padding:1px 5px;margin:3px 0 1px;
}
table.standings td.num{font-family:'JetBrains Mono';font-size:11.5px;color:var(--text-dim);}
table.standings td.diff.pos{color:var(--live);}
table.standings td.diff.neg{color:#e0553e;}
table.standings tr:last-child td{border-bottom:none;}
table.standings tr.be td.team{color:var(--gold);}
table.standings tr.be td.rank{box-shadow:inset 3px 0 0 var(--gold);}
table.standings td:last-child{padding-right:12px;}
.pool-games{padding:2px 12px 12px;font-size:11px;color:var(--text-dim);}
.pool-games .g{display:flex;gap:8px;padding:2px 0;align-items:baseline;
  cursor:pointer;border-radius:5px;margin:0 -4px;padding-left:4px;padding-right:4px;}
.pool-games .g:hover,.pool-games .g:focus-visible{background:var(--panel-2);outline:none;}
.pool-games .g:focus-visible{box-shadow:inset 0 0 0 1px var(--line);}
.pool-games .g .t{font-family:'JetBrains Mono';font-size:10px;color:var(--text-faint);flex:none;width:74px;}
.pool-games .g .s{font-family:'JetBrains Mono';flex:none;color:var(--text);}
.pool-games .g.live .s{color:var(--live);font-weight:600;}
.pool-games summary{cursor:pointer;font-size:10px;letter-spacing:.4px;text-transform:uppercase;color:var(--text-faint);padding:6px 0;}
.notice{padding:14px 12px;font-size:11.5px;color:var(--text-dim);line-height:1.6;}
.notice a{color:var(--gold);}
.notice code{font-family:'JetBrains Mono';font-size:10.5px;background:var(--panel);padding:1px 5px;border-radius:4px;}

/* ---------------- simulated-data banner (?sim=...) ---------------- */
.sim-banner{
  position:fixed;left:0;right:0;bottom:0;z-index:70;display:flex;align-items:center;gap:10px;
  justify-content:center;background:#e0b13e;color:#0a0e12;font-size:10.5px;font-weight:700;
  letter-spacing:.3px;padding:5px 10px;text-align:center;
}
.sim-banner a{color:#0a0e12;text-decoration:underline;flex:none;}

/* ---------------- boot / error ---------------- */
.boot{
  position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  flex-direction:column;gap:10px;background:var(--bg);z-index:60;text-align:center;padding:24px;
}
.boot .spin{
  width:26px;height:26px;border-radius:50%;border:3px solid var(--line);border-top-color:var(--gold);
  animation:rot .8s linear infinite;
}
@keyframes rot{to{transform:rotate(360deg);}}
.boot p{font-size:12px;color:var(--text-dim);margin:0;max-width:340px;line-height:1.6;}
.boot.hidden{display:none;}
.boot button{
  font-family:inherit;font-size:12px;font-weight:600;color:var(--text);background:var(--panel);
  border:1px solid var(--line);border-radius:8px;padding:7px 14px;cursor:pointer;
}

@media (min-width:640px){
  header h1{font-size:17px;} header .sub{font-size:10.5px;}
  .popover{min-width:230px;}
}
/* A rating that includes a projected game reads slightly lighter than one
   settled on results alone. */
table.rankings td.rating.proj{color:var(--live);}
table.rankings td.team .lvnow i{font-style:normal;color:var(--text-faint);}
.tg.club{opacity:.85;}
.tg.club .tg-opp i{display:block;font-style:normal;font-size:9px;letter-spacing:.4px;
  text-transform:uppercase;color:var(--gold);margin-top:1px;}

/* ---------------- playoff bracket ---------------- */
/* A family groups the brackets it contains -- 16 of them for a 32-team playoff,
   one per pair of places -- so the place headings below read as a list inside it
   rather than as sixteen unrelated sections. */
.bkt-family{border-bottom:2px solid var(--line);}
.bkt-fam-head{
  display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;
  padding:12px 12px 6px;background:var(--panel);
  border-bottom:1px solid var(--line);
}
.bkt-fam-head h2{
  font-family:'Barlow Condensed',serif;font-weight:700;font-size:18px;margin:0;
  text-transform:uppercase;letter-spacing:.4px;
}
.bkt-fam-head .meta{font-size:10px;color:var(--text-faint);font-family:'JetBrains Mono';}
.bkt-block{border-bottom:1px solid var(--line);padding-bottom:6px;}
.bkt-family > .bkt-block:last-child{border-bottom:0;}
.bkt-block h2{font-size:14px;color:var(--text-dim);}
/* Half the brackets in a full placement draw are a single game -- the 3rd place
   game, the 7th, and so on. One card needs no column layout and no scroll. */
.bkt-block.single .bracket{overflow:visible;}
.bkt-block.single .bkt-col{width:auto;max-width:220px;}
.bkt-head{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;padding:11px 12px 8px;}
.bkt-head h2{font-family:'Barlow Condensed';font-weight:700;font-size:16px;margin:0;
  text-transform:uppercase;letter-spacing:.3px;}
.bkt-head .meta{font-size:10px;color:var(--text-faint);font-family:'JetBrains Mono';}
/* Five columns can't fit a phone, so it scrolls sideways the way a bracket should. */
.bracket{
  display:flex;gap:12px;padding:0 12px 10px;overflow-x:auto;
  -webkit-overflow-scrolling:touch;scrollbar-width:thin;
}
.bkt-col{display:flex;flex-direction:column;flex:none;width:158px;}
.bkt-round{
  font-size:9px;letter-spacing:.7px;text-transform:uppercase;color:var(--text-faint);
  font-family:'JetBrains Mono';padding:0 0 6px;position:sticky;top:0;background:var(--bg);
}
/* space-around is what aligns each match between its two feeders in the column
   to its left — the classic CSS bracket trick, no absolute positioning needed. */
.bkt-matches{display:flex;flex-direction:column;justify-content:space-around;flex:1;gap:6px;}
.bkt-match{
  background:var(--panel);border:1px solid var(--line);border-radius:5px;overflow:hidden;
  cursor:pointer;flex:none;
}
.bkt-match:hover{border-color:var(--text-faint);}
.bkt-match:focus-visible{outline:2px solid var(--gold);outline-offset:1px;}
.bkt-match.live{border-color:rgba(46,194,126,.5);}
.bkt-side{display:flex;align-items:center;gap:6px;padding:4px 6px;font-size:11.5px;}
.bkt-side + .bkt-side{border-top:1px solid rgba(38,49,59,.7);}
.bkt-side .n{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  color:var(--text-dim);}
.bkt-side .s{font-family:'JetBrains Mono';font-size:11px;color:var(--text-faint);flex:none;}
/* The winner is the only emphasised thing in a played match. */
.bkt-side.win .n{color:var(--text);font-weight:600;}
.bkt-side.win .s{color:var(--text);font-weight:600;}
.bkt-side.tbd .n{font-style:italic;color:var(--text-faint);}
.bkt-meta{
  font-family:'JetBrains Mono';font-size:8.5px;color:var(--text-faint);
  padding:2px 6px 4px;display:flex;align-items:center;gap:3px;
}
.bkt-note{font-size:10.5px;color:var(--text-faint);padding:0 12px 8px;margin:0;line-height:1.5;}

/* A long team name is clipped rather than wrapped: a two-line row throws the
   whole column out of alignment, and the full name is on hover either way.
   Fixed layout is what makes the clip possible — with auto layout the Team
   column just grows to fit the longest name and the ellipsis never fires. */
table.rankings{table-layout:fixed;}
table.rankings col.c-rank{width:30px;}
table.rankings col.c-rating{width:46px;}
table.rankings col.c-wl{width:44px;}
table.rankings col.c-gd{width:38px;}
table.rankings col.c-seed{width:36px;}
/* Only ever holds a delta like "▲12", and its header is a single glyph. */
table.rankings col.c-mv{width:38px;}
table.rankings td.team{overflow:hidden;}
table.rankings td.team .tline{display:flex;align-items:center;min-width:0;}
table.rankings td.team .tname{
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;
}
/* The country and any tag keep their full width; only the name gives way. */
table.rankings td.team .ctry,
table.rankings td.team .tag-seed{flex:none;}
table.rankings td.team .lvnow{
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
