/* ------------------------------------------------------------------------------------------------
   Finals broadcast: one head-to-head match, for a stream overlay.

   The same home as the qualifying broadcast (merged-queues/broadcast.css) — an OBS browser source a
   few hundred pixels tall, read off a viewer's screen — so the same two rules: nothing scrolls, and
   the type is sized to the window rather than to a phone. Same tokens too, restated rather than shared
   so the stylesheets stay independent; the two pages are different shapes, not themes of each other.
   ------------------------------------------------------------------------------------------------ */

:root {
  color-scheme: light dark;
  --bg: #ffffff;
  --text: #111827;
  --border: #d0d0d8;
  --muted: #6b7280;
  --warning: #b45309;
  --on-game: #059669;
  --panel-bg: rgba(127, 127, 127, 0.07);
  --win-bg: rgba(5, 150, 105, 0.12);
  /* The players' tints: blue, red, green, gold — the classic four, so a four-player group format
     has its colours waiting. Deliberately not the amber/violet/emerald/pink the queue board tints
     its tournaments with: on an event weekend those mean "which tournament", and two players in
     one match are in the same one. Only the first two are used today. */
  --player-0: rgba(59, 130, 246, 0.22);
  --player-1: rgba(239, 68, 68, 0.20);
  --player-2: rgba(34, 197, 94, 0.22);
  --player-3: rgba(234, 179, 8, 0.28);
}

/* Dark by default — broadcast.js stamps <html data-theme="dark"> unless the URL says ?theme=light —
   because the page's home is OBS's browser, which can't state a colour-scheme preference and would
   render light, on a stream layout that is dark. The preference block below is for a page opened in
   an ordinary browser with no data-theme at all. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #0f1117;
    --text: #f3f4f6;
    --border: #3f3f46;
    --muted: #9ca3af;
    --warning: #fbbf24;
    --on-game: #34d399;
    --panel-bg: rgba(255, 255, 255, 0.06);
    --win-bg: rgba(52, 211, 153, 0.18);
    --player-0: rgba(96, 165, 250, 0.36);
    --player-1: rgba(248, 113, 113, 0.34);
    --player-2: rgba(74, 222, 128, 0.32);
    --player-3: rgba(250, 204, 21, 0.34);
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #0f1117;
  --text: #f3f4f6;
  --border: #3f3f46;
  --muted: #9ca3af;
  --warning: #fbbf24;
  --on-game: #34d399;
  --panel-bg: rgba(255, 255, 255, 0.06);
  --win-bg: rgba(52, 211, 153, 0.18);
  --player-0: rgba(96, 165, 250, 0.36);
  --player-1: rgba(248, 113, 113, 0.34);
  --player-2: rgba(74, 222, 128, 0.32);
  --player-3: rgba(250, 204, 21, 0.34);
}

:root[data-theme="light"] {
  color-scheme: light;
}

/* One knob for every size on the page, from the smaller of width and height — see the qualifying
   broadcast for why. The height term is set by the whole stack now that it is one column: the header,
   the scoreboard's heading and two rows, the game in progress, and a best of 5's rows under their
   header — which a 270px window holds at 6vh, with a best of 7's extra rows scaled down by fitStage. */
html {
  font-size: clamp(13px, min(2.85vw, 6vh), 44px);
}

body {
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  margin: 0;
  /* A little more above than below: the top edge is the one the stream layout crops closest to. */
  padding: 0.6rem 0.6rem 0.35rem;
  background: var(--bg);
  color: var(--text);
  line-height: 1.25;
  /* Nothing scrolls, by design: the page fits itself to the window (see fitStage in broadcast.js). */
  overflow: hidden;
  height: 100vh;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
}

/* The stage and the controls set their own display, which would otherwise beat the hidden attribute's
   UA rule; broadcast.js toggles visibility through that attribute. */
[hidden] { display: none !important; }

/* ---- Header ------------------------------------------------------------------------------------ */

/* The round name, over the scoreboard's first three columns. */
h1.round {
  grid-column: 1 / 4;
  grid-row: 1;
}

/* The match's length, over the wins column — the number it explains. */
.best-of {
  grid-column: 4;
  grid-row: 1;
  align-self: baseline;
  text-align: right;
}

/* The top right: the result once there is one, and the status line after it. Stretched across its
   column so the result has the column's whole width while the status line is hidden — hidden, the
   status line is folded to no width (see the chrome rules below) rather than merely invisible. */
.aside {
  grid-column: 5;
  grid-row: 1;
  justify-self: stretch;
  align-self: baseline;
  display: flex;
  justify-content: flex-end;
  align-items: baseline;
  box-sizing: border-box;
  padding-left: 0.6rem;
  min-width: 0;
}

/* When the result's name would not fit (broadcast.js measures), "Best of N" goes and the aside takes
   the whole row, over the round name's columns, at the width broadcast.js gives it: what the round
   name's text leaves. Right-aligned, so the overlap is only ever the blank part of the name's box. */
.stage.result-wide .best-of { display: none; }
.stage.result-wide .aside { grid-column: 1 / -1; justify-self: end; }

/* Every one-line text on the page clips sideways only ("clip visible"), not "hidden": the line boxes
   are tight and Segoe UI's descenders reach below them, so a hidden overflow takes the bottom off
   every y and g. The ellipsis only needs the inline axis clipped. */
h1 {
  font-size: 1.15rem;
  font-weight: 700;
  line-height: 1.15;
  margin: 0;
  white-space: nowrap;
  overflow: clip visible;
  text-overflow: ellipsis;
  min-width: 0;
}

.best-of {
  color: var(--muted);
  font-size: 0.8rem;
  white-space: nowrap;
}

/* The result, once there is one, at the top right; the winner's name is already the green one on the
   scoreboard, so this is plain. It has the column while the status line is folded away, and gives
   the status line its width back — sliding left, the name shortening — while the chrome is showing
   (the pointer is moving, or ?chrome=1). When the two are too much for the line, the name goes first,
   to nothing, and only then the status line, from its left: the name's width is 0 in the sizing, so
   the result's own minimum — which it never shrinks below — is its lead and score, kept whole. */
.result {
  flex: 1 1 auto;
  display: flex;
  justify-content: flex-end;
  align-items: baseline;
  font-size: 0.95rem;
  font-weight: 600;
  white-space: pre;
}

/* Of the result's three pieces — "Final · ", the name, " wins 3–2" — only the name gives way when the
   line is too long: the lead and the score keep their size, and the name between them takes the
   ellipsis. */
.result > * { flex: none; }

.result-name {
  /* Grown from nothing to its text and no further, rather than sized to its text: see .result. The
     minimum keeps a few letters and the ellipsis — "Final ·  wins 3–2" with no name reads wrong. */
  width: 0;
  flex: 1 1 auto;
  max-width: max-content;
  min-width: 2.5rem;
  overflow: clip visible;
  text-overflow: ellipsis;
}

/* The "Updated …" clock and its controls, after the result. Short of room it is clipped from the
   left — its content is packed to the end — so the clock goes before the dot and the gear. */
.status {
  margin: 0 0 0 0.6rem;
  color: var(--muted);
  font-size: 0.8rem;
  white-space: nowrap;
  display: inline-flex;
  justify-content: flex-end;
  align-items: center;
  flex: 0 1 auto;
  min-width: 0;
  overflow: clip visible;
}

.snapshot-status {
  font: inherit;
  color: var(--muted);
  background: transparent;
  border: 0;
  padding: 0 0 0 0.45rem;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
}

.snapshot-dot {
  width: 0.55rem;
  height: 0.55rem;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.35;
}

.snapshot-status.pulse .snapshot-dot { animation: snapshot-pulse 0.9s ease-out; }

@keyframes snapshot-pulse {
  0% { opacity: 1; transform: scale(1.6); }
  100% { opacity: 0.35; transform: scale(1); }
}

.snapshot-status[aria-pressed="true"] .snapshot-dot { opacity: 1; }

/* The gear: the same size and colour as the dot, so it reads as part of the status line rather than
   as a control the stream's viewers are meant to notice. The padding is the target. */
.open-controls {
  font: inherit;
  color: var(--muted);
  background: transparent;
  border: 0;
  padding: 0.15rem 0 0.15rem 0.55rem;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
}

.open-controls svg {
  width: 0.85rem;
  height: 0.85rem;
  fill: currentColor;
  opacity: 0.55;
}

.open-controls:hover svg,
.open-controls:focus-visible svg { opacity: 1; }

/* The status line is chrome — hidden unless the page was asked for it (?chrome=1), and shown while
   the pointer is moving, which is the operator in OBS's interact window. broadcast.js sets both
   attributes. Hidden, it is folded to no width as well as faded, so the result beside it has the
   whole column; the fold is what the result is seen sliding along as the chrome comes and goes. The
   open max-width is only a ceiling above the line's own width, which is what it grows to. */
:root[data-chrome="0"] .status {
  opacity: 0;
  pointer-events: none;
  max-width: 0;
  margin-left: 0;
  transition: opacity 0.25s, max-width 0.25s, margin-left 0.25s;
}

:root[data-chrome="0"][data-pointer="active"] .status {
  opacity: 1;
  pointer-events: auto;
  max-width: 20rem;
  margin-left: 0.6rem;
}

@media (prefers-reduced-motion: reduce) {
  .snapshot-status.pulse .snapshot-dot { animation: none; }
  .status { transition: none; }
}

/* ---- The view ---------------------------------------------------------------------------------- */

/* One grid for the whole page. The scoreboard's four columns — position, seed, name, wins — size to
   their content, and a fifth takes what is left for the game in progress, beside the players rather
   than under them. Row 1 is the round name (over the first three columns), the match's length (over
   the wins) and the top-right aside; row 2 the scoreboard's headings; rows 3 and 4 the players; row 5
   the games, across everything, with the height that is left — fitStage scales their rows down when
   a long match has more of them than the window holds.

   The name column can shrink below its content (the fifth column can't go below its minimum), which
   is when fitTogether steps the two names down; the round name spanning it stretches it to fit itself
   when the title is the longer thing. */
.stage {
  display: grid;
  grid-template-columns: auto auto minmax(0, auto) auto minmax(9rem, 1fr);
  grid-template-rows: auto auto auto auto minmax(0, 1fr);
  align-items: baseline;
  gap: 0.2rem 0.35rem;
  flex: 1;
  min-height: 0;
}

/* The game in progress, beside the scoreboard's heading and two rows, on their vertical middle. */
.now {
  grid-column: 5;
  grid-row: 2 / 5;
  align-self: center;
  padding-left: 0.6rem;
}

.panel.games {
  grid-column: 1 / -1;
  grid-row: 5;
  align-self: stretch;
}

/* Each row's cells are laid out by the stage's grid, so the chip columns are shared: a player without
   a seed still has their name start where the other's does. Each cell names its column, so the rows
   hold their shape when the game line — which occupies the fifth column — is gone. */
.side,
.score-head { display: contents; }

.position { grid-column: 1; }
.seed, .score-head > :nth-child(2) { grid-column: 2; }
.player, .score-head > :nth-child(3) { grid-column: 3; }
.wins, .wins-head { grid-column: 4; }

/* The column names over the scoreboard, in the games list's header style. The first column (P1/P2)
   is left unnamed; its chips say what they are. */
.score-head > * {
  color: var(--muted);
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  line-height: 1.2;
}

.score-head .position {
  visibility: hidden;
  padding-top: 0;
  padding-bottom: 0;
}

.score-head .wins-head { text-align: right; justify-self: end; }

/* "P1" / "P2": who plays first in the game in progress, tinted like the player everywhere else. Bolder
   than the seed, since it is the one that changes game to game. */
.position,
.seed {
  font-size: 0.68rem;
  font-weight: 600;
  padding: 0.02rem 0.3rem;
  border-radius: 0.25rem;
  border: 1px solid var(--border);
  white-space: nowrap;
  min-width: 1.4rem;
  text-align: center;
  box-sizing: border-box;
}

.position { font-weight: 700; }

.seed { color: var(--muted); }

.position:empty,
.seed:empty { visibility: hidden; }

.side[data-side="0"] .position { background: var(--player-0); }
.side[data-side="1"] .position { background: var(--player-1); }
.side[data-side="2"] .position { background: var(--player-2); }
.side[data-side="3"] .position { background: var(--player-3); }

.player {
  font-size: 1.6rem;
  font-weight: 700;
  line-height: 1.15;
  white-space: nowrap;
  overflow: clip visible;
  text-overflow: ellipsis;
  min-width: 0;
}

/* A tight line box: the digit is the tallest thing on its row, and at a normal line height it was
   setting the rows' pitch well above the names' — which, shrunk to fit, sit in shorter boxes — so the
   players looked spaced apart and the game line crowded under them. */
.wins {
  font-size: 1.6rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  line-height: 0.85;
  min-width: 1.2em;
  text-align: right;
  padding-left: 0.4rem;
  justify-self: end;
}

/* The player who has won the match, once it is over. */
.side.won .player,
.side.won .wins { color: var(--on-game); }

/* The game in progress on one line: the marker, its number, and the machine — the machine the biggest
   type on the line and the part that gives way. */
.now { min-width: 0; }

.now-line {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  min-width: 0;
}

.now-marker {
  color: var(--on-game);
  font-size: 0.9rem;
  flex: none;
}

.now-title {
  color: var(--muted);
  font-size: 0.85rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  white-space: nowrap;
  flex: none;
}

.now-arena {
  font-size: 1.35rem;
  font-weight: 700;
  line-height: 1.15;
  white-space: nowrap;
  overflow: clip visible;
  text-overflow: ellipsis;
  min-width: 0;
}

/* No machine chosen yet, or the match is over: a quieter line in the machine's place. */
.now-arena.idle {
  font-weight: 500;
  color: var(--muted);
}

/* ---- The games ---------------------------------------------------------------------------------- */

.panel {
  background: var(--panel-bg);
  border-radius: 0.5rem;
  padding: 0.2rem 0.4rem 0.3rem;
  min-width: 0;
  min-height: 0;
  /* Clipped both ways, unlike the one-line texts: rows that run past the panel (a source shorter
     than the fitter was given, an OBS scale) must stop at its rounded bottom edge, not paint over it. */
  overflow: clip;
  display: flex;
  flex-direction: column;
}

h2 {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin: 0 0 0.1rem;
  white-space: nowrap;
  overflow: clip visible;
  text-overflow: ellipsis;
  min-width: 0;
}

.panel-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
  flex: none;
}

/* number | machine | picked by | winner, one grid for the header and every row (each row is
   display: contents), so a column is one width from top to bottom and its header sits over its
   values. The machine is the column that gives way. Sized in em off this container, which fitStage
   (broadcast.js) scales down to fit the window when a long match has more rows than it holds. */
.rows {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  align-items: baseline;
  gap: 0.12em 0.45em;
  align-content: start;
  min-height: 0;
  font-size: 1rem;
  line-height: 1.25;
}

.row { display: contents; }

/* A player's name as a chip tinted like their scoreboard row: a rectangle with the corners barely
   rounded, and no more padding than the name needs, since the column has none to spare. */
.row .chip {
  font-size: 0.85em;
  font-weight: 600;
  padding: 0.02em 0.3em;
  border-radius: 0.25em;
  border: 1px solid var(--border);
  white-space: nowrap;
  text-align: center;
}

.row .chip[data-side="0"] { background: var(--player-0); }
.row .chip[data-side="1"] { background: var(--player-1); }
.row .chip[data-side="2"] { background: var(--player-2); }
.row .chip[data-side="3"] { background: var(--player-3); }

.row .num {
  color: var(--muted);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.row .machine {
  white-space: nowrap;
  overflow: clip visible;
  text-overflow: ellipsis;
}

.row .picked,
.row .winner {
  white-space: nowrap;
  justify-self: start;
}

/* The header row: the column names, in the small print, each over its column. */
.row.head {
  color: var(--muted);
  font-size: 0.7em;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding-bottom: 0;
}

.row.head .num { font-weight: 600; }

/* The game in progress, at the foot of the list: no winner yet, so the word instead of a chip. */
.row .winner.playing {
  color: var(--on-game);
  font-weight: 600;
  font-size: 0.85em;
}

.rows .none {
  grid-column: 1 / -1;
  color: var(--muted);
  font-size: 0.95rem;
  padding: 0.1rem 0.25rem;
}

/* ---- The controls ------------------------------------------------------------------------------ */

/* The one place the page scrolls: a bracket round has more matches, and a bank more machines, than a
   short window holds, and the operator is the only one looking. */
.controls {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.controls-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}

.controls-buttons {
  display: flex;
  gap: 0.4rem;
  flex: none;
}

/* A completed round on the match list, folded: its heading is the summary. */
.round-group > summary {
  cursor: pointer;
  list-style: none;
}

.round-group > summary::before {
  content: "\25B8";
  display: inline-block;
  width: 1em;
}

.round-group[open] > summary::before { content: "\25BE"; }

.round-group > .match-button {
  display: grid;
  width: 100%;
  box-sizing: border-box;
  margin-top: 0.3rem;
}

.controls-hint {
  margin: 0;
  color: var(--muted);
  font-size: 0.95rem;
}

.control {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.match-list,
.played-list {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

/* The bracket the match belongs to, and its round, as a strip above the matches — only where the
   board carries more than one bracket, since on a single one the round alone says where we are. */
.match-group {
  color: var(--muted);
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-top: 0.2rem;
}

/* One match: seeds, names and the score, tall enough to hit from OBS's interact window. */
.match-button {
  font: inherit;
  font-size: 0.95rem;
  color: inherit;
  background: var(--panel-bg);
  border: 1px solid var(--border);
  border-radius: 0.45rem;
  padding: 0.35rem 0.6rem;
  text-align: left;
  cursor: pointer;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 0 0.5rem;
  min-width: 0;
  line-height: 1.25;
}

.match-button:hover,
.match-button:focus-visible { border-color: var(--text); }

.match-button[aria-selected="true"] { border-color: var(--on-game); box-shadow: inset 0 0 0 1px var(--on-game); }

.match-button .pairing {
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.match-button .match-score {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.match-button .match-state {
  grid-column: 1 / -1;
  color: var(--muted);
  font-size: 0.8rem;
}

.field {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}

.field-label {
  color: var(--muted);
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* Every machine on one screen: as many columns as fit. */
.arena-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
  gap: 0.3rem;
}

.arena-button,
.choice-button {
  font: inherit;
  font-size: 0.95rem;
  font-weight: 600;
  color: inherit;
  background: var(--panel-bg);
  border: 1px solid var(--border);
  border-radius: 0.45rem;
  padding: 0.3rem 0.6rem 0.35rem;
  text-align: left;
  cursor: pointer;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  line-height: 1.2;
}

/* The name over its "game 2" marker, so a long name has the button's whole width to wrap in. */
.arena-button {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.05rem;
}

/* The name wraps rather than truncating: the operator picking a machine needs the whole name. */
.arena-button .arena-label {
  min-width: 0;
  white-space: normal;
  overflow-wrap: anywhere;
}

.arena-button:hover,
.arena-button:focus-visible,
.choice-button:hover,
.choice-button:focus-visible { border-color: var(--text); }

.arena-button[aria-selected="true"],
.choice-button[aria-checked="true"] { border-color: var(--on-game); box-shadow: inset 0 0 0 1px var(--on-game); }

/* A machine already used in this match: still pickable (a rematch on a machine happens), but marked. */
.arena-button .used {
  color: var(--muted);
  font-size: 0.75rem;
  font-weight: 500;
  flex: none;
}

/* The players side by side, each tinted like their row on the scoreboard — and, where the choice
   allows it, "Match Play" after them, untinted. */
.choice {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
}

.choice .choice-button { flex: 1 1 auto; }

.choice-button[data-side="0"] { background: var(--player-0); }
.choice-button[data-side="1"] { background: var(--player-1); }
.choice-button[data-side="2"] { background: var(--player-2); }
.choice-button[data-side="3"] { background: var(--player-3); }

.control-hint {
  margin: 0;
  color: var(--muted);
  font-size: 0.85rem;
}

/* The games table: one row per game — its number, machine and what Match Play has for it on a line,
   the machine grid under that, then the three choices side by side, wrapping on a narrow window. */
.games-control-list {
  display: flex;
  flex-direction: column;
}

.game-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.25rem 1.2rem;
  padding: 0.35rem 0;
  border-top: 1px solid var(--border);
}

/* The game in progress is marked on its number and its tag; the rows are otherwise alike, so the eye
   isn't asked to learn two layouts. */
.game-row.current .game-what .num,
.game-row.current .game-what .game-now {
  color: var(--on-game);
}

.game-row .game-what .game-now {
  font-size: 0.8rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* The game on a line of its own — number, machine, what Match Play has — with the controls under it. */
.game-row .game-what {
  flex: 1 1 100%;
  min-width: 0;
  display: flex;
  align-items: baseline;
  gap: 0.45rem;
  font-size: 0.95rem;
  line-height: 1.25;
}

.game-row .game-what .num {
  color: var(--muted);
  font-weight: 600;
}

.game-row .game-what .game-machine {
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.game-row .game-what .game-recorded {
  color: var(--muted);
  font-size: 0.8rem;
}

.game-row .field { flex: 0 1 auto; }

/* The machine grid takes the whole row for its width, the choices dropping under it. */
.game-row .field.wide {
  flex: 1 1 100%;
  min-width: 0;
}

/* The untinted "Match Play" / "Unknown" / "Playing" buttons, and the "Match Play" tile on a grid. */
.choice-button.fallback,
.arena-button.fallback { background: transparent; }

.game-row .choice-button {
  font-size: 0.85rem;
  padding: 0.2rem 0.5rem;
}

.controls-foot {
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
  padding: 0.3rem 0 0.5rem;
  border-top: 1px solid var(--border);
}

.pill {
  font: inherit;
  font-size: 0.85rem;
  color: inherit;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 0.25rem 0.8rem;
  cursor: pointer;
  flex: none;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  line-height: 1.2;
}

.pill:hover,
.pill:focus-visible { border-color: var(--text); }

.warning {
  margin: 0.2rem 0 0;
  color: var(--warning);
  font-size: 0.85rem;
}
