/* --------------------------------------------------------------------------
   The dashboard — shown only once a round has ended
   -------------------------------------------------------------------------- */
.wf-scoreboard {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 20px;
  padding-bottom: 18px;
  border-bottom: 1px solid var(--rule);
}
.wf-sb-word {
  margin: 0;
  font-size: 13px;
  color: var(--muted);
}
.wf-sb-word b {
  font-family: var(--font-display);
  font-size: 17px;
  font-weight: 700;
  letter-spacing: 0.16em;
  color: var(--ink);
}
/* The result, stated once and plainly. The studio does not shout, so the
   celebration is the accent and the count-up in the table, not an exclamation
   mark and not confetti. */
.wf-sb-headline {
  margin: 0;
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 700;
  color: var(--ink);
}
.wf-sb-headline.is-yours {
  color: var(--accent-text);
}

.wf-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12px;
}
.wf-table th {
  font-family: var(--font-display);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  text-align: left;
  padding: 0 8px 6px 0;
  border-bottom: 1px solid var(--rule);
  white-space: nowrap;
}
.wf-table td {
  padding: 7px 8px 7px 0;
  border-bottom: 1px solid var(--rule);
  color: var(--ink);
  vertical-align: baseline;
}
.wf-table tr:last-child td { border-bottom: none; }
.wf-table .c-num,
.wf-table th.c-num {
  text-align: right;
  padding-right: 0;
  font-variant-numeric: tabular-nums;   /* columns of digits must line up */
}
.wf-table .c-place {
  width: 2.4em;
  padding-left: 10px;        /* clears the winner's accent bar */
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.wf-table th.c-place { padding-left: 10px; }
.wf-table .c-pts {
  font-family: var(--font-display);
  font-weight: 700;
  min-width: 2.2ch;                     /* the count-up must not resize the column */
}
.wf-table .is-you td { color: var(--ink); font-weight: 600; }
/* the winner's line: an accent rule down its edge, and nothing louder */
.wf-table .is-top td {
  background: color-mix(in srgb, var(--accent) 9%, transparent);
}
.wf-table .is-top td:first-child {
  box-shadow: inset 2px 0 0 var(--accent);
  color: var(--accent-text);
  font-weight: 700;
}
.wf-table .is-top .c-pts { color: var(--accent-text); }

@media (max-height: 640px) {
  .wf-scoreboard { gap: 7px; margin-bottom: 14px; padding-bottom: 12px; }
  .wf-table td { padding: 5px 8px 5px 0; }
}

/* --------------------------------------------------------------------------
   Dialogs
   -------------------------------------------------------------------------- */
.wf-dialog {
  max-width: 27rem;
  padding: 22px 24px;
  background: var(--chip);
  color: var(--ink);
  border: 1px solid var(--rule);
  border-radius: 12px;
  font-family: var(--font-body);
}
.wf-dialog::backdrop { background: rgba(20, 15, 10, 0.55); }
.wf-dialog-h {
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.14em;
  margin: 0 0 10px;
  color: var(--ink);
}
.wf-dialog p { margin: 0 0 10px; line-height: 1.6; }
.wf-dialog-btns { display: flex; gap: 10px; flex-wrap: wrap; margin: 16px 0 0; }

/* --------------------------------------------------------------------------
   End of a match
   -------------------------------------------------------------------------- */
.wf-roundend { max-width: 30rem; }
.wf-re-title {
  font-family: var(--font-display);
  font-size: clamp(1.05rem, 4vw, 1.35rem);
  font-weight: 700;
  letter-spacing: 0.06em;
  line-height: 1.2;
  text-wrap: balance;
  margin: 0 0 4px;
  color: var(--accent-text);
  outline: none;
}
.wf-re-word { font-size: 13px; color: var(--muted); margin: 0 0 14px; }
.wf-re-lead {
  margin: 0 0 8px;
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 600;
  color: var(--ink);
}
/* Climbed or slipped since the last round. The arrow is the glance; the
   sr-only text beside it is the same fact in words, so the meaning does not
   live in a shape or a colour alone. */
.wf-move { margin-left: 6px; font-size: 12px; font-weight: 700; }
.wf-move.up { color: var(--correct); }
.wf-move.down { color: var(--muted); }
.wf-roundend .wf-table { margin-bottom: 12px; }
/* the intermission, counted down. tabular digits so the line does not jiggle */
.wf-re-next {
  margin: 0;
  padding-top: 10px;
  border-top: 1px solid var(--rule);
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

/* ---------------- the two dialogs that cannot be sized to their content ----
   Both of these hold a table of up to sixteen players, so neither has a
   knowable height: two players and no awards is a short card, sixteen players
   and six awards is over a thousand pixels against a 644px viewport. Left to
   themselves they simply overflowed, and overflow here is UNREACHABLE — a
   modal dialog is capped by the UA at about `100% - 2em` and neither of them
   scrolled, one because `overflow: hidden` keeps the falling tiles inside it
   and the other because nothing had ever set an overflow at all.

   The answer in both cases is not to scroll the DIALOG. It is to scroll a box
   INSIDE it, so `.wf-endmatch`'s clip goes on doing its one job untouched, and
   so a foot can stay put underneath. Written once for both, because the second
   one was found by going looking after the first was fixed — and two copies of
   a fix is how they come to disagree.

   `min-height: 0` on the scroller is the part that is easy to leave out and
   fatal without: a flex child will not shrink below its own content, so the box
   grows to its full thousand pixels and never scrolls at all.

   The feet hold what must not scroll away. END THE MATCH exists because an
   endless room has no last round, and the round-end dialog closes itself when
   the next round starts — so the pause IS the host's only window, and a control
   below the fold during it is a control that is not there. SAVE and COPY are
   the same argument with a clock on it: the room closes in five minutes and
   takes the result with it. */
.wf-endmatch,
.wf-roundend {
  max-height: 88vh;                      /* for anything without dvh */
  max-height: min(90dvh, 52rem);
  padding: 0;                            /* it moves onto the two children */
}
/* THE `[open]` IS LOAD-BEARING AND IS NOT A TIDINESS.
 *
 * A closed <dialog> is hidden by the UA's own `dialog:not([open]) { display:
 * none }` — and an AUTHOR rule beats a UA rule whatever the specificity says,
 * so a bare `display: flex` here overrides it and the dialog stays on the
 * screen after close() has run. It is not a small bug: `close()` does take it
 * out of the top layer, so the backdrop goes and the page behind is live and
 * clickable, while a dead copy of last round's result sits over the board with
 * no way to dismiss it — its own CLOSE button calls close() again and nothing
 * happens. It also freezes the intermission line, because the only thing that
 * repaints that checks `roundEnd.open`, which is now false.
 *
 * Shipped exactly that way for two commits. Anything setting `display` on a
 * dialog has to say WHEN. */
.wf-endmatch[open],
.wf-roundend[open] {
  display: flex;
  flex-direction: column;
}
/* An author max-width OVERRIDES the UA's own `dialog:modal` cap, so a bare
   34rem is 544px on a 390px phone and the dialog runs off the side. Both were
   already too wide for a small screen at 30rem and 27rem; widening the result
   card without the min() would have made a latent bug into an obvious one. */
.wf-endmatch { max-width: min(34rem, calc(100vw - 2rem)); }
/* 30rem, which is what it already was — the round-end dialog is not the one
   that needed more room, only the one that needed to stop overflowing. */
.wf-roundend { max-width: min(30rem, calc(100vw - 2rem)); }
.wf-dlg-scroll {
  overflow-y: auto;
  min-height: 0;
  padding: 22px 24px 6px;
  /* the page behind a modal does not scroll, but a phone will still rubber-band
     the whole document once this box hits its end */
  overscroll-behavior: contain;
}
/* The rule and the fill are what stop the last row appearing to sit on top of
   the buttons as it passes underneath. */
.wf-dlg-foot {
  flex: none;
  padding: 12px 24px 18px;
  border-top: 1px solid var(--rule);
  background: var(--chip);
}
.wf-dlg-foot .wf-dialog-btns { margin: 0; }
.wf-dlg-foot .wf-note { margin: 10px 0 0; }
/* The countdown travels with the buttons, not with the table: it is the line
   that decides whether anybody needs to press anything. It used to draw its own
   separator above itself, which is exactly the rule the foot now draws — so
   that one comes off, or the two stack into a double line. */
.wf-dlg-foot .wf-re-next {
  margin: 0 0 10px;
  padding-top: 0;
  border-top: none;
}
/* The winner's name, and nothing competing with it. No confetti and no
   exclamation mark: the celebration is the size of the type, the accent, and
   the points counting up in the table — the same count-up the studio page
   uses for its own honest numbers. */
.wf-em-title {
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 6vw, 2.1rem);
  font-weight: 700;
  letter-spacing: 0.04em;
  line-height: 1.15;
  text-wrap: balance;
  margin: 0 0 6px;
  color: var(--accent-text);
  outline: none;                 /* focused programmatically, not by tabbing */
}
.wf-em-sub {
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 600;
  color: var(--muted);
  margin: 0 0 16px;
}
.wf-endmatch .wf-table { margin-bottom: 12px; }
.wf-em-you {
  font-size: 13px;
  color: var(--ink);
  padding-top: 10px;
  border-top: 1px solid var(--rule);
  margin: 0;
}
/* ---------------- session awards ----------------
   The cards under the final table, in the dialog and in the panel that outlives
   it. They are worth no points and can move no placing, so they are allowed to
   be the warm part of a screen that is otherwise a ledger.

   Three lines each, in the order somebody reads them: what the award is, who
   took it, and what they did. The value sits on the right of the winner's own
   line rather than under it, because it is the evidence for the name beside it.

   Every colour is a token. `.badge-plat` once held a literal rgba() and stayed
   electric cyan while the cream theme moved around it; a card that did the same
   would be one alien chip in the middle of the result. */
.wf-awards {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--rule);
}
.wf-awards h3 {
  margin: 0 0 8px;
  font-size: 12px;
  letter-spacing: .12em;
  color: var(--muted);
  font-weight: 600;
}
.wf-award-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.wf-award {
  display: grid;
  grid-template-columns: 1fr auto;
  column-gap: 12px;
  padding: 8px 0;
  border-bottom: 1px solid var(--rule);
}
.wf-award:last-child { border-bottom: none; }
.wf-award-name {
  grid-column: 1 / -1;
  font-size: 11px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted);
}
.wf-award-who {
  grid-column: 1;
  font-size: 16px;
  font-weight: 600;
  color: var(--ink);
}
.wf-award-val {
  grid-column: 2;
  align-self: end;
  font-size: 14px;
  font-weight: 600;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.wf-award-note {
  grid-column: 1 / -1;
  font-size: 12px;
  color: var(--muted);
}
/* Your own card, marked the way the table marks your own row: by colour on the
   text, never by a border or a background that would shift the grid under it. */
.wf-award.is-yours .wf-award-who,
.wf-award.is-yours .wf-award-val { color: var(--accent-text); }

/* "Nothing here is stored", and the room's own closing time counting down
   beside it. Set as a note rather than a warning on purpose: it is how this
   works, not something going wrong. The digits are tabular so a ticking
   countdown does not make the whole sentence twitch. */
.wf-em-keep {
  margin: 10px 0 0;
  font-variant-numeric: tabular-nums;
}
/* The tiles fall OVER the dialog and are not part of it: absolutely
   positioned, no pointer events, and behind nothing — the result stays
   readable the whole way through, because the result is the point and the
   celebration is the decoration. */
.wf-cheer {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 2;
}
.wf-endmatch { position: relative; overflow: hidden; }
/* The same pair of buttons in the standings panel, which is what stays on the
   screen once the dialog is dismissed — the dialog is a celebration, this is
   the last place the result can still be taken away from. */
.wf-sb-keep {
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--rule);
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.wf-sb-keep .wf-note { font-variant-numeric: tabular-nums; }
/* the title rises once as the result lands; never for someone who asked for
   less motion, and the rule sits inside no-preference so it fails safe */
@media (prefers-reduced-motion: no-preference) {
  .wf-endmatch[open] .wf-em-title { animation: wcrise 520ms ease both; }
  .wf-endmatch[open] .wf-em-sub { animation: wcrise 520ms 90ms ease both; }
}
@keyframes wcrise {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}
#wf-help { max-height: 86svh; overflow: auto; }
.help-ex { margin: 14px 0; }
.help-ex p { margin: 8px 0 0; font-size: 14px; color: var(--muted); }
.help-row { display: flex; gap: 5px; }
.help-row .tile { width: 34px; height: 34px; font-size: 17px; border-radius: 7px; }

/* --------------------------------------------------------------------------
   Footer — present, below the fold
   -------------------------------------------------------------------------- */
.page-play .site-foot {
  margin: 0;
  padding: 22px 16px 28px;
  border-top: 1px solid var(--rule);
  color: var(--muted);
  font-size: 12px;
}
.page-play .foot-nav a { color: var(--muted); font-family: var(--font-display); letter-spacing: 0.16em; }
.page-play .foot-nav a:hover { color: var(--accent-text); }
.page-play .foot-promise, .page-play .foot-line { font-size: 12px; }

/* --------------------------------------------------------------------------
   Motion
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .tile { transition: background-color 0.15s ease, border-color 0.15s ease; }
  .tile.is-flipped { transform: none; }
  .tile.pop, .wf-row.shake, .wf-row.is-win .tile { animation: none !important; }
  .key:active { transform: none; }
  .page-play, .wf-toast { transition: none; }
  /* the armed state stays — it is information, not decoration; only the
     pulsing that carries it is dropped */
  .key.wide.is-armed { animation: none; }
  .wf-row.is-ready::after { animation: none; opacity: 1; }
}


/* --------------------------------------------------------------------------
   The knockout announcement
   --------------------------------------------------------------------------
   Somebody going out, and somebody winning. Both used to arrive in the toast
   strip, which is the correct weight for NOT IN WORD LIST and the wrong weight
   for the most consequential thing that happens to a player all match.

   It ANNOUNCES and never blocks: fixed over everything, `pointer-events: none`
   so the page underneath stays live, and gone in under two seconds with the
   standings arriving immediately behind it. Nothing waits on a press.

   The wash is the page's own background at high opacity rather than a black
   scrim — this is the game raising its voice, not a modal, and a dark overlay
   on a cream board reads as something having gone wrong. */
/* `display: grid` here is safe against the `hidden` attribute, and it is worth
   saying why, because the dialogs two hundred lines up were NOT. The UA rule
   for `[hidden]` carries `!important`, so it beats an author display; the UA
   rule for `dialog:not([open])` does not, which is the whole reason a closed
   dialog stayed on the screen. Checked rather than assumed. */
.wf-flash {
  position: fixed;
  inset: 0;
  z-index: 40;
  display: grid;
  place-items: center;
  padding: 24px;
  pointer-events: none;
  background: var(--bg);
  opacity: 0;
  transition: opacity 400ms ease;
}
.wf-flash b {
  font-family: var(--font-display);
  font-size: clamp(2rem, 11vw, 4.5rem);
  font-weight: 700;
  letter-spacing: 0.04em;
  line-height: 1.05;
  text-align: center;
  text-wrap: balance;
  color: var(--ink);
  transform: scale(0.92);
  transition: transform 420ms cubic-bezier(0.16, 0.9, 0.3, 1.2);
}
/* Going out is the accent — the same colour the clock takes when it is running
   out, because it is the same kind of news. Winning is the solved-tile green,
   which in this game has only ever meant a word coming right. */
.wf-flash[data-tone="out"] b { color: var(--accent-text); }
.wf-flash[data-tone="win"] b { color: var(--correct); }

.wf-flash.is-on { opacity: 0.97; transition-duration: 220ms; }
.wf-flash.is-on b { transform: scale(1); }

/* Reduced motion still gets TOLD — it is information, not decoration, and the
   toast underneath is gone in a moment. What it loses is the movement: no
   scale, and a plain cut in and out rather than a fade. */
@media (prefers-reduced-motion: reduce) {
  .wf-flash, .wf-flash b { transition: none; }
  .wf-flash b { transform: none; }
}
