/* Satellite Uplink — restyled to the TF|2 CTF Stats design system (2026-07-21).
   Palette / type / chamfered cards mirror stats.aoloach.com. Game pick icons and
   Discord avatars/names are left intact; only their framing is restyled. */

:root {
  --bg:        #0a0c10;
  --panel:     #0e1219;
  --panel-2:   #0c1016;
  --border:    #232d3b;
  --hairline:  #1a2230;
  --ink:       #e6ebf2;
  --muted:     #8a93a2;
  --label:     #6b7686;
  --faint:     #4a5361;
  --cyan:      #38d4e6;
  --imc:       #ffb060;   /* IMC orange  */
  --militia:   #7fb4ff;   /* Militia blue */
  --loss:      #d86a5a;
  --tile:      #17242f;   /* pick-tile fill — a touch lighter/bluer than the avatar + available icons */
}

* { box-sizing: border-box; }

body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  background-image: radial-gradient(ellipse at 50% -12%, #131c28 0%, #0a0c10 58%);
  background-repeat: no-repeat;
  background-attachment: fixed;
  color: var(--ink);
  font-family: 'Manrope', system-ui, -apple-system, sans-serif;
  font-variant-numeric: tabular-nums;
  min-height: 100vh;
}
::selection { background: var(--cyan); color: #04121a; }
a { color: var(--cyan); text-decoration: none; }
a:hover { color: #7fe3f0; }

#page-container { position: relative; min-height: 100vh; }
#content-wrap {
  max-width: 1500px;
  margin: 0 auto;
  padding: 22px 20px 64px;
}

/* ---- masthead ---- */
.masthead {
  display: flex; align-items: baseline; gap: 12px;
  margin: 4px 2px 22px;
}
.wordmark {
  font-family: 'Exo 2', sans-serif; font-weight: 700; letter-spacing: .02em;
  font-size: 18px; color: #cdd6e2;
}
.wordmark .pipe { color: var(--cyan); font-weight: 600; }
.masthead .sub {
  font-family: 'Exo 2', sans-serif; font-weight: 500; font-size: 12px;
  letter-spacing: .12em; text-transform: uppercase; color: var(--label);
}
.mnav {   /* cross-links to the stats site, pushed to the right like the stats nav */
  margin-left: auto; display: flex; gap: 22px; align-items: baseline;
  font-family: 'Exo 2', sans-serif; font-weight: 500; font-size: 14px;
}
.mnav a { color: var(--muted); text-decoration: none; }
.mnav a:hover { color: var(--cyan); }

/* ---- chamfered card (unclipped element; fill on ::before, frame on ::after,
        so absolutely-positioned pick menus are never clipped) ---- */
.channel {
  position: relative;
  padding: 18px 22px;
  margin-bottom: 14px;
}
/* Fill sits BEHIND content (z-index:-1) rather than lifting every child to z-index:1 --
   lifting children made each sub-section its own stacking context, which trapped the
   pick menus below the "Available"/callout areas. The card itself stays context-free so
   a menu's z-index can rise above everything on the page. */
.channel::before {   /* opaque chamfered fill */
  content: ''; position: absolute; inset: 0; z-index: -1;
  background: var(--panel);
}
.channel::after {    /* 1px chamfered frame */
  content: ''; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: var(--border);
}
/* lobby = top box: BL + BR chamfers */
.lobby::before {
  clip-path: polygon(0 0, 100% 0, 100% calc(100% - 12px), calc(100% - 12px) 100%, 12px 100%, 0 calc(100% - 12px));
  /* faint white-pilot silhouette + cyan visor/jet glow on the right; left stays solid behind the text */
  background:
    linear-gradient(100deg, var(--panel) 45%, rgba(14,18,25,.80) 82%, rgba(14,18,25,.70) 100%),
    url('/images/cyan_glow.png')   right -12px center / auto 88% no-repeat,
    url('/images/white_pilot.png') right -12px center / auto 88% no-repeat,
    var(--panel);
}
.lobby::after  { clip-path: polygon(0 0, 100% 0, 100% calc(100% - 12px), calc(100% - 12px) 100%, 12px 100%, 0 calc(100% - 12px), 0 0, 1px 1px, 1px calc(100% - 12px), 12px calc(100% - 1px), calc(100% - 12px) calc(100% - 1px), calc(100% - 1px) calc(100% - 12px), calc(100% - 1px) 1px, 1px 1px); }
/* every other box: TL + BR chamfers */
.teams::before { clip-path: polygon(12px 0, 100% 0, 100% calc(100% - 12px), calc(100% - 12px) 100%, 0 100%, 0 12px); }
.teams::after  { clip-path: polygon(12px 0, 100% 0, 100% calc(100% - 12px), calc(100% - 12px) 100%, 0 100%, 0 12px, 12px 0, 12px 1px, 1px 12px, 1px calc(100% - 1px), calc(100% - 12px) calc(100% - 1px), calc(100% - 1px) calc(100% - 12px), calc(100% - 1px) 1px, 12px 1px); }

/* ---- headings ---- */
.lobby h1 {
  font-family: 'Exo 2', sans-serif; font-weight: 700; font-size: 26px;
  letter-spacing: -.01em; margin: 0 0 2px;
}
.teams h2 {
  font-family: 'Exo 2', sans-serif; font-weight: 700; font-size: 17px;
  letter-spacing: .01em; margin: 0 0 4px; padding-bottom: 12px;
  border-bottom: 1px solid var(--hairline);
}
/* team accents: a colored top hairline + a heading in the team colour */
.team-militia h2 { color: var(--militia); }
.team-imc h2     { color: var(--imc); }
.team-militia::after { background: linear-gradient(var(--militia), var(--militia)) top/100% 2px no-repeat, var(--border); }
.team-imc::after     { background: linear-gradient(var(--imc), var(--imc))         top/100% 2px no-repeat, var(--border); }

/* ---- team channel layout ---- */
#channel_trees { display: block; }
#team_channels { display: flex; flex-wrap: wrap; gap: 14px; }
.teams { flex: 1 1 440px; min-width: 340px; margin-bottom: 0; }

/* ---- user rows ---- */
.channel ul { list-style: none; margin: 6px 0 0; padding: 0; }
li.user {
  display: flex; align-items: center; gap: 9px;
  padding: 7px 4px; border-bottom: 1px solid var(--hairline);
}
li.user:last-child { border-bottom: none; }
.avatar {
  width: 30px; height: 30px; border-radius: 50%;
  box-shadow: 0 0 0 1px var(--border); flex: 0 0 auto;
}
.uname {
  font-size: 14px; color: var(--ink); font-weight: 500;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  /* names are verbatim scoreboard/discord handles — never transform case */
}
/* the lobby list icons sit before the avatar; give a touch of breathing room */
.lobby li.user { padding: 6px 4px; }

/* ---- pick tiles (the titan / ordnance picker) ---- */
.dropdown { position: relative; display: inline-block; }
.dropbtn {
  position: relative; width: 40px; height: 40px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: none; cursor: pointer; color: var(--muted);
  background: var(--tile);
  font-family: 'Exo 2', sans-serif; font-size: 7px; font-weight: 600;
  letter-spacing: 0; text-transform: uppercase; overflow: hidden;
  clip-path: polygon(6px 0, 100% 0, 100% calc(100% - 6px), calc(100% - 6px) 100%, 0 100%, 0 6px);
  transition: background .12s;
}
.dropbtn::after {   /* 1px chamfered frame on the tile */
  content: ''; position: absolute; inset: 0; pointer-events: none; background: #2f3a4a;
  clip-path: polygon(6px 0, 100% 0, 100% calc(100% - 6px), calc(100% - 6px) 100%, 0 100%, 0 6px, 6px 0, 6px 1px, 1px 6px, 1px calc(100% - 1px), calc(100% - 6px) calc(100% - 1px), calc(100% - 1px) calc(100% - 6px), calc(100% - 1px) 1px, 6px 1px);
}
/* open/hover tile: cyan outline OPEN at the bottom, chamfered top-left only, so it flows into
   the menu below (cyan, open at the top) -> one continuous outline tying the slot to its menu */
.dropdown:hover .dropbtn, .dropdown.open .dropbtn {
  background: #14202a;
  clip-path: polygon(6px 0, 100% 0, 100% 100%, 0 100%, 0 6px);
}
.dropdown:hover .dropbtn::after, .dropdown.open .dropbtn::after {
  background: var(--cyan);
  clip-path: polygon(6px 0, 100% 0, 100% 100%, calc(100% - 1px) 100%, calc(100% - 1px) 1px, 7px 1px, 1px 7px, 1px 100%, 0 100%, 0 6px);
}
.dropbtn img { display: block; width: 30px !important; height: 30px !important; }
.icon_image { max-width: 32px; }

/* hover menu of choices */
.dropdown-content {
  /* top:100% (no gap) so the cursor can travel from the tile into the menu without
     crossing a dead zone that would drop :hover and close it before a click lands */
  display: none; position: absolute; z-index: 50; top: 100%; left: 0;
  background: #10161f; padding: 3px;
  /* single narrow column, 40px wide to match the tile so the cyan outlines line up */
  grid-template-columns: 34px; gap: 4px;
  box-shadow: 0 10px 24px rgba(0,0,0,.55);
  clip-path: polygon(0 0, 100% 0, 100% calc(100% - 6px), calc(100% - 6px) 100%, 0 100%);
}
/* cyan outline on the menu, OPEN at the top so it joins the tile's outline above (chamfered
   bottom-right only) -> tile + menu read as one cyan-outlined unit for this slot */
.dropdown-content::after {
  content: ''; position: absolute; inset: 0; pointer-events: none; background: var(--cyan);
  clip-path: polygon(0 0, 0 100%, calc(100% - 6px) 100%, 100% calc(100% - 6px), 100% 0, calc(100% - 1px) 0, calc(100% - 1px) calc(100% - 6px), calc(100% - 6px) calc(100% - 1px), 1px calc(100% - 1px), 1px 0);
}
/* Hover to peek (desktop) OR click to pin open (robust + works on touch) */
.dropdown:hover .dropdown-content, .dropdown.open .dropdown-content { display: grid; }
.dropdown-menu-button {
  width: 34px; height: 34px; padding: 0; border: 1px solid var(--hairline);
  background: var(--panel-2); cursor: pointer; border-radius: 4px;
  display: inline-flex; align-items: center; justify-content: center; transition: border-color .1s, background .1s;
}
.dropdown-menu-button:hover { border-color: var(--cyan); background: #14202a; }
.dropdown-menu-button img { width: 28px; height: 28px; display: block; }

/* ---- "available" strip ---- */
.channel hr {
  border: none; border-top: 1px solid var(--hairline); margin: 14px 0 10px;
}
.avail-label {
  font-family: 'Manrope', sans-serif; font-size: 11px; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase; color: var(--label);
  margin-bottom: 8px;
}
.avail-row { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 4px; }
.avail-icon {
  width: 30px; height: 30px; border-radius: 6px;
  background: var(--panel-2); box-shadow: inset 0 0 0 1px var(--hairline);
}
.warn { color: var(--loss); font-size: 12.5px; font-weight: 600; margin: 8px 0 0; }

/* ---- team building ----
   Its own shelf between the picker and the callouts. The container collapses when
   empty, so it takes no vertical space at all rather than sitting there as a
   frame around nothing for the hours a lobby is not full. */
#teambuild_container:empty { display: none; }
.teambuild { position: relative; padding: 18px 22px; margin-top: 20px; }
.teambuild::before {
  content: ''; position: absolute; inset: 0; z-index: -1; background: var(--panel);
  clip-path: polygon(12px 0, 100% 0, 100% calc(100% - 12px), calc(100% - 12px) 100%, 0 100%, 0 12px);
}
.teambuild::after {
  content: ''; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: linear-gradient(var(--cyan), var(--cyan)) top/100% 2px no-repeat, var(--border);
  clip-path: polygon(12px 0, 100% 0, 100% calc(100% - 12px), calc(100% - 12px) 100%, 0 100%, 0 12px, 12px 0, 12px 1px, 1px 12px, 1px calc(100% - 1px), calc(100% - 12px) calc(100% - 1px), calc(100% - 1px) calc(100% - 12px), calc(100% - 1px) 1px, 12px 1px);
}
.teambuild h2 {
  font-family: 'Exo 2', sans-serif; font-weight: 700; font-size: 17px;
  letter-spacing: .01em; margin: 0 0 4px; padding-bottom: 12px;
  color: var(--cyan); border-bottom: 1px solid var(--hairline);
}
/* Where to play. A recommendation is muted; a server that actually exists is
   cyan and says "server", because the two are different claims and reading one
   as the other would send people to a box that is not there. */
.tb-region {
  display: inline-flex; align-items: baseline; gap: 9px; margin-top: 12px;
  padding: 7px 12px; background: rgba(138, 147, 162, .08);
  box-shadow: inset 2px 0 0 var(--faint);
}
.tb-region.is-live {
  background: rgba(56, 212, 230, .10); box-shadow: inset 2px 0 0 var(--cyan);
}
.tb-regionlabel {
  font-family: 'Manrope', sans-serif; font-weight: 600; font-size: 10px;
  letter-spacing: .12em; text-transform: uppercase; color: var(--label);
}
.tb-region.is-live .tb-regionlabel { color: var(--cyan); }
.tb-regionband {
  font-family: 'Exo 2', sans-serif; font-weight: 700; font-size: 14px;
  color: var(--ink);
}
.tb-regioncity { font-size: 11.5px; color: var(--muted); }

.tb-actions { margin-top: 12px; display: flex; align-items: center; flex-wrap: wrap; gap: 4px 14px; }
/* The pair being compared, outside the button: stated as two tags when it is
   unambiguous, offered as two dropdowns when more than two team calls are full
   (two pugs forming -- a human picks the pair). Team names take the channel
   colours the tree already uses: IMC amber, Militia blue, anything else neutral. */
.tb-teamrow { display: inline-flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.tb-teamtag, .tb-teampick {
  font-family: 'Exo 2', sans-serif; font-weight: 700; font-size: 14px;
  letter-spacing: .02em; color: #fff; padding: 9px 14px;
  background: rgba(138, 147, 162, .10); box-shadow: inset 0 0 0 1px var(--border);
}
.tb-teampick {
  border: none; cursor: pointer; -webkit-appearance: none; appearance: none;
  border-radius: 0; padding-right: 26px;
  background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%),
                    linear-gradient(135deg, var(--muted) 50%, transparent 50%);
  background-position: calc(100% - 14px) 55%, calc(100% - 9px) 55%;
  background-size: 5px 5px, 5px 5px; background-repeat: no-repeat;
}
.tb-teampick option { background: var(--panel-2); color: var(--ink); }
.tb-team-imc {
  background-color: rgba(255, 176, 96, .12); box-shadow: inset 0 0 0 1px var(--imc);
}
.tb-team-militia {
  background-color: rgba(127, 180, 255, .12); box-shadow: inset 0 0 0 1px var(--militia);
}
.tb-teamvs {
  font-family: 'Exo 2', sans-serif; font-weight: 700; font-size: 12px;
  color: var(--faint);
}
.tb-btn {
  position: relative; display: inline-flex; align-items: baseline; gap: 10px;
  font-family: 'Exo 2', sans-serif; font-weight: 700; font-size: 14px;
  letter-spacing: .02em; color: var(--cyan); cursor: pointer; border: none;
  background: #0e2229; padding: 11px 20px; margin: 3px 8px 3px 0;
  clip-path: polygon(8px 0, 100% 0, 100% calc(100% - 8px), calc(100% - 8px) 100%, 0 100%, 0 8px);
  transition: background .12s;
}
.tb-btn::after {
  content: ''; position: absolute; inset: 0; pointer-events: none; background: #2f4a52;
  clip-path: polygon(8px 0, 100% 0, 100% calc(100% - 8px), calc(100% - 8px) 100%, 0 100%, 0 8px, 8px 0, 8px 1px, 1px 8px, 1px calc(100% - 1px), calc(100% - 8px) calc(100% - 1px), calc(100% - 1px) calc(100% - 8px), calc(100% - 1px) 1px, 8px 1px);
}
.tb-btn:hover { background: #123038; }
.tb-btn.is-pending { color: var(--muted); cursor: default; }
.tb-count {
  font-family: 'Manrope', sans-serif; font-weight: 600; font-size: 11px;
  letter-spacing: .06em; text-transform: uppercase; color: var(--label);
}

/* Card containers: three across by default; site.js measures whether any name
   row would wrap and demotes to lay-21 (third card full-width under the first
   two) or lay-1 (all stacked). Rows wrap only when even a full-width card
   cannot hold a roster on one line. */
/* Cards size to their content and pack left, rather than stretching to fill a
   third each -- a card whose roster is narrow carried the rest as dead space.
   fit-content caps a card at the container, so the wrap fallback still forces
   rows to wrap instead of overflowing. */
.tb-options, .tb-eval {
  display: grid; grid-template-columns: repeat(3, fit-content(100%));
  justify-content: start; gap: 12px; margin-top: 16px;
}
.tb-options.lay-21, .tb-eval.lay-21 { grid-template-columns: repeat(2, fit-content(100%)); }
.tb-options.lay-21 > :nth-child(3), .tb-eval.lay-21 > :nth-child(3) {
  grid-column: 1 / -1; justify-self: start;
}
.tb-options.lay-1, .tb-eval.lay-1 { grid-template-columns: fit-content(100%); }
.tb-option {
  position: relative; padding: 14px 16px; background: var(--panel-2);
  clip-path: polygon(8px 0, 100% 0, 100% calc(100% - 8px), calc(100% - 8px) 100%, 0 100%, 0 8px);
}
/* The recommended split is marked, not explained: the ordering already carries
   the reason, and a per-option justification would invent a distinction the
   model does not support. */
.tb-option.is-rec { background: #101a22; box-shadow: inset 2px 0 0 var(--cyan); }
/* Names in the display face at semibold, matching the stats site's scoreboards
   and match pages (Exo 2 600) so the same person reads the same on both. Spaced
   rather than comma-separated: at five per side the commas were doing no work
   that the gap does not do more legibly. */
/* The tint is deliberately faint. It is there to separate the two sides and to
   give the colour name something to refer to -- not to decorate, and not loudly
   enough that one side looks more attractive than the other. */
/* The set's name, which is the handle people say out loud. The two halves below
   are a lighter and a darker shade of it and carry no name of their own -- who
   ends up which side is not settled until the match starts. */
.tb-setname {
  font-family: 'Exo 2', sans-serif; font-weight: 800; font-size: 12px;
  letter-spacing: .16em; text-transform: uppercase; color: var(--set);
  margin-bottom: 9px;
}
.tb-side {
  display: flex; flex-wrap: wrap; gap: 3px 14px;
  padding: 8px 10px; margin: 2px 0;
  background: var(--side-tint);
  box-shadow: inset 2px 0 0 var(--side);
}
.tb-name {
  font-family: 'Exo 2', sans-serif; font-weight: 600; font-size: 13.5px;
  letter-spacing: .005em; color: var(--ink);
}
/* The evaluate block's split layout. Column 1 is sized by the WIDER roster,
   column 2 by the two number boxes -- so the narrower team centres on the wider
   and the numbers align with each other. minmax(0, max-content): the roster
   takes its natural width, but can shrink and wrap when the CARD is capped at
   the container in the wrap fallback. The old fixed `calc(100% - 72px)` cap
   assumed a card of definite width; once cards size to content that percentage
   resolved against an indefinite width and wrapped long rosters prematurely.
   Children are placed by order: side, odds, vs, side, odds. */
.tb-splits {
  display: grid; grid-template-columns: minmax(0, max-content) max-content;
  column-gap: 6px; row-gap: 2px; align-items: stretch;
}
.tb-splits > :nth-child(1) { grid-area: 1 / 1; }
.tb-splits > :nth-child(2) { grid-area: 1 / 2; }
.tb-splits > :nth-child(3) { grid-area: 2 / 1; }
.tb-splits > :nth-child(4) { grid-area: 3 / 1; }
.tb-splits > :nth-child(5) { grid-area: 3 / 2; }
/* Both BARS fill the column (sized by the wider roster); only the names centre
   within them. The bar shrinking with its content read as a broken layout. */
.tb-splits .tb-side { margin: 0; max-width: 100%; justify-content: center; }
.tb-splits .tb-vs { margin: 1px 0; }
/* The team's chance: tint only (the accent bar caps the roster box, once),
   dimmed so it cannot read as a name. Stretch matches it to its roster's
   height however the names wrap. */
.tb-oddsbox {
  display: flex; align-items: center; padding: 8px 12px; white-space: nowrap;
  background: var(--side-tint);
  font-family: 'Exo 2', sans-serif; font-weight: 800; font-size: 13.5px;
  color: var(--muted);
}
/* The players an arrangement moves, marked on their NEW sides. */
.tb-name.tb-moved { color: var(--cyan); }
.tb-vs {
  font-family: 'Exo 2', sans-serif; font-size: 10px; font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase; color: var(--faint);
  text-align: center; margin: 3px 0;
}
.tb-meta {
  margin-top: 10px; padding-top: 8px; border-top: 1px solid var(--hairline);
  font-size: 11px; letter-spacing: .04em; color: var(--label);
}
/* The evaluate flow: a progression rather than a set of alternatives, so the
   blocks are labelled by what they are instead of colour-named. */
.tb-block {
  padding: 14px 16px; background: var(--panel-2);
  clip-path: polygon(8px 0, 100% 0, 100% calc(100% - 8px), calc(100% - 8px) 100%, 0 100%, 0 8px);
}
.tb-blocklabel {
  font-family: 'Exo 2', sans-serif; font-weight: 800; font-size: 11px;
  letter-spacing: .14em; text-transform: uppercase; color: var(--label);
  margin-bottom: 9px;
}
.tb-plain { font-size: 13px; color: var(--ink); margin: 4px 0 0; }
.tb-plain b { font-family: 'Exo 2', sans-serif; font-weight: 600; }

.tb-error { font-size: 12px; margin: 14px 0 0; color: var(--loss); }
/* Sits ABOVE the teams, so the caveat is read before the thing it qualifies. */
.tb-warn { font-size: 12.5px; font-weight: 600; margin: 12px 0 0; color: var(--loss); }
.tb-warn + .tb-options { margin-top: 14px; }

/* ---- callouts + buttons ---- */
#callout_container { margin-top: 20px; }
button.dropbtn.callout, .callout-btn { /* callout control buttons */ }
.callout-btn {
  position: relative; display: inline-flex; align-items: center;
  font-family: 'Exo 2', sans-serif; font-weight: 700; font-size: 13px;
  letter-spacing: .02em; color: var(--cyan); cursor: pointer; border: none;
  background: #0e2229; padding: 10px 18px; margin: 3px 8px 3px 0;
  clip-path: polygon(8px 0, 100% 0, 100% calc(100% - 8px), calc(100% - 8px) 100%, 0 100%, 0 8px);
  transition: background .12s;
}
.callout-btn::after {
  content: ''; position: absolute; inset: 0; pointer-events: none; background: #2f4a52;
  clip-path: polygon(8px 0, 100% 0, 100% calc(100% - 8px), calc(100% - 8px) 100%, 0 100%, 0 8px, 8px 0, 8px 1px, 1px 8px, 1px calc(100% - 1px), calc(100% - 8px) calc(100% - 1px), calc(100% - 1px) calc(100% - 8px), calc(100% - 1px) 1px, 8px 1px);
}
.callout-btn:hover { background: #123038; }
.callout-btn:hover::after { background: var(--cyan); }
#inner_callout_container { margin-top: 12px; }
#inner_callout_container iframe { max-width: 100%; border: 1px solid var(--border); border-radius: 6px; }

/* ---- footer ---- */
.footer {
  position: absolute; bottom: 0; width: 100%; height: 40px;
  display: flex; align-items: center; justify-content: center;
  font-family: 'Manrope', sans-serif; font-size: 11px; letter-spacing: .08em;
  text-transform: uppercase; color: var(--faint);
}

@media (max-width: 720px) {
  .teams { flex: 1 1 100%; }
  #content-wrap { padding: 16px 12px 56px; }
}
