/* The tournament's screens (docs/tournament.md section 2; #90 step 1; Tournament/TournamentScreens.cs):
   Home's Tournament card, the setup (the game setup's look: setup-grid, rows, presets, seats), the
   intro card before each game, the standings between games and the final podium. Text sizes come
   from the layout tokens (tokens.css), never under --fs-small; menus reflow with data-fit up to
   200 % text, and the standings' bar column is the first thing to go. Rank changes are an arrow
   and a number, a greyed game is faded, crossed out and says why: never colour alone. */

/* ------------------------------------------------------------ Home's card */

.tcard {
  display: flex;
  align-items: center;
  gap: 0.9em;
  width: 100%;
  margin-bottom: 0.8em;
  padding: 0.6em 0.9em;
  border-radius: 1em;
  border: 2px solid var(--ui-line);
  background: var(--ui-card);
  text-align: start;
  cursor: pointer;
}

.tcard-art {
  display: flex;
  flex: none;
  gap: 0.15em;
}

.tcard-art:not(.tcard-pic) svg {
  display: block;
  width: 1.5em;
  height: 1.5em;
}

/* The card's picture: the TV's Tournament tile (#620, the owner's pick C3; Shell/HomePick.cs
   TourneyPicture) on the tile's yellow, the size of a game row's picture (home.css .phone-room). */
.tcard-pic {
  display: grid;
  place-items: center;
  inline-size: calc(var(--fs-base) * 4.2);
  min-block-size: calc(var(--fs-base) * 4.2);
  border-radius: var(--r-m);
  background: linear-gradient(135deg, var(--do), var(--do-end));
}

.tcard-pic .ttile-pic {
  inline-size: 100%;
  block-size: calc(var(--fs-base) * 4.2);
}

/* How many can play, as a game row's facts. */
.tcard-facts {
  color: var(--ui-dim);
  font-size: max(var(--fs-small), 0.8em);
  font-weight: 700;
}

.tcard-text {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.1em;
  overflow-wrap: anywhere;
}

.tcard-name {
  font-size: 1.2em;
  font-weight: 900;
}

.tcard-tag {
  color: var(--ui-dim);
  font-size: max(var(--fs-small), 0.85em);
}

/* "Carry on the tournament?" (#90 step 6): the card's place on Home, with its own buttons. */
.tresume {
  flex-wrap: wrap;
  cursor: default;
}

.tresume .tcard-text {
  flex: 1 1 14em;
}

.tresume-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5em;
  margin-inline-start: auto;
}

.tresume-actions .tend-ask {
  flex-basis: 100%;
  font-weight: 900;
}

/* Home on a TV or laptop never scrolls (home.css): a slimmer card leaves more of the column to
   the chosen game's picture (#133). */
@media (min-width: 1200px) and (min-height: 500px) {
  .home-games .tcard {
    padding: 0.4em 0.8em;
  }
}

/* ------------------------------------------------------------ setup */

.tsetup-art {
  display: flex;
  flex: none;
  gap: 0.2em;
}

.tsetup-art svg {
  display: block;
  width: 2.2em;
  height: 2.2em;
}

.tpool {
  flex: 1;
  min-width: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 12em), 1fr));
  gap: 0.6em;
}

.chip.tgame {
  display: flex;
  align-items: center;
  gap: 0.6em;
  padding: 0.4em 0.7em;
  text-align: start;
  min-width: 0;
}

.tgame-art {
  flex: 0 0 3.6em;
}

.tgame-art img {
  display: block;
  width: 100%;
  height: auto;
}

.tgame-text {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.1em;
  overflow-wrap: anywhere;
}

.tgame-text span {
  font-size: max(var(--fs-small), 0.8em);
  font-weight: 700;
  opacity: 0.85;
}

/* Off: dimmer. Does not fit this group: faded, crossed out, with the reason under it. */
.chip.tgame[aria-pressed='false'] {
  opacity: 0.7;
}

.chip.tgame.unfit {
  opacity: 0.55;
  border-style: dashed;
  cursor: not-allowed;
}

.chip.tgame.unfit b {
  text-decoration: line-through;
}

.chip.tgame.unfit img {
  filter: grayscale(1);
}

/* The games as dark tiles, as the setup's presets (A · Console, #792): one that is in keeps its dark
   fill and gets the white ring, never a white fill (a wall of them outshone Start on a TV). */
.screen.setup .rows .chip.tgame {
  border-color: transparent;
  background: var(--ui-raised);
  color: var(--ui-text);
}

.screen.setup .rows .chip.tgame[aria-pressed='true'] {
  border-color: var(--focus);
  background: var(--ui-key);
}

.screen.setup .rows .chip.tgame.unfit {
  border-color: var(--ui-line);
}

.high-contrast .screen.setup .rows .chip.tgame {
  border-color: var(--ui-text);
}

.high-contrast .screen.setup .rows .chip.tgame[aria-pressed='true'] {
  border-color: var(--focus);
  box-shadow: inset 0 0 0 2px var(--focus);
}

.tpick-hint {
  font-size: max(var(--fs-small), 0.85em);
}

/* A phone or tablet: the choices, how many games, More options (#270). */
.tgames-line {
  margin: 0.3em 0;
}

.tourney-setup .fold {
  margin-top: 0.3em;
  padding: 0 0.9em;
  border: 2px solid var(--ui-line);
  border-radius: 0.7em;
  font-weight: 800;
}

/* ------------------------------------------------------------ between games */

.screen.tourney {
  position: relative;
  max-width: 64em;
  width: 100%;
  margin: 0 auto;
  padding-top: max(1.4em, var(--safe-top));
  padding-bottom: max(1.4em, var(--safe-bottom));
}

.thead {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.4em 1.2em;
}

.tcount {
  margin: 0;
  font-size: 1.5em;
  font-weight: 900;
}

.tnext,
.ttimer {
  margin: 0;
  color: var(--ui-dim);
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

.tnext {
  font-size: 1.1em;
}

/* "Ana takes the lead!" (#90 polish): the news of the game just played, over the table. */
.tlead {
  margin: 0;
  font-size: 1.25em;
  font-weight: 900;
  color: var(--do);
}

/* The team game just played, a side a line (#90 step 7): who won, who lost, the points each. */
.tsides-result {
  margin: 0;
  font-weight: 800;
  overflow-wrap: anywhere;
}

.tsides-result > span {
  display: block;
}

/* Where the table has every line it can get (a short screen at big text: its rows and the host's
   buttons must all stay in sight), the line goes; the room's screen still says it and pops. */
:root[data-fit-y='short']:not([data-fit='wide']) :is(.tlead, .tsides-result) {
  display: none;
}

/* Who is ready on the standings (#748): the ✓ by a name, and the touch screen's own button. */
.tready-mark {
  color: var(--ok);
  font-size: max(var(--fs-small), 0.85em);
  font-weight: 800;
  white-space: nowrap;
}

/* Where every line counts (a short screen or an upright phone, outside the wide layout): the count and
   how to say ready go; the ✓ by each name and a touch screen's I'm ready button stay. */
:root:is([data-fit-y='short'], [data-bp='xs']):not([data-fit='wide'])
  :is(.tready-count, .tready-how) {
  display: none;
}

.tready-btn {
  margin-inline-start: 0.4em;
  min-height: var(--touch-min);
}

/* Which step of the intro card (#298): "1 of 2: the game", "2 of 2: the controls". */
.tstep {
  margin: 0;
  font-size: max(var(--fs-small), 1em);
  font-weight: 800;
  color: var(--ui-dim);
}

.tintro-nocontrols {
  margin: 0;
}

.tdouble,
.tstopped {
  margin: 0;
  padding: 0.4em 0.8em;
  border-radius: 0.7em;
  border: 2px solid var(--ui-line);
  font-weight: 900;
}

.tdouble {
  align-self: flex-start;
  background: var(--ui-card);
  color: var(--do);
}

/* The intro card: the game's picture, name and one line of rules. */
.tintro-card {
  display: flex;
  align-items: center;
  gap: 1.4em;
}

.tintro-card .gcard-art {
  flex: 0 0 min(16em, 36%);
}

.tintro-card .gcard-art img {
  display: block;
  width: 100%;
  height: auto;
  max-height: 22vh;
  object-fit: contain;
  -webkit-mask-image: radial-gradient(ellipse 72% 72% at 50% 50%, #000 62%, transparent 100%);
}

.tintro-text {
  min-width: 0;
}

/* Step 1 (#298): the game's main clip over its still (js/clips.ts), its logo before its name, its goal,
   then how you win. The still is there at once; the clip fades in over it once it plays. */
.tintro-card .tstep-clip {
  flex: 0 0 min(22em, 40%);
}

.tstep-clip {
  position: relative;
  display: block;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border-radius: 0.7em;
}

.tstep-clip img,
.tstep-clip video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.tstep-clip video {
  position: absolute;
  inset: 0;
  opacity: 0;
}

.tstep-clip.playing video {
  opacity: 1;
}

/* The game's kept picture, only when even the still cannot load (offline: media/ is not kept). */
.tstep-fallback {
  display: none;
}

.tstep-clip.no-still > img {
  display: none;
}

.tstep-clip.no-still .tstep-fallback {
  display: block;
  height: 100%;
}

.tstep-fallback img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* Offline the icon cannot load: it goes, gap and all (js/clips.ts). */
.tintro-icon[hidden] {
  display: none;
}

.tintro-icon {
  display: inline-block;
  width: 1em;
  height: 1em;
  margin-inline-end: 0.3em;
  vertical-align: -0.12em;
  border-radius: 0.2em;
}

.tintro-goal {
  margin: 0.4em 0 0;
  font-size: 1.15em;
  line-height: calc(1.4 * var(--line-k));
}

.tintro-name {
  margin: 0;
  font-size: 2.2em;
  font-weight: 900;
  line-height: calc(1.1 * var(--line-k));
}

.tintro-line {
  margin: 0.4em 0 0;
  font-size: max(var(--fs-small), 1em);
  line-height: calc(1.4 * var(--line-k));
}

.tintro-controls .pause-controls {
  font-size: max(var(--fs-small), 0.9em);
}

/* ---- the intro card on Home's hero layout (A · Console, plan 2.6; #413)

   A TV's or a laptop's step 1 at its usual text size: the game's clip fills the screen (its still
   at once, the clip over it once it plays: js/clips.ts), under the fades, and the card's words stand
   on the start side over the dark band, as Home's hero does: "Game 2 of 5" the meta line in yellow,
   the name big, the goal, how you win; then who is ready and the host's buttons. The picture runs
   left to right whatever the page does (turned as a whole right to left, plan 2.8). At big text, on
   a tablet upright or a phone, the card keeps its picture beside or above its words, over the faded
   backdrop (TournamentScreens.Backdrop). */
@media (orientation: landscape) and (min-width: 900px) and (min-height: 501px) {
  :root[data-fit='wide'] .tourney-intro.tstep-game {
    --hero-end: calc(max(2em, var(--safe-start)) + var(--hero-w) + 2em);
    max-width: none;
    margin: 0;
    padding-inline: max(2em, var(--safe-start)) max(2em, var(--safe-end));
  }

  /* The clip is the backdrop here: the faded still behind the page is not drawn twice. */
  :root[data-fit='wide'] .tourney-intro.tstep-game > .tourney-bg {
    display: none;
  }

  /* The band follows this section's own --hero-end: it has class fades (tokens.css). */
  :root[data-fit='wide'] .tourney-intro.tstep-game::before {
    content: '';
    position: fixed;
    inset: 0;
    z-index: -1;
    background: var(--fade-top), var(--fade-foot), var(--fade-side);
    pointer-events: none;
  }

  /* High contrast: the band solid where the words are, as Home's hero. */
  :root[data-fit='wide'].high-contrast .tourney-intro.tstep-game::before {
    background:
      var(--fade-top), var(--fade-foot),
      linear-gradient(var(--fade-dir), var(--bg) 0 var(--hero-end), transparent var(--hero-end));
  }

  :root[data-fit='wide'] .tourney-intro.tstep-game .tintro-card .tstep-clip {
    position: fixed;
    inset: 0;
    z-index: -2;
    aspect-ratio: auto;
    border-radius: 0;
    direction: ltr;
    pointer-events: none;
  }

  :root[data-fit='wide'][dir='rtl'] .tourney-intro.tstep-game .tintro-card .tstep-clip {
    transform: scaleX(-1);
  }

  :root[data-fit='wide'] .tourney-intro.tstep-game .tstep-clip :is(img, video) {
    object-fit: cover;
  }

  /* The words in the hero's column, no box round them. */
  :root[data-fit='wide'] .tourney-intro.tstep-game .tintro-body {
    display: block;
    width: var(--hero-w);
    max-width: 100%;
  }

  :root[data-fit='wide'] .tourney-intro.tstep-game .tintro-card {
    display: block;
    padding: 0;
    border: 0;
    background: none;
    box-shadow: none;
  }

  :root[data-fit='wide'] .tourney-intro.tstep-game .thead {
    justify-content: flex-start;
    width: var(--hero-w);
    max-width: 100%;
  }

  /* "Game 2 of 5", the meta line. */
  :root[data-fit='wide'] .tourney-intro.tstep-game .tcount {
    color: var(--do);
    font-size: max(var(--fs-small), 1.05em);
    font-weight: 800;
    letter-spacing: 0.05em;
    text-transform: uppercase;
  }

  /* Spaced letters break Arabic's joined ones. */
  :root[data-fit='wide']:lang(ar) .tourney-intro.tstep-game .tcount {
    letter-spacing: 0;
  }

  :root[data-fit='wide'] .tourney-intro.tstep-game .tintro-name {
    margin: 0.25em 0 0.1em;
    font-size: calc(var(--fs-base) * 3.2);
    font-weight: 1000;
    letter-spacing: -0.02em;
    line-height: calc(1.05 * var(--line-k));
  }

  :root[data-fit='wide'] .tourney-intro.tstep-game .tintro-goal {
    font-size: max(1.1em, calc(var(--fs-base) * 1.4));
    font-weight: 600;
    line-height: calc(1.25 * var(--line-k));
  }

  :root[data-fit='wide'] .tourney-intro.tstep-game .tintro-side {
    margin-top: 1.2em;
  }

  /* The host's buttons from the column's start edge, Next first, as the hero's Play. */
  :root[data-fit='wide'] .tourney-intro.tstep-game .tintro-side .pg-actions {
    justify-content: flex-start;
  }

  /* The host's buttons in the screen's bottom corner (#748: never in the middle of the page), clear
     of the game's words on the other side. */
  :root[data-fit='wide'] .tourney-intro.tstep-game .tactions.thost {
    position: fixed;
    z-index: 2;
    inset-block-end: max(1.5em, var(--safe-bottom));
    inset-inline-end: max(2em, var(--safe-end));
    max-width: calc(100% - var(--hero-end) - 2em);
    margin: 0;
    justify-content: flex-end;
  }

  /* Too many buttons for one row beside the words, and the words end above the bar (#90 polish;
     js/layout.ts fitIntroBar): the whole width, so End tournament does not wrap to a row of its own. */
  :root[data-fit='wide'] .tourney-intro.tstep-game .tactions.thost.tbar-wide {
    max-width: calc(100% - max(2em, var(--safe-start)) - max(2em, var(--safe-end)));
  }
}

/* A card for the players who hold the same thing (#298): each one's look and name, wrapping. */
/* A row's short label (ControlGroups.RowHtml): only on a small card (the controls step on a TV, below). */
.ctl-short {
  display: none;
}

/* A row's box: no box of its own but on a small card (below), so the card's grid holds its label and keys. */
.ctl-row {
  display: contents;
}

/* The controls step's bots as one chip, or a side's name and bots heading its chips: only at big text
   on a TV (below). */
.tchip.tbots,
.tside-label {
  display: none;
}

.ctl-who {
  display: flex;
  flex-wrap: wrap;
  gap: 0.2em 0.8em;
  min-width: 0;
}

.ctl-member {
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
}

/* Who is ready: a chip per entrant; ✓ and the words say it, the filled chip only adds to it. */
.tchips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5em;
  margin: 0;
  padding: 0;
  list-style: none;
}

.tchip-btn {
  display: flex;
  align-items: center;
  gap: 0.4em;
  padding-block: 0.35em;
  padding-inline: 0.5em 0.8em;
  border-radius: 999px;
  border: 2px solid var(--c-60);
  background: transparent;
  font-weight: 800;
}

button.tchip-btn {
  cursor: pointer;
}

.tchip.ready .tchip-btn {
  background: var(--c-16);
}

.tchip-btn svg {
  display: block;
  flex: none;
}

.tchip-state {
  color: var(--ui-dim);
  font-size: max(var(--fs-small), 0.8em);
}

.tchip.ready .tchip-state {
  color: var(--ui-text);
  font-weight: 900;
}

.tchip.away .tchip-btn {
  border-style: dashed;
  opacity: 0.6;
}

.tready .hint {
  margin-top: 0.5em;
}

/* A game of sides (step 7): who is with whom, side by side under each side's name; the bot that
   evens the sides says so in words (its chip is dotted too, never colour alone). */
.tsides {
  display: flex;
  align-items: stretch;
  gap: 0.8em;
}

.tside {
  flex: 1 1 0;
  min-width: 0;
  padding: 0.7em 0.9em;
}

.tside-name {
  margin: 0 0 0.4em;
  font-size: 1.3em;
  font-weight: 900;
}

.tside-vs {
  align-self: center;
  margin: 0;
  font-size: 1.4em;
  font-weight: 900;
  color: var(--ui-dim);
}

/* On the controls step the sides are a compact row (#298): the names smaller, the panels tight. */
.tsides.compact .tside {
  padding: 0.4em 0.7em;
}

.tsides.compact .tside-name {
  margin-bottom: 0.25em;
  font-size: 1em;
}

.tsides.compact .tside-vs {
  font-size: 1em;
}

.tchip.even .tchip-btn {
  border-style: dotted;
}

.tsitout {
  margin: 0.5em 0 0;
  font-weight: 700;
}

.tactions {
  margin-top: 0.2em;
}

/* The intro card's host buttons stay in the page, right under the game's words, never pinned to the
   foot: on a phone at big text, held either way, three pinned buttons covered most of the card (#298).
   The standings' too on a phone where their bar would take more than a third of the screen (tbar-loose,
   measured after layout: js/layout.ts fitBars), where four pinned buttons once filled the screen and the
   table was never in sight (#345); "Host's buttons" at the top goes to them. Else a phone keeps the
   pinned bar, its buttons two to a row; so does a TV or a computer (below: nobody scrolls a TV), and
   another screen's own buttons. */
.tourney-intro .tactions.thost,
:root:is([data-bp='xs'], [data-bp='s-land']) .tourney-standings .tactions.thost.tbar-loose {
  position: static;
  margin: 0.2em 0 0;
  padding: 0;
  background: none;
  box-shadow: none;
}

/* "↓ Host's buttons" (#298's review): on the intro card only on an upright screen that is not wide,
   where the host's buttons come after the clip and the words, two or three screens down at big text;
   on the standings where their buttons are not pinned (above, #345). */
.thead .tjump {
  display: none;
  gap: 0.3em;
  /* One line on a small phone at 200 %. */
  font-size: max(var(--fs-small), 0.85em);
}

@media (orientation: portrait) {
  :root:not([data-fit='wide']) .tourney-intro .thead .tjump {
    display: inline-flex;
  }
}

:root:is([data-bp='xs'], [data-bp='s-land']) .tourney-standings.tbar-free .thead .tjump {
  display: inline-flex;
}

/* There, a row of the table is up to five lines tall (#345): the gaps are smaller and the room's code
   goes to the foot of the page, so the first place shows under the title on a 320×568 phone. */
:root:is([data-bp='xs'], [data-bp='s-land']) .tourney-standings.tbar-free {
  gap: 0.5em;
}

:root:is([data-bp='xs'], [data-bp='s-land']) .tourney-standings.tbar-free .troom {
  order: 1;
}

/* An upright phone between games with a vote or the host's pick (#90 polish): the table first, so each
   player sees their place and points without scrolling past the cards; the vote or the pick after it,
   then the rest. A TV or a computer has them side by side (below). */
:root[data-bp='xs'] .tourney-standings > .tpick:has(~ .tstand-box) {
  order: 1;
}

:root[data-bp='xs'] .tourney-standings > .tpick ~ :not(.tstand-box) {
  order: 2;
}

/* A phone's bar of the standings' buttons: two to a row, so it takes half the height (and stays pinned
   on more phones). */
:root:is([data-bp='xs'], [data-bp='s-land']) .tourney-standings .tactions.thost .btn {
  flex: 1 1 calc(50% - 0.3em);
}

.tactions .btn .start-where {
  display: block;
  font-size: max(var(--fs-small), 0.75em);
  font-weight: 700;
}

.tend-ask {
  flex-basis: 100%;
  margin: 0;
  text-align: center;
  font-weight: 900;
}

.twait {
  border: 2px solid var(--ui-line);
}

/* The host's break (#90 step 5): one big word, and how it goes on. */
.tbreak {
  border: 2px dashed var(--ui-line);
  text-align: center;
}

.tbreak-line {
  margin: 0;
  font-size: 2em;
  font-weight: 900;
  letter-spacing: 0.04em;
}

.tbreak .hint {
  margin: 0.2em 0 0;
}

/* The room's players between games (#90 step 5): their cards with ⋯ (Make host, Take out), the knocks. */
.tplayers h2 {
  margin: 0 0 0.4em;
}

.tplayers .players {
  margin: 0 0 0.5em;
}

.tplayers .hint {
  margin: 0.3em 0;
}

.twait-line {
  margin: 0;
  font-size: 1.2em;
  font-weight: 900;
}

.twait-clock {
  font-variant-numeric: tabular-nums;
}

/* Quiet dark panels with no edge (A · Console, plan 2.6; high contrast: the white one). */
.screen.tourney .panel {
  border-color: transparent;
}

.high-contrast .screen.tourney .panel {
  border-color: var(--ui-text);
}

/* ------------------------------------------------------------ the standings table */

/* Names break between their words, never inside one ("Pyra/mid" at 320 px and 200 %, #322), so the
   table may be wider than a very narrow screen: it scrolls in here then. Positioned, so its
   screen-reader words (.sr-only, absolute) are inside it, not past the screen's edge. */
.tstand-box {
  position: relative;
  overflow-x: auto;
}

.pg-table.tstand {
  margin: 0;
  font-size: 1.05em;
}

.tstand td {
  vertical-align: middle;
}

/* After a game each row slides from its old place to its new one (#90 polish; js/standings.ts sets
   tslide once a game and the delay, so a redraw carries the slide on). --from: places gone up. */
.tstand.tslide tbody tr {
  animation: tstand-slide 0.8s cubic-bezier(0.2, 0.8, 0.2, 1) var(--slide-delay, 0.3s) backwards;
}

@keyframes tstand-slide {
  from {
    transform: translateY(calc(var(--from, 0) * 100%));
  }
}

.reduced-motion .tstand.tslide tbody tr {
  animation: none;
}

@media (prefers-reduced-motion: reduce) {
  .tstand.tslide tbody tr {
    animation: none;
  }
}

.tstand .trank {
  width: 2.6em;
  font-weight: 900;
}

.tplayer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.3em 0.45em;
}

.tplayer svg {
  flex: none;
}

.tbot,
.tgone,
.tside-tag {
  font-size: max(var(--fs-small), 0.75em);
  font-weight: 800;
  padding: 0.05em 0.45em;
  border-radius: 0.5em;
  border: 1px solid var(--ui-line);
  color: var(--ui-dim);
}

.tgame-col {
  white-space: nowrap;
}

.tplus {
  color: var(--ui-dim);
}

.tbar-col {
  width: 28%;
}

.tbar {
  display: block;
  width: var(--w);
  min-width: 0.3em;
  height: 0.8em;
  border-radius: 0.4em;
  background: var(--c);
}

.tstand .ttotal {
  font-size: 1.15em;
  font-weight: 900;
}

.tmove {
  white-space: nowrap;
  font-weight: 900;
}

.tstand tr.faded {
  opacity: 0.55;
}

/* A · Console (#413): each row dark and rounded, as the match's cards and the results' rows; each
   player's shape a badge ringed in their colour; the total in the score size where the text is at
   its usual size (big text keeps the room for the rows). */
.pg-table.tstand {
  border-collapse: separate;
  border-spacing: 0 0.25em;
}

/* Big text: a thin line between the rows, as before, so 8 rows keep fitting above the buttons. */
:root:not([data-fit='wide']) .pg-table.tstand {
  border-spacing: 0 2px;
}

.tstand tbody td {
  border-top: 0;
  background: var(--ui-card);
}

.tstand tbody td:first-child {
  border-start-start-radius: var(--r-m);
  border-end-start-radius: var(--r-m);
}

.tstand tbody td:last-child {
  border-start-end-radius: var(--r-m);
  border-end-end-radius: var(--r-m);
}

.high-contrast .tstand tbody td {
  box-shadow:
    inset 0 2px var(--ui-text),
    inset 0 -2px var(--ui-text);
}

.tstand .tplayer > svg {
  box-sizing: content-box;
  padding: 0.2em;
  border-radius: 50%;
  background: var(--bg);
  box-shadow: inset 0 0 0 max(2px, 0.1em) var(--c);
}

.tstand tbody tr.mine td {
  background: var(--ui-raised);
}

:root[data-fit='wide'] .tstand .ttotal {
  font-size: 1.5em;
}

:root[data-fit='wide'] .tstand tbody td {
  padding-block: 0.25em;
}

/* The final on a TV or a laptop (#413): the results' layout (#412), the winner's line across the
   top, the podium beside the table, the buttons at the foot, so a shared step's tall podium never
   pushes the buttons off. Big text and phones keep the column. */
@media (orientation: landscape) and (min-width: 1200px) and (min-height: 501px) {
  :root[data-fit='wide'] .tourney-final:has(> .tpodium) {
    display: grid;
    grid-template-columns: minmax(0, 26em) minmax(0, 1fr);
    column-gap: 2em;
    align-items: center;
    max-width: 80em;
  }

  :root[data-fit='wide'] .tourney-final:has(> .tpodium) > * {
    grid-column: 1 / -1;
  }

  :root[data-fit='wide'] .tourney-final:has(> .tpodium) > .tpodium {
    grid-column: 1;
    width: 100%;
    margin-inline: 0;
  }

  :root[data-fit='wide'] .tourney-final:has(> .tpodium) > .tpodium + .tstand-box {
    grid-column: 2;
  }
}

/* The final has the podium beside or above its table: the totals a step smaller there. */
:root[data-fit='wide'] .tourney-final .tstand .ttotal {
  font-size: 1.25em;
}

:root[data-fit='wide'] .tstand .trank {
  font-size: 1.2em;
}

/* ------------------------------------------------------------ the final podium */

.tfinal-title {
  margin: 0;
  font-size: 1.8em;
  font-weight: 900;
}

/* The winner's line big, as the results' (#412), where the text is at its usual size. */
:root[data-fit='wide'] .tfinal-title {
  font-size: calc(var(--fs-base) * 2);
  font-weight: 1000;
  line-height: calc(1.1 * var(--line-k));
}

.tpodium .tpts {
  color: var(--ui-dim);
  font-size: max(var(--fs-small), 0.8em);
}

/* ------------------------------------------------------------ big text, narrow screens */

/* Under 50 lines of text wide (a phone, a split window, 200 % text on a TV): the bar goes first,
   the intro card stacks, the controls go one under another, the chips and buttons take the width. */
:root:not([data-fit='wide']) .tbar-col {
  display: none;
}

:root:not([data-fit='wide']) .tintro-card {
  flex-direction: column;
  align-items: flex-start;
  gap: 0.6em;
}

:root[data-fit='narrow'] .tcount,
:root[data-fit='narrow'] .tfinal-title {
  font-size: 1.25em;
}

:root[data-fit='narrow'] .tintro-name {
  font-size: 1.6em;
}

:root[data-fit='narrow'] .tsides {
  flex-direction: column;
}

:root[data-fit='narrow'] .tstand .tgame-col {
  white-space: normal;
}

:root[data-fit='narrow'] .tstand th,
:root[data-fit='narrow'] .tstand td {
  padding: 0.3em 0.25em;
}

:root[data-fit='narrow'] .tactions .btn {
  flex: 1 1 100%;
}

:root[data-fit='narrow'] .tcard-art:not(.tcard-pic) svg {
  width: 1.1em;
  height: 1.1em;
}

/* "Next: Tessellate · in 12 s": the dot only while there is a timer. */
.tnext .ttimer:not(:empty)::before {
  content: '· ';
}

/* Big text: the intro card's old picture goes (the name and the rules stay in sight); podium names wrap.
   A clip stays (#298): it shows what the words cannot, so it goes above the words, a third of the
   screen tall at most; on a phone on its side it stays beside them. */
:root:not([data-fit='wide']) .tintro-card .gcard-art {
  display: none;
}

:root:not([data-fit='wide']) .tintro-card:has(.tstep-clip) {
  flex-direction: column;
  align-items: stretch;
  gap: 0.8em;
}

:root:not([data-fit='wide']) .tintro-card .tstep-clip {
  flex: none;
  align-self: center;
  /* Sized by its width (its height follows, 4:3): never wider than the card, never over a third of the screen tall. */
  width: min(100%, 44vh);
  height: auto;
}

/* A phone on its side: the clip beside the words, half the screen tall at most. (Not "short" alone: an
   upright phone at big text is short too, and there the words need the whole width.) */
@media (orientation: landscape) {
  :root[data-fit-y='short']:not([data-fit='wide']) .tintro-card:has(.tstep-clip) {
    flex-direction: row;
  }

  /* At the top: the words run long at big text, and a clip in the middle of them left the first screen half empty. */
  :root[data-fit-y='short']:not([data-fit='wide']) .tintro-card .tstep-clip {
    align-self: flex-start;
    width: min(45%, 73vh);
  }
}

/* The intro card's two boxes (TournamentScreens.Intro): no box of their own, but on a TV or a computer
   at big text. */
.tintro-body,
.tintro-side,
.tside-rest {
  display: contents;
}

/* An upright phone on step 1 (#90 polish): who is ready, with "Tap your name", comes right under the
   title, before the game's clip and words, so a player readies without scrolling (the clip and the
   words pushed the chips under the pinned Leave bar). The rest of the side follows the words, as on
   the controls step. */
:root[data-bp='xs'] .tstep-game .tintro-card {
  order: 1;
}

:root[data-bp='xs'] .tstep-game .tintro-side > :not(.tready) {
  order: 2;
}

/* A TV or a computer at big text (#298's review): nobody scrolls a TV from the couch, so step 1 fits on
   one screen. The game's words on the left; on the right the host's buttons, then "Ready? Press Ⓐ",
   then who is ready. The clip takes what height is left under the words, down to nothing (it goes when
   too small to see), and everything is a little tighter than elsewhere. Measured on a 1080p TV: all of
   it fits with 8 players at 100 % and 150 % text and with 4 at 200 % (56 px text, 19 lines a screen);
   more players at 200 % run the last chips off the foot, under the buttons and the hint. */
@media (orientation: landscape) {
  :root:not([data-fit='wide'], [data-bp='xs'], [data-bp='s-land'])
    :is(.tstep-game, .tstep-controls) {
    height: 100%;
    min-height: 0;
    gap: 0.4em;
    padding-top: max(0.4em, var(--safe-top));
    padding-bottom: max(0.4em, var(--safe-bottom));
  }

  :root:not([data-fit='wide'], [data-bp='xs'], [data-bp='s-land'])
    :is(.tstep-game, .tstep-controls)
    .tcount {
    font-size: 1.2em;
  }

  :root:not([data-fit='wide'], [data-bp='xs'], [data-bp='s-land']) .tstep-game .tintro-body {
    display: flex;
    flex: 1 1 0;
    min-height: 0;
    gap: 0.8em;
  }

  :root:not([data-fit='wide'], [data-bp='xs'], [data-bp='s-land'])
    .tstep-game
    .tintro-body
    > .tintro-card {
    flex: 3 1 0;
    min-width: 0;
    min-height: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0.4em;
    padding: 0.5em 0.7em;
    overflow-y: auto;
  }

  :root:not([data-fit='wide'], [data-bp='xs'], [data-bp='s-land'])
    .tstep-game
    .tintro-card
    .tstep-clip {
    flex: 1 1 0;
    width: 100%;
    min-height: 0;
    aspect-ratio: auto;
    container-type: size;
  }

  :root:not([data-fit='wide'], [data-bp='xs'], [data-bp='s-land']) .tstep-game .tintro-text {
    flex: none;
    order: -1;
  }

  :root:not([data-fit='wide'], [data-bp='xs'], [data-bp='s-land']) .tstep-game .tintro-name {
    font-size: 1.2em;
  }

  :root:not([data-fit='wide'], [data-bp='xs'], [data-bp='s-land']) .tstep-game .tintro-goal {
    font-size: 1em;
  }

  :root:not([data-fit='wide'], [data-bp='xs'], [data-bp='s-land']) .tstep-game .tintro-goal,
  :root:not([data-fit='wide'], [data-bp='xs'], [data-bp='s-land']) .tstep-game .tintro-line {
    line-height: calc(1.3 * var(--line-k));
  }

  :root:not([data-fit='wide'], [data-bp='xs'], [data-bp='s-land']) .tstep-game .tintro-side {
    display: flex;
    flex: 2 1 0;
    flex-direction: column;
    min-width: 0;
    gap: 0.4em;
    overflow-y: auto;
  }

  /* 150 % on a TV: half the width each, so the chips go two to a row. So too a tablet or a computer at
     200 % (m: a 1024×768 tablet's right column was too narrow for the buttons on two rows, and its
     fourth chip went off the foot); a TV at 200 % keeps the words their width. */
  :root[data-fit='medium']:not([data-bp='xs'], [data-bp='s-land'])
    .tstep-game
    .tintro-body
    > .tintro-card,
  :root[data-fit='medium']:not([data-bp='xs'], [data-bp='s-land']) .tstep-game .tintro-side,
  :root[data-fit='narrow'][data-bp='m'] .tstep-game .tintro-body > .tintro-card,
  :root[data-fit='narrow'][data-bp='m'] .tstep-game .tintro-side {
    flex: 1 1 0;
  }

  :root:not([data-fit='wide'], [data-bp='xs'], [data-bp='s-land'])
    :is(.tstep-game, .tstep-controls)
    .tactions {
    justify-content: flex-start;
    gap: 0.4em;
  }

  :root:not([data-fit='wide'], [data-bp='xs'], [data-bp='s-land'])
    :is(.tstep-game, .tstep-controls)
    .tactions
    .btn {
    flex: 0 1 auto;
    padding: 0.25em 0.9em;
  }

  :root:not([data-fit='wide'], [data-bp='xs'], [data-bp='s-land'])
    :is(.tstep-game, .tstep-controls)
    .tready {
    display: flex;
    flex-direction: column;
    gap: 0.3em;
  }

  :root:not([data-fit='wide'], [data-bp='xs'], [data-bp='s-land'])
    :is(.tstep-game, .tstep-controls)
    .tready
    .hint {
    order: -1;
    margin: 0;
  }

  :root:not([data-fit='wide'], [data-bp='xs'], [data-bp='s-land'])
    :is(.tstep-game, .tstep-controls)
    .tchips {
    gap: 0.3em;
  }

  :root:not([data-fit='wide'], [data-bp='xs'], [data-bp='s-land'])
    :is(.tstep-game, .tstep-controls)
    .tchip-btn {
    padding-block: 0.1em;
    padding-inline: 0.4em 0.6em;
    line-height: calc(1.25 * var(--line-k));
  }

  /* The controls step on a TV or a computer, at every text size (#298, PR 5's review): every card on
     screen, no scrolling, for up to 8 players. One column the width of the screen, tight; the cards
     in a grid across it, compact: the keys alone (the words after them, a label's brackets, the Pause
     and Describe rows are out of sight, not out of screen readers': TournamentScreens.ControlRowHtml),
     at the small text size. Measured at 1080p, 1280×720 and 1024×768 at 100, 150 and 200 % with the
     keys, the arrows, a gamepad and two phones (four cards) and 8 chips, and a teams game. */
  :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-content: start;
    gap: 0.4em 1em;
    padding-top: max(0.4em, var(--safe-top));
    padding-bottom: max(0.4em, var(--safe-bottom));
  }

  /* One row on top: "Game 3 of 5", the title, the room's code. The rest the whole width. ("2 of 2:
     the controls" is out of sight there: the title says it.) */
  :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls > *,
  :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls .tintro-side > *,
  :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls .tside-rest > * {
    grid-column: 1 / -1;
  }

  :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls > .thead {
    grid-column: 1;
  }

  :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls .tstep-title {
    grid-column: 2;
    align-self: baseline;
  }

  :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls .tintro-side > .troom {
    grid-column: 3;
    align-self: baseline;
  }

  :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls .thead .tstep {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls .tcount {
    font-size: 1.2em;
  }

  :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls .tstep-title {
    margin: 0;
    font-size: 1.2em;
  }

  :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls .tactions {
    justify-content: flex-start;
    gap: 0.4em;
  }

  :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls .tactions .btn {
    flex: 0 1 auto;
    padding: 0.25em 0.9em;
  }

  :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls .tready {
    display: flex;
    flex-direction: column;
    gap: 0.3em;
  }

  :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls .tready .hint {
    order: -1;
    margin: 0;
  }

  :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls .tchips {
    gap: 0.3em;
  }

  :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls .tchip-btn {
    padding-block: 0.1em;
    padding-inline: 0.4em 0.6em;
    font-size: max(var(--fs-small), 0.9em);
    line-height: calc(1.25 * var(--line-k));
  }

  /* With the how-to clips (#749): the step is one screen high, and below the top rows the rest is a
     column whose clips take what height is left over the cards, down to nothing (they go when too
     small to see). The cards stay on screen, as without them: no row or gap of the clips' own costs
     them height (a "Double points" row only when there is one; the clips' gap is taken back), and
     where the cards still would not fit, the clips go. js/layout.ts fitClips sets data-clips (and
     data-clips-double): plain attributes, no :has(), whose matching costs every page's style work, and
     no class, which a redraw compares to keep its scroll place. */
  :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls[data-clips] {
    height: 100%;
    min-height: 0;
    grid-template-rows: auto minmax(0, 1fr);
  }

  :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls[data-clips][data-clips-double] {
    grid-template-rows: auto auto minmax(0, 1fr);
  }

  :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls[data-clips] > .tdouble {
    grid-row: 2;
  }

  :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls[data-clips] .tside-rest {
    display: flex;
    flex-direction: column;
    grid-row: -2;
    gap: 0.4em;
    min-height: 0;
  }

  :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls[data-clips] .tcontrols-clips {
    flex: 1 1 0;
    min-height: 0;
    margin-block-start: -0.4em;
    container-type: size;
    align-content: center;
  }

  :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls .tcontrols-clips .tclips-arena {
    width: min(100cqw, 36em, (100cqh - 3.2em) * 16 / 9);
    min-width: 0;
  }

  /* An empty note takes no room (it stays in the page for screen readers when it says something). */
  :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls .note:empty {
    position: absolute;
  }

  :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls .pause-controls {
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 7em), 1fr));
    gap: 0.4em;
    font-size: var(--fs-small);
  }

  :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls .ctl-card {
    padding: 0.3em 0.6em;
  }

  :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls .ctl-card h4 {
    flex-wrap: wrap;
    margin-block-end: 0.15em;
  }

  :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls .ctl-card dl {
    gap: 0.1em 0.5em;
  }

  :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls .ctl-card :is(kbd, .pb) {
    margin-inline: 0 0.1em;
  }

  :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls .ctl-card kbd {
    min-width: 1.1em;
    padding-inline: 0.2em;
  }

  :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls .ctl-card :is(h4, dl) {
    line-height: calc(1.15 * var(--line-k));
  }

  /* At big text a little tighter still. */
  :root:not([data-fit='wide'], [data-bp='xs'], [data-bp='s-land']) .tstep-controls .tstep-title {
    font-size: 1em;
  }

  :root:not([data-fit='wide'], [data-bp='xs'], [data-bp='s-land']) .tstep-controls {
    gap: 0.2em 0.6em;
  }

  :root:not([data-fit='wide'], [data-bp='xs'], [data-bp='s-land']) .tstep-controls .ctl-card kbd {
    min-width: 1em;
    padding-inline: 0.12em;
  }

  :root:not([data-fit='wide'], [data-bp='xs'], [data-bp='s-land'])
    .tstep-controls
    .ctl-card
    :is(kbd, .pb) {
    margin-inline-end: 0.05em;
  }

  :root:not([data-fit='wide'], [data-bp='xs'], [data-bp='s-land']) .tstep-controls .ctl-card h4 {
    margin-block-end: 0;
  }

  :root:not([data-fit='wide'], [data-bp='xs'], [data-bp='s-land']) .tstep-controls .tchip-btn {
    padding-block: 0.05em;
    line-height: calc(1.15 * var(--line-k));
  }

  :root:not([data-fit='wide'], [data-bp='xs'], [data-bp='s-land']) .tstep-controls .ctl-card {
    padding: 0.15em 0.5em;
  }

  :root:not([data-fit='wide'], [data-bp='xs'], [data-bp='s-land']) .tstep-controls .ctl-card dl {
    row-gap: 0;
  }

  :root:not([data-fit='wide'], [data-bp='xs'], [data-bp='s-land']) .tstep-controls .tchip.tbots {
    display: list-item;
  }

  :root:not([data-fit='wide'], [data-bp='xs'], [data-bp='s-land']) .tstep-controls .tside-label {
    display: list-item;
    align-self: center;
    margin-inline-end: 0.3em;
    font-weight: 900;
    list-style: none;
  }

  :root:not([data-fit='wide'], [data-bp='xs'], [data-bp='s-land']) .tstep-controls .tside-bots {
    color: var(--ui-dim);
    font-size: max(var(--fs-small), 0.85em);
  }

  /* "Game 3 of 5" small there: the title (the game) has the room on the top row. */
  :root:not([data-fit='wide'], [data-bp='xs'], [data-bp='s-land']) .tstep-controls .tcount {
    font-size: max(var(--fs-small), 0.85em);
  }

  :root:not([data-fit='wide'], [data-bp='xs'], [data-bp='s-land'])
    .tstep-controls
    .tchip.tbots
    .tchip-btn {
    border-color: var(--ui-line);
    color: var(--ui-dim);
  }

  /* At big text the sides one under the other, each a line: its name before its chips, which wrap
     (no "v" line between them: the names say it). (.compact twice: before the sides' rules below.) */
  :root:not([data-fit='wide'], [data-bp='xs'], [data-bp='s-land'])
    .tstep-controls
    .tsides.compact.compact {
    flex-direction: column;
    gap: 0.3em;
  }

  :root:not([data-fit='wide'], [data-bp='xs'], [data-bp='s-land'])
    .tstep-controls
    .tsides.compact.compact
    .tside {
    flex: none;
    padding: 0.1em 0.5em;
  }

  /* Its heading out of sight but read: its name heads its chips' line instead (.tside-label). */
  :root:not([data-fit='wide'], [data-bp='xs'], [data-bp='s-land'])
    .tstep-controls
    .tsides.compact.compact
    .tside-name {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  :root:not([data-fit='wide'], [data-bp='xs'], [data-bp='s-land'])
    .tstep-controls
    .tsides.compact.compact
    .tchips {
    align-items: center;
    gap: 0.2em 0.3em;
  }

  :root:not([data-fit='wide'], [data-bp='xs'], [data-bp='s-land'])
    .tstep-controls
    .tsides.compact.compact
    .tchip-btn {
    white-space: nowrap;
  }

  :root:not([data-fit='wide'], [data-bp='xs'], [data-bp='s-land'])
    .tstep-controls
    .tsides.compact
    .tside-vs {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  /* A row's short label in sight, its full one read in its place (ControlGroups.RowHtml). */
  :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls .ctl-card .ctl-short {
    display: inline;
  }

  /* Each row a line of its own, flowing like words: its label wraps where it must, and its keys follow
     its last word as one block, or go under it where they do not fit; so nothing spills out of the card,
     no label is squeezed to a letter's width, and the keys never split. */
  :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls .ctl-card dl {
    display: block;
  }

  :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls .ctl-card .ctl-row {
    display: block;
  }

  :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls .ctl-card dt {
    display: inline;
    overflow-wrap: break-word;
  }

  :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls .ctl-card dd {
    display: inline-block;
    max-width: 100%;
    margin-inline-start: 0.4em;
  }

  /* At big text the device's name is out of sight too (the names and the keys say whose card it is),
     and a game's minor rows; and the bots' chips are one chip ("3 bots": they are always ready). */
  :root:not([data-fit='wide'], [data-bp='xs'], [data-bp='s-land']) .tstep-controls .ctl-card h4 em,
  :root:not([data-fit='wide'], [data-bp='xs'], [data-bp='s-land'])
    .tstep-controls
    :is(.ctl-minor, .tchip.bot),
  :root:not([data-bp='xs'], [data-bp='s-land'])
    .tstep-controls
    :is(.ctl-more, .ctl-extra, .ctl-full) {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  /* The sides: side by side where the step is 30 lines of text wide or more (a 1080p TV at 200 %, a
     computer at 200 %), else one under the other (a tablet at 200 %): each a line of its own, its name
     beside its chips, which wrap. */
  @container tstep (min-width: 30em) {
    :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls .tsides.compact {
      flex-direction: row;
    }
  }

  :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls .tsides.compact .tside {
    flex: 1 1 0;
    min-width: 0;
    padding: 0.3em 0.6em;
  }

  :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls .tsides.compact .tside-name {
    margin: 0 0 0.2em;
  }

  /* One under the other: each side a line, its name beside its chips, and no "v" line between them
     (the names say it; screen readers keep it). */
  @container tstep (width < 30em) {
    :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls .tsides.compact {
      gap: 0.3em;
    }

    :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls .tsides.compact .tside {
      display: flex;
      flex-wrap: wrap;
      align-items: center;
      gap: 0.3em;
    }

    :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls .tsides.compact .tside-name {
      margin: 0;
      margin-inline-end: 0.3em;
    }

    :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls .tsides.compact .tchips {
      flex: 1 1 0;
      min-width: 0;
    }

    :root:not([data-bp='xs'], [data-bp='s-land']) .tstep-controls .tsides.compact .tside-vs {
      position: absolute;
      width: 1px;
      height: 1px;
      overflow: hidden;
      clip-path: inset(50%);
      white-space: nowrap;
    }
  }

  /* The standings on a TV or a computer (PR 5's reviews): the host's buttons pinned to the foot, on one
     row (not one each the width of the screen); and on a screen that is not tall for its text (by its
     height, not its width: 1366×768 at 150 % too) the table's rows tight, so 8 players and the
     buttons are all on screen, none under the bar, at 1080p, 1600×900, 1366×768, 1280×720 and
     1024×768 at every text size. */
  :root:not([data-bp='xs'], [data-bp='s-land']) .tourney-standings .tactions.thost {
    position: sticky;
    z-index: 1;
    inset-block-end: 0;
    /* At the foot even when the table is short (#748): never in the middle of the screen. */
    margin: auto -0.5em 0;
    padding: 0.4em 0.5em;
    background: var(--bg);
    box-shadow: 0 -0.6em 0.8em var(--bg);
  }

  :root:not([data-bp='xs'], [data-bp='s-land']) .tourney-standings .tactions .btn {
    flex: 0 1 auto;
  }

  :root:not([data-fit-y='tall'], [data-bp='xs'], [data-bp='s-land']) .tourney-standings {
    gap: 0.4em;
    padding-top: max(0.4em, var(--safe-top));
    padding-bottom: max(0.4em, var(--safe-bottom));
  }

  :root:not([data-fit-y='tall'], [data-bp='xs'], [data-bp='s-land']) .tourney-standings .tstand {
    font-size: max(var(--fs-small), 0.9em);
  }

  :root:not([data-fit-y='tall'], [data-bp='xs'], [data-bp='s-land'])
    .tourney-standings
    .tstand
    :is(th, td) {
    padding-block: 0.1em;
    line-height: calc(1 * var(--line-k));
  }

  :root:not([data-fit-y='tall'], [data-bp='xs'], [data-bp='s-land'])
    .tourney-standings
    .tstand
    .ttotal {
    font-size: 1em;
  }

  :root:not([data-fit-y='tall'], [data-bp='xs'], [data-bp='s-land'])
    .tourney-standings
    .tstand
    :is(.tbot, .tside-tag) {
    padding-block: 0;
    line-height: calc(1 * var(--line-k));
  }

  :root:not([data-fit-y='tall'], [data-bp='xs'], [data-bp='s-land'])
    .tourney-standings
    .tactions
    .btn {
    padding: 0.25em 0.9em;
  }
}

/* The place for the controls' clips (#749): nothing shows while it is empty, nor where the controls
   cards would not fit beside them (js/layout.ts fitClips). */
.tcontrols-clips:empty,
.tstep-controls:not([data-clips]) .tcontrols-clips {
  display: none;
}

/* The how-to clips for someone new to the game (#749): the practice arena, as tall as fits above the
   controls cards, and its line under it. */
.tcontrols-clips {
  display: grid;
  gap: 0.35em;
  justify-items: center;
}

.tcontrols-clips .tclips-arena {
  width: min(100%, 36em, (100vh - 22em) * 16 / 9);
  width: min(100%, 36em, (100dvh - 22em) * 16 / 9);
  min-width: min(100%, 14em);
  cursor: default;
}

.tcontrols-clips .practice-clip {
  margin: 0;
  max-width: 36em;
  text-align: center;
  color: var(--ui-text);
}

/* The controls step's width, for its sides (above). */
.tstep-controls {
  container: tstep / inline-size;
}

/* The how-to clips with too little room left to see them (#749): nothing shows. */
@container (max-height: 7em) {
  .tcontrols-clips > * {
    visibility: hidden;
  }
}

/* A clip squeezed under two lines of text tall shows nothing. */
@container (max-height: 2em) {
  .tstep-clip > * {
    visibility: hidden;
  }
}

.tpodium .names span {
  white-space: normal;
  overflow-wrap: anywhere;
}

/* "· Bot" breaks away from the name as a whole, never in the middle. */
.tpodium .names .tpod-bot {
  white-space: nowrap;
}

/* A shared place (#217): the step stays as wide as the others (never wider than 1st), its shapes
   wrap to a second row, and each name is a pill in its player's colour, one under another, so a
   name that wraps never runs into the next one. */
.tpodium .shared .who {
  flex-wrap: wrap;
  max-width: 100%;
}

.tpodium .shared .names {
  gap: 0.3em;
}

.tpodium .shared .names .tname {
  padding: 0.15em 0.6em;
  border-radius: 0.6em;
  border-inline-start: 0.25em solid var(--c);
  background: var(--c-16);
  text-align: center;
}

.twhy {
  margin: 0;
  color: var(--ui-dim);
  font-weight: 700;
}

/* ------------------------------------------------------------ picking the next game (#90 step 4) */

/* The setup's playlist: numbered chips in order, each takes its game out again. */
.tlist-box {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5em;
}

.tlist {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4em;
  margin: 0;
  padding: 0;
  list-style: none;
}

.chip.tlist-item b {
  margin-inline-end: 0.2em;
}

.chip.tlist-item.unfit {
  opacity: 0.55;
  border-style: dashed;
}

/* On the standings: the vote's cards, or the games the host may pick. */
.tpick {
  width: 100%;
  margin: 0.4em 0;
  display: flex;
  flex-direction: column;
  gap: 0.5em;
}

.tpick-title {
  margin: 0;
  font-size: 1.3em;
  font-weight: 900;
}

.tpick .hint {
  margin: 0;
}

.tvote {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 14em), 1fr));
  gap: 0.8em;
}

/* One card (A · Console, #413): the game's picture across its top with the pad button and key on
   it, then the name, its rules, the votes and the voters' badges. The card in the lead says so in
   words, has a light edge and a ★ in its corner: never yellow, which is for the one thing to do
   (#448 review), and never colour alone. */
.tvote-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.3em;
  min-width: 0;
  padding: 0.6em 0.8em 0.7em;
  overflow: hidden;
  border-radius: var(--r-l);
  border: 2px solid transparent;
  background: var(--ui-card);
  color: inherit;
  font: inherit;
  text-align: start;
  cursor: pointer;
}

.tvote-card.lead {
  border-color: var(--ui-text);
}

.tvote-card.lead::after {
  content: '★';
  position: absolute;
  inset-block-start: 0.35em;
  inset-inline-end: 0.5em;
  display: grid;
  place-items: center;
  width: 1.7em;
  height: 1.7em;
  border-radius: var(--r-pill);
  background: var(--ui-text);
  color: var(--bg);
  font-size: 1.1em;
  line-height: 1;
}

.high-contrast .tvote-card {
  border-color: var(--ui-line);
}

.high-contrast .tvote-card.lead {
  border-color: var(--ui-text);
}

.tvote-keys {
  display: flex;
  align-items: center;
  gap: 0.35em;
}

.tvote-keys .pb {
  font-size: 1.3em;
}

.tvote-art {
  align-self: stretch;
  margin: -0.6em -0.8em 0.2em;
  padding: 0.6em 0.8em 0.2em;
  background: var(--ui-raised);
}

.tvote-art img {
  display: block;
  width: 100%;
  height: auto;
  max-height: 18vh;
  object-fit: contain;
}

/* The pad button and key over the picture, at its start corner. */
:root[data-fit='wide'] .tvote-keys {
  position: absolute;
  inset-block-start: 0.5em;
  inset-inline-start: 0.6em;
  z-index: 1;
}

.tvote-name {
  font-size: 1.3em;
  font-weight: 900;
  overflow-wrap: anywhere;
}

.tvote-line {
  color: var(--ui-dim);
  font-size: max(var(--fs-small), 0.85em);
  font-weight: 700;
  overflow-wrap: anywhere;
}

/* A team game's split on its vote card and the host's pick ("Teams · 3 v 3 with a bot", #90 step 7):
   a tag in words (a rounded box: it may wrap at big text) (not colour alone) that wraps at big text; it stays when the rules line goes. */
.tteams-tag {
  align-self: flex-start;
  max-width: 100%;
  padding: 0.05em 0.55em;
  border: max(1px, 0.08em) solid currentColor;
  border-radius: 0.6em;
  font-size: max(var(--fs-small), 0.8em);
  font-weight: 800;
  overflow-wrap: anywhere;
}

.tgame-text .tteams-tag {
  opacity: 1;
}

.tvote-count {
  font-weight: 900;
  font-variant-numeric: tabular-nums;
}

.tvote-who {
  display: flex;
  flex-wrap: wrap;
  gap: 0.2em;
  min-height: 22px;
}

.tvote-who svg {
  display: block;
}

/* A voter: their shape on a dark disc ringed in their colour, as the room's badges (#405). */
.tbadge {
  display: grid;
  place-items: center;
  width: 1.6em;
  height: 1.6em;
  border-radius: 50%;
  background: var(--bg);
  box-shadow: inset 0 0 0 max(2px, 0.12em) var(--c);
}

.tbadge svg {
  width: 0.95em;
  height: 0.95em;
}

/* The host's choices are buttons, never "off": full strength (a chip's aria-pressed=false dims it). */
.tpicks .chip.tpickgame {
  border-width: 2px;
  opacity: 1;
}

.tpicked,
.ttarget {
  margin: 0.2em 0 0;
  font-weight: 800;
}

.tpicked {
  color: var(--ui-dim);
}

/* Between games on a TV or a laptop (#273, #413): the next game's vote beside the standings, so the
   vote, every row and the host's buttons are on one screen (a gamepad cannot scroll there). The vote
   cards stand one under another, the picture at the start and the words beside it; at 150 % the
   picture and the rules go, the name and the votes stay. 200 % keeps one column. */
@media (orientation: landscape) and (min-width: 1200px) {
  :root:is([data-fit='wide'], [data-fit='medium'])
    .tourney-standings:has(> .tvote-box + .tstand-box) {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr);
    column-gap: 2em;
    align-items: start;
    max-width: 80em;
  }

  :root:is([data-fit='wide'], [data-fit='medium'])
    .tourney-standings:has(> .tvote-box + .tstand-box)
    > * {
    grid-column: 1 / -1;
  }

  :root .tourney-standings > .tvote-box:has(+ .tstand-box) {
    margin: 0;
    padding: 0;
    background: none;
  }

  :root:is([data-fit='wide'], [data-fit='medium'])
    .tourney-standings:has(> .tvote-box + .tstand-box)
    > .tvote-box {
    grid-column: 1;
  }

  /* 150 % and 200 %: how to vote goes, as each card shows its button (and says it, for a screen
     reader); that you can change your vote and how a tie goes stay. */
  :root:not([data-fit='wide'])
    .tourney-standings
    > .tvote-box:has(+ .tstand-box)
    > .hint
    .tvote-how {
    display: none;
  }

  :root:is([data-fit='wide'], [data-fit='medium']) .tourney-standings > .tvote-box + .tstand-box {
    grid-column: 2;
  }

  :root:is([data-fit='wide'], [data-fit='medium']) .tvote-box:has(+ .tstand-box) .tvote {
    grid-template-columns: minmax(0, 1fr);
    gap: 0.5em;
  }

  /* A card a row: its picture small at the start, the button, the name, then the votes and voters
     (wrapping under it when the name is long). The rules are on the game's intro card. */
  :root .tvote-box:has(+ .tstand-box) .tvote-card {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    column-gap: 0.7em;
    row-gap: 0.2em;
    padding-block: 0.45em;
  }

  :root[data-fit='wide'] .tvote-box:has(+ .tstand-box) .tvote-art {
    order: -1;
    flex: 0 0 5.5em;
    align-self: stretch;
    display: grid;
    place-items: center;
    margin-block: -0.45em;
    margin-inline: -0.8em 0;
    padding: 0.25em;
  }

  :root[data-fit='wide'] .tvote-box:has(+ .tstand-box) .tvote-art img {
    max-height: 3.6em;
  }

  :root .tvote-box:has(+ .tstand-box) .tvote-keys {
    position: static;
  }

  :root .tvote-box:has(+ .tstand-box) .tvote-line {
    display: none;
  }

  :root .tvote-box:has(+ .tstand-box) .tvote-count {
    margin-inline-start: auto;
  }

  :root .tvote-box:has(+ .tstand-box) .tvote-card.lead .tvote-count {
    margin-inline-end: 2em;
  }

  :root .tvote-box:has(+ .tstand-box) .tvote-who {
    min-height: 0;
  }

  :root .tvote-box:has(+ .tstand-box) .tvote-who:empty {
    display: none;
  }

  :root .tvote-box:has(+ .tstand-box) .tvote-card.lead::after {
    inset-block-start: 50%;
    translate: 0 -50%;
  }

  /* 150 %: the table has the larger share, a touch smaller, so a name and its "Bot" stay on one line. */
  :root[data-fit='medium'] .tourney-standings:has(> .tvote-box + .tstand-box) {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.8fr);
    column-gap: 1.2em;
  }

  :root[data-fit='medium'] .tourney-standings > .tvote-box + .tstand-box .pg-table.tstand {
    font-size: 0.95em;
  }

  /* The bars say the totals again: beside the vote the names have their room instead. */
  :root:is([data-fit='wide'], [data-fit='medium'])
    .tourney-standings:has(> .tvote-box + .tstand-box)
    .tbar-col {
    display: none;
  }
}

/* 200 % between games: one column (beside each other, names and votes wrap and the rows still run
   off; #475 keeps that limit). The vote compact, its cards in a row with their button, name and
   votes (the rules are on the intro card), so the vote and the host's buttons are in the first
   screen; the table follows it under the pinned buttons. */
@media (orientation: landscape) and (min-width: 1200px) {
  :root[data-fit='narrow'] .tourney-standings > .tvote-box:has(+ .tstand-box) .tvote {
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 9em), 1fr));
  }
}

/* Big text: the vote's pictures go first (names, rules and votes stay). */
:root:not([data-fit='wide']) .tvote-art {
  display: none;
}

/* The intro card over a tournament's waiting room (#90 step 3): the whole page, as it is between
   games, so the paused game and its HUD are not read through it. :where keeps the page's
   background first. The seat toast waits, as over another screen's lobby. */
.pg-overlay > .screen.tourney {
  isolation: isolate;
  align-self: stretch;
  justify-self: stretch;
  overflow-y: auto;
  max-height: 100%;
  max-width: none;
  padding-inline: max(2em, calc((100% - 60em) / 2));
}

.pg-overlay > :where(.screen.tourney) {
  background: var(--bg);
}

html:has(#lobby:not(.hidden) .tourney) #toast {
  visibility: hidden;
}

/* Nothing of the match over the card (#335): its round pill, banner, hints and coach line have
   layers of their own above the overlay, so while the card covers the waiting room every part of
   the HUD but its overlays waits (as under the results, #412), and the world's labels too. What
   the match says about its link ("Reconnecting…", "Lost the connection…") stays over the card. */
html:has(#lobby:not(.hidden) > .tourney) .pg-hud > :not(.pg-overlay, :has(.pg-overlay), .reconnect),
html:has(#lobby:not(.hidden) > .tourney) #labels {
  visibility: hidden;
}

/* The room's code, small: a friend who has to join again finds it here (#90 step 3). */
.troom {
  margin: 0;
  color: var(--ui-dim);
  font-size: var(--fs-small);
}

/* Another screen's own players (#251): "You", in words, on the chip and in the table. */
.tyou {
  padding: 0 0.45em;
  border-radius: 0.5em;
  background: var(--ui-text);
  color: var(--ui);
  font-size: var(--fs-small);
  font-weight: 800;
}
