/*
The page, in one stylesheet. Nothing here knows a rule of the game --
what a control is, whether it is dead and what colour it is, is what
the server sent.

Two palettes, on purpose. The page around the board is in Discord's
dark theme. The board and the jumbotron bar are drawn from scratch
over the same values, in the teams' `render.py` colours and the
bundled typefaces (docs/web-app-redesign.md). There are no coloured
buttons: the answer to a question is the thing on the board lit in
gold, and anything else is the one neutral outlined control.
*/

@font-face {
  font-family: "Board";
  src: url("/fonts/RobotoSlab-Regular.ttf") format("truetype");
  font-weight: 400;
}
@font-face {
  font-family: "Board";
  src: url("/fonts/RobotoSlab-Bold.ttf") format("truetype");
  font-weight: 700;
}
@font-face {
  font-family: "Goal";
  src: url("/fonts/RacingSansOne-Regular.ttf") format("truetype");
}

:root {
  color-scheme: dark;

  /* Discord's dark theme. */
  --page: #313338;
  --panel: #2b2d31;
  --deep: #1e1f22;
  --field: #383a40;
  --line: #3f4147;
  --text: #dbdee1;
  --strong: #f2f3f5;
  --muted: #949ba4;
  --faint: #6d6f78;
  --link: #00a8fc;
  --blurple: #5865f2;
  --blurple-hover: #4752c4;
  --grey: #4e5058;
  --grey-hover: #6d6f78;
  --green: #248046;
  --green-hover: #1a6334;
  --red: #da373c;
  --red-hover: #a12828;
  --yours: rgba(250, 168, 26, 0.08);
  --yours-edge: #f0b232;
  --gold: #f0b232;

  /* The bot's board (render.py). */
  --b-code: #c8d1dc;
  --b-goal: #0c141c;
  --b-team: #202a35;
  --b-clock: #f5d76e;
  --b-quiet: #9eabb8;

  --topbar: 48px;
  --side: 380px;
}

* { box-sizing: border-box; }

/* A panel's own display never wins over `hidden`. */
[hidden] { display: none !important; }

html, body { height: 100%; }

body {
  margin: 0;
  background: var(--page);
  color: var(--text);
  font: 15px/1.4 "gg sans", "Noto Sans", "Helvetica Neue", Helvetica, Arial,
    sans-serif;
  -webkit-font-smoothing: antialiased;
}

img { display: block; }

/* -- The top bar ------------------------------------------------------ */

.topbar {
  height: var(--topbar);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 0 16px;
  background: var(--page);
  border-bottom: 1px solid var(--deep);
  box-shadow: 0 1px 0 rgba(4, 4, 5, 0.2);
  position: sticky;
  top: 0;
  z-index: 5;
}
.topbar-title { display: flex; align-items: center; gap: 8px; min-width: 0; }
.back {
  color: var(--muted);
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}
.back:hover, .back:focus-visible { color: var(--strong); }
.hash { color: var(--faint); font-size: 24px; font-weight: 500; }
.channel-name { color: var(--strong); font-weight: 600; white-space: nowrap; }
.topbar-divider { width: 1px; height: 24px; background: var(--line); margin: 0 4px; }
.topic {
  color: var(--muted);
  font-size: 14px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* The topic as the name's editor, before kickoff: the text itself is
   the button, with a pencil that brightens on hover. */
.topic-edit {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  max-width: 100%;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
}
.topic-edit .topic-text {
  overflow: hidden;
  text-overflow: ellipsis;
  border-bottom: 1px dashed var(--faint);
}
.topic-edit .topic-pencil { color: var(--faint); font-size: 13px; }
.topic-edit:hover, .topic-edit:focus-visible { color: var(--strong); }
.topic-edit:hover .topic-pencil, .topic-edit:focus-visible .topic-pencil { color: var(--gold); }
.topic .topic-field { width: 260px; }

/* -- The two columns ---------------------------------------------------- */

.app {
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--side);
  gap: 16px;
  padding: 16px;
  height: calc(100vh - var(--topbar));
  height: calc(100dvh - var(--topbar));
}

.main {
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-height: 0;
  overflow-y: auto;
}

/* The sidebar: one panel with four tabs across its head -- Log, Chat,
   Teams, Rules -- and the one showing under them (step 10 of
   docs/web-app-redesign.md). */
.sidebar {
  display: flex;
  flex-direction: column;
  min-height: 0;
  background: var(--panel);
  border: 1px solid var(--deep);
  border-radius: 12px;
  overflow: hidden;
}
.side-tabs { display: flex; flex: none; border-bottom: 1px solid var(--line); }
.side-tab {
  flex: 1;
  position: relative;
  padding: 9px 6px;
  border: 0;
  border-bottom: 2px solid transparent;
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-weight: 700;
  font-size: 13px;
  cursor: pointer;
}
.side-tab:hover { color: var(--text); }
.side-tab:focus-visible { outline: 2px solid var(--blurple); outline-offset: -2px; }
.sidebar[data-pane="log"] .side-tab[data-pane="log"],
.sidebar[data-pane="chat"] .side-tab[data-pane="chat"],
.sidebar[data-pane="teams"] .side-tab[data-pane="teams"],
.sidebar[data-pane="rules"] .side-tab[data-pane="rules"] {
  color: var(--strong);
  border-bottom-color: var(--blurple);
}
/* A dot on a tab that is not showing: red for news, gold for your move. */
.side-tab.news::after {
  content: "";
  position: absolute;
  top: 8px;
  right: 14%;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--red);
}
.side-tab.yours::after { background: var(--gold); }

.pane {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  padding: 10px 12px;
}
@media (min-width: 961px) {
  .sidebar:not([data-pane="log"]) > [data-pane-for="log"],
  .sidebar:not([data-pane="chat"]) > [data-pane-for="chat"],
  .sidebar:not([data-pane="teams"]) > [data-pane-for="teams"],
  .sidebar:not([data-pane="rules"]) > [data-pane-for="rules"] { display: none; }
}

.panel {
  background: var(--panel);
  border: 1px solid var(--deep);
  border-radius: 8px;
  padding: 12px 14px;
}

.panel-label {
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--muted);
  margin-bottom: 8px;
}

.quiet { color: var(--muted); font-size: 13px; margin: 0; }

/* -- The board panel ---------------------------------------------------- */

.board-panel { padding: 10px; }
/* What to do with a meeple just picked up, at the foot of the window
   -- never over the field, where it would hide what is clicked next --
   until it is put down or put back. */
.pick-toast {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 50;
  width: max-content;
  max-width: calc(100vw - 32px);
  padding: 8px 14px;
  border-radius: 8px;
  border: 1px solid var(--gold);
  background: rgba(17, 18, 20, 0.92);
  color: #fff;
  font-size: 14px;
  font-weight: 600;
  text-align: center;
  pointer-events: none;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
}
.pick-toast[hidden] { display: none; }
.board-empty { color: var(--muted); text-align: center; margin: 60px 0; }

/* The sideline under the field (step 6 of docs/web-app-redesign.md):
   each team's bench and back bench as boxes edged in the team's colour,
   home's under the home end and the visitors' under theirs, holding the
   meeples the field draws. */
.benches {
  display: flex;
  gap: 16px;
  margin-top: 10px;
  padding: 10px 14px;
  background: var(--deep);
  border-radius: 14px;
}
.sideline-team {
  position: relative;
  flex: 1;
  display: flex;
  gap: 8px;
  align-items: flex-start;
  justify-content: flex-start;
  min-width: 0;
  flex-wrap: wrap;
  border-radius: 12px;
}
.sideline-team.visiting { justify-content: flex-end; }
/* A bench that is the answer (the Coaching Offer): edged in gold. */
.sideline-team.lit { cursor: pointer; }
.sideline-team.lit .bench-box {
  border-color: var(--gold);
  box-shadow: 0 0 0 1px var(--gold), 0 0 16px rgba(240, 178, 50, 0.4);
}
.sideline-chips { align-self: center; }
.bench-box {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 8px 10px 6px;
  border-radius: 12px;
  border: 2px solid color-mix(in srgb, var(--team) 33%, transparent);
  background: var(--panel);
  min-width: 96px;
}
.bench-head { display: flex; gap: 8px; align-items: baseline; }
.bench-title { font-size: 11px; font-weight: 800; letter-spacing: 1px; color: var(--team); }
.bench-said { font-size: 10px; color: var(--faint); }
.bench-pieces { display: flex; gap: 2px; min-height: 76px; align-items: flex-start; }
.bench-piece {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  width: 78px;
}
.bench-body { position: relative; display: inline-flex; justify-content: center; }
.bench-name {
  font-size: 12px;
  font-weight: 700;
  color: var(--strong);
  white-space: nowrap;
  max-width: 78px;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bench-name.lit { color: var(--gold); }
.bench-chip-line { display: inline-flex; flex-wrap: wrap; justify-content: center; gap: 3px; }
.bench-chip-line .chip { white-space: normal; text-align: center; line-height: 1.15; }
.bench-empty { color: var(--muted); font-size: 12px; align-self: center; padding: 0 8px; }

/* -- The prompt ------------------------------------------------------------ */

.prompt.yours {
  background: linear-gradient(var(--yours), var(--yours)), var(--panel);
  box-shadow: inset 3px 0 0 var(--yours-edge);
}
.prompt.yours .panel-label { color: var(--yours-edge); }

.ask { margin: 0 0 10px; white-space: pre-wrap; }
.ask:empty { display: none; }
.prompt-picture {
  display: block;
  max-width: 100%;
  height: auto;
  margin: 0 0 10px;
  border-radius: 4px;
}

/* -- The question box --------------------------------------------------
   The canvas's: a state tag, the outcome large and first, the ask at
   17px, a muted line for what is lit on the board, and the picture
   the question is asked over on the right. The edge is the tag's
   colour; which tag is the server's reading (`_box_state`). */

.qbox {
  --edge: var(--line);
  --tag: var(--grey);
  --tag-ink: #fff;
  display: flex;
  gap: 18px;
  min-height: 150px;
  /* In the play area's column it holds its content's height rather
     than being squeezed under the panels after it. */
  flex-shrink: 0;
  border-radius: 14px;
  border-left: 5px solid var(--edge);
  padding: 14px 18px 16px;
}
.qbox[data-state="yours"] { --edge: var(--gold); --tag: var(--gold); --tag-ink: var(--deep); }
.qbox[data-state="waiting"] { --edge: var(--line); --tag: var(--grey); }
.qbox[data-state="now"] { --edge: var(--blurple); --tag: var(--blurple); }
.qbox[data-state="full_time"] { --edge: var(--green); --tag: var(--green); }
.qbox-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 8px; }
.qbox .ask { margin: 0; font-size: 17px; line-height: 1.35; color: var(--strong); }
.qbox-aside {
  flex: 0 0 auto;
  max-width: 45%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding-left: 18px;
  border-left: 1px solid var(--line);
}
.qbox-aside .prompt-picture { margin: 0; }

.state-tag {
  display: inline-flex;
  align-items: center;
  background: var(--tag);
  color: var(--tag-ink);
  border-radius: 5px;
  padding: 2px 6px;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.2px;
  line-height: 1;
  text-transform: uppercase;
  white-space: nowrap;
}

.lit-line { margin: 0; font-size: 13px; color: var(--muted); }

/* The outcome: the dice at 84px beside the model's own headline, in
   the display face, and the line under it. */
.outcome {
  display: flex;
  align-items: center;
  gap: 26px;
  padding: 14px 20px 16px;
  border-radius: 12px;
  background: var(--deep);
  border: 1px solid var(--line);
  box-shadow: inset 4px 0 0 var(--outcome, var(--gold));
}
.outcome-dice { display: block; height: 180px; width: auto; max-width: 45%; object-fit: contain; }
.outcome-words { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.outcome-headline {
  font-family: "Goal", "Board", sans-serif;
  font-size: 46px;
  line-height: 1;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--outcome, var(--gold));
}
.outcome-headline strong, .outcome-headline em { color: inherit; font-weight: inherit; font-style: inherit; }
.outcome-detail { font-size: 17px; font-weight: 700; color: var(--strong); white-space: pre-line; }
/* The roll's arithmetic, written out by the model (`Headline.working`). */
.outcome-working { font-size: 15px; line-height: 1.4; color: var(--text); }

/* The outcome and, at full time, the numbers beside it. */
.outcome-row { display: flex; flex-wrap: wrap; align-items: stretch; gap: 14px; }
.outcome-row > .outcome { flex: 1 1 420px; }
.outcome-row > [hidden] { display: none; }

/* Full time: each side's numbers in its colour, the statistic between
   them, and the ways on (step 5 of docs/web-app-redesign.md). */
.full-time {
  flex: 0 1 340px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px 16px;
  border-radius: 12px;
  background: var(--deep);
  border: 1px solid var(--line);
}
.ft-stats { border-collapse: collapse; width: 100%; }
.ft-stats th {
  font-family: "Goal", "Board", sans-serif;
  font-weight: 400;
  font-size: 18px;
  letter-spacing: 1px;
  text-transform: uppercase;
  padding-bottom: 4px;
}
.ft-stats th:first-child, .ft-number:first-child { text-align: right; }
.ft-stats th:last-child, .ft-number:last-child { text-align: left; }
.ft-number { font-size: 20px; font-weight: 700; padding: 2px 10px; font-variant-numeric: tabular-nums; }
.ft-label { text-align: center; font-size: 13px; color: var(--muted); padding: 2px 6px; white-space: nowrap; }
.ft-links { align-items: center; gap: 12px; }
.ft-links .btn { text-decoration: none; }
.rematch-wrap { display: flex; flex-direction: column; gap: 6px; }

/* The reveal: both cards face up, what the cards said between them. */
.reveal { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.reveal-card { margin: 0; width: 120px; border-radius: 10px; overflow: hidden; border: 2px solid transparent; }
.reveal-card.won { border-color: var(--gold); box-shadow: 0 0 16px rgba(240, 178, 50, 0.35); }
.reveal-card img { display: block; width: 100%; height: auto; }
.reveal-between {
  font-family: "Goal", "Board", sans-serif;
  font-size: 30px;
  letter-spacing: 2px;
  color: var(--strong);
}
.reveal-between.tie { color: var(--gold); }

/* The owed step: its own strip above the box. */
.owed-strip {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 14px;
  background: var(--panel);
  border-radius: 14px;
  border-left: 5px solid var(--blurple);
  padding: 12px 18px;
}
.owed-strip p { margin: 0; flex: 1; }


@media (max-width: 960px) {
  .qbox { flex-direction: column; }
  .qbox-aside { max-width: 100%; padding-left: 0; border-left: 0; }
  .outcome { flex-wrap: wrap; gap: 14px; }
  .outcome-headline { font-size: 34px; }
}

.controls { display: flex; flex-direction: column; gap: 8px; }
.group-label {
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--muted);
  margin: 4px 0 0;
}
.note-line { font-size: 13px; color: var(--muted); margin: 0; }
.row { display: flex; flex-wrap: wrap; gap: 8px; }
.prompt.busy .controls { opacity: 0.6; pointer-events: none; }

/* The one neutral control, where nothing on the board can be the
   answer: outlined, no fill, no colour (step 4 of
   docs/web-app-redesign.md). A setting's value as it stands is edged
   in gold. */
.btn {
  font: inherit;
  font-size: 14px;
  font-weight: 700;
  line-height: 16px;
  min-height: 36px;
  padding: 8px 16px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: transparent;
  color: var(--text);
  cursor: pointer;
  transition: background-color 0.17s ease, border-color 0.17s ease;
}
.btn:hover:not(:disabled) { background: rgba(255, 255, 255, 0.04); border-color: var(--muted); }
.btn.current { border-color: var(--gold); background: rgba(240, 178, 50, 0.14); color: var(--strong); }
.btn.small { min-height: 30px; padding: 5px 12px; font-size: 13px; }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }
.btn.current:disabled { opacity: 1; cursor: default; }
.btn:focus-visible { outline: 2px solid var(--link); outline-offset: 2px; }

/* The things the question box draws to be clicked: the die, a speed's
   faces, the whistle, the REMATCH mark, and the note. */
.big-die, .face, .whistle, .rematch-mark {
  font: inherit;
  background: transparent;
  border: 0;
  padding: 0;
  color: inherit;
  cursor: pointer;
}
.big-die { display: inline-flex; flex-direction: column; align-items: center; gap: 6px; }
.big-die-ring {
  display: inline-flex;
  padding: 6px;
  border-radius: 50%;
  box-shadow: 0 0 0 3px var(--gold), 0 0 22px rgba(240, 178, 50, 0.45);
}
.big-die-word { font-size: 12px; font-weight: 700; color: var(--gold); }
.big-die:hover .big-die-ring { box-shadow: 0 0 0 3px var(--gold), 0 0 30px rgba(240, 178, 50, 0.7); }
.faces { display: flex; flex-wrap: wrap; gap: 14px; }
.face {
  display: inline-flex;
  padding: 5px;
  border-radius: 50%;
  box-shadow: 0 0 0 3px var(--gold), 0 0 16px rgba(240, 178, 50, 0.4);
}
.face:disabled { box-shadow: 0 0 0 1px var(--line); opacity: 0.4; cursor: not-allowed; }
.whistle-wrap { display: flex; flex-direction: column; gap: 6px; }
.whistle { display: inline-flex; align-items: center; gap: 10px; }
.whistle-disc {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 54px;
  height: 54px;
  border-radius: 50%;
  background: var(--deep);
  box-shadow: 0 0 0 1px var(--line);
}
.whistle.lit .whistle-disc { box-shadow: 0 0 0 3px var(--gold), 0 0 18px rgba(240, 178, 50, 0.4); }
.whistle-label { font-size: 13px; font-weight: 700; color: var(--muted); }
.whistle.lit .whistle-label { color: var(--gold); }
.whistle:disabled { cursor: not-allowed; }
.rematch-mark {
  align-self: flex-start;
  font-family: "Goal", "Board", sans-serif;
  font-size: 34px;
  letter-spacing: 2px;
  color: var(--gold);
  padding: 6px 18px;
  border-radius: 10px;
  box-shadow: 0 0 0 3px var(--gold), 0 0 22px rgba(240, 178, 50, 0.4);
}
.qbox.note-lit { cursor: pointer; box-shadow: inset 0 0 0 2px var(--gold); }
.note-chip { display: inline-flex; }

/* The lit line: what is lit on the board and why, and what is dark. */
.lit-line { display: flex; flex-direction: column; gap: 2px; }
.lit-item { color: var(--text); }
.lit-item.dark { color: var(--muted); }

/* The keyboard's list of the same controls, out of sight until one of
   them has the focus. */
.keys {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  margin: 0;
  padding: 0;
}
.keys:focus-within {
  position: static;
  width: auto;
  height: auto;
  clip: auto;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  list-style: none;
}
.keys button { font: inherit; font-size: 13px; background: transparent; color: var(--text); border: 1px solid var(--line); border-radius: 6px; padding: 4px 8px; }

.chooser {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 8px;
  border-radius: 8px;
  background: var(--deep);
}
.chooser-label { font-size: 14px; }
.chooser label { font-size: 12px; color: var(--muted); font-weight: 600; }
select {
  font: inherit;
  font-size: 14px;
  color: var(--text);
  background: var(--field);
  border: 1px solid var(--deep);
  border-radius: 4px;
  padding: 6px 8px;
  min-width: 10em;
  max-width: 100%;
}

/* A hand of maneuver cards: the printed cards are the buttons, 150px
   wide, the gambits in a row of their own under the basic three. */
.hand-rows { display: flex; flex-direction: column; gap: 8px; }
.hand-label { font-size: 12px; font-weight: 700; letter-spacing: 1px; text-transform: uppercase; color: var(--muted); }
.hand-label .quiet { text-transform: none; letter-spacing: 0; font-weight: 400; }
.hand {
  display: grid;
  grid-template-columns: repeat(auto-fill, 150px);
  gap: 10px;
}
.hand-card {
  padding: 0;
  border: 2px solid transparent;
  border-radius: 10px;
  background: none;
  cursor: pointer;
  overflow: hidden;
  transition: transform 0.12s ease, border-color 0.12s ease;
}
.hand-card img { width: 100%; height: auto; }
.hand-card:not(:disabled) { border-color: rgba(240, 178, 50, 0.55); }
.hand-card:hover:not(:disabled) {
  border-color: var(--gold);
  transform: translateY(-4px) scale(1.06);
  box-shadow: 0 0 18px rgba(240, 178, 50, 0.35);
}
.hand-card:disabled { opacity: 0.35; cursor: not-allowed; }
.hand-card.withheld { filter: grayscale(0.6); }
/* The card laid face down: ringed in gold, and dead, since the same
   card twice is refused; the others may still replace it. */
.hand-card.picked:disabled {
  opacity: 1;
  cursor: default;
  border-color: var(--gold);
  box-shadow: 0 0 0 2px var(--gold), 0 0 18px rgba(240, 178, 50, 0.45);
  position: relative;
}
.hand-card-chip {
  position: absolute;
  left: 6px;
  right: 6px;
  bottom: 6px;
  padding: 3px 6px;
  border-radius: 6px;
  background: rgba(30, 31, 34, 0.9);
  color: var(--gold);
  font-size: 11px;
  font-weight: 700;
  text-align: center;
}

/* The hands held face down beside the hand. */
.hand-table { display: flex; flex-direction: column; gap: 6px; }

/* A refusal: a red-edged strip inside the box it refused. */
.refusal {
  border-left: 3px solid var(--red);
  background: rgba(218, 55, 60, 0.08);
  border-radius: 0 8px 8px 0;
  padding: 8px 12px;
  font-size: 13px;
  display: flex;
  justify-content: space-between;
  gap: 12px;
  align-items: center;
}
.refusal p { margin: 0; }
.linkish {
  font: inherit;
  font-size: 13px;
  background: none;
  border: 0;
  padding: 0;
  color: var(--link);
  cursor: pointer;
}

/* -- The jumbotron bar: across the top of the play area ---------------------
   The teams and the score on the left, a rule, the clock and its track,
   and a time-out tile per team. Racing Sans One for the display type,
   the clock in the board's yellow. */

.jumbotron {
  flex: none;
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 12px 20px;
  background: var(--deep);
  border: 1px solid var(--line);
  border-radius: 14px;
  color: var(--text);
}
.jumbo-teams {
  flex: 1 1 auto;
  min-width: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  gap: 20px;
}
.jumbo-side { min-width: 0; display: flex; flex-direction: column; gap: 2px; align-items: flex-start; }
.jumbo-side.visiting { align-items: flex-end; text-align: right; }
.jumbo-team {
  font-family: "Goal", "Board", sans-serif;
  font-size: 26px;
  letter-spacing: 1px;
  line-height: 1;
  text-transform: uppercase;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}
.jumbo-arrow { font-size: 14px; color: var(--muted); }
.jumbo-coach {
  font-size: 12px;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}
.jumbo-coach b { color: var(--text); }
.jumbo-ball {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  font-weight: 800;
  color: var(--gold);
}
.jumbo-score { display: flex; flex-direction: column; align-items: center; gap: 2px; min-width: 120px; }
.jumbo-goals {
  font-family: "Goal", "Board", sans-serif;
  font-size: 44px;
  line-height: 1;
  color: var(--strong);
  white-space: nowrap;
}
.jumbo-brand { font-size: 11px; letter-spacing: 2px; color: var(--muted); }
.jumbo-rule { flex: none; align-self: stretch; width: 1px; background: var(--line); }

.jumbo-clock { flex: 0 1 330px; min-width: 220px; display: flex; flex-direction: column; gap: 6px; }
.jumbo-time { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.jumbo-minute {
  font-family: "Goal", "Board", sans-serif;
  font-size: 30px;
  line-height: 1;
  color: var(--b-clock);
}
.jumbo-half { font-size: 12px; font-weight: 700; color: var(--text); }
.jumbo-last {
  align-self: center;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.08em;
  color: #fff;
  background: var(--red);
  border-radius: 4px;
  padding: 2px 6px;
}
.jumbo-track { display: flex; gap: 2px; }
.jumbo-track .seg { flex: 1; height: 6px; border-radius: 2px; background: rgba(255, 255, 255, 0.12); }
.jumbo-track .seg.filled { background: var(--gold); }
.jumbo-marks { display: flex; justify-content: space-between; font-size: 11px; color: var(--muted); }
.jumbo-note { font-size: 12px; font-weight: 700; color: var(--strong); }

.jumbo-tiles { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.timeout-tile {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: 8px;
  font: inherit;
  text-align: left;
  min-width: 0;
}
.timeout-tile .tile-words { display: inline-flex; align-items: baseline; gap: 6px; min-width: 0; }
.tile-title { font-family: "Goal", "Board", sans-serif; font-size: 11px; letter-spacing: 1px; }
.timeout-tile small {
  font-size: 10px;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.timeout-tile.held { border: 1.5px solid var(--team); color: var(--team); background: transparent; }
.timeout-tile.spent {
  border: 1.5px dashed var(--grey);
  color: var(--faint);
  text-decoration: line-through;
}
.timeout-tile.spent small { color: var(--faint); }
.timeout-tile.lit {
  gap: 8px;
  padding: 6px 12px;
  border: 0;
  border-radius: 10px;
  background: var(--gold);
  color: #1e1f22;
  box-shadow: 0 0 0 3px rgba(240, 178, 50, 0.35), 0 0 18px rgba(240, 178, 50, 0.6);
  cursor: pointer;
}
.timeout-tile.lit .tile-words { flex-direction: column; align-items: flex-start; gap: 0; line-height: 1.05; }
.timeout-tile.lit .tile-title { font-size: 15px; }
.timeout-tile.lit small { font-weight: 800; color: #1e1f22; }
.timeout-tile.lit:hover { filter: brightness(1.08); }
.timeout-tile.lit:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

/* -- The game log ----------------------------------------------------------- */

.log-panel, .chat-panel { display: flex; flex-direction: column; min-height: 0; }

.journal {
  flex: 1 1 auto;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding-right: 4px;
  font-size: 14px;
}

/* The edge is the entry's kind: a new play blurple, a goal gold, a
   roll grey, the clock faint, a line the panel line. */
.entry { border-left: 3px solid var(--line); padding-left: 10px; }
.entry.kind-new_play { border-left-color: var(--blurple); }
.entry.kind-goal { border-left-color: var(--gold); }
.entry.kind-roll { border-left-color: var(--grey-hover); }
.entry.kind-clock { border-left-color: var(--deep); color: var(--muted); }
.log-minute {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--faint);
  margin: 4px 0 -4px;
}
.entry p { margin: 0 0 3px; white-space: pre-wrap; word-wrap: break-word; }
.entry .stamp { font-size: 11px; color: var(--faint); }
/* A roll's dice, as the bot posts them: at their own size up to the
   log's width, never stretched past it. */

/* The model's `#`, `##` and `###`. */
.headline {
  display: block;
  font-size: 16px;
  font-weight: 700;
  color: var(--strong);
  margin: 2px 0;
}
.headline.h1 { font-size: 17px; }
.headline.h3 { font-size: 15px; }

.emoji {
  display: inline-block;
  width: 1.3em;
  height: 1.3em;
  vertical-align: -0.3em;
  object-fit: contain;
}
/* A role badge in a sentence: not the board's absolutely placed
   `.badge`, whose class it shares -- in text it sits in the line. */
.emoji.badge {
  width: auto; height: 1.15em; vertical-align: -0.2em;
  position: static; z-index: auto; background: none; border: 0; box-shadow: none;
}
.emoji.species { width: 1.15em; height: 1.15em; vertical-align: -0.2em; }

.coach {
  background: rgba(88, 101, 242, 0.3);
  color: #c9cdfb;
  border-radius: 3px;
  padding: 0 2px;
  font-weight: 500;
}

strong { font-weight: 700; color: var(--strong); }

/* -- The chat --------------------------------------------------------------- */

.chat {
  flex: 1 1 auto;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 14px;
  padding-right: 4px;
}
.chat-line { margin: 0; word-wrap: break-word; }
.chat-who { font-weight: 600; margin-right: 6px; }
.chat-line time { font-size: 11px; color: var(--faint); margin-right: 6px; }

.chat-form { margin-top: 8px; display: flex; gap: 8px; }
.chat-form .chat-input { flex: 1 1 auto; min-width: 0; }
.chat-send { flex: 0 0 auto; }
.chat-line.yours .chat-who::after { content: " (you)"; font-weight: 400; color: var(--faint); }
.chat-input {
  width: 100%;
  font: inherit;
  font-size: 14px;
  color: var(--text);
  background: var(--field);
  border: 0;
  border-radius: 8px;
  padding: 10px 12px;
}
.chat-input::placeholder { color: var(--faint); }
.chat-input:focus { outline: 2px solid var(--link); }

/* -- The board --------------------------------------------------------------
   Drawn at a fixed width and scaled to its box, so every proportion is the
   bot's board's whatever the screen. */

.board-fit { position: relative; width: 100%; }

.stage {
  position: absolute;
  top: 0;
  left: 0;
  width: 1200px;
  transform-origin: 0 0;
  background: var(--deep);
  border-radius: 14px;
  padding: 12px 14px 14px;
  color: var(--text);
  user-select: none;
}

/* A card is `render.draw_card`'s picture, frame and marks included. */
.card {
  position: relative;
  flex: 0 1 80px;
  min-width: 0;
  border: 0;
  border-radius: 7px;
  background: none;
  cursor: zoom-in;
  padding: 0;
}
.card img { width: 100%; height: auto; aspect-ratio: 116 / 160; }
.card:hover { box-shadow: 0 0 0 2px #fff; }
.card:focus-visible { outline: 2px solid var(--link); }

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

/* The zone names over the spaces and the ranges under them, each as
   wide as the spaces it names -- set in from the goals by a goal's
   width and its gap. */
.field-row { display: flex; gap: 8px; padding: 0 78px; }
.zone-name {
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: "Goal", "Board", sans-serif;
  font-size: 14px;
  letter-spacing: 3px;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
}
.field-spaces { display: flex; gap: 8px; align-items: stretch; }

/* A goal: `#0c141c` edged in the defending side's colour, GOAL upright
   in Racing Sans One with the d12 for its O, turned to read along it. */
.goal {
  flex: 0 0 70px;
  position: relative;
  background: var(--b-goal);
  border: 2px solid var(--team);
  border-radius: 10px;
  overflow: hidden;
}
.goal.lit { box-shadow: 0 0 0 3px var(--gold), 0 0 24px rgba(240, 178, 50, 0.5); cursor: pointer; padding: 0; font: inherit; }
button.goal { display: block; }
.goal-chips {
  position: absolute;
  left: 50%;
  bottom: 8px;
  transform: translateX(-50%);
  z-index: 2;
}
/* The ✕ a pass is put out of play at, past the end: clicked, or the
   ball dropped on it. */
.goal.out-lit { overflow: visible; }
.out-mark {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  z-index: 3;
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  font-size: 34px;
  font-weight: 800;
  line-height: 1;
  color: var(--gold);
  text-shadow: 0 0 12px rgba(240, 178, 50, 0.6);
  cursor: pointer;
}
.out-mark::before {
  content: "";
  position: absolute;
  top: -6px;
  left: 50%;
  width: 46px;
  height: 46px;
  transform: translateX(-50%);
  border-radius: 50%;
  background: var(--deep);
  box-shadow: 0 0 0 3px var(--gold), 0 0 18px rgba(240, 178, 50, 0.5);
  z-index: -1;
}
.out-chip .chip { white-space: nowrap; }
.goal-word {
  position: absolute;
  left: 50%;
  top: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 22px;
  font-family: "Goal", sans-serif;
  font-size: 62px;
  line-height: 1;
  color: var(--team);
  white-space: nowrap;
}
.goal.home .goal-word { transform: translate(-50%, -50%) rotate(-90deg); }
.goal.visiting .goal-word { transform: translate(-50%, -50%) rotate(90deg); }
.goal-word .die { flex: none; }

/* A space: two lanes, the visitors' in the top half against the right
   edge and home's in the bottom half against the left. An end zone's
   spaces carry the defending side's colour faintly; midfield is the
   panel grey. It clips: nothing leaves the space it stands on. */
.space {
  position: relative;
  flex: 1 1 0;
  min-width: 0;
  min-height: 320px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 8px 6px 22px;
  background: var(--panel);
  border: 2px solid rgba(255, 255, 255, 0.07);
  border-radius: 10px;
  /* Not `overflow: hidden`: a piece at the lane's edge wears its
     badges off its own body -- the token count off the bottom right,
     the condition off the bottom left -- and a visiting fan is
     right-aligned, so the front piece's token hangs past the space.
     Clipped, it read as a chip out of the token (the author,
     2026-09-27). The badge is drawn over the gap and the neighbour's
     edge instead, above them by its own z-index. */
}
.space.tinted { background: color-mix(in srgb, var(--tint) 12%, var(--panel)); }
/* A space that is the answer: dashed gold, faintly lit, its chip at
   the foot. */
.space.lit {
  border: 2px dashed var(--gold);
  box-shadow: inset 0 0 0 999px rgba(240, 178, 50, 0.10);
  cursor: pointer;
  /* Room at the foot for the chip, under the names. */
  padding-bottom: 84px;
}
.space-chips {
  position: absolute;
  left: 4px;
  right: 4px;
  bottom: 6px;
  z-index: 70;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
}
.space-chips .chip { max-width: 100%; white-space: normal; text-align: center; line-height: 1.15; }
.space-code {
  position: absolute;
  top: 6px;
  left: 8px;
  font-size: 11px;
  font-weight: 800;
  color: var(--muted);
}
.kickoff-ring {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 54px;
  height: 54px;
  border: 2px solid rgba(255, 255, 255, 0.12);
  border-radius: 50%;
  transform: translate(-50%, -50%);
  pointer-events: none;
}
.lane { display: flex; min-height: 140px; min-width: 0; }
.lane.visiting { justify-content: flex-end; align-items: flex-start; padding-top: 12px; }
.lane.home { justify-content: flex-start; align-items: flex-end; }

/* A fan: each piece where `board.py` put it, the badges and the ball
   over the lot, and the names one to a line underneath. */
.fan { position: relative; display: block; flex: none; }
.fan-piece { position: absolute; }
.fan-name, .fan-chip-line {
  position: absolute;
  transform: translateX(calc(-50% + var(--nudge, 0px)));
  white-space: nowrap;
  line-height: 1;
  z-index: 40;
}
/* Drawn on the 1200px field and scaled down with it, so larger than
   the page's own text to read at the scale a laptop shows it. */
.fan-name { font-size: 20px; font-weight: 700; color: var(--strong); }
.fan-name.lit { color: var(--gold); }
.chip {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  background: var(--gold);
  color: var(--deep);
  border-radius: 5px;
  padding: 2px 6px;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.2px;
}
.chip-cost { display: inline-flex; align-items: center; gap: 3px; }
.chip-button { font: inherit; padding: 0; border: 0; background: none; cursor: pointer; }
.chip-button:hover .chip { filter: brightness(1.1); }
.fan-chip-line { display: inline-flex; gap: 4px; }
.chip-cost img { width: 14px; height: 14px; }
/* On the field, which is scaled down with it, a chip is drawn larger. */
.stage .chip { border-radius: 7px; padding: 3px 9px; font-size: 18px; }
.stage .chip-cost img { width: 22px; height: 22px; }

.badge {
  position: absolute;
  z-index: 50;
  display: inline-flex;
  align-items: center;
  background: var(--deep);
  border: 1px solid var(--line);
  box-shadow: 0 3px 6px rgba(0, 0, 0, 0.6);
}
.badge img { width: 16px; height: 16px; }
.badge.tokens {
  gap: 1px;
  border-radius: 10px;
  padding: 1px 5px 1px 2px;
  font-size: 12px;
  font-weight: 800;
  line-height: 1;
  color: var(--gold);
}
.badge.condition { border-radius: 50%; padding: 2px; }

/* The ball: the d12 showing its speed on a dark ring, on its holder,
   or larger at the centre of the empty space it is loose on. */
.held-ball, .loose-ball { position: absolute; z-index: 60; display: inline-flex; }
.loose-ball { left: 50%; top: 50%; transform: translate(-50%, -50%); }
/* The ball as an answer: the maneuver, or sending nobody. */
.ball-button {
  position: relative;
  display: inline-flex;
  padding: 0;
  border: 0;
  background: none;
  border-radius: 50%;
  cursor: pointer;
  touch-action: none;
}
.ball-button.lit { box-shadow: 0 0 0 3px var(--gold), 0 0 18px rgba(240, 178, 50, 0.55); }
.ball-button.draggable { cursor: grab; }
.ball-button.dragging { cursor: grabbing; z-index: 200; }
.ball-chips {
  position: absolute;
  left: 50%;
  bottom: calc(100% + 4px);
  transform: translateX(-50%);
  white-space: nowrap;
}
.die.ringed {
  padding: 2px;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.5);
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.3), 0 4px 8px rgba(0, 0, 0, 0.7);
  box-sizing: content-box;
}
.die text { font-family: "Board", sans-serif; }

/* The meeple: `render.MEEPLE_PATH` in the team's colour, edged in its
   ink (gold when lit), the species icon over the role letters. */
.meeple {
  position: relative;
  display: block;
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
  filter: drop-shadow(0 3px 3px rgba(0, 0, 0, 0.55));
}
.meeple.lit, .meeple.pickable, .meeple.picked { cursor: pointer; }
/* The thing picked up in a Coaching Choice: a dashed gold edge until
   it is put down somewhere lit, or put back. */
.meeple.picked { filter: drop-shadow(0 0 8px rgba(240, 178, 50, 0.7)); }
.meeple.pickable { cursor: grab; }
.drag-ghost {
  position: fixed;
  z-index: 1000;
  pointer-events: none;
  transform: translate(-50%, -50%);
  opacity: 0.85;
}
.meeple:focus-visible { outline: 2px solid var(--link); outline-offset: 2px; }
.meeple svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.meeple-role, .species-icon {
  position: absolute;
  left: 50%;
  transform: translate(-50%, -50%);
}
.meeple-role { font-family: "Board", sans-serif; font-weight: 700; line-height: 1; }
.species-icon {
  background: currentColor;
  -webkit-mask: var(--icon) center / contain no-repeat;
  mask: var(--icon) center / contain no-repeat;
}

/* The ranges: where each side may shoot from, in its colour, and the
   kickoff space between them. The side on the ball's is lit gold
   while it stands in range. */
.band {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 22px;
  border-radius: 6px;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 1px;
  white-space: nowrap;
  overflow: hidden;
  color: var(--team, var(--muted));
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.08);
}
.band.lit { color: var(--gold); background: rgba(240, 178, 50, 0.18); border-color: var(--gold); }

/* -- The card and board viewer ------------------------------------------------ */

.viewer {
  border: 0;
  padding: 0;
  background: transparent;
  max-width: 96vw;
  max-height: 94vh;
  overflow: visible;
}
.viewer::backdrop { background: rgba(0, 0, 0, 0.85); }
.viewer-body {
  display: flex;
  justify-content: center;
  align-items: flex-start;
  max-height: 90vh;
  overflow: auto;
}
.viewer-body > img {
  max-height: 86vh;
  max-width: min(460px, 90vw);
  width: auto;
  height: auto;
  border-radius: 14px;
}
.viewer-body.board { width: 94vw; }
.viewer-body.board > div { width: 100%; }
.viewer-close {
  position: fixed;
  top: 12px;
  right: 16px;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 0;
  font-size: 24px;
  line-height: 1;
  color: #fff;
  background: rgba(255, 255, 255, 0.12);
  cursor: pointer;
}
.viewer-caption { color: var(--muted); font-size: 14px; text-align: center; margin-top: 8px; }
.viewer-caption a { color: var(--link); }

.peek {
  position: fixed;
  z-index: 20;
  cursor: pointer;
  filter: drop-shadow(0 8px 24px rgba(0, 0, 0, 0.6));
}
.peek img { width: min(260px, calc(100vw - 16px)); height: auto; border-radius: 12px; }
.peek.pinned img { box-shadow: 0 0 0 2px var(--gold); cursor: zoom-in; }

/* A phone's own tabs and its strip are not drawn on a wider screen,
   and the Move tab's pane is only a grouping there. */
.strip, .lit-repeat { display: none; }
.move-pane { display: contents; }

/* -- A phone: one screen ------------------------------------------------------
   (step 11 of docs/web-app-redesign.md). The score and the field stay on
   screen; tabs -- Move, Log, Chat, Teams, Rules -- switch what fills the
   rest, and only the tab showing scrolls. Held upright, the field is the
   narrow one and the move a bottom sheet with the tabs along its foot;
   on its side, the desktop field whole with the score and the clock in
   the top bar and the move one slim strip under the field. */

@media (max-width: 960px) {
  .app {
    display: flex;
    flex-direction: column;
    height: calc(100vh - var(--topbar));
    height: calc(100dvh - var(--topbar));
    padding: 8px 12px 0;
    gap: 8px;
    overflow: hidden;
  }
  .main, .sidebar { display: contents; }
  /* A phone's own tabs switch the screen; the sidebar's are not drawn. */
  .side-tabs { display: none; }
  .topbar-divider { display: none; }
  /* The topic stays, cut short, because before kickoff it is where
     the game is renamed (the author, 2026-09-27). */
  .topbar-title, .room-title, .topic { min-width: 0; overflow: hidden; }
  .topic .topic-field { width: 150px; }
  .you-pill { padding: 4px 10px; font-size: 12px; gap: 6px; }
  .you-pill .pill-lead, .you-pill .pill-team { display: none; }

  .board-panel { order: 2; flex: none; padding: 0; background: none; border: 0; }
  .benches { margin-top: 6px; gap: 6px; padding: 6px; flex-direction: column; }
  .sideline-team.visiting { justify-content: flex-start; }

  /* What a tab holds: the one that is showing fills the rest and
     scrolls; the others are not drawn. */
  .move-pane, .pane {
    order: 4;
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 10px;
  }
  .pane { background: var(--panel); border: 1px solid var(--deep); border-radius: 8px; }
  body:not([data-show="move"]) .move-pane,
  body:not([data-show="log"]) [data-tab="log"],
  body:not([data-show="chat"]) [data-tab="chat"],
  body:not([data-show="teams"]) [data-tab="teams"],
  body:not([data-show="rules"]) [data-tab="rules"] { display: none !important; }

  .strip { display: flex; order: 5; flex: none; }
  .tabs { display: flex; }
  .tab {
    position: relative;
    font: inherit;
    font-weight: 700;
    color: var(--muted);
    background: transparent;
    border: 0;
    cursor: pointer;
  }
  body[data-show="move"] .tab[data-show="move"],
  body[data-show="log"] .tab[data-show="log"],
  body[data-show="chat"] .tab[data-show="chat"],
  body[data-show="teams"] .tab[data-show="teams"],
  body[data-show="rules"] .tab[data-show="rules"] { color: var(--strong); }
  /* A dot on a tab that is not showing: red for news, gold on Move
     where the question is this coach's. */
  .tab.news::after {
    content: "";
    position: absolute;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--red);
  }
  .tab.yours::after { background: var(--gold); }
  .strip[data-state="yours"] { --tag: var(--gold); --tag-ink: var(--deep); }
  .strip[data-state="waiting"] { --tag: var(--grey); --tag-ink: #fff; }
  .strip[data-state="now"] { --tag: var(--blurple); --tag-ink: #fff; }
  .strip[data-state="full_time"] { --tag: var(--green); --tag-ink: #fff; }

  .qbox { flex-direction: column; min-height: 0; gap: 10px; }
  .qbox-aside { max-width: 100%; padding-left: 0; border-left: 0; }
  .outcome { flex-wrap: wrap; gap: 14px; }
  .outcome-headline { font-size: 34px; }
  .hand { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* Held upright: the compact jumbotron, the narrow field, and the sheet. */
@media (max-width: 960px) and (orientation: portrait) {
  :root { --topbar: 44px; }
  .topbar { padding: 0 12px; background: var(--deep); border-bottom-color: var(--line); }

  /* One line: the teams and the score, the minute and the half, and
     the ball's d12 beside the side that has it. The coaches, the track
     and the tiles are the wide screen's; a time out that is lit is on
     the sheet with everything else lit. */
  .jumbotron { order: 1; gap: 8px; padding: 6px 10px; border-radius: 12px; }
  .jumbo-teams { display: flex; align-items: center; gap: 6px; flex: 1 1 auto; min-width: 0; }
  .jumbo-side { flex: 0 1 auto; flex-direction: row; align-items: center; gap: 3px; }
  .jumbo-side.visiting { order: 3; flex-direction: row-reverse; }
  .jumbo-score { order: 2; min-width: 0; }
  .jumbo-team { font-size: 13px; letter-spacing: 0.3px; }
  .jumbo-arrow { font-size: inherit; color: inherit; }
  .jumbo-goals { font-size: 24px; }
  .jumbo-coach, .jumbo-brand, .jumbo-rule, .jumbo-track, .jumbo-marks, .jumbo-tiles { display: none; }
  .jumbo-ball { font-size: 0; gap: 0; }
  .jumbo-clock { flex: none; min-width: 0; gap: 0; align-items: flex-end; }
  /* The minute over the half, so the teams keep the width. */
  .jumbo-time { flex-direction: column; align-items: flex-end; gap: 1px; flex-wrap: nowrap; white-space: nowrap; }
  .jumbo-minute { font-size: 20px; }
  .jumbo-half { font-size: 10px; color: var(--muted); }
  .jumbo-last { font-size: 7px; letter-spacing: 0; padding: 1px 3px; }
  .jumbo-note { font-size: 9px; text-align: right; }

  .board-panel > .benches { display: none; }

  /* The sheet: the Move tab's pane over the page's foot, edged in the
     tag's colour, and the tabs along its foot. */
  .move-pane {
    --edge: var(--line);
    margin: 0 -12px;
    padding: 10px 12px 12px;
    background: var(--panel);
    border-radius: 14px 14px 0 0;
    border-top: 4px solid var(--edge);
  }
  .move-pane[data-state="yours"] { --edge: var(--gold); }
  .move-pane[data-state="now"] { --edge: var(--blurple); }
  .move-pane[data-state="full_time"] { --edge: var(--green); }
  .move-pane > .panel, .move-pane > .qbox { background: none; border: 0; padding: 0; border-radius: 0; }
  .move-pane .qbox .ask { font-size: 14px; }
  .pane { margin: 0 -12px; border-radius: 14px 14px 0 0; border-width: 4px 0 0; border-color: var(--line); }
  .strip { margin: 0 -12px; background: var(--panel); border-top: 1px solid var(--line); }
  .strip-ask, #strip-state { display: none !important; }
  .tabs { flex: 1; }
  .tab { flex: 1; padding: 10px 4px; font-size: 12px; border-top: 2px solid transparent; }
  body[data-show="move"] .tab[data-show="move"],
  body[data-show="log"] .tab[data-show="log"],
  body[data-show="chat"] .tab[data-show="chat"],
  body[data-show="teams"] .tab[data-show="teams"],
  body[data-show="rules"] .tab[data-show="rules"] { border-top-color: var(--blurple); }
  .tab.news::after { top: 8px; right: 14%; }

  /* What is lit on the field, again, large enough to tap. */
  .lit-repeat {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 8px 6px;
    padding: 8px 10px;
    border-radius: 10px;
    background: var(--deep);
  }
  .lit-repeat[hidden] { display: none; }
  .repeat-label { flex-basis: 100%; font-size: 10px; font-weight: 800; letter-spacing: 1px; color: var(--muted); }
  .repeat-item { display: flex; flex-direction: column; align-items: center; gap: 4px; min-width: 78px; max-width: 132px; text-align: center; }
  .repeat-name { font-size: 12px; font-weight: 700; color: var(--gold); max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .repeat-item.held .repeat-name { color: var(--muted); font-weight: 600; white-space: normal; }
  .repeat-chips { display: flex; flex-wrap: wrap; justify-content: center; gap: 3px; }
  .repeat-chips .chip { white-space: normal; line-height: 1.15; }
  .repeat-thing {
    min-width: 50px;
    min-height: 50px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 4px;
    border-radius: 10px;
    border: 2px dashed var(--gold);
    background: rgba(240, 178, 50, 0.1);
    color: var(--gold);
    font: inherit;
    font-weight: 800;
    cursor: pointer;
  }
  .repeat-thing.ball { border-style: solid; border-radius: 50%; }
  .repeat-thing.out { font-size: 26px; }
  .repeat-code { font-size: 20px; }
  .repeat-goal, .repeat-tile { font-family: "Goal", "Board", sans-serif; color: var(--team); font-size: 14px; letter-spacing: 1px; }
  .repeat-thing.goal, .repeat-thing.tile { border-style: solid; background: var(--b-goal); }

  /* The narrow field, laid out at the screen's width, unscaled: the
     seven spaces between narrow goals, 30px meeples with their role
     and species and no names, badges scaled with them. */
  .stage.narrow { position: relative; width: 100%; padding: 6px; border-radius: 10px; }
  .stage.narrow .pitch { gap: 4px; }
  .stage.narrow .field-row { gap: 2px; padding: 0 20px; }
  .stage.narrow .zone-name { font-size: 9px; letter-spacing: 1.5px; }
  .stage.narrow .field-spaces { gap: 2px; }
  .stage.narrow .goal { flex: 0 0 18px; border-width: 1.5px; border-radius: 6px; }
  .stage.narrow .goal-word { font-size: 15px; gap: 7px; }
  .stage.narrow .goal-chips, .stage.narrow .out-chip,
  .stage.narrow .space-chips, .stage.narrow .ball-chips { display: none; }
  .stage.narrow .out-mark { font-size: 16px; }
  .stage.narrow .out-mark::before { width: 24px; height: 24px; top: -4px; }
  .stage.narrow .space {
    min-height: 0;
    height: 180px;
    padding: 12px 1px 2px;
    border-width: 1.5px;
    border-radius: 6px;
  }
  .stage.narrow .space.lit { padding-bottom: 2px; border-width: 1.5px; }
  .stage.narrow .space-code { top: 2px; left: 4px; font-size: 9px; }
  .stage.narrow .kickoff-ring { width: 26px; height: 26px; border-width: 1.5px; }
  .stage.narrow .lane { min-height: 0; flex: 1 1 0; }
  .stage.narrow .lane.visiting { padding-top: 0; }
  .stage.narrow .badge img { width: 9px; height: 9px; }
  .stage.narrow .badge.tokens { font-size: 8px; padding: 0 3px 0 1px; border-radius: 6px; }
  .stage.narrow .badge.condition { padding: 1px; }
  .stage.narrow .band { height: 12px; font-size: 7px; letter-spacing: 0.5px; border-radius: 3px; }
  .stage.narrow .ball-button.lit { box-shadow: 0 0 0 2px var(--gold), 0 0 8px rgba(240, 178, 50, 0.55); }
  .stage.narrow .die.ringed { padding: 1px; }
}

/* The phone's sheet held upright, and a tablet's column on its side:
   the box opens on the question -- its tag, the ask and what is lit,
   then the box's own controls; the outcome and the reveal of what just
   happened follow them, so answering never needs a scroll. */
@media (max-width: 960px) and (orientation: portrait),
  (min-width: 961px) and (max-width: 1400px) and (orientation: landscape) and (any-pointer: coarse) {
  .qbox-main > * { order: 5; }
  .qbox-main > :first-child { order: 0; }
  .qbox-main > #refusal { order: 1; }
  .qbox-main > #ask { order: 2; }
  .qbox-main > #lit { order: 3; }
  .qbox-main > #lit-repeat { order: 4; }
  .qbox-main > .outcome-row { order: 8; }
  .qbox-main > #reveal { order: 9; }
  .qbox-main > #rematch-note { order: 10; }
  .outcome { padding: 10px 12px; }
  .outcome-dice { height: 110px; }
  .outcome-headline { font-size: 26px; }
  .outcome-detail { font-size: 14px; }
  .outcome-working { font-size: 13px; }
  .reveal-card { width: 96px; }
  .reveal-between { font-size: 22px; }
}

/* On its side: the desktop field whole, the score and the clock in the
   top bar, and the move one slim strip under the field with the tabs as
   pills in it. The page scrolls under the top bar, the strip kept at
   the foot of the screen while there is more under it. */
@media (max-width: 960px) and (orientation: landscape) {
  :root { --topbar: 38px; }
  .app { overflow-y: auto; padding-bottom: 0; }
  .move-pane { flex: none; overflow: visible; min-height: 50vh; }
  /* A sidebar pane is a screen high under the top bar, less the strip,
     and scrolls in itself: the log opens on its latest lines. */
  .pane { flex: none; height: calc(100dvh - var(--topbar) - 56px); overflow-y: auto; }
  .topbar-title .back { font-size: 13px; }

  /* The jumbotron, laid over the middle of the top bar as one line. */
  .jumbotron {
    position: fixed;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    z-index: 6;
    height: var(--topbar);
    max-width: calc(100vw - 280px);
    padding: 0 6px;
    gap: 10px;
    background: none;
    border: 0;
    border-radius: 0;
  }
  .jumbo-teams { display: flex; align-items: center; gap: 8px; flex: none; }
  .jumbo-side { flex-direction: row; align-items: center; gap: 4px; }
  .jumbo-side.visiting { order: 3; flex-direction: row-reverse; }
  .jumbo-score { order: 2; min-width: 0; }
  .jumbo-team { font-size: 15px; }
  .jumbo-arrow { font-size: inherit; color: inherit; }
  .jumbo-goals { font-size: 22px; }
  .jumbo-coach, .jumbo-brand, .jumbo-track, .jumbo-marks, .jumbo-note { display: none; }
  .jumbo-rule { align-self: center; height: 18px; }
  .jumbo-ball { font-size: 0; gap: 0; }
  .jumbo-clock { flex: none; min-width: 0; flex-direction: row; align-items: center; gap: 8px; }
  .jumbo-time { flex-wrap: nowrap; white-space: nowrap; gap: 6px; }
  .jumbo-minute { font-size: 18px; }
  .jumbo-half { font-size: 10px; color: var(--muted); }
  .jumbo-last { font-size: 8px; padding: 1px 4px; }
  /* Only a time out that may be called is drawn up here. */
  .jumbo-tiles > :not(.lit) { display: none; }
  .timeout-tile.lit { padding: 2px 8px; }
  .timeout-tile.lit .tile-title { font-size: 11px; }
  .timeout-tile.lit small { display: none; }

  .board-panel { order: 1; }
  /* Last in the column, so it stays at the foot of the screen however
     far down the page is read. */
  .strip {
    order: 5;
    position: sticky;
    bottom: 0;
    z-index: 4;
    align-items: center;
    gap: 12px;
    margin: 0 -2px;
    padding: 6px 12px;
    background: var(--panel);
    border-radius: 10px 10px 0 0;
    border-left: 4px solid var(--tag, var(--line));
    box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.35);
  }
  .strip-ask {
    flex: 1;
    min-width: 0;
    font-size: 13px;
    color: var(--strong);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .strip-ask br { display: none; }
  .strip-ask:not(:empty) { cursor: pointer; }
  .tabs { flex: none; gap: 2px; }
  .tab { padding: 4px 10px; border-radius: 12px; font-size: 11px; }
  body[data-show="move"] .tab[data-show="move"],
  body[data-show="log"] .tab[data-show="log"],
  body[data-show="chat"] .tab[data-show="chat"],
  body[data-show="teams"] .tab[data-show="teams"],
  body[data-show="rules"] .tab[data-show="rules"] { background: var(--field); }
  .tab.news::after { top: 2px; right: 2px; width: 6px; height: 6px; }
  .move-pane, .pane { order: 4; scroll-margin-top: 8px; }
}

/* -- A tablet on its side: two columns ------------------------------------
   A touch screen held on its side and wider than a phone -- an iPad, a
   Surface, 961px to 1400px across -- has the room for the field and the
   move side by side, and not for the desktop's field, question box and
   sidebar at once, which put the question under the fold. The jumbotron
   runs whole across the top; the desktop field and its sideline fill
   the left column; the phone's tabs head the right one, Move first, and
   only the tab showing scrolls. Before kickoff it is the desktop's
   table, which fits as it is. `TABLET` in app.js is the same query. */
@media (min-width: 961px) and (max-width: 1400px) and (orientation: landscape) and (any-pointer: coarse) {
  :root { --side: clamp(320px, 32vw, 400px); }
  body:not(.at-table) .app {
    grid-template-rows: auto auto minmax(0, 1fr);
    grid-template-areas: "jumbo jumbo" "field tabs" "field pane";
    gap: 10px 12px;
    padding: 12px;
  }
  body:not(.at-table) .main, body:not(.at-table) .sidebar { display: contents; }
  body:not(.at-table) .side-tabs { display: none; }
  body:not(.at-table) .jumbotron { grid-area: jumbo; }
  body:not(.at-table) .board-panel {
    grid-area: field;
    align-self: start;
    max-height: 100%;
    min-height: 0;
    overflow-y: auto;
  }

  /* The tabs, as the sidebar's own head. */
  body:not(.at-table) .strip {
    grid-area: tabs;
    display: flex;
    background: var(--panel);
    border: 1px solid var(--deep);
    border-radius: 12px;
    overflow: hidden;
  }
  .strip-ask, #strip-state { display: none !important; }
  .tabs { display: flex; flex: 1; }
  .tab {
    flex: 1;
    position: relative;
    padding: 11px 6px;
    border: 0;
    border-bottom: 2px solid transparent;
    background: transparent;
    color: var(--muted);
    font: inherit;
    font-weight: 700;
    font-size: 14px;
    cursor: pointer;
  }
  body[data-show="move"] .tab[data-show="move"],
  body[data-show="log"] .tab[data-show="log"],
  body[data-show="chat"] .tab[data-show="chat"],
  body[data-show="teams"] .tab[data-show="teams"],
  body[data-show="rules"] .tab[data-show="rules"] {
    color: var(--strong);
    border-bottom-color: var(--blurple);
  }
  .tab.news::after {
    content: "";
    position: absolute;
    top: 9px;
    right: 12%;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--red);
  }
  .tab.yours::after { background: var(--gold); }

  /* What a tab holds: the one showing fills the column and scrolls. */
  body:not(.at-table) .move-pane, body:not(.at-table) .pane {
    grid-area: pane;
    min-height: 0;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 10px;
  }
  body:not(.at-table) .pane {
    background: var(--panel);
    border: 1px solid var(--deep);
    border-radius: 12px;
  }
  body:not(.at-table):not([data-show="move"]) .move-pane,
  body:not(.at-table)[data-show="move"] .pane { display: none; }

  /* The question box, a column wide. */
  body:not(.at-table) .qbox { flex-direction: column; gap: 10px; flex-shrink: 0; }
  .qbox-aside { max-width: 100%; padding-left: 0; border-left: 0; }
  .outcome { flex-wrap: wrap; gap: 14px; }
  .hand { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* -- The room: two seats, and who is watching --------------------------- */

.seats { display: flex; flex-direction: column; gap: 6px; }
.seat {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  border-radius: 4px;
  background: var(--deep);
}
.seat.yours { box-shadow: inset 3px 0 0 var(--yours-edge); background: var(--yours); }
.seat-label { color: var(--muted); font-size: 12px; font-weight: 700; min-width: 9.5em; }
.seat-name { color: var(--strong); flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; }
.seat-name.empty { color: var(--faint); font-style: italic; }
.seat .btn { padding: 2px 10px; min-height: 26px; font-size: 13px; }
.room-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin-top: 8px; }

/* -- The table, before kickoff ------------------------------------------ */

/* Row 1 of the canvas: two seat cards, the settings as pills, the
   question box and the sideline. Nothing here says which control is
   live -- that is `state.table`, drawn by app.js's drawTable. */

body.at-table .jumbotron, body.at-table .board-panel { display: none; }
.table-area { display: flex; flex-direction: column; gap: 12px; flex-shrink: 0; }
.seat-cards { display: flex; gap: 14px; }
.seat-card {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 16px 18px;
  border-radius: 14px;
  background: var(--panel);
  border: 1px solid var(--line);
}
.seat-card.yours { border-color: var(--gold); }
.seat-card.open { border-style: dashed; }
.seat-card.drop-over, .sideline-strip.drop-over { box-shadow: 0 0 0 2px var(--gold); }
.seat-card-head { display: flex; align-items: center; gap: 8px; }
.tag-chip {
  display: inline-flex;
  align-items: center;
  border-radius: 5px;
  padding: 2px 6px;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.2px;
  line-height: 1;
  white-space: nowrap;
  background: var(--grey);
  color: #fff;
}
.tag-chip.you { background: var(--gold); color: var(--deep); }
.seat-out {
  background: none;
  border: 1px solid var(--line);
  border-radius: 6px;
  color: var(--muted);
  font: inherit;
  font-size: 12px;
  line-height: 1;
  padding: 4px 7px;
  cursor: pointer;
}
.seat-out:hover, .seat-out:focus-visible { color: var(--strong); border-color: var(--muted); }
.seat-holder {
  font-family: "Goal", sans-serif;
  font-size: 26px;
  line-height: 1;
  color: var(--strong);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.seat-holder.draggable { cursor: grab; }
.seat-holder.empty { font-family: inherit; font-size: 15px; font-weight: 700; color: var(--faint); }
button.seat-holder.empty {
  background: none;
  border: 1px dashed var(--line);
  border-radius: 8px;
  padding: 10px 12px;
  text-align: left;
  color: var(--gold);
  cursor: pointer;
}
button.seat-holder.empty:hover, button.seat-holder.empty:focus-visible { border-color: var(--gold); }
.seat-team { display: flex; align-items: center; gap: 8px; font-size: 14px; }
.seat-team b { color: var(--strong); }
.seat-team.owed { color: var(--gold); }
.team-dot.big { width: 16px; height: 16px; }
.seat-hint { margin-top: auto; font-size: 12px; color: var(--muted); }
.seat-hint .linkish { font-size: 12px; }
.table-teams { display: flex; flex-direction: column; gap: 6px; }
.swatch-label { font-size: 11px; color: var(--muted); }
.swatches { display: flex; flex-wrap: wrap; gap: 6px; }
.swatch {
  width: 44px;
  height: 44px;
  border-radius: 10px;
  border: 3px solid transparent;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  cursor: pointer;
}
.swatch .emoji { width: 26px; height: 26px; }
.swatch.picked { border-color: var(--gold); }
.swatch.greyed { opacity: 0.3; }
.swatch:disabled { cursor: default; }
.swatch:not(:disabled):hover, .swatch:focus-visible { border-color: var(--strong); }

.settings-panel { border-radius: 14px; padding: 16px 18px; display: flex; flex-direction: column; gap: 10px; }
.settings-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.settings-head .quiet { font-size: 11px; }
.table-setting { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.setting-label { width: 90px; font-size: 12px; font-weight: 800; color: var(--muted); }
.setting-note { font-size: 11px; color: var(--muted); }
.setting-definition { color: var(--text); }
.pills { display: inline-flex; flex-wrap: wrap; gap: 4px; }
.pill {
  padding: 5px 12px;
  border-radius: 14px;
  border: 1px solid var(--line);
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
}
.pill:not(:disabled):hover, .pill:focus-visible { color: var(--strong); border-color: var(--muted); }
.pill.current { border-color: var(--gold); background: rgba(240, 178, 50, 0.14); color: var(--strong); cursor: default; }
.pill:disabled:not(.current) { opacity: 0.45; cursor: not-allowed; }
.name-field.small { padding: 6px 10px; font-size: 13px; font-weight: 400; width: 220px; }

.table-box { border-radius: 14px; }
.table-controls { display: flex; flex-direction: column; gap: 8px; margin-top: 4px; }
.table-row { align-items: flex-start; gap: 18px; }
.table-row .coin-later { margin-top: 5px; }
.gold { color: var(--gold); }
.coin-later { display: inline-flex; align-items: center; gap: 8px; font-size: 12px; color: var(--muted); opacity: 0.5; }
.coin.small { width: 44px; height: 44px; }
.coin.big { width: 120px; height: 120px; filter: drop-shadow(0 6px 12px rgba(0, 0, 0, 0.6)); }
.coin-button {
  align-self: flex-start;
  background: none;
  border: 0;
  padding: 0;
  border-radius: 50%;
  cursor: pointer;
}
.coin.mid { width: 88px; height: 88px; filter: drop-shadow(0 4px 10px rgba(0, 0, 0, 0.55)); }
.coin-button.coin-pair { border-radius: 16px; padding: 8px 14px 6px; }
.coin-pair .coin-faces { gap: 18px; }
.coin-pair .coin-face figcaption { color: var(--muted); }
.coin-pair.lit .coin-face figcaption { color: var(--gold); }
.coin-button.lit { box-shadow: 0 0 0 3px var(--gold), 0 0 22px rgba(240, 178, 50, 0.45); }
.coin-button:disabled { cursor: default; opacity: 0.6; }
.toss { display: flex; flex-wrap: wrap; align-items: center; gap: 26px; }
.coin-faces { display: flex; align-items: flex-end; gap: 10px; }
.coin-face { margin: 0; display: flex; flex-direction: column; align-items: center; gap: 4px; }
.coin-face figcaption { font-family: "Goal", sans-serif; font-size: 14px; letter-spacing: 1px; }
.coin-face.dim { opacity: 0.45; }
.coin-face.dim figcaption { font-family: inherit; font-size: 10px; color: var(--muted); }
.mini-field { flex: 1 1 360px; display: flex; gap: 6px; align-items: stretch; height: 70px; min-width: 0; }
.mini-goal {
  width: 110px;
  flex: 0 0 110px;
  border-radius: 8px;
  background: var(--b-goal);
  border: 2px solid var(--faint);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  color: var(--faint);
  font: inherit;
  padding: 0;
}
.mini-goal.lit { border-color: var(--gold); color: var(--gold); cursor: pointer; box-shadow: 0 0 14px rgba(240, 178, 50, 0.3); }
.mini-goal.lit:hover, .mini-goal.lit:focus-visible { box-shadow: 0 0 0 2px var(--gold), 0 0 18px rgba(240, 178, 50, 0.45); }
.mini-goal-word { display: inline-flex; align-items: center; gap: 5px; font-family: "Goal", sans-serif; font-size: 16px; line-height: 1; }
.mini-goal-side { font-size: 11px; font-weight: 700; color: var(--muted); }
.mini-space {
  flex: 1;
  border-radius: 6px;
  background: var(--panel);
  border: 1px solid var(--line);
  padding: 4px;
  font-size: 10px;
  color: var(--muted);
}

.sideline-strip { border-radius: 14px; padding: 12px 18px; display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }
.sideline-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  background: var(--deep);
  border-radius: 14px;
  padding: 3px 10px 3px 6px;
}
.sideline-chip.draggable { cursor: grab; }
.sideline-chip.dinky { border: 1px dashed var(--line); }
.sideline-chip.dinky:hover, .sideline-chip.dinky:focus-visible { border-color: var(--gold); }
.presence { width: 8px; height: 8px; border-radius: 50%; background: var(--green); }
.sideline-strip .btn { border-color: transparent; color: var(--muted); min-height: 30px; padding: 5px 12px; font-size: 13px; }
.sideline-strip .btn:hover { color: var(--strong); }

/* The top bar's identity: one pill, its edge the seat's gold before
   the toss and the team's colour after. */
.room-title { display: inline-flex; align-items: baseline; gap: 8px; min-width: 0; }
.room-title .channel-name { font-family: "Goal", sans-serif; font-size: 18px; letter-spacing: 1px; font-weight: 400; }
.room-title .hash { font-size: inherit; color: var(--muted); }
.you-pill {
  --pill-edge: var(--line);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 30px;
  padding: 0 12px;
  border-radius: 15px;
  border: 1px solid var(--pill-edge);
  background: var(--panel);
  font-size: 13px;
  line-height: 1;
  color: var(--text);
  white-space: nowrap;
}
.you-pill strong { color: var(--strong); font-weight: 700; }

@media (max-width: 960px) {
  .seat-cards { flex-direction: column; }
  .mini-goal { width: 70px; flex-basis: 70px; }
}

/* -- The front door ----------------------------------------------------- */

/* Row 1 of the canvas: who you are and a new room on the left, your
   rooms and the rooms with a seat free as cards on the right. A card
   with a gold edge is waiting on you (the server's `your_move`). */

.wordmark { font-family: "Goal", sans-serif; font-size: 18px; letter-spacing: 1px; color: var(--strong); }
.named-button {
  background: none;
  border: 0;
  padding: 4px 8px;
  border-radius: 6px;
  color: var(--strong);
  font: inherit;
  font-weight: 700;
  cursor: pointer;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.named-button:hover { background: var(--field); }
.named-button:focus-visible { outline: 2px solid var(--link); }
.me { position: relative; }
.me-menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 20;
  width: min(300px, calc(100vw - 32px));
  padding: 14px;
  border-radius: 10px;
  border: 1px solid var(--deep);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.me-menu[hidden] { display: none; }
.me-name { display: flex; flex-direction: column; gap: 8px; margin: 0; }
.me-row { display: flex; gap: 8px; }
.me-row .name-field { flex: 1; width: auto; min-width: 0; }
.me-divider { height: 1px; background: var(--deep); }
.btn.danger { color: var(--red); border-color: var(--red); }
.btn.danger:hover:not(:disabled) { background: var(--red); color: var(--strong); }
.field-label { font-size: 11px; font-weight: 800; letter-spacing: 1px; color: var(--muted); }
.faint { color: var(--faint); }
.grow { flex: 1; }

.front-door {
  display: flex;
  gap: 20px;
  width: min(1180px, 100%);
  margin: 0 auto;
  padding: 20px 24px;
}
.front-left { flex: 0 0 400px; display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.front-right { flex: 1; display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.front-right section { display: flex; flex-direction: column; gap: 14px; }
.front-card { border-radius: 14px; padding: 22px 22px 20px; display: flex; flex-direction: column; gap: 12px; }
.front-title { font-family: "Goal", sans-serif; font-size: 34px; letter-spacing: 1px; color: var(--strong); line-height: 1; }
.front-card .quiet { line-height: 1.45; }
.name-field {
  background: var(--field);
  border: 0;
  border-radius: 8px;
  padding: 10px 12px;
  color: var(--strong);
  font: inherit;
  font-size: 15px;
  font-weight: 700;
}
.name-field:focus { outline: 2px solid var(--link); }
.refusal-line { margin: 0; font-size: 13px; color: var(--gold); }
.new-room {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 18px 16px;
  border-radius: 12px;
  border: 2px dashed var(--gold);
  background: rgba(240, 178, 50, 0.05);
}
.new-room-button {
  display: flex;
  flex-direction: column;
  gap: 6px;
  align-items: flex-start;
  text-align: left;
  background: none;
  border: 0;
  padding: 0;
  color: var(--text);
  font: inherit;
  cursor: pointer;
}
.new-room-word { font-family: "Goal", sans-serif; font-size: 20px; color: var(--gold); }
.new-room-button:hover .new-room-word, .new-room-button:focus-visible .new-room-word { text-decoration: underline; }
.new-room-button:focus-visible { outline: 2px solid var(--link); outline-offset: 4px; }
.ticks { display: flex; flex-wrap: wrap; gap: 18px; font-size: 12px; color: var(--muted); }
.ticks label { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; }
.ticks input { accent-color: var(--gold); }
.reading-room { padding: 16px 22px; gap: 8px; }
.reading-room .linkish { color: var(--text); text-align: left; }
.linkish.faint { color: var(--faint); }

.list-head { display: flex; align-items: center; gap: 10px; }
.list-head .quiet { margin-left: auto; font-size: 12px; }
#open { margin-top: 8px; }
.room-list { display: flex; flex-direction: column; gap: 14px; }
.room-card {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 14px 16px;
  border-radius: 12px;
  background: var(--panel);
  border: 1px solid var(--line);
  color: var(--text);
  text-decoration: none;
}
.room-card:hover, .room-card:focus-visible { border-color: var(--muted); }
.room-card.your-move { border-color: var(--gold); }
.card-head { display: flex; align-items: center; gap: 10px; min-width: 0; }
.card-number { font-family: "Goal", sans-serif; font-size: 17px; color: var(--strong); white-space: nowrap; }
.card-number .hash { font-size: inherit; color: var(--muted); }
.card-topic { font-size: 14px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.status-chip {
  display: inline-flex;
  align-items: center;
  border-radius: 5px;
  padding: 2px 6px;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.2px;
  line-height: 1;
  text-transform: uppercase;
  white-space: nowrap;
  background: var(--grey);
  color: #fff;
}
.status-chip.lobby { background: var(--blurple); }
.status-chip.setup { background: var(--gold); color: var(--deep); }
.status-chip.in_progress { background: var(--green); }
.card-seats { display: flex; flex-wrap: wrap; align-items: center; gap: 16px; }
.card-seat { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; }
.card-seat b { color: var(--strong); }
.card-seat b.free { color: var(--gold); }
.card-facts { font-size: 11px; color: var(--muted); }
.team-dot { display: inline-block; width: 12px; height: 12px; border-radius: 50%; flex: 0 0 auto; }
.team-dot.none { border: 2px dashed var(--faint); }

@media (max-width: 860px) {
  .front-door { flex-direction: column; padding: 16px; }
  .front-left { flex: 0 0 auto; }
}

/* The statistics: `d12ball/stats.py`'s tables, 58 characters wide, as
   the bot posts them in a code block -- a finished game's under its
   prompt, every web game's on /stats. */
.stats-tables { display: flex; flex-direction: column; gap: 8px; margin: 8px 0; }
.stats-table {
  margin: 0;
  padding: 8px 10px;
  background: var(--deep);
  border-radius: 4px;
  font-family: "DejaVu Sans Mono", ui-monospace, monospace;
  font-size: 12px;
  line-height: 1.35;
  overflow-x: auto;
  color: var(--text);
}
.linkish.danger-link { color: var(--red); }
body.front .front-door.stats-door {
  width: min(640px, calc(100% - 32px));
  margin: 12vh auto 0;
  flex-direction: column;
  gap: 12px;
  padding: 12px 14px;
}
.stats-door select { font: inherit; background: var(--field); color: var(--text); border: 0; border-radius: 4px; padding: 6px; }

/* -- The rules (webapp/static/aids.js) -----------------------------------------
   The Rules tab in the sidebar and the Reading Room at /rules: the
   Charter by Law, the Learn to Play and the References, every picture
   the model's own drawing, and no PDF. */

.topbar-end { display: flex; align-items: center; gap: 12px; min-width: 0; }

.search-input {
  width: 100%;
  background: var(--field);
  border: 0;
  border-radius: 8px;
  padding: 8px 10px;
  color: var(--text);
  font: inherit;
  font-size: 13px;
}
.search-input:focus-visible { outline: 2px solid var(--blurple); }
.rules-search { position: relative; display: flex; flex-direction: column; gap: 6px; }
.rules-results {
  margin: 0;
  padding: 6px;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 2px;
  max-height: 40vh;
  overflow: auto;
  background: var(--deep);
  border-radius: 8px;
  font-size: 13px;
}
.rules-hit { display: flex; gap: 8px; padding: 4px 6px; border-radius: 6px; color: var(--text); text-decoration: none; }
.rules-hit:hover, .rules-hit:focus-visible { background: var(--field); color: var(--strong); }
.rules-number { color: var(--gold); font-variant-numeric: tabular-nums; margin-right: 6px; }

/* The chips that switch what is read: gold for the one showing. */
.chips { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.chip-tab {
  display: inline-flex;
  align-items: center;
  border: 1px solid transparent;
  border-radius: 5px;
  padding: 3px 7px;
  background: var(--grey);
  color: #fff;
  font: inherit;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  white-space: nowrap;
  cursor: pointer;
}
.chip-tab.small { text-transform: none; font-size: 12px; font-weight: 700; }
.chip-tab.current { background: var(--gold); color: #1e1f22; }
.chip-tab:focus-visible { outline: 2px solid #fff; outline-offset: 1px; }
.reading-link { margin-left: auto; font-size: 12px; color: var(--link); text-decoration: none; }
.reading-link:hover { text-decoration: underline; }

/* The Rules tab. */
.rules-panel { padding: 0; }
.rules-tab { display: flex; flex-direction: column; gap: 10px; min-height: 0; flex: 1; padding: 10px 12px; }
.rules-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding-right: 2px; }
.law-list { display: flex; flex-direction: column; gap: 1px; }
.law-row {
  display: flex;
  gap: 10px;
  align-items: baseline;
  width: 100%;
  padding: 5px 10px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--text);
  font: inherit;
  font-size: 13px;
  text-align: left;
  cursor: pointer;
}
.law-row:hover { background: var(--field); }
.law-row.open { background: var(--field); color: var(--strong); }
.law-row.open .toc-number { color: var(--gold); }
.toc-number { width: 22px; flex: none; font-family: "Goal", sans-serif; color: var(--muted); }
.law-text { padding: 4px 6px 12px 38px; font-size: 13px; line-height: 1.5; }
.law-text h4 { margin: 12px 0 4px; font-size: 14px; }
.law-sections { color: var(--muted); font-size: 12px; margin-bottom: 6px; }
.law-sections a { color: var(--text); }
.law-part { font-size: 11px; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); }
.panel-label.appendices { margin: 12px 0 4px 10px; }
.flash { animation: flash 1.6s ease-out 1; border-radius: 6px; }
@keyframes flash {
  0% { box-shadow: 0 0 0 2px var(--gold); background: rgba(240, 178, 50, 0.12); }
  100% { box-shadow: 0 0 0 2px transparent; background: transparent; }
}
.learn-title { color: var(--strong); font-family: "Goal", sans-serif; font-weight: 400; font-size: 22px; margin: 4px 0 8px; }
.learn-contents { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.learn { font-size: 14px; }

/* The References: the cards, the roles and the species. */
.references { display: flex; flex-direction: column; gap: 8px; }
.ref-cards { display: flex; flex-wrap: wrap; gap: 6px; }
.ref-card img { width: 74px; height: auto; border-radius: 8px; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.5); }
.ref-card:hover img, .ref-card:focus-visible img { outline: 2px solid var(--gold); }
.ref-table { border-collapse: collapse; font-size: 12px; width: 100%; }
.ref-table th { color: var(--muted); font-size: 10px; font-weight: 800; text-align: left; padding: 2px 4px; }
.ref-table td { padding: 3px 4px; vertical-align: middle; }
.ref-table .num { font-weight: 800; text-align: center; }
.ref-table tr td.num:nth-of-type(3) { color: #e24b4a; }
.ref-table tr td.num:nth-of-type(4) { color: #97c459; }
.ref-table .ability { color: var(--muted); font-size: 11px; }
.ref-table .ability-name { display: block; font-weight: 700; color: var(--strong); white-space: nowrap; }
.ref-table .species-team { display: block; font-weight: 700; white-space: nowrap; }
.ref-table td { vertical-align: top; }

/* The refusal's Law, under its sentence: the strip wraps so the
   citation takes a line of its own before Dismiss. */
.refusal { flex-wrap: wrap; }
.refusal #refusal-text { flex: 1 1 60%; }
.refusal-law { order: 3; flex: 1 1 100%; margin: 0; font-size: 13px; color: var(--muted); }

/* The Teams tab: both rosters as tables. */
.teams-panel { overflow-y: auto; }
.rosters { display: flex; flex-direction: column; gap: 14px; }
.roster-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin-bottom: 4px; }
.roster-team { font-family: "Goal", sans-serif; font-size: 16px; letter-spacing: 0.04em; text-transform: uppercase; }
.roster-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.roster-table th { color: var(--muted); font-size: 10px; font-weight: 800; text-align: left; padding: 2px 4px; border-bottom: 1px solid var(--line); }
.roster-table td { padding: 4px; border-bottom: 1px solid rgba(63, 65, 71, 0.5); vertical-align: middle; }
.roster-table tr[tabindex] { cursor: pointer; }
.roster-table tr[tabindex]:hover, .roster-table tr[tabindex]:focus-visible { background: var(--field); outline: none; }
.roster-table tr.benched { color: var(--muted); }
.roster-table .num { text-align: center; font-weight: 700; width: 28px; }
.roster-table .who { white-space: nowrap; font-weight: 600; }
.roster-table .tokens { white-space: nowrap; }
.roster-table .token { display: inline-block; width: 15px; height: 15px; margin-right: 1px; vertical-align: middle; }
.roster-table .where { color: var(--muted); white-space: nowrap; text-align: right; }
.role-dot {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  margin-right: 6px;
  border-radius: 50%;
  color: #fff;
  font-size: 10px;
  font-weight: 800;
  vertical-align: middle;
  text-shadow: 0 0 2px rgba(0, 0, 0, 0.8);
}
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* The Reading Room (/rules): the Laws on the left, the Law text in the
   middle, the References on the right. */
body.reading-room { height: 100vh; height: 100dvh; display: flex; flex-direction: column; overflow: hidden; }
.room-bar { background: var(--deep); border-bottom: 1px solid var(--line); height: 52px; flex: none; }
.reading-title { font-family: "Goal", sans-serif; font-size: 18px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--strong); white-space: nowrap; }
.room-bar .rules-search { width: min(320px, 36vw); }
.room-bar .rules-results { position: absolute; top: 38px; left: 0; right: 0; z-index: 10; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5); }
.reading { flex: 1; min-height: 0; display: flex; gap: 24px; padding: 22px 26px; }
.reading-contents { width: 260px; flex: 0 0 260px; overflow-y: auto; }
.reading-contents ol { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 1px; }
.reading-contents a { display: flex; gap: 10px; align-items: baseline; padding: 5px 10px; border-radius: 6px; color: var(--text); text-decoration: none; font-size: 13px; }
.reading-contents a:hover { background: var(--field); }
.reading-contents a.current { background: var(--field); color: var(--strong); }
.reading-contents a.current .toc-number { color: var(--gold); }
.reading-contents li.appendix { margin-top: 2px; }
.reading-text { flex: 1; min-width: 0; overflow-y: auto; padding: 0 30px; border-left: 1px solid var(--line); border-right: 1px solid var(--line); }
.reading-refs { width: 360px; flex: 0 0 360px; overflow-y: auto; display: flex; flex-direction: column; gap: 8px; }
.law { scroll-margin-top: 8px; padding-bottom: 12px; }
.law-eyebrow { font-size: 11px; font-weight: 800; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
.law-mark { color: var(--gold); font-family: "Board", sans-serif; font-size: 18px; font-weight: 700; margin-right: 10px; }
.rules-intro { color: var(--muted); }
.roster-cards { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 10px; }
.roster-cards img { width: 180px; height: auto; border-radius: 10px; }
.reading .chips + .chips { margin-top: 8px; }

/* The rules' own text, in the Rules tab, the Learn to Play and the
   Reading Room alike. */
.rules { line-height: 1.55; }
.rules h1 { color: var(--strong); font-size: 26px; margin: 8px 0; }
.rules h2 { color: var(--strong); font-family: "Goal", sans-serif; font-weight: 400; font-size: 30px; margin: 22px 0 8px; }
.rules h3 { color: var(--strong); font-family: "Goal", sans-serif; font-weight: 400; font-size: 20px; letter-spacing: 0.02em; margin: 16px 0 4px; }
.rules h4, .rules h5, .rules h6 { color: var(--strong); font-size: 15px; margin: 14px 0 4px; }
.rules a { color: var(--link); }
.rules p { margin: 0 0 8px; }
.rules p.note { color: var(--muted); font-size: 0.93em; margin-left: 16px; }
.rules code { background: var(--deep); border-radius: 3px; padding: 0 3px; }
.rules blockquote { margin: 8px 0; padding-left: 12px; border-left: 3px solid var(--line); color: var(--muted); }
.rules-table { overflow-x: auto; }
.rules table { border-collapse: collapse; margin: 8px 0; font-size: 0.93em; }
.rules th, .rules td { border: 1px solid var(--line); padding: 4px 8px; vertical-align: top; }
.rules th { background: var(--deep); color: var(--strong); }
.rules figure { margin: 12px 0; }
.rules figure img { max-width: 100%; height: auto; border-radius: 6px; }
.rules figcaption { color: var(--muted); font-size: 13px; }
.rules-section { scroll-margin-top: 8px; }
.law-text.rules h2, .learn.rules h2 { font-size: 20px; }
.law-text.rules h3, .learn.rules h3 { font-size: 16px; }

@media (max-width: 960px) {
  body.reading-room { height: auto; overflow: visible; }
  .room-bar { height: auto; flex-wrap: wrap; padding: 8px 16px; }
  .room-bar .topbar-end { flex-wrap: wrap; width: 100%; }
  .room-bar .rules-search { width: 100%; }
  .reading { flex-direction: column; padding: 12px 16px; gap: 16px; }
  .reading-contents, .reading-refs { width: auto; flex: none; }
  .reading-contents ol { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); }
  .reading-text { padding: 0; border: 0; overflow: visible; }
}

/* The Coaching Choice's box: a line for each move made on the board,
   then the formation tiles, above the whistle and set off from it by a
   rule (step 6; reordered by the author, 2026-09-26). */
.how {
  display: flex;
  flex-direction: column;
  gap: 8px;
  border-bottom: 1px solid var(--line);
  padding-bottom: 12px;
  margin-bottom: 6px;
}
/* The Spreadable reminder, under the whistle. */
.footnote { margin: 4px 0 0; font-size: 14px; color: var(--muted); }
.how-row { display: flex; gap: 16px; align-items: center; flex-wrap: wrap; }
.how-label { font-size: 11px; font-weight: 800; color: var(--muted); }
.how-line { margin: 0; font-size: 12px; color: var(--muted); }
.how-line b { color: var(--strong); }
.formations { display: flex; gap: 6px; flex-wrap: wrap; }
.formation {
  font: inherit;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 6px 8px;
  border-radius: 8px;
  border: 2px solid var(--line);
  background: var(--deep);
  color: var(--muted);
  cursor: pointer;
}
.formation:hover:not(:disabled) { border-color: var(--gold); color: var(--strong); }
.formation:focus-visible { outline: 2px solid var(--link); outline-offset: 2px; }
.formation.now { border-color: var(--gold); background: rgba(240, 178, 50, 0.1); color: var(--strong); cursor: default; }
.formation-dots { display: flex; width: 84px; height: 14px; align-items: center; }
.formation-zone {
  flex: 1;
  display: flex;
  justify-content: center;
  gap: 2px;
  border-right: 1px solid var(--line);
}
.formation-zone:last-child { border-right: 0; }
.formation-zone .dot { width: 6px; height: 6px; border-radius: 50%; }
.formation-name { font-size: 11px; font-weight: 800; }
.picked-line { align-items: center; gap: 12px; font-size: 13px; }
.picked-line b { color: var(--gold); }

/* The shootout's secret order (step 7 of docs/web-app-redesign.md): a
   slot per shooter in the question box, the ones already sent solid
   and the ones still to fill dashed gold, the players still to place
   beside them lit, and under them Start again and the whistle. */
.order-panel {
  display: flex;
  flex-direction: column;
  gap: 10px;
  border-top: 1px solid var(--line);
  padding-top: 10px;
}
.order-main { display: flex; gap: 18px; flex-wrap: wrap; align-items: flex-start; }
.order-column { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.order-column .group-label { margin: 0; }
.order-slots, .order-pool { display: flex; gap: 8px; flex-wrap: wrap; }
.order-pool { min-height: 104px; align-items: flex-start; }
.order-slot {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  width: 86px;
  height: 104px;
  box-sizing: border-box;
  padding-top: 4px;
  border: 2px solid var(--line);
  border-radius: 10px;
  background: var(--deep);
}
.order-slot.empty { border-style: dashed; border-color: var(--gold); }
.order-number { font-family: "Goal", sans-serif; font-size: 16px; line-height: 1; color: var(--gold); }
.order-slot.sent .order-number { color: var(--muted); }
.order-piece {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  width: 78px;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
}
button.order-piece { cursor: grab; }
button.order-piece:focus-visible { outline: 2px solid var(--link); outline-offset: 2px; border-radius: 6px; }
.order-meeple {
  position: relative;
  display: block;
  filter: drop-shadow(0 3px 3px rgba(0, 0, 0, 0.55));
}
.order-meeple svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.order-name {
  font-size: 12px;
  font-weight: 700;
  color: var(--strong);
  white-space: nowrap;
  max-width: 78px;
  overflow: hidden;
  text-overflow: ellipsis;
}
.order-piece.lit .order-name { color: var(--gold); }
.order-empty { font-size: 13px; color: var(--muted); align-self: center; }
.order-foot { display: flex; gap: 16px; align-items: center; flex-wrap: wrap; }

/* Whether each side has answered the shootout's secret question: a tag
   in the team's colour once it has, grey until then. */
.shootout-sides { display: flex; flex-direction: column; gap: 6px; }
.side-tag {
  display: inline-flex;
  align-items: center;
  padding: 3px 8px;
  border-radius: 5px;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.2px;
  line-height: 1.1;
  color: var(--muted);
  border: 1px solid var(--line);
}
.side-tag.done { color: var(--strong); background: var(--grey); border-color: var(--team); }
