/* ═══════════════════════════════════════════════════════════════════════════
   THE GAMBIT — chess for turd.motes.org
   Governed by CHESS.md. Its own file, so nothing here changes any other page.

   ── On the typography ──────────────────────────────────────────────────────
   The arcade's typeface is Press Start 2P, and at 9px it is close to unreadable
   for anything longer than a label. It is kept here, but only for what it is
   good at: the page title and the small all-caps eyebrows that say which
   section you are in. Those carry the arcade's identity, and they are short.

   Everything a person has to READ -- a bot's description, a rule, an opponent's
   name, the reason a game ended -- is set in Space Grotesk at a size meant for
   reading. Anything that is a NUMBER you compare or a POSITION you read --
   clocks, ratings, move lists -- is set in JetBrains Mono, which has tabular
   figures, so a clock does not jitter as its digits change.

   Three typefaces, three jobs, each doing the one it is good at.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  /* Type. --gb-display is the site's; the other two are self-hosted. */
  --gb-display: 'Press Start 2P', 'Courier New', monospace;
  --gb-ui: 'Space Grotesk', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --gb-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;

  /* A 1.25 scale off a 15px base. 15 rather than the arcade's 12 because
     nobody should have to lean in to read whose turn it is. */
  --gb-fs-xs:   11px;
  --gb-fs-sm:   13px;
  --gb-fs-base: 15px;
  --gb-fs-lg:   19px;
  --gb-fs-xl:   24px;

  /* Spacing, on a 4px rhythm. */
  --gb-1: 4px;  --gb-2: 8px;  --gb-3: 12px; --gb-4: 16px;
  --gb-5: 24px; --gb-6: 32px; --gb-7: 48px;

  /* Ink. Three levels, all contrast-checked against the surfaces below. The
     old palette used --text-dim for body copy at roughly 3:1, under the
     readable floor. */
  --gb-ink:    #e9efeb;   /* primary   ~15:1 on surface */
  --gb-ink-2:  #a8c0b2;   /* secondary  ~8:1 */
  --gb-ink-3:  #7d9488;   /* meta       ~5:1 */

  /* Surfaces. Raised rather than outlined: the old design put a 2px border on
     everything, which makes every element shout equally loudly. */
  --gb-bg:      #07070f;
  --gb-surface: #101423;
  --gb-raised:  #171c2e;
  --gb-line:    #232a3d;
  --gb-line-2:  #313a52;

  --gb-accent:  #ffd700;   /* the arcade's gold, for what matters most */
  --gb-live:    #35e07a;   /* your turn, online, happening now */
  --gb-warn:    #ff9f43;
  --gb-danger:  #ff5b5b;

  --gb-radius: 10px;
  --gb-radius-sm: 6px;
  --gb-shadow: 0 1px 2px rgba(0,0,0,.4), 0 8px 24px rgba(0,0,0,.28);
}


/* ── Page shell ─────────────────────────────────────────────────────────── */
.gb-wrap {
  max-width: 1160px; margin: 0 auto; padding: var(--gb-5) var(--gb-4) var(--gb-7);
  font-family: var(--gb-ui);
  font-size: var(--gb-fs-base);
  line-height: 1.6;
  color: var(--gb-ink);
  -webkit-font-smoothing: antialiased;
}

.gb-wrap a { color: var(--gb-accent); }


/* ── The bar at the top of a Gambit page ────────────────────────────────────
   Shared by the lobby and the board. The pixel masthead that used to sit here
   was the loudest thing on either page and the first thing between a player
   and the game; this is a name, what you are looking at, and the controls. */
.gb-topbar {
  display: flex; align-items: center; gap: var(--gb-4);
  margin-bottom: var(--gb-4);
}
.gb-mark {
  display: inline-flex; align-items: baseline; gap: var(--gb-2);
  text-decoration: none; white-space: nowrap;
}
.gb-mark-glyph { color: var(--gb-accent); font-size: var(--gb-fs-lg); }
.gb-mark-name {
  font-family: var(--gb-ui); font-size: var(--gb-fs-lg); font-weight: 600;
  letter-spacing: .01em; color: var(--gb-ink);
}
.gb-mark:hover .gb-mark-name { color: var(--gb-accent); }

/* An icon button. Quiet until you want it. */
.gb-tool {
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; flex: none;
  background: none; border: 1px solid transparent; border-radius: var(--gb-radius-sm);
  color: var(--gb-ink-3); cursor: pointer;
  transition: color .15s, background .15s, border-color .15s;
}
.gb-tool svg {
  width: 19px; height: 19px; fill: none; stroke: currentColor;
  stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round;
}
.gb-tool:hover { color: var(--gb-ink); background: var(--gb-surface); }
.gb-tool:focus-visible { outline: 2px solid var(--gb-accent); outline-offset: 2px; }
.gb-tool[aria-pressed="true"] { color: var(--gb-accent); border-color: rgba(255,215,0,.35); }
.gb-tool:disabled { opacity: .35; cursor: default; }

/* ── Masthead (still used by the admin and invite pages) ────────────────── */
.gb-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  flex-wrap: wrap; gap: var(--gb-4);
  padding-bottom: var(--gb-4); margin-bottom: var(--gb-5);
  border-bottom: 1px solid var(--gb-line);
}

.gb-title {
  font-family: var(--gb-display);
  font-size: var(--gb-fs-xl);
  color: var(--gb-accent);
  letter-spacing: .02em; line-height: 1.35;
  text-shadow: 3px 3px 0 #000;
  margin: 0;
}

.gb-tagline {
  font-size: var(--gb-fs-sm); color: var(--gb-ink-3);
  margin-top: var(--gb-2); max-width: 46ch;
}


/* Your ratings, as a compact stat row rather than three stacked lines. It has
   to be allowed to wrap: four of them side by side do not fit a 320px phone,
   and a flex row that will not wrap sets the min-content width of the whole
   page. */
/* Your ratings, as one quiet strip. They used to be four stacked blocks of
   label / number / record, which on a phone filled half of the first screen
   with numbers nobody came to the page to read. The win-loss-draw line is
   in the tooltip, and in full on the Record tab. */
.gb-stats {
  display: flex; flex-wrap: wrap; align-items: baseline;
  gap: var(--gb-2) var(--gb-4); margin-left: auto;
}

.gb-stat {
  display: inline-flex; align-items: baseline; gap: 5px;
}

.gb-stat-label {
  font-size: var(--gb-fs-xs); color: var(--gb-ink-3);
  letter-spacing: .1em; text-transform: uppercase;
}

.gb-stat-value {
  font-family: var(--gb-mono); font-size: var(--gb-fs-base); font-weight: 700;
  color: var(--gb-ink); font-variant-numeric: tabular-nums;
}


.gb-prov { color: var(--gb-ink-3); font-weight: 400; }


/* ── Tabs ───────────────────────────────────────────────────────────────── */
.gb-tabs {
  display: flex; flex-wrap: wrap; gap: var(--gb-1);
  border-bottom: 1px solid var(--gb-line); margin-bottom: var(--gb-5);
}

.gb-tab {
  font-family: var(--gb-ui); font-size: var(--gb-fs-sm); font-weight: 500;
  letter-spacing: .04em;
  background: none; color: var(--gb-ink-3); cursor: pointer;
  border: none; border-bottom: 2px solid transparent;
  padding: var(--gb-3) var(--gb-4); margin-bottom: -1px;
  transition: color .15s, border-color .15s;
  min-height: 44px;                       /* a real touch target */
}

.gb-tab:hover { color: var(--gb-ink); }

.gb-tab.on { color: var(--gb-accent); border-bottom-color: var(--gb-accent); }

.gb-tab:focus-visible { outline: 2px solid var(--gb-accent); outline-offset: -2px; }

.gb-tab-badge {
  display: none; background: var(--gb-live); color: #04210f;
  font-family: var(--gb-mono); font-size: var(--gb-fs-xs); font-weight: 700;
  padding: 1px 6px; border-radius: 999px; margin-left: var(--gb-2);
}

.gb-pane { display: none; }

.gb-pane.on { display: block; animation: gbFade .18s ease-out; }

@keyframes gbFade { from { opacity: 0; transform: translateY(3px); } to { opacity: 1; } }


/* ── Sections ───────────────────────────────────────────────────────────── */
/* A section heading, not an announcement. Press Start 2P at 11px was both
   hard to read and the loudest thing in the column it was labelling. */
.gb-eyebrow {
  font-family: var(--gb-ui);
  font-size: var(--gb-fs-xs); font-weight: 600; color: var(--gb-ink-3);
  letter-spacing: .14em; text-transform: uppercase; line-height: 1.4;
  margin: var(--gb-6) 0 var(--gb-3);
}

.gb-eyebrow:first-child { margin-top: 0; }

.gb-note-text {
  font-size: var(--gb-fs-sm); color: var(--gb-ink-2);
  max-width: 68ch;                        /* prose stops being readable past this */
  margin-bottom: var(--gb-4);
}


/* ── Cards ──────────────────────────────────────────────────────────────── */
.gb-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: var(--gb-3);
}

/* Raised, not outlined. A grid of boxes each drawn with a full border is
   most of what made this page read as clunky; the surface alone separates
   a card from the page behind it. */
.gb-card {
  background: var(--gb-surface); border: 1px solid transparent;
  border-radius: var(--gb-radius); padding: var(--gb-3) var(--gb-4);
  display: flex; flex-direction: column; gap: 5px;
  transition: border-color .15s, transform .15s, background .15s;
}

.gb-card:hover { border-color: var(--gb-line-2); background: var(--gb-raised); }

a.gb-card:hover { transform: translateY(-1px); }

a.gb-card { text-decoration: none; }

.gb-card h3 {
  font-family: var(--gb-ui); font-size: var(--gb-fs-base); font-weight: 700;
  color: var(--gb-ink); margin: 0; line-height: 1.35;
}

.gb-card p { font-size: var(--gb-fs-sm); color: var(--gb-ink-2); margin: 0; flex: 1; }

.gb-card .gb-meta {
  font-family: var(--gb-mono); font-size: var(--gb-fs-xs); color: var(--gb-ink-3);
  font-variant-numeric: tabular-nums;
}

.gb-card > .gb-btn {
  align-self: flex-start; width: auto; min-height: 34px;
  padding: var(--gb-1) var(--gb-3); margin-top: var(--gb-1);
}
.gb-live-card {
  box-shadow: inset 2px 0 0 rgba(255,215,0,.45);
}

.gb-live-card:hover { border-color: var(--gb-accent); }

.gb-live-bot { color: var(--gb-ink-3); text-transform: uppercase; letter-spacing: .04em; }


.gb-empty {
  grid-column: 1 / -1;
  font-size: var(--gb-fs-sm); color: var(--gb-ink-3);
  background: none; border: 1px dashed var(--gb-line);
  border-radius: var(--gb-radius); padding: var(--gb-5);
  text-align: center; max-width: 60ch; margin: 0 auto;
}


/* ── Buttons ────────────────────────────────────────────────────────────── */
.gb-btn {
  font-family: var(--gb-ui); font-size: var(--gb-fs-sm); font-weight: 500;
  letter-spacing: .03em;
  background: var(--gb-raised); color: var(--gb-ink);
  border: 1px solid var(--gb-line-2); border-radius: var(--gb-radius-sm);
  padding: var(--gb-3) var(--gb-4); cursor: pointer; width: 100%;
  min-height: 42px;
  transition: background .15s, border-color .15s, color .15s;
}

.gb-btn:hover { background: #1f2740; border-color: #46527a; }

.gb-btn:focus-visible { outline: 2px solid var(--gb-accent); outline-offset: 2px; }

.gb-btn:disabled { opacity: .5; cursor: default; }

.gb-btn.gold {
  background: var(--gb-accent); color: #1a1400;
  border-color: var(--gb-accent); font-weight: 700;
}

.gb-btn.gold:hover { background: #ffe14d; border-color: #ffe14d; }

.gb-btn.danger { color: var(--gb-danger); border-color: #5a2020; }

.gb-btn.danger:hover { background: #2a1212; border-color: var(--gb-danger); }

/* Wraps rather than overflows. Two buttons whose labels are sentences --
   "Post an open seek" beside "Practice vs the engine" -- add up to more than a
   360px phone has, and a row that cannot wrap pushes the whole page sideways
   instead of taking a second line. */
.gb-btn-row { display: flex; flex-wrap: wrap; gap: var(--gb-2); }

.gb-btn-row .gb-btn { width: auto; flex: 1 1 auto; white-space: nowrap; }


/* The repeated action on a list of cards. Outlined rather than filled: three
   solid gold slabs down a page compete with each other and with the one
   genuinely singular action, and nothing reads as primary any more. */
.gb-btn.ghost {
  background: none; color: var(--gb-ink-2);
  border-color: var(--gb-line-2); font-weight: 500;
}

.gb-btn.ghost:hover { background: var(--gb-raised); color: var(--gb-ink); }


/* ── Control bars ───────────────────────────────────────────────────────── */
.gb-bar {
  display: flex; align-items: center; flex-wrap: wrap; gap: var(--gb-3);
  margin-bottom: var(--gb-3);
}

.gb-bar-label {
  font-size: var(--gb-fs-xs); color: var(--gb-ink-3);
  letter-spacing: .1em; text-transform: uppercase; min-width: 56px;
}

.gb-bar-go { width: auto !important; margin-left: auto; }


.gb-choice-row { display: flex; flex-wrap: wrap; gap: var(--gb-1); }

.gb-chip {
  font-family: var(--gb-ui); font-size: var(--gb-fs-sm); font-weight: 500;
  padding: var(--gb-2) var(--gb-3); cursor: pointer; min-height: 38px;
  background: transparent; color: var(--gb-ink-3);
  border: 1px solid var(--gb-line); border-radius: 999px;
  transition: color .15s, border-color .15s, background .15s;
}

.gb-chip:hover { color: var(--gb-ink); border-color: var(--gb-line-2); }

.gb-chip.on {
  color: var(--gb-accent); border-color: var(--gb-accent);
  background: rgba(255,215,0,.09);
}

.gb-chip:focus-visible { outline: 2px solid var(--gb-accent); outline-offset: 2px; }

#gb-level .gb-chip { font-family: var(--gb-mono); min-width: 40px; }

/* Time controls, grouped under the rating they count towards. Seven loose
   chips is a wall of numbers; four labelled clusters is four choices. The
   gap between groups is wider than the gap inside one, because that spacing
   is what does the grouping -- the labels only name it. */
.gb-choice-grouped { gap: var(--gb-4); align-items: flex-end; }

.gb-choice-group { display: flex; flex-wrap: wrap; gap: var(--gb-1); }

.gb-choice-group-label {
  flex: 100%; font-size: var(--gb-fs-xs); color: var(--gb-ink-3);
  letter-spacing: .08em; text-transform: uppercase;
  margin-bottom: calc(var(--gb-1) * -1 + 2px);
}

.gb-choice-grouped .gb-chip { font-family: var(--gb-mono); }


/* ── Challenges ─────────────────────────────────────────────────────────── */
.gb-challenges { display: flex; flex-direction: column; gap: var(--gb-2); }

.gb-challenges:not(:empty) { margin-bottom: var(--gb-5); }

.gb-challenge {
  display: flex; align-items: center; gap: var(--gb-3); flex-wrap: wrap;
  background: var(--gb-raised);
  border: 1px solid var(--gb-accent); border-left-width: 3px;
  border-radius: var(--gb-radius); padding: var(--gb-3) var(--gb-4);
  font-size: var(--gb-fs-sm);
}

.gb-challenge.mine { border-color: var(--gb-line-2); }

.gb-challenge-who { color: var(--gb-ink); flex: 1; min-width: 180px; font-weight: 500; }

.gb-challenge-speed {
  font-family: var(--gb-mono); font-size: var(--gb-fs-xs); color: var(--gb-ink-3);
}

.gb-challenge-left {
  font-family: var(--gb-mono); font-size: var(--gb-fs-base); font-weight: 700;
  color: var(--gb-accent); font-variant-numeric: tabular-nums;
}

.gb-challenge-left.urgent { color: var(--gb-danger); }

.gb-challenge-btns { display: flex; gap: var(--gb-2); }

.gb-challenge-btns .gb-btn { width: auto; padding: var(--gb-2) var(--gb-4); min-height: 38px; }

@media (prefers-reduced-motion: reduce) {

  #gb-board.in-check, #gb-board.refused, .gb-pane.on { animation: none; }

  a.gb-card:hover { transform: none; }
}


/* ── Credits ────────────────────────────────────────────────────────────── */
.gb-credits {
  font-size: var(--gb-fs-xs); color: var(--gb-ink-3); line-height: 1.9;
  margin-top: var(--gb-7); padding-top: var(--gb-4);
  border-top: 1px solid var(--gb-line); max-width: 70ch;
}

.gb-credits a { color: var(--gb-ink-2); }

.gb-credits strong {
  display: block; color: var(--gb-ink-2); letter-spacing: .1em;
  text-transform: uppercase; margin-bottom: var(--gb-2);
}


/* ── Small screens ──────────────────────────────────────────────────────── */
@media (max-width: 560px) {

  .gb-wrap { padding: var(--gb-4) var(--gb-3) var(--gb-6); }
  /* The bar stacks: name, then what this is, then the numbers. */
  .gb-topbar { flex-wrap: wrap; gap: var(--gb-1) var(--gb-3); }
  .gb-topbar .gb-tagline { order: 2; flex-basis: 100%; margin: 0; }
  /* Compact: four ratings do not fit one line on a phone whatever is done
     to them, so they get two tight ones rather than two loose ones. */
  .gb-stats { order: 3; flex-basis: 100%; margin-left: 0; gap: 2px var(--gb-3); }
  .gb-stat-label { font-size: 10px; letter-spacing: .06em; }
  .gb-stat-value { font-size: var(--gb-fs-sm); }

  .gb-grid { grid-template-columns: 1fr; }

  .gb-bar-go { margin-left: 0; width: 100% !important; }
}


/* ── The exhibition ladder ────────────────────────────────────────
   Engine games, which have never counted towards a rating and never
   will. The record is kept anyway, because climbing the ladder is most
   of what a beginner does here and a ladder you cannot see yourself on
   is not much of a ladder. */
.gb-ladder {
  display: flex; flex-direction: column;
  border: 1px solid var(--gb-line); border-radius: var(--gb-radius);
  overflow: hidden;
}

.gb-rung {
  display: grid; align-items: center; gap: var(--gb-3);
  grid-template-columns: 28px minmax(180px, 1fr) 90px 110px 90px 72px;
  padding: var(--gb-3) var(--gb-4);
  background: var(--gb-surface); font-size: var(--gb-fs-sm);
}

.gb-rung + .gb-rung { border-top: 1px solid var(--gb-line); }

/* A beaten level is marked on the left edge as well as by the word, so
   it does not rely on colour alone. */
.gb-rung.beaten { box-shadow: inset 3px 0 0 var(--gb-live); }


.gb-rung-level {
  font-family: var(--gb-mono); font-size: var(--gb-fs-base); font-weight: 700;
  color: var(--gb-ink-3); min-width: 20px; text-align: right;
}

.gb-rung-name { font-weight: 500; color: var(--gb-ink); min-width: 0; }

.gb-rung-flag {
  font-family: var(--gb-mono); font-size: 10px; font-weight: 700;
  color: var(--gb-live); border: 1px solid rgba(53,224,122,.4);
  border-radius: 999px; padding: 1px 7px; margin-left: var(--gb-2);
  letter-spacing: .06em; vertical-align: 1px;
}

.gb-rung-who { flex: 1; color: var(--gb-ink-2); }

.gb-rung-who strong { color: var(--gb-accent); font-weight: 700; }

/* How long a game against this bot tends to run -- the rung has room to
   spare between its two W-L-D columns, and it is a fair question to ask
   before picking an opponent: THE COURT drags a beginner's game out much
   longer than THE JANITOR does. */
.gb-rung-length {
  font-family: var(--gb-mono); font-size: var(--gb-fs-sm);
  color: var(--gb-ink-3); font-variant-numeric: tabular-nums;
  min-width: 84px;
}

.gb-rung-score {
  font-family: var(--gb-mono); color: var(--gb-ink-2);
  font-variant-numeric: tabular-nums; text-align: right;
}

.gb-rung-rec, .gb-rung-length { text-align: right; }

.gb-rung-play { width: auto; min-height: 32px; padding: 5px 10px; }

.gb-rung-action { min-width: 0; }

.gb-rung-none { color: var(--gb-ink-3); font-style: italic; }


/* The six columns need about 630px before they start colliding, and
   .gb-ladder clips what does not fit -- so between 561px and 720px the PLAY
   button was not merely cramped, it was off the edge and unreachable. Below
   760px each rung becomes a small card instead: the name and its button on
   the first line, the three numbers labelled underneath. The header row goes
   away with the columns it was labelling. */
@media (max-width: 760px) {

  .gb-rung-head { display: none; }

  .gb-rung {
    grid-template-columns: 26px minmax(0, 1fr) minmax(0, 1fr) auto;
    grid-template-areas:
      "level name   name    play"
      "level record length  score"
      "who   who    who     who";
    gap: var(--gb-2);
    align-items: start;
  }

  .gb-ladder .gb-rung-level  { grid-area: level; text-align: left; line-height: 1.5; }

  .gb-ladder .gb-rung-name   { grid-area: name; align-self: center; }

  .gb-ladder .gb-rung-rec    { grid-area: record; min-width: 0; }

  .gb-ladder .gb-rung-length { grid-area: length; min-width: 0; }

  .gb-ladder .gb-rung-score  { grid-area: score; min-width: 0; }

  .gb-ladder .gb-rung-play   { grid-area: play; align-self: center; }

  .gb-ladder .gb-rung-beaters, .gb-ladder .gb-rung-who { grid-area: who; margin-top: 0; }


  /* With the header gone, each number says what it is. */
  .gb-ladder .gb-rung-rec,
  .gb-ladder .gb-rung-length,
  .gb-ladder .gb-rung-score { text-align: left; }

  .gb-rung-rec::before, .gb-rung-length::before, .gb-rung-score::before {
    display: block; font-family: var(--gb-ui); font-size: 10px;
    letter-spacing: .08em; text-transform: uppercase; color: var(--gb-ink-3);
  }

  .gb-rung-rec::before    { content: 'Its record'; }

  .gb-rung-length::before { content: 'Game length'; }

  .gb-rung-score::before  { content: 'Yours'; }
}


/* Narrower still, and three columns of label-over-number stop fitting:
   "Game length" breaks across two lines and takes "~45 moves" with it. One
   labelled line each instead, which is taller by a hair and legible. */
@media (max-width: 420px) {

  .gb-rung {
    grid-template-columns: 26px minmax(0, 1fr) auto;
    grid-template-areas:
      "level name   play"
      "level record record"
      "level length length"
      "level score  score"
      "who   who    who";
    row-gap: var(--gb-1);
  }

  .gb-rung-rec::before, .gb-rung-length::before, .gb-rung-score::before {
    display: inline; margin-right: var(--gb-2);
  }
}


/* ── The archive ──────────────────────────────────────────────────
   Finished games. Every one is stored whole; this is the way back to
   the replay, the engine review and the PGN, all of which live on the
   board page. Result is carried by a word first and a colour second. */
.gb-archive {
  display: flex; flex-direction: column;
  border: 1px solid var(--gb-line); border-radius: var(--gb-radius);
  overflow: hidden;
}

.gb-past {
  display: flex; align-items: baseline; gap: var(--gb-3);
  padding: var(--gb-3) var(--gb-4);
  background: var(--gb-surface); font-size: var(--gb-fs-sm);
  text-decoration: none; color: var(--gb-ink);
  transition: background .12s;
}

.gb-past + .gb-past { border-top: 1px solid var(--gb-line); }

.gb-past:hover { background: var(--gb-raised); }

.gb-past.win  { box-shadow: inset 3px 0 0 var(--gb-live); }

.gb-past.loss { box-shadow: inset 3px 0 0 var(--gb-danger); }

.gb-past.draw { box-shadow: inset 3px 0 0 var(--gb-ink-3); }


.gb-past-result { font-weight: 700; min-width: 42px; }

.gb-past.win .gb-past-result  { color: var(--gb-live); }

.gb-past.loss .gb-past-result { color: var(--gb-danger); }

.gb-past.draw .gb-past-result { color: var(--gb-ink-2); }


.gb-past-who { color: var(--gb-ink); min-width: 170px; }

.gb-past-tag {
  font-family: var(--gb-mono); font-size: 10px; color: var(--gb-ink-3);
  border: 1px solid var(--gb-line-2); border-radius: 999px;
  padding: 1px 6px; margin-left: var(--gb-2);
}

.gb-past-opening {
  color: var(--gb-accent); font-size: var(--gb-fs-xs); min-width: 150px;
}

.gb-past-meta {
  font-family: var(--gb-mono); font-size: var(--gb-fs-xs); color: var(--gb-ink-3);
  flex: 1;
}

.gb-past-when {
  font-family: var(--gb-mono); font-size: var(--gb-fs-xs); color: var(--gb-ink-3);
  margin-left: auto;
}


@media (max-width: 720px) {

  .gb-past { flex-wrap: wrap; gap: var(--gb-2); }

  .gb-past-who, .gb-past-opening { min-width: 0; }

  .gb-past-meta { flex-basis: 100%; }
}


/* Progressive disclosure. A handful of names in the row, the rest one click
   away -- people do want the whole list, they just do not want to read it by
   accident. <details> rather than script: it is keyboard-accessible and works
   with no JavaScript at all. */
.gb-more { display: inline; }

.gb-more > summary {
  display: inline; cursor: pointer; color: var(--gb-ink-3);
  text-decoration: underline dotted; text-underline-offset: 3px;
}

.gb-more > summary:hover { color: var(--gb-accent); }

.gb-more[open] > summary::after { content: ' —'; }


/* Form inputs, for the admin page. The site has no styled input anywhere
   else, so these are defined here rather than inherited from nothing. */
.gb-input {
  font-family: var(--gb-ui); font-size: var(--gb-fs-sm);
  background: var(--gb-raised); color: var(--gb-ink);
  border: 1px solid var(--gb-line-2); border-radius: var(--gb-radius-sm);
  padding: var(--gb-2) var(--gb-3); min-height: 42px;
}

.gb-input:focus-visible { outline: 2px solid var(--gb-accent); outline-offset: 2px; }

.gb-input::placeholder { color: var(--gb-ink-3); }


/* A barred player, told plainly and without drama. */
.gb-banned {
  border: 1px solid var(--gb-danger); border-left-width: 3px;
  border-radius: var(--gb-radius); background: #1d1116;
  padding: var(--gb-4); margin-bottom: var(--gb-5);
  font-size: var(--gb-fs-sm); color: var(--gb-ink);
}

.gb-banned strong { color: var(--gb-danger); display: block; margin-bottom: var(--gb-1); }


/* A button that reads as a link. Used where an empty state offers the
   alternative in the middle of a sentence. */
.gb-link {
  background: none; border: none; padding: 0; cursor: pointer;
  font: inherit; color: var(--gb-accent);
  text-decoration: underline; text-underline-offset: 3px;
}

.gb-link:hover { color: #ffe14d; }


/* ── The training ladder ──────────────────────────────────────────
   A separate number, and it has to look separate. */
.gb-stat.training .gb-stat-value { color: var(--gb-live); }



/* Two records per rung, both as W–L–D, in monospace so the columns line up
   down the ladder. The names behind the opponent's record are one click away
   rather than spelled out in a sentence on every row. */
.gb-rung-rec {
  font-family: var(--gb-mono); font-size: var(--gb-fs-sm);
  color: var(--gb-ink-2); font-variant-numeric: tabular-nums;
  min-width: 78px;
}

.gb-rung-rec .gb-more > summary { color: var(--gb-ink-2); }

.gb-rung-rec .gb-more[open] > summary { color: var(--gb-accent); }

.gb-rung-beaters {
  grid-column: 2 / -1; display: block; margin-top: calc(var(--gb-1) * -1);
  font-family: var(--gb-ui); font-size: var(--gb-fs-xs);
  color: var(--gb-ink-3); line-height: 1.6;
}

.gb-rung-beaters strong { color: var(--gb-accent); font-weight: 700; }


/* A header row, so the two record columns are labelled once instead of
   explained on every line. */
.gb-rung-head {
  background: var(--gb-raised);
  font-size: var(--gb-fs-xs); color: var(--gb-ink-3);
  letter-spacing: .08em; text-transform: uppercase;
}

.gb-rung-head .gb-rung-name,
.gb-rung-head .gb-rung-rec,
.gb-rung-head .gb-rung-score { font-family: var(--gb-ui); color: var(--gb-ink-3); }


/* Reference text, folded away. A player who wants to climb the ladder does
   not need a paragraph in front of it, but the paragraph should still exist
   for whoever wonders what the number means. */
.gb-explain { margin-bottom: var(--gb-4); }

.gb-explain > summary {
  cursor: pointer; list-style: none;
  font-size: var(--gb-fs-sm); color: var(--gb-ink-2);
  padding: var(--gb-2) 0;
}

.gb-explain > summary::-webkit-details-marker { display: none; }

.gb-explain > summary::after {
  content: ' ▸'; color: var(--gb-ink-3);
}

.gb-explain[open] > summary::after { content: ' ▾'; }

.gb-explain > summary:hover { color: var(--gb-ink); }

.gb-explain .gb-note-text { margin: var(--gb-2) 0 0; }


@media (pointer: coarse) {


  /* 44px is the floor for anything a finger has to hit. These are all
     controls that were sized for a mouse. */
  .gb-chip { min-height: 44px; padding: var(--gb-2) var(--gb-4); }

  /* Keep the 44px height -- that is the thumb -- but take the width back.
     Seven time controls at mouse padding stack into four rows on a phone and
     push everything worth reading off the screen; the labels are three or
     four monospace characters and never needed the room. */
  .gb-choice-grouped .gb-chip { padding-left: var(--gb-2); padding-right: var(--gb-2);
                                min-width: 56px; }

  .gb-choice-grouped { gap: var(--gb-3); }

  .gb-challenge-btns .gb-btn { min-height: 44px; }

  .gb-ladder .gb-rung-play { min-height: 44px; padding: 5px 14px; }

  .gb-tab { min-height: 48px; }

  /* A <summary> is a button as far as a thumb is concerned. */
  .gb-explain > summary, #gb-other-active > summary { padding: var(--gb-3) 0; }
}


/* ── Small screens, continued ──────────────────────────────────────
   The lobby's own cramped spots, below the 560px line the rest of the
   page already uses. */
@media (max-width: 560px) {

  /* Two sentence-long labels do not fit one line; let them take two. */
  .gb-bar-go .gb-btn { flex: 1 1 100%; }

  /* The time control and the buttons that follow it are separate
     decisions, and reading as one run-on row made that hard to see. */
  .gb-bar { gap: var(--gb-2); }

  .gb-bar-label { min-width: 100%; }

  /* A four-up stat row on a 320px screen wraps to two lines; keep the
     gap tight enough that it does not read as two sections. */
  .gb-stats { gap: var(--gb-4) var(--gb-5); }
}

/* ── The locked landing ──────────────────────────────────────────────────
   What somebody sees when they follow a shared link to chess without being
   logged in. See CHESS.md 3. */
.gb-locked { max-width: 640px; margin: var(--gb-6) auto; display: grid; gap: var(--gb-4); }
.gb-locked-lead { font-size: var(--gb-fs-lg); color: var(--gb-ink); line-height: 1.55; margin: 0; }
.gb-locked-note { font-size: var(--gb-fs-sm); color: var(--gb-ink-3); line-height: 1.6; margin: 0; }
.gb-locked .gb-btn-row { justify-content: flex-start; flex-wrap: wrap; }
.gb-locked .gb-btn { width: auto; }
.gb-locked-game {
  font-family: var(--gb-mono); font-size: var(--gb-fs-sm);
  color: var(--gb-accent); margin: 0;
}
.gb-locked-game strong { color: var(--gb-ink); font-weight: 600; }

/* A quiet "?" beside a heading, for the one sentence a player might want.
   Anything longer than a sentence does not belong in a tooltip -- and, on
   the evidence of what this replaced, probably does not belong on the page
   either. Focusable, so it is reachable without a mouse. */
.gb-why {
  display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px; margin-left: 6px; vertical-align: 1px;
  border: 1px solid var(--gb-line-2); border-radius: 50%;
  font-family: var(--gb-ui); font-size: 10px; font-weight: 600;
  line-height: 1; color: var(--gb-ink-3); cursor: help;
  letter-spacing: 0; text-transform: none;
}
.gb-why:hover, .gb-why:focus-visible { color: var(--gb-accent); border-color: var(--gb-accent); }
.gb-why:focus-visible { outline: 2px solid var(--gb-accent); outline-offset: 2px; }
