/* The results celebration and the pause menu extras (#72 should 14 and 19; Game/Results.cs,
   Game/PauseModel.cs): confetti in the winner's colour, a podium, "Play again ✓" votes, buttons
   locked for 2 s, the pause menu's pages and the hold-to-confirm Quit. Reduced motion: a few
   pieces that fade in place, no bounce. Uses app.css's variables. */

/* ------------------------------------------------------------ confetti */

.confetti {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}

/* Sized from the screen's base size, not the text size: 200 % text does not double them. */
.confetti i {
  position: absolute;
  top: -4vh;
  inset-inline-start: var(--x);
  width: calc(var(--fs-base) * 0.5 * var(--s));
  height: calc(var(--fs-base) * 0.95 * var(--s));
  border-radius: calc(var(--fs-base) * 0.12);
  background: var(--c);
  opacity: 0;
  animation: confetti-fall var(--t) cubic-bezier(0.3, 0.1, 0.6, 1) var(--d) 1 forwards;
}

.confetti i:nth-child(3n) {
  border-radius: 50%;
  height: calc(var(--fs-base) * 0.5 * var(--s));
}

@keyframes confetti-fall {
  0% {
    opacity: 1;
    transform: translate(0, 0) rotate(0deg);
  }
  85% {
    opacity: 1;
  }
  100% {
    opacity: 0;
    transform: translate(var(--dx), 108vh) rotate(var(--r));
  }
}

/* Calm: 14 pieces drift a little and fade, no spin. */
.reduced-motion .confetti i:nth-child(n + 15) {
  display: none;
}

.reduced-motion .confetti i {
  top: calc(4vh + var(--s) * 18vh);
  animation: confetti-calm 3.2s ease-out var(--d) 1 forwards;
}

@keyframes confetti-calm {
  0% {
    opacity: 0;
    transform: translateY(0);
  }
  25% {
    opacity: 0.9;
  }
  100% {
    opacity: 0;
    transform: translateY(3vh);
  }
}

/* ------------------------------------------------------------ results dialog and podium */

/* A · Console (plan 2.6, #412): the board stays in sight behind a dark fade, and the results are no
   box of their own. The winner's line in the display size, the podium as three dark blocks, the
   table as dark rounded rows, one yellow Play again at the foot. Only the results: this overlay
   also holds Siegeometry's perk draft and its solo results, which keep their boxes. */
.pg-overlay:has(> .pg-dialog.results) {
  /* One row as tall as the overlay: the dialog fills it and scrolls inside, never taller. */
  grid-template-rows: minmax(0, 1fr);
  background: none;
}

/* The fade is a layer of its own under the confetti and the dialog, so it fades in by its opacity
   (a gradient cannot fade by its colour, as the pause menu's dim does), and the dialog never
   becomes a layer under something else while it does. */
.pg-overlay:has(> .pg-dialog.results)::before {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--fade-board);
  pointer-events: none;
  animation: pg-fade 0.25s ease-out;
}

.high-contrast .pg-overlay:has(> .pg-dialog.results)::before {
  background: var(--bg);
}

.reduced-motion .pg-overlay:has(> .pg-dialog.results)::before {
  animation: none;
}

/* The board stays in sight, not the match's words: the cards, the pill, Pause, the hints and the
   labels in the world (Siegeometry's numbers, "You") fade out under the results, so none of them
   reads through the winner's line or the rows. Only faded: specs and screen readers still find
   them, and a press cannot land on one. */
.pg-hud:has(#pg-results:not(.hidden) > .pg-dialog.results) > :not(.pg-overlay, :has(.pg-overlay)),
html:has(#pg-results:not(.hidden) > .pg-dialog.results) #labels {
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--t-move);
}

/* The whole height (inside the safe area), a column: what it has is in the middle, the buttons at
   the foot; taller than that, it scrolls under them (#226). Its width is a container, so the
   winner's line knows how wide it may be (100cqi). Above app.css's dialog at big text (data-fit
   narrow: a solid box, 94vw), which it is not. */
.pg-overlay > .pg-dialog.results {
  position: relative;
  display: flex;
  flex-direction: column;
  align-self: stretch;
  box-sizing: border-box;
  width: min(100%, 64rem);
  min-width: 0;
  max-width: none;
  max-height: none;
  overflow-y: auto;
  background: none;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  container-type: inline-size;
}

/* A bigger screen leaves the safe area clear (5 % on a TV), and a little more. Phones have theirs
   in hud-layout.css (the overlay's padding). */
@media (min-width: 600px), (orientation: landscape) {
  @media (min-height: 500px), (orientation: portrait) {
    .pg-overlay:has(> .pg-dialog.results) {
      padding-block: max(2vh, var(--safe-top)) max(2vh, var(--safe-bottom));
      padding-inline: max(2vw, var(--safe-start)) max(2vw, var(--safe-end));
    }
  }
}

/* "Brave Sphere wins!" in the display size (3.2), fitted to the dialog's width: C# writes the
   line's letters (--display-len), so it keeps to one line where there is room; a narrow screen at
   big text breaks it between words, and one long name inside it, never past the edge. Its cap is
   two thirds of Home's title (5.4 × the base there): the podium and the rows keep their room. */
/* Nothing in the column gives way: taller than the dialog, the dialog scrolls (not the table's
   own box, which would hide its rows under the buttons). */
.pg-overlay > .pg-dialog.results > * {
  flex-shrink: 0;
}

.pg-overlay > .pg-dialog.results .results-title {
  --display-box: 100cqi;
  margin: auto 0 0;
  font-size: max(
    1.2rem,
    min(calc(var(--fs-base) * 3.6), calc(var(--display-box) / (var(--display-len) * 0.62)))
  );
  font-weight: 1000;
  overflow-wrap: anywhere;
}

.results-title {
  animation: results-pop 0.5s cubic-bezier(0.2, 1.4, 0.4, 1) both;
}

:root:lang(ar) .pg-overlay > .pg-dialog.results .results-title {
  font-weight: 800;
}

/* The game's "why" line under it, a step smaller than the body (never under --fs-small), so even
   where the winner's line is at its floor (200 % on a phone) it reads as the bigger one. */
.pg-dialog.results > .pg-why {
  margin: 0.5em 0 0;
  font-size: max(var(--fs-small), 0.85rem);
}

@keyframes results-pop {
  from {
    transform: scale(0.6);
    opacity: 0;
  }
}

/* The podium: each step a dark block with the place, the shapes standing on it, the names under
   them; the top step's shapes the biggest, each block's edge in its first shape's colour. */
.podium {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  gap: 0.6em;
  margin: 1em auto 1.2em;
  /* A width of its own: sized to its content, a shared top step shrank to its narrowest name. */
  width: 100%;
  max-width: 30em;
}

.podium .step {
  display: flex;
  flex-direction: column;
  align-items: center;
  flex: 0 1 9em;
  min-width: 0;
}

.podium .step.empty {
  visibility: hidden;
}

/* Players sharing a step wrap. */
.podium .who {
  display: flex;
  flex-wrap: wrap;
  gap: 0.15em;
  justify-content: center;
  max-width: 100%;
}

.podium .shape {
  display: block;
  filter: drop-shadow(0 0.2em 0.25em var(--shadow));
  animation: podium-in 0.5s cubic-bezier(0.2, 1.5, 0.4, 1) both;
}

.podium .shape svg {
  display: block;
  width: min(calc(var(--fs-base) * 2.6), 14cqi);
  height: min(calc(var(--fs-base) * 2.6), 14cqi);
}

/* The winner big (three or four sharing the top step: as big as the others), never wider than
   its step (a third of the dialog, cqi). The shapes follow the screen's base size, not the text
   size, so they do not balloon at 200 % (3.2). */
.podium .s1 .shape svg {
  width: min(calc(var(--fs-base) * 3.8), 20cqi);
  height: min(calc(var(--fs-base) * 3.8), 20cqi);
}

.podium .s1 .who:has(> :nth-child(3)) svg {
  width: min(calc(var(--fs-base) * 2.6), 7cqi);
  height: min(calc(var(--fs-base) * 2.6), 7cqi);
}

.podium .s3 .shape {
  animation-delay: 0.15s;
}

.podium .s2 .shape {
  animation-delay: 0.3s;
}

.podium .s1 .shape {
  animation:
    podium-in 0.55s cubic-bezier(0.2, 1.5, 0.4, 1) 0.5s both,
    podium-hop 1.1s ease-in-out 1.2s 3;
}

@keyframes podium-in {
  from {
    transform: translateY(-1.5em) scale(0.4);
    opacity: 0;
  }
}

@keyframes podium-hop {
  50% {
    transform: translateY(-0.35em);
  }
}

.podium .names {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin: 0.3em 0 0.4em;
  font-weight: 900;
  line-height: calc(1.15 * var(--line-k));
  max-width: 100%;
}

/* Cut sideways only (clip, not hidden): a tall letter (an accent, Arabic) draws whole above and
   below its line (#84). A clipped box sizes to its text unless told otherwise (hidden did not):
   min-width 0 lets it give way. Safari 15 has no clip: hidden there, the "…" kept. */
.podium .names span {
  min-width: 0;
  max-width: 100%;
  overflow-x: clip;
  text-overflow: ellipsis;
  white-space: nowrap;
}

@supports not (overflow-x: clip) {
  .podium .names span {
    overflow: hidden;
  }
}

.podium .block {
  box-sizing: border-box;
  width: 100%;
  display: grid;
  place-items: center;
  border-radius: var(--r-m) var(--r-m) 0 0;
  border-block-start: max(3px, 0.12em) solid var(--c);
  background: var(--ui-card);
  font-size: var(--fs-score);
  font-weight: 900;
  font-variant-numeric: tabular-nums;
}

.high-contrast .podium .block {
  border: 2px solid var(--ui-text);
  border-block-end: 0;
}

.podium .s1 .block {
  height: 2.6em;
}

.podium .s2 .block {
  height: 1.8em;
}

.podium .s3 .block {
  height: 1.2em;
}

/* A team match's podium (#788): each step says its team's name where a place number would be. */
.podium.teams .block .team-name {
  padding-inline: 0.3em;
  font-size: max(var(--fs-small), 0.42em);
  font-variant-numeric: normal;
  line-height: 1.1;
  text-align: center;
  overflow-wrap: anywhere;
}

/* The buttons' wrapper adds no box, so the button row sticks to the dialog. */
#results-actions {
  display: contents;
}

/* The buttons at the foot: below what the results have, or pinned there while the podium and the
   table scroll under them (8 rows at 720p, or big text, are taller than the screen, #226). The
   dialog's bottom padding moves into the row, so the row ends where the dialog does. Phones (xs,
   s-land) have their own sticky row in hud-layout.css; these two queries are everything else. */
.pg-dialog.results .pg-actions {
  margin-top: auto;
}

@media (min-width: 600px), (orientation: landscape) {
  @media (min-height: 500px), (orientation: portrait) {
    .pg-dialog.results {
      padding-bottom: 0;
    }

    .pg-dialog.results .pg-actions {
      position: sticky;
      bottom: 0;
      z-index: 2;
      padding: 0.9em 0 1.4em;
      /* Dark under the buttons, fading out at the sides and, by the mask, over the top of its
         padding (the buttons start below it): rows that scroll under them go dark, and the row has
         no hard edges over the board. */
      background: linear-gradient(90deg, transparent, var(--bg) 6%, var(--bg) 94%, transparent);
      -webkit-mask-image: linear-gradient(transparent, #000 0.8em);
    }

    /* The lock bar just under the buttons, not at the dialog's edge. */
    .pg-dialog.results .pg-actions.locked::after {
      bottom: 0.7em;
    }

    /* app.css gives a narrow dialog all-round padding (big text): the bottom stays 0 here too,
       or rows would show in the strip under the buttons. */
    :root[data-fit='narrow'] .pg-dialog.results {
      padding-bottom: 0;
    }

    :root[data-fit='narrow'] .pg-dialog.results .pg-actions {
      padding-bottom: 1em;
    }

    :root[data-fit='narrow'] .pg-dialog.results .pg-actions.locked::after {
      bottom: 0.4em;
    }
  }
}

/* A phone upright at big text (data-fit-y short, layout.ts): pinned buttons would cover most of
   the screen (three of them, each two lines, at 200 % on a 320×568 phone), so they follow the
   table instead; the winner's line shows first, and the focus does not scroll to them. */
@media (max-width: 599.98px) and (orientation: portrait) {
  /* A screen that waits has one short bar there (or its "Leave the room?"), not three buttons:
     that stays pinned, so who it waits for is in sight at big text (#854). */
  :root[data-fit-y='short']
    .pg-dialog.results
    .pg-actions:not(:has(> .results-wait), .results-ask) {
    position: static;
    box-shadow: none;
  }

  /* The pinned bar ends where the dialog does: big text gives a narrow dialog all-round padding
     (narrow.css), and a table row showed in that strip under the bar. */
  :root[data-fit='narrow'] .pg-dialog.results:has(.results-wait, .results-ask) {
    padding-bottom: 0;
  }
}

/* But not on a small phone (320×568 at 200 %): there the bar alone took half the screen and the
   question hid the winner's line, so they follow the table too, as the three buttons do (#226;
   decided by the orchestrator, 2026-11-11). The question scrolls into view when it is asked. */
@media (max-width: 599.98px) and (orientation: portrait) and (max-height: 699.98px) {
  :root[data-fit-y='short'] .pg-dialog.results .pg-actions {
    position: static;
    box-shadow: none;
  }
}

/* A TV or a laptop (wide at this text size, landscape, not a phone on its side): the podium beside
   the table under the winner's line, so eight rows fit with the buttons and none hides under them
   (a gamepad cannot scroll). The column again at big text (data-fit medium or narrow). */
@media (orientation: landscape) and (min-width: 1200px) and (min-height: 501px) {
  :root[data-fit='wide'] .pg-overlay > .pg-dialog.results {
    display: grid;
    grid-template-columns: minmax(0, 26em) minmax(0, 1fr);
    /* What it has in the middle (the 1fr rows around it), the buttons at the foot. */
    grid-template-rows: 1fr auto auto auto auto 1fr auto;
    column-gap: 1.5em;
    width: min(100%, 76rem);
  }

  :root[data-fit='wide'] .pg-dialog.results > *,
  :root[data-fit='wide'] .pg-dialog.results .pg-actions {
    grid-column: 1 / -1;
  }

  :root[data-fit='wide'] .pg-dialog.results .results-title {
    grid-row: 2;
    margin: 0;
  }

  :root[data-fit='wide'] .pg-dialog.results .pg-why {
    grid-row: 3;
  }

  /* Centred by auto margins, not align-self: taller than their row, they start at its top (where
     the dialog scrolls from) instead of running above it. */
  :root[data-fit='wide'] .pg-dialog.results :is(.podium, .results-table) {
    grid-row: 4;
    margin-block: auto;
    padding-block-start: 0.6em;
  }

  :root[data-fit='wide'] .pg-dialog.results .podium {
    grid-column: 1;
    margin-inline: 0;
  }

  /* Its last row clear of the button row's shadow; its end strips narrow, so a TV's eight names
     stay on one line each. */
  :root[data-fit='wide'] .pg-dialog.results .results-table {
    grid-column: 2;
    padding-block: 0.3em 0.4em;
    --edge: 0.75em;
  }

  :root[data-fit='wide'] .pg-dialog.results .votes {
    grid-row: 5;
  }

  :root[data-fit='wide'] .pg-dialog.results .pg-actions {
    grid-row: 7;
    margin: 0;
  }
}

/* The same screens at big text (data-fit medium or narrow): the column, as side by side made the
   table too narrow (#412). The podium was 430–600 px tall there, so on a 1080p TV at 150 % and
   200 % the table's rows started under the buttons (none in Arabic) and a gamepad cannot scroll
   to them (#475). There the podium is compact: smaller shapes and names, the place in the body size
   on lower blocks, less room around it; the winner's line a step smaller; the buttons on one row.
   The winner, the podium and the table's first rows show above the buttons. That step stays a
   display size: --fs-base is the screen's (28 px on a 1080p TV), not the 200 % body text (56 px),
   so 2.4 × it made the winner's line only 1.2 × the rows' words; 3.1 × keeps it over 1.5 × (#664). */
@media (orientation: landscape) and (min-width: 1200px) and (min-height: 501px) {
  :root:not([data-fit='wide']) .pg-overlay > .pg-dialog.results .results-title {
    font-size: max(
      1.2rem,
      min(calc(var(--fs-base) * 3.1), calc(var(--display-box) / (var(--display-len) * 0.62)))
    );
  }

  :root:not([data-fit='wide']) .pg-dialog.results .podium {
    margin-block: 0.4em 0.5em;
  }

  :root:not([data-fit='wide']) .pg-dialog.results .podium .shape svg {
    width: calc(var(--fs-base) * 1.9);
    height: calc(var(--fs-base) * 1.9);
  }

  :root:not([data-fit='wide']) .pg-dialog.results .podium .s1 .shape svg {
    width: calc(var(--fs-base) * 2.6);
    height: calc(var(--fs-base) * 2.6);
  }

  :root:not([data-fit='wide']) .pg-dialog.results .podium .s1 .who:has(> :nth-child(3)) svg {
    width: calc(var(--fs-base) * 1.6);
    height: calc(var(--fs-base) * 1.6);
  }

  :root:not([data-fit='wide']) .pg-dialog.results .podium .names {
    margin-block: 0.15em 0.25em;
    font-size: max(var(--fs-small), 0.8em);
  }

  :root:not([data-fit='wide']) .pg-dialog.results .podium .block {
    font-size: var(--fs-base);
  }

  :root:not([data-fit='wide']) .pg-dialog.results .podium .s1 .block {
    height: 1.9em;
  }

  :root:not([data-fit='wide']) .pg-dialog.results .podium .s2 .block {
    height: 1.4em;
  }

  :root:not([data-fit='wide']) .pg-dialog.results .podium .s3 .block {
    height: 1em;
  }

  /* The buttons on one row (four at 200 % took two, 400 px): their words a step smaller, less room
     inside them and around. */
  :root:not([data-fit='wide']) .pg-dialog.results .pg-actions {
    gap: 0.4em;
    padding-top: 0.5em;
  }

  :root:not([data-fit='wide']) .pg-dialog.results .pg-actions .btn {
    padding: 0.35em 0.55em;
    font-size: 0.9em;
  }
}

/* Each game's table keeps its columns; its rows are dark and rounded, as the match's cards.
   Whole words may make a table wider than a narrow screen (eight columns on a phone upright, #396):
   it scrolls sideways in its own box then, and the page never does. Positioned, so anything
   absolute in it (.sr-only) scrolls with it, not past the screen's edge. */
.results-table {
  position: relative;
  display: flex;
  overflow-x: auto;
  width: 100%;
  max-width: 52em;
  margin-inline: auto;
  /* More to see (#396): the box's end edge fades what is under it. A table that fits leaves that
     strip empty (the spacers below), so nothing shows; one that goes on fades out there. The strip
     is narrower on a phone, where every pixel of the table counts. */
  --edge: 1.5em;
  -webkit-mask-image: linear-gradient(var(--fade-dir), #000 calc(100% - var(--edge)), transparent);
}

@media (max-width: 599.98px) {
  .results-table {
    --edge: 1em;
  }
}

.results-table .pg-table {
  flex: 0 0 auto;
  width: calc(100% - 2 * var(--edge));
  border-collapse: separate;
  border-spacing: 0 0.3em;
  margin: 0 0 0.4em;
}

/* A strip at each end: the table that fits sits in the middle, clear of the fade; moved all the
   way along, its last column clears it too. */
.results-table::before,
.results-table::after {
  content: '';
  flex: 0 0 var(--edge);
}

.results-table .pg-table th {
  padding-block: 0 0.1em;
}

.results-table .pg-table td {
  padding-block: 0.45em;
  border-top: 0;
  background: var(--ui-card);
}

.results-table .pg-table td:first-child {
  border-start-start-radius: var(--r-m);
  border-end-start-radius: var(--r-m);
}

.results-table .pg-table td:last-child {
  border-start-end-radius: var(--r-m);
  border-end-end-radius: var(--r-m);
}

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

/* "Play again? Ⓐ" with each gamepad player's tick. */
.votes {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 0.4em 0.6em;
  min-height: 0;
}

.votes:empty {
  display: none;
}

.votes .pg-why {
  margin: 0.3em 0 0;
}

.votes-label {
  color: var(--ui-dim);
  font-weight: 800;
}

.vote {
  display: inline-flex;
  align-items: center;
  gap: 0.3em;
  padding: 0.2em 0.6em;
  border-radius: 0.7em;
  border: 2px solid var(--ui-line);
  font-weight: 800;
}

.vote.on {
  border-color: var(--c);
  background: var(--c-16);
}

.vote b {
  min-width: 1em;
  text-align: center;
}

.vote.on b {
  color: var(--c);
}

.votes-count {
  color: var(--ui-dim);
  font-variant-numeric: tabular-nums;
}

/* A screen that did not make the match (#854). Where the host's Play again is, a grey bar names
   who this screen waits for ("Waiting for Ana to pick"): the size of a button, but not one, so
   nothing is there to press. It holds the focus (with no ring), so arrows and Tab start in the dialog. */
.pg-actions > .results-wait {
  margin: 0;
  padding: 0.6em 1.3em;
  border: 2px solid transparent;
  border-radius: var(--r-pill);
  background: var(--ui-quiet);
  color: var(--ui-dim);
  font-weight: 800;
}

.high-contrast .pg-actions > .results-wait {
  border-color: var(--ui-dim);
  color: var(--ui-text);
}

/* Its Leave: quiet, in the dialog's top corner at the start side, out of the buttons' row (the
   first row of the wide layout's grid, the column's first line). It asks once. */
.pg-dialog.results > .results-leave {
  align-self: flex-start;
  justify-self: start;
  /* Clear of the winner's line where the column is tight (a phone at 200 %). */
  margin: 0 0 0.4em;
  color: var(--ui-dim);
}

/* The bar holds the focus, so arrows and Tab start in the dialog; but it is no button, and no ring
   says "press me". */
.pg-actions > .results-wait:focus {
  outline: none;
}

/* The match's code chip sits in the corner that Leave has: under these results it goes (a screen
   that joined needs no code to join by). */
:root:has(.pg-overlay:not(.hidden) > .pg-dialog.results > .results-leave) .code-chip {
  visibility: hidden;
}

/* "Leave the room?" over Stay and Leave, in the buttons' place. */
.pg-actions > .results-ask-q {
  flex-basis: 100%;
  margin: 0;
  font-weight: 800;
  text-align: center;
}

/* Locked for 2 s (4 s with Timers Long, none with Off): a bar fills under the buttons, then they wake up. */
/* Low weight: on phones hud-layout.css keeps the buttons sticky at the bottom (also positioned). */
:where(.pg-actions.locked) {
  position: relative;
  padding-bottom: 0.5em;
}

.pg-actions.locked::after {
  content: '';
  position: absolute;
  inset-inline-start: 20%;
  inset-inline-end: 20%;
  bottom: 0;
  height: 0.22em;
  border-radius: 0.2em;
  background: var(--ui-text);
  opacity: 0.5;
  /* It fills from where a line starts: the left, the right in right to left (below). */
  transform-origin: 0 50%;
  animation: results-lock var(--lock, 2s) linear both; /* --lock: the Timers setting */
}

@keyframes results-lock {
  from {
    transform: scaleX(0);
  }
}

.reduced-motion .results-title,
.reduced-motion .podium .shape {
  animation: none;
}

.reduced-motion .pg-actions.locked::after {
  animation-timing-function: steps(4);
}

/* ------------------------------------------------------------ pause menu */

/* Nearly opaque: the menu's text must not mix with the board behind it. */
.pg-dialog.pause {
  background: var(--bg);
}

.high-contrast .pg-dialog.pause {
  background: var(--ui);
}

.pg-dialog.pause {
  max-width: min(90vw, 56em);
}

/* The pause menu and the results over all of the match's HUD (#391): paused, the hint bar sits
   above the dim so it can be read (hints.css), and on a phone the coach line and the banners have
   a layer of their own (coach.css), so at big text they drew over the menu's buttons. The overlay
   makes no layer, so its dim stays under them; the dialog itself is above them all. The overlay
   fades in by its dim, not by its opacity: while an element's opacity runs it is a layer of its
   own, and the hint bar would be over the dialog for that moment. */
.pg-overlay > .pg-dialog {
  position: relative;
  z-index: 7;
}

.pg-overlay {
  animation-name: pg-dim-in;
}

/* The pause dialog fades in too: it stays put (only its body is drawn again). Not the overlays
   whose contents are drawn again while they show (the waiting room and the tournament's card in
   #lobby, Siegeometry's perk draft in #pg-results): a fade there would play at every redraw, and
   the paused game would blink through (#508 review). */
#pg-pause > .pg-dialog {
  animation: pg-fade 0.25s ease-out;
}

@keyframes pg-dim-in {
  from {
    background-color: transparent;
  }
}

.reduced-motion #pg-pause > .pg-dialog {
  animation: none;
}

/* What the match says about itself stays over the pause menu: a toast, and "Lost the connection…"
   (a paused online match whose Wi-Fi went; #508 review). Both sit beside the HUD and the pause
   overlay in the match's page (Game/HudCommon.cs). */
:root :is(.toast, .reconnect) {
  z-index: 8;
}

/* Low weight (:where): hud-layout.css fits it into a phone's safe area instead. */
:where(.pg-dialog.pause) {
  max-height: 94vh;
  overflow-y: auto;
}

.pause-by {
  margin: 0.1em 0 0.4em;
}

/* Phones only (hud-layout.css): a bigger screen has the chip. */
.pause-code {
  margin: 0.1em 0 0.4em;
}

.pause-code b {
  letter-spacing: 0.15em;
}

.pause-menu {
  display: grid;
  /* Controls, How to play, Settings, Test controllers: two by two. */
  grid-template-columns: repeat(2, minmax(8em, 1fr));
  gap: 0.6em;
  margin-top: 0.9em;
}

/* Resume, Full screen (#87, where the browser has it) and Use as a controller (a phone playing
   as its own screen) after the four pages, take a whole row: no button is left alone in a row. */
.pause-menu .btn.primary,
.pause-menu .fs-btn,
.pause-menu [data-act='to-controller'] {
  grid-column: 1 / -1;
}

/* Big enough to tap (#72: at least 44 px). */
.pause-menu .btn,
.pause-quit .btn,
.pg-dialog.pause .pg-actions .btn {
  min-height: 44px;
}

.pause-quit {
  border-top: 1px solid var(--ui-line);
  padding-top: 0.9em;
}

.pause-sub {
  margin: 0.4em 0 0.6em;
  font-size: 1.2em;
  font-weight: 900;
}

.pause-controls {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16em), 1fr));
  gap: 0.7em;
  text-align: start;
}

/* A player's controls: a dark card (A · Console, #415) with their colour down its start side;
   high contrast: the white edge. */
.ctl-card {
  padding: 0.7em 0.9em;
  border-radius: var(--r-m);
  border: 2px solid transparent;
  border-inline-start: 0.3em solid var(--c);
  background: var(--ui-card);
}

.high-contrast .ctl-card {
  border-color: var(--ui-text);
  border-inline-start-color: var(--c);
}

.ctl-card h4 {
  display: flex;
  align-items: center;
  gap: 0.4em;
  margin: 0 0 0.4em;
  font-size: 1em;
  font-weight: 900;
}

.ctl-card h4 em {
  margin-inline-start: auto;
  font-style: normal;
  font-size: max(var(--fs-small), 0.8em);
  color: var(--ui-dim);
}

.ctl-card dl {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.25em 0.8em;
  margin: 0;
}

.ctl-card dt {
  color: var(--ui-dim);
}

.ctl-card dd {
  margin: 0;
}

.ctl-card kbd,
.ctl-card .pb {
  margin-inline-end: 0.15em;
}

.pause-help {
  max-height: 52vh;
  overflow-y: auto;
  text-align: start;
  padding-inline-end: 0.4em;
}

/* How to play in the pause menu (#791): the rules take the height the dialog has left (a smaller
   "Paused" over them), so a game's first step shows whole at 720p; the dialog is a column the box
   fills. */
.pg-dialog.pause:has(.pause-help) {
  display: flex;
  flex-direction: column;
}

.pg-dialog.pause:has(.pause-help) > h2 {
  margin-block: 0;
  font-size: 1.4em;
}

.pg-dialog.pause > #pause-body:has(> .pause-help) {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
}

#pause-body > .pause-help {
  flex: 1 1 auto;
  min-height: 8em;
  max-height: none;
}

/* While there is more under its edge (js/ui.ts): the box fades there and "More below" shows; at
   the end both go. */
.pause-help.more-below {
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 3em), transparent);
}

.pause-more {
  margin: 0.3em 0 0;
  color: var(--ui-dim);
  font-size: max(var(--fs-small), 0.85em);
  font-weight: 700;
  visibility: hidden;
}

.pause-help.more-below + .pause-more {
  visibility: visible;
}

.pause-settings {
  text-align: start;
}

.pause-settings .row > .label {
  min-width: 7em;
}

.pause-settings .ctl {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4em;
}

.pause-settings .count {
  min-width: 3.2em;
}

/* Quiet pills, white when picked, as on Settings (A · Console, #415). */
.pause-settings .chip:not([aria-pressed='true']) {
  border-color: transparent;
  background: var(--ui-raised);
}

.high-contrast .pause-settings .chip:not([aria-pressed='true']) {
  border-color: var(--ui-text);
}

/* The button that leaves (Quit): held, its fill grows with --hold (0…1, set by C#); let go sooner, it asks. */
.btn.hold {
  position: relative;
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  touch-action: none;
  user-select: none;
}

.btn.hold .hold-fill {
  position: absolute;
  inset: 0;
  background: var(--warn);
  opacity: 0.55;
  transform: scaleX(var(--hold, 0));
  transform-origin: 0 50%;
}

/* Right to left, both bars fill from the right (#84). */
:root[dir='rtl'] .pg-actions.locked::after,
:root[dir='rtl'] .btn.hold .hold-fill {
  transform-origin: 100% 50%;
}

.btn.hold .hold-text {
  position: relative;
}

/* ------------------------------------------------------------ small screens */

@media (max-width: 600px), (max-height: 500px) {
  .podium .step {
    width: 6em;
  }

  .podium .s1 .block {
    height: 2em;
  }

  .podium .s2 .block {
    height: 1.4em;
  }

  .podium .s3 .block {
    height: 1em;
  }

  .podium .shape svg {
    width: min(calc(var(--fs-base) * 2.2), 14cqi);
    height: min(calc(var(--fs-base) * 2.2), 14cqi);
  }

  .podium .s1 .shape svg {
    width: min(calc(var(--fs-base) * 3), 20cqi);
    height: min(calc(var(--fs-base) * 3), 20cqi);
  }

  .pause-menu {
    grid-template-columns: 1fr;
  }
}

/* Big text (#72: data-fit narrow, under 36 lines of text wide, e.g. 200 % on a tablet): one
   column of pause buttons, and their key labels may wrap, so nothing sticks out sideways. */
:root[data-fit='narrow'] .pause-menu {
  grid-template-columns: 1fr;
}

:root[data-fit='narrow'] .pause-menu .btn {
  flex-wrap: wrap;
  white-space: normal;
  min-width: 0;
}

/* A phone on its side: no room for the podium; the table already shows the order. The winner's
   line keeps to a size that leaves the rows and the buttons their room. */
@media (max-height: 500px) {
  .podium {
    display: none;
  }

  .pg-overlay > .pg-dialog.results .results-title {
    font-size: min(var(--fs-display), 1.8rem);
  }
}

/* Hints only for inputs that are there (Shell/App.InputHints.cs, #70): no gamepad and no phone,
   no Ⓐ / Ⓑ badges; a touch screen or a match of gamepads only, no key labels. */
.no-pad :is(.pg-dialog, .pg-pause-btn) button .pb {
  display: none;
}

/* Hints only for what is here (#266): the badge or key chip on a button. Never by CSS in a sentence,
   which would leave a hole: sentences say it per input (Shell/InputWords.cs). */
.no-pad button > .pb,
.no-pad :is(.gpick-play, .tvote-keys) .pb,
.no-gamepad button > .pb-start,
.no-keys button > kbd,
.no-keys .tvote-keys kbd,
.no-keys :is(.pg-dialog, .pg-pause-btn) button kbd {
  display: none;
}

/* Hold Back to leave (#72 should 23): the line under Quit. */
.pause-hold-hint {
  margin: 0.6em 0 0;
  font-size: max(var(--fs-small), 0.85em);
}

/* "Hold Ⓑ or Esc" (Ui/Html.HoldKeys): only the inputs that are there; neither (a touch screen
   with no gamepad), no hold line at all, since tapping is the way. */
.no-pad :is(.hk-pad, .hk-or),
.no-keys :is(.hk-keys, .hk-or),
.no-pad.no-keys .hk-all {
  display: none;
}

/* A touch screen with no pad: nothing to test, and its pause menu keeps its rows (Settings has it). */
:root[data-touch].no-pad .pause-menu [data-act='pads'] {
  display: none;
}
