/* Contract Rummy's table, on the card room's felt (../cards/cards.css).

   Steadiness first: the table fills the window; the bottom panel (status,
   tools, the two moves) and your hand never change size; the piles keep a
   column of their own; every player's tile is sized from the number of
   players and the window alone. Everything that comes and goes (buy prompts,
   badges, ribbons, lay-off buttons, what you're building) appears in space
   already set aside for it or floats over the table, so nothing you might
   be about to click moves. */

.felt.rummy { position: relative; height: calc(100dvh - 2 * var(--frame)); min-height: 0; display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; }
.felt.rummy.docked { grid-template-columns: minmax(0, 1fr) 300px; }
.rummy .tablemain { display: flex; flex-direction: column; gap: 8px; min-height: 0; min-width: 0; }
.rummy .logdock { min-height: 0; display: flex; flex-direction: column; }
.rummy .logdock:empty { display: none; }
.rummy .logdock .gamelog { flex: 1; }
/* the log's drawer: over the table's right edge, from under the top bar to
   just above your moves (table.js fitLog sets top and bottom), never reflowing it */
.rummy .gamelog.drawer {
  position: absolute; z-index: 30; right: 14px; top: 64px; bottom: 260px; width: min(340px, calc(100% - 28px));
  box-shadow: -10px 10px 30px rgba(0, 0, 0, .35);
}
/* the log's open: a pick (tint and ring), not a filled button */
.rummy .logbtn.on { background: var(--pick-tint); box-shadow: var(--pick-ring); }

/* the board: everyone's tiles round the table, you at the bottom and the
   piles in the middle (table.js layout, kit/seats.js ringSeats); on a phone,
   the piles above a list of who's down */
.rummy .board { flex: 1; min-height: 0; position: relative; display: grid; grid-template-columns: auto minmax(0, 1fr); grid-template-rows: minmax(0, 1fr); gap: 8px; }
.rummy .board.ringed { grid-template-columns: minmax(0, 1fr); }
/* The tiles scroll only if they must (while you build a meld over their
   foot). A tile's turn ring stands 5px out, so the padding keeps it whole. */
.rummy .tilewrap {
  min-height: 0; min-width: 0; overflow: hidden auto; scrollbar-gutter: stable; scrollbar-width: thin;
  padding: 12px 6px 6px; display: flex; flex-direction: column; gap: 8px;
}
.rummy .tile.me { background: color-mix(in srgb, var(--ink) 9%, var(--panel)); }
.rummy .tile .youmark { font-weight: 400; color: var(--soft); }
/* A name keeps at least five letters' room; the count gives way first. */
.rummy .tilehead .who { column-gap: .75em; }
.rummy .tilehead .who > .name { min-width: min(5em, 100%); }
/* (a count that won't fit beside a long name is just its number: table.js fitCounts) */
.rummy .tilehead .count.short .cw { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.rummy .tilehead .who > .count { min-width: 0; flex: 0 1 auto; }
/* The glance (ADR 0054): each seat's cards in hand, then its score, Figures
   (the score never gives way; the count's word goes first: fitCounts) */
.rummy :is(.tilehead, .seat) :is(.count, .pts) .house-figure-noun { margin-left: .25em; }
.rummy .tilehead .who > .pts { flex: none; min-width: 0; overflow: visible; }
/* Dense tiles (the header is a narrow column beside the melds: three
   players on a laptop, say): the face sits above the name so the name has
   the column's whole width, and it wraps rather than ending in an ellipsis;
   "· you" moves down whole. */
.rummy .tiles.dense .tilehead { grid-template-columns: minmax(0, 1fr); }
.rummy .tiles.dense .tilehead .who > .name { white-space: normal; overflow-wrap: anywhere; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; }
.rummy .tiles.dense .tilehead .youmark { white-space: nowrap; }
.rummy .tilehead .name.bare .youmark { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
/* Narrow tiles (table.js T.narrow: eight players on a tablet, say): the
   name has the first line to itself, the count and the badge the second
   (table.js sizes the tile's body for the taller header). */
.rummy .tiles.narrow .tilehead {
  height: 48px; grid-template-columns: auto minmax(0, 1fr) auto; grid-template-areas: "face name pts" "count count badge"; row-gap: 4px;
}
.rummy .tiles.narrow .tilehead .pts { grid-area: pts; justify-self: end; }
.rummy .tiles.narrow .tilehead .face { grid-area: face; }
.rummy .tiles.narrow .tilehead .who { display: contents; }
.rummy .tiles.narrow .tilehead .name { grid-area: name; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 14px; }
.rummy .tiles.narrow .tilehead .count { grid-area: count; }
.rummy .tiles.narrow .tilehead .badgeslot { grid-area: badge; width: 64px; }
.rummy .tile.away :is(.face, .who) { opacity: .6; }
.rummy .notyet { margin: 0; height: 100%; display: grid; place-items: center; color: var(--soft); font-size: var(--t-note); }
/* a player's melds just landed: their tile glows once */
.rummy .landed { animation: landed 1.3s ease-out; }
@keyframes landed { 15%, 40% { box-shadow: 0 0 0 3px color-mix(in srgb, var(--ink) 70%, transparent), 0 0 22px 4px color-mix(in srgb, var(--ink) 30%, transparent); } }

/* seats on phones: fixed-width chips that never wrap; one badge in a reserved spot */
.rummy .seats { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; padding: 6px; margin: -6px -6px 0; flex: none; }
.rummy .seats::-webkit-scrollbar { display: none; }
@media (min-width: 641px) and (min-height: 521px) { .rummy .seats { display: none; } }
.rummy .seat { flex: 0 1 222px; min-width: 196px; display: grid; grid-template-columns: auto minmax(0, 1fr) 64px; gap: 8px; padding: 4px 6px 4px 4px; }
.rummy .seat .face { position: relative; }
.rummy .seat.me { background: color-mix(in srgb, var(--ink) 10%, var(--chip)); }
.rummy .seat .youmark { font-weight: 400; color: var(--soft); }
.rummy .seat .who { min-width: 0; }
.rummy .seat .name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rummy :is(.seat, .tile) .downmark { color: var(--ink); font-weight: 700; }
/* "Pass for them" is an action: a filled button, on two short lines in the badge's own space */
.rummy :is(.seat, .tile) button.badge.passfor {
  white-space: normal; line-height: 1.1; padding: 2px 3px; letter-spacing: .02em; text-transform: none; font-size: 11px;
  background: var(--btn); color: var(--btn-ink); border: var(--btn-edge); border-radius: var(--btn-radius);
}
.rummy :is(.seat, .tile) .passfor .short { display: none; }
/* (melds in the tile already say who's down) */
.rummy .tile .downmark { display: none; }
.rummy .tile button.badge.passfor { min-height: 0; height: 22px; padding: 0 3px; white-space: nowrap; font-size: 10.5px; letter-spacing: 0; }
.rummy .tiles.dense .tile .badge { width: 100%; }
.rummy .seat.away { opacity: 1; }
.rummy .seat.away :is(.face, .who) { opacity: .6; }

/* piles: side by side in the middle of the table, with room for the 3px
   outline a pile you can take gets */
.rummy .piles { flex-direction: column; align-items: center; gap: 12px; padding: 7px; width: calc(var(--cw) + 34px); }
.rummy .piles.across { flex-direction: row; align-items: flex-start; width: calc(var(--cw) * 2 + 52px); }
/* (in the middle of a ring of short rows, eight players on a laptop: the
   room the outline needs, no more, so the labels stay off the tiles) */
.rummy .tiles > .middle > .piles { padding-block: 3px; }
.rummy .pile { width: calc(var(--cw) + 20px); }
.rummy .pile .count { display: block; width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* melds: a fixed slot each in their owner's tile (table.js sizes them) */
.rummy .meldslots { display: flex; flex-direction: column; gap: 8px; }
.rummy .slotrow { display: flex; gap: 8px; height: var(--slot-h); }
.rummy .slotrow > .meld { flex: none; }
/* the last hand: everyone else's cards face down in their tile, as many as
   they hold, until someone lays all three runs there */
.rummy .backs { height: 100%; display: flex; justify-content: center; align-items: center; }
.rummy .backs .card { flex: none; }
.rummy .backs .card + .card { margin-left: calc(var(--cw-small) * -.8); }
/* a tile across a whole row of the ring (yours, below the middle): its melds centered */
.rummy .tile.across .slotrow { justify-content: center; }
.rummy .meld.flying { position: fixed; }
.rummy .meld { position: relative; min-width: 0; padding: 2px; border-radius: 10px; border: 2px solid transparent; }
.rummy .meld.target { border-color: color-mix(in srgb, var(--turn) 70%, transparent); cursor: pointer; }
.rummy .meld.dim { opacity: .45; }
.rummy .meld .cards { position: relative; }
/* a fan overlaps as much as its slot needs (--step: how much of each card shows) */
.rummy .meld .cards .card + .card { margin-left: calc(var(--step, calc(var(--cw-small) * .58)) - var(--cw-small)); }
/* too tight to read: what it is, on a tag over its foot (at the right,
   clear of every card's corner; pointing at it shows the whole fan) */
.rummy .meldtag {
  position: absolute; right: 2px; bottom: 3px; z-index: 3; padding: 0 6px; border-radius: 99px; white-space: nowrap;
  font: 800 12px/1.35 var(--ui-font); background: var(--sheet); color: var(--ink); border: 1px solid var(--ink);
}
/* on its way to the table: its place is kept, unseen, until it lands */
.rummy .landing { visibility: hidden; }
/* just played on a meld: a dot in the color of whoever played it, in the
   card's empty bottom-left corner */
.rummy .meld .card.laid::before {
  content: ''; position: absolute; left: 5%; bottom: 5%; width: 9px; height: 9px; border-radius: 50%;
  background: var(--dot); box-shadow: 0 0 0 1.5px #111;
}
/* condensed melds (only where full fans would be too small to read): the
   same width however long they get, with two lines beneath */
.rummy .meld.condensed { cursor: default; }
.rummy .meld.condensed:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.rummy .cset, .rummy .crun { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; }
.rummy .cset { padding-top: 4px; }
.rummy .card.stack { box-shadow: 3px -3px 0 0 var(--card), 3px -3px 0 1px rgba(0, 0, 0, .45), 6px -6px 0 0 var(--card), 6px -6px 0 1px rgba(0, 0, 0, .45); }
.rummy .cset .pill, .rummy .jchip {
  white-space: nowrap; border-radius: 99px; font: 800 12px/1.25 var(--ui-font); padding: 0 6px;
  background: var(--chip); color: var(--ink); border: 1.5px solid var(--ink);
}
.rummy .crun .ends { display: flex; align-items: stretch; }
.rummy .crun .ends .card + .card { margin-left: 0; }
/* the bridge between a run's ends */
.rummy .crun .bridge { position: relative; width: calc(var(--cw-small) * .3); flex: none; }
.rummy .crun .bridge::before { content: ''; position: absolute; left: -3px; right: -3px; top: 50%; height: 3px; margin-top: -1.5px; border-radius: 2px; background: var(--ink); opacity: .6; }
.rummy :is(.cset, .crun) .caption { font: 700 12px/1.3 var(--ui-font); color: var(--ink); white-space: nowrap; }
/* the jokers inside a run, on their own line: "★6♣ ★7♣ +2" */
.rummy .crun .chips { display: flex; gap: 2px; max-width: 100%; overflow: hidden; }
.rummy .jchip { padding: 0 4px; }
/* a condensed meld's whole fan, while you point at it */
.rummy .meldpop {
  position: fixed; z-index: 44; pointer-events: none; display: flex; flex-direction: column; gap: 6px; align-items: flex-start;
  padding: 10px 12px 8px; border-radius: 12px; background: var(--sheet); color: var(--ink); border: var(--chip-edge);
  box-shadow: 0 12px 30px rgba(0, 0, 0, .45);
}
.rummy .meldpop .poplabel { font: 700 12px/1.2 var(--ui-font); }
/* how many of your cards would go on a meld ("+2"): a chip on the last
   card's top right corner, standing out past it, clear of every index */
.rummy .meld .plus {
  position: absolute; top: -7px; right: -7px; z-index: 3; pointer-events: none;
  font: 800 11px/1.35 var(--ui-font); padding: 0 5px; border-radius: 99px;
  background: var(--turn); color: #111; box-shadow: 0 1px 4px rgba(0, 0, 0, .45);
}
/* Where a card would land: a card-sized slot in the fan, dashed (it isn't
   there yet) and ringed in the turn color with a soft glow, the card's name
   in its corner like an index. It takes a card's place, so the meld keeps
   its width; pointing at it (or focusing it) brings the glow up. */
.rummy .meld .spot {
  position: relative; flex: none; width: var(--cw-small); height: calc(var(--cw-small) * 1.4); padding: 0;
  border-radius: var(--card-radius); border: 2px dashed var(--turn); cursor: pointer;
  background: color-mix(in srgb, var(--turn) 22%, var(--room)); color: var(--turn);
  box-shadow: 0 0 10px 1px color-mix(in srgb, var(--turn) 45%, transparent);
  font: 800 max(12px, calc(var(--cw-small) * .3))/1 var(--ui-font); letter-spacing: -.04em;
  transition: box-shadow .14s ease;
}
.rummy .meld .spot:is(:hover, :focus-visible) { box-shadow: 0 0 0 3px color-mix(in srgb, var(--turn) 45%, transparent), 0 0 16px 3px color-mix(in srgb, var(--turn) 55%, transparent); }
.rummy .meld .spot:focus-visible { outline: 2px solid var(--focus, var(--ink)); outline-offset: 2px; }
.rummy .meld .spotix { position: absolute; left: 7%; top: 5%; white-space: nowrap; }
/* (a slot on the low end shows only its left edge: its name sits there) */
.rummy .meld .cards > :is(.card, .spot) + :is(.card, .spot) { margin-left: calc(var(--step, calc(var(--cw-small) * .58)) - var(--cw-small)); }
/* condensed: slots take the bridge's place, overlapping the ends they join */
.rummy .ends.slotted { display: flex; align-items: flex-start; }
.rummy .ends.slotted > * + * { margin-left: calc(var(--cw-small) * -.55); }
.rummy .crun .ends.slotted > .card + .card { margin-left: 0; }
.rummy .crun .ends.slotted.both > .card + .card { margin-left: calc(var(--cw-small) * -.45); }
.rummy .cset .ends.slotted > .spot { margin-left: calc(var(--cw-small) * -.6); }
/* Your card going in a joker's place: the card, dashed (it isn't there
   yet) and ringed like a spot, with a chip saying the joker comes out
   ("★ out"), or, when pressing it takes the joker, "Take ★". */
.rummy .meld .card.ghost {
  outline: 2px dashed var(--turn); outline-offset: -2px;
  background: color-mix(in srgb, var(--card) 62%, var(--room));
  box-shadow: 0 0 10px 1px color-mix(in srgb, var(--turn) 45%, transparent);
}
.rummy .meld .card.ghost[role="button"] { cursor: pointer; }
.rummy .meld .card.ghost[role="button"]:is(:hover, :focus-visible) { box-shadow: 0 0 0 3px color-mix(in srgb, var(--turn) 45%, transparent), 0 0 16px 3px color-mix(in srgb, var(--turn) 55%, transparent); }
.rummy .meld .ghosttag {
  position: absolute; left: 50%; bottom: -7px; translate: -50% 0; z-index: 3; pointer-events: none; white-space: nowrap;
  font: 800 11px/1.35 var(--ui-font); letter-spacing: 0; padding: 0 5px; border-radius: 99px;
  background: var(--turn); color: var(--turn-ink); box-shadow: 0 1px 4px rgba(0, 0, 0, .45);
}
.rummy .jchip.wins { background: var(--turn); color: var(--turn-ink); border-color: var(--turn); }
/* a card in your hand that can win a joker: a ★ chip on its top edge */
.rummy .hand .card .wins {
  position: absolute; left: 50%; top: -9px; translate: -50% 0; z-index: 3; pointer-events: none;
  font: 800 12px/1.35 var(--ui-font); padding: 0 6px; border-radius: 99px;
  background: var(--turn); color: var(--turn-ink); box-shadow: 0 1px 4px rgba(0, 0, 0, .45);
}
/* (picked, the table shows the trade instead, and Discard's chip has the top edge) */
.rummy .hand .card.sel .wins { display: none; }
/* Once you're down, a card in your hand that goes on the table glows: a
   ring in the turn color with a soft glow, as a slot it would land in. */
.rummy .hand .card.playable { box-shadow: var(--card-shadow), 0 0 0 2px var(--turn), 0 0 12px 2px color-mix(in srgb, var(--turn) 55%, transparent); }
.rummy .hand .card.playable.sel { box-shadow: var(--select), 0 0 0 2px var(--turn), 0 0 12px 2px color-mix(in srgb, var(--turn) 55%, transparent); }
.rummy .tablenote { margin: auto; font-size: 14px; text-align: center; }
/* the last hand: tiles are headers only, and this is the open space below
   them, where whoever goes out lays their runs */
.rummy .spread { flex: 1; min-height: 120px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; padding: 12px; border-radius: 14px; border: var(--panel-edge); }
.rummy .spread .meldslots { flex-direction: row; gap: 14px; }
.rummy .spreadhead { margin: 0; font-size: 15px; }

/* building your contract: a tray over your own tile (empty until you go
   down), so everyone else's stays in view */
.rummy .staging {
  position: absolute; grid-column: 2; grid-row: 1; left: 6px; top: 12px; width: fit-content; max-width: calc(100% - 12px); z-index: 6;
  display: flex; gap: 10px; flex-wrap: nowrap; overflow-x: auto; padding: 8px;
  border-radius: 14px; background: var(--sheet); border: var(--chip-edge); box-shadow: 0 10px 28px rgba(0, 0, 0, .4);
}
.rummy .staging[hidden] { display: none !important; }
/* (the ring has one column, the piles inside it: the tray's area is the
   tiles' own, or it lands in an empty column past the window's right edge) */
.rummy .board.ringed .staging { grid-column: 1; }
/* (and your tile's "Not down yet" makes way for it) */
.rummy .board:has(> .staging:not([hidden])) .tile.me .notyet { visibility: hidden; }
/* the tray's way out: Cancel, after the melds */
.rummy .staging .trayend { flex: none; display: flex; align-items: center; padding: 0 2px; }
/* your draw locked in while buyers decide: chosen, a tint and an inner ring, never the fill */
.rummy .btn.slot.chosen, .rummy .btn.slot.chosen.alt { background: var(--pick-tint); box-shadow: var(--pick-ring); }
.rummy .pile.stock.chosen .card { box-shadow: var(--card-shadow), 0 0 0 3px var(--turn); }
/* more melds past an edge (a phone's last hand): that edge fades */
.rummy .staging.more-right { -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 32px), transparent); mask-image: linear-gradient(to right, #000 calc(100% - 32px), transparent); }
.rummy .staging.more-left { -webkit-mask-image: linear-gradient(to left, #000 calc(100% - 32px), transparent); mask-image: linear-gradient(to left, #000 calc(100% - 32px), transparent); }
.rummy .staging.more-left.more-right { -webkit-mask-image: linear-gradient(to right, transparent, #000 32px, #000 calc(100% - 32px), transparent); mask-image: linear-gradient(to right, transparent, #000 32px, #000 calc(100% - 32px), transparent); }
/* (small cards, so it covers as little of the next tile as it can) */
.rummy .staging .group { --cw-small: clamp(34px, calc(var(--cw) * .5), 56px); padding: 6px 8px 8px; }
.rummy .group { display: flex; flex-direction: column; gap: 6px; padding: 8px 10px 10px; flex: none; }
.rummy .group.good { border: 2px solid var(--good); }
.rummy .group.bad { border: 2px dashed var(--bad); }
.rummy .grouphead { gap: 6px; font-size: 13px; flex-wrap: nowrap; }
.rummy .grouphead .ok { color: var(--good); font-weight: 800; }
.rummy .grouphead .no { color: var(--bad); max-width: 16em; }
.rummy .grouphead .btn.quiet { min-height: 32px; font-size: 13px; padding: 2px 6px; }

/* the bottom panel: status, tools and moves, always the same size */
.rummy .dock {
  flex: none; display: flex; flex-direction: column; gap: 8px; padding: 8px 10px 10px;
  border-radius: 14px; background: var(--panel); border: 2px solid transparent; transition: border-color .2s, background-color .2s;
}
.rummy .dock.yours { border-color: var(--turn); background: color-mix(in srgb, var(--turn) 9%, var(--panel)); }
.rummy .status { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: start; gap: 4px 12px; }
.rummy .saybox { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.rummy .sayline { min-height: 2.9em; display: flex; align-items: flex-start; gap: 8px; }
.rummy .say {
  margin: 0; font-size: var(--t-body); line-height: 1.45; min-width: 0; flex: 1; /* (so "Take it back" beside it never moves) */
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.rummy .say b { color: var(--turn); }
.rummy .saylink { flex: none; }
.rummy .saylink .btn { margin-top: -6px; }
.rummy .timer { width: 184px; display: flex; flex-direction: column; gap: 3px; font-size: var(--t-note); padding-top: 4px; }
.rummy .timer.off { visibility: hidden; }
/* a new hand being dealt (table.js dealCue): your cards and the discard's wait to be turned up */
.felt.rummy.dealing .hand .card, .felt.rummy.dealing .discards .card { visibility: hidden; }
/* the countdown is the room kit's (.clock: bar, seconds); here it stacks, filling the timer */
.rummy .timer .clock { display: flex; flex-direction: column; align-items: stretch; gap: 3px; }
.rummy .timer .clockbar { width: auto; }
.rummy .timer .clockfill { background: var(--turn); }
.rummy .timer .clock.low .clockfill { background: var(--bad); }
.rummy .timer :is(.clocktext, .notimer) { min-height: 1.45em; font-variant-numeric: tabular-nums; color: var(--soft); }
/* the upcard has no timer: the bar's place stays, with a calm word over it */
.rummy .timer { position: relative; }
.rummy .timer.untimed .clock { visibility: hidden; }
.rummy .timer .notimer { display: none; position: absolute; right: 0; bottom: 0; white-space: nowrap; }
.rummy .timer.untimed .notimer { display: block; visibility: inherit; }
.rummy .controls { display: flex; justify-content: space-between; align-items: center; gap: 10px; }
/* (after the moves in the page, for the keyboard; drawn before them) */
.rummy .toolrow { display: flex; gap: 14px; align-items: center; min-width: 0; order: -1; }
.rummy .tgroup { display: flex; gap: var(--s2, 8px); align-items: center; flex-wrap: nowrap; }
.rummy .tool { min-height: var(--tool-h); font-size: var(--t-small); padding: 4px 12px; }
.rummy .tool.mover { min-width: 40px; font-size: 18px; padding: 0; }
.rummy .sorters kbd { opacity: .7; }
/* Make says what it will make; room for its longest label, so it never resizes */
.rummy .tool.maker { min-width: 8.6em; }
.rummy .actions { display: grid; grid-template-columns: 260px 260px; gap: 8px; margin-left: auto; flex: none; }
.rummy .act { width: 100%; min-width: 0; padding-inline: 10px; }
.rummy .act .label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* your hand, after you draw with nothing picked: a turn-yellow ring and
   tint inside it (nothing changes size), and on a computer "↓ Pick a card
   to discard" on its top edge, over the space the hand keeps above its cards */
.rummy .handwrap { position: relative; flex: none; min-width: 0; order: 2; }
.rummy .hand { border-radius: 12px; transition: box-shadow .15s, background-color .15s; padding: 18px 8px 8px; min-height: calc(var(--cw) * 1.4 + 26px); }
.rummy .hand.cue { box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--turn) 75%, transparent); background-color: color-mix(in srgb, var(--turn) 8%, transparent); }
.rummy .handcue {
  position: absolute; top: 9px; left: 16px; z-index: 2; pointer-events: none; white-space: nowrap; /* (table.js puts it just past the last card) */
  padding: 1px 10px; border-radius: 99px; font: 700 var(--t-note)/1.35 var(--ui-font);
  background: var(--turn); color: var(--turn-ink);
}
.rummy .handcue::before { content: '↓ '; }
/* the Discard chip: a second handle on the dock's Discard, just above the
   one card picked (table.js places it); never on touch screens. The hand
   keeps a taller strip above its cards there, so the chip over a lifted
   card stays clear of the dock's buttons. */
@media (pointer: fine) and (min-width: 641px) and (min-height: 521px) {
  .rummy .hand { padding-top: 40px; min-height: calc(var(--cw) * 1.4 + 48px); }
}
.rummy .discardchip {
  position: absolute; left: 0; top: 0; z-index: 35; min-height: 26px; padding: 2px 10px; font-size: 14px; line-height: 1; white-space: nowrap;
  box-shadow: 0 4px 12px rgba(0, 0, 0, .4);
}
.rummy .discardchip kbd { font-size: 10px; }
/* (No glide: it's placed before it shows, and moves with its card.) */
.rummy .discardchip { transition: none; }
/* Asking "…anyway?" draws an outline in the warning color, not a fill, here
   and in the dock, so the one filled button (Go down) stays the only one;
   the words keep the outlined button's own ink, readable in every style. */
.rummy .discardchip.confirm, .rummy .btn.slot.act.confirm, .rummy .btn.slot.act.confirm.alt {
  background: var(--btn2); color: var(--btn2-ink); border: 2.5px solid var(--confirm, var(--bad));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--confirm, var(--bad)) 40%, transparent);
}
.rummy .discardchip.confirm { box-shadow: 0 0 0 3px color-mix(in srgb, var(--confirm, var(--bad)) 40%, transparent), 0 4px 12px rgba(0, 0, 0, .4); }
.rummy .discardchip.away, body.handdrag .rummy .discardchip { visibility: hidden; }
@media (pointer: coarse), (max-width: 640px), (max-height: 520px) {
  .rummy .discardchip, .rummy .handcue { display: none; }
}

/* the title says the hand and its contract; clicking it replays the intro */
.rummy .titlebtn {
  appearance: none; background: none; border: 0; padding: 0; margin: 0; font: inherit; color: inherit; text-align: left;
  display: inline-block; max-width: 100%; cursor: pointer; border-radius: 4px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; vertical-align: bottom;
}
.rummy .titlebtn:hover { text-decoration: underline dotted; text-underline-offset: 4px; }
.rummy .titlebtn:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.rummy .bar .title { overflow: visible; }

/* the hand intro: a little table of its own, with the contract dealt out */
.introcard:has(.rintro) { min-width: min(460px, calc(100vw - 24px)); padding-bottom: 58px; }
.rintro { display: flex; flex-direction: column; align-items: center; }
.rintro .kicker { margin: 0; font: 800 15px/1.2 var(--ui-font); letter-spacing: .16em; text-transform: uppercase; color: var(--ink); }
.rintro .kicker .pip { opacity: .75; margin: 0 .5em; letter-spacing: .25em; }
/* the seven hands: played, this one, to come */
.rintro .progress { display: flex; gap: 6px; margin: 8px 0 0; }
.rintro .progress i { width: 9px; height: 9px; border-radius: 50%; border: 1.5px solid var(--ink); opacity: .55; }
.rintro .progress i.done { background: var(--ink); }
.rintro .progress i.now { background: var(--turn); border-color: var(--turn); opacity: 1; scale: 1.25; }
.rintro .dealer { margin: 6px 0 0; font-size: 13px; color: var(--ink); opacity: .85; }
.rintro .headline {
  margin: 4px 0 0; font: var(--display-weight) 50px/1.05 var(--display); color: var(--turn);
  text-shadow: 0 2px 0 rgba(0, 0, 0, .25);
}
.rintro .examples { display: flex; justify-content: center; align-items: flex-start; gap: 26px; margin-top: 18px; flex-wrap: wrap; }
.rintro .example { margin: 0; display: flex; flex-direction: column; align-items: center; gap: 12px; }
.rintro .fan { --cw: 54px; padding-top: 4px; }
.rintro .fan .card { box-shadow: 0 3px 8px rgba(0, 0, 0, .35); }
.rintro .fan .card + .card { margin-left: calc(var(--cw) * -0.44); }
.rintro figcaption { font: 700 11px/1 var(--ui-font); letter-spacing: .12em; text-transform: uppercase; color: var(--soft); }
.rintro .headline.long { font-size: 40px; }
.rintro .lastrule { margin: 16px 0 0; max-width: 30em; font-size: 15px; line-height: 1.4; }
.rintro .lastrule b { color: var(--turn); }
/* the flourish: a poker chip slapped down on the bottom edge, in room the
   card keeps clear for it, so it never covers what the card says */
.rintro .chipspot { position: absolute; left: 50%; bottom: -46px; width: 92px; height: 92px; margin-left: -46px; }
.rintro .burst {
  position: absolute; inset: -34px; border-radius: 50%; opacity: 0; clip-path: inset(44% 0 0 0); /* rays below and beside it, never over the card's words */
  background: repeating-conic-gradient(from -4deg, var(--turn) 0 8deg, transparent 8deg 36deg);
  -webkit-mask: radial-gradient(circle, transparent 0 52%, #000 53% 70%, transparent 71%);
  mask: radial-gradient(circle, transparent 0 52%, #000 53% 70%, transparent 71%);
}
.rintro .chip {
  position: absolute; inset: 0; border-radius: 50%;
  display: grid; place-items: center; color: #111; rotate: -12deg;
  background:
    radial-gradient(circle, var(--turn) 0 57%, transparent 57.5%),
    repeating-conic-gradient(from 6deg, #fff 0 14deg, var(--turn) 14deg 45deg);
  box-shadow: 0 8px 18px rgba(0, 0, 0, .45), inset 0 0 0 2px rgba(0, 0, 0, .25);
}
.rintro .chip::before { content: ''; position: absolute; inset: 15px; border-radius: 50%; border: 2px dashed color-mix(in srgb, #000 30%, transparent); }
.rintro .chip span { font: 900 15px/1.02 var(--display); text-transform: uppercase; letter-spacing: .02em; }
/* short windows (a phone on its side): a compact card, so it and its chip fit */
@media (max-height: 520px) {
  .introcard:has(.rintro) { padding: 10px 18px 40px; }
  .rintro .kicker { font-size: 12px; }
  .rintro .progress { margin-top: 4px; }
  .rintro .dealer { margin-top: 2px; font-size: 12px; }
  .rintro .headline, .rintro .headline.long { font-size: 26px; }
  .rintro .examples { margin-top: 8px; gap: 14px; }
  .rintro .example { gap: 6px; }
  .rintro .fan { --cw: 32px; }
  .rintro .lastrule { margin-top: 8px; font-size: 13px; }
  .rintro .chipspot { bottom: -30px; width: 60px; height: 60px; margin-left: -30px; }
  .rintro .burst { inset: -20px; }
  .rintro .chip::before { inset: 10px; }
  .rintro .chip span { font-size: 10px; }
}


/* the host's "Start without waiting" waits a moment before it can be pressed */
.later { animation: later 0s 1s both; }
@keyframes later { from { visibility: hidden; } to { visibility: visible; } }

/* the score sheet: at the end of a hand or the game, the house's result
   sheet (house/end.js), wide enough for seven hands, a chart and everyone's
   leftovers, its tables read left to right */
.house-scrim-result .house-sheet.cr-result { --house-sheet-width: 780px; max-height: min(88dvh, calc(100dvh - 2 * var(--s3, 16px))); }
.house-result .scoresheet { align-self: stretch; text-align: left; min-width: 0; }
.house-result .house-post:empty { display: none; }
.scroll { overflow-x: auto; }
.scoresheet .legend { font-size: var(--t-note); margin: 0 0 8px; display: flex; flex-wrap: wrap; gap: 2px 10px; }
.scoresheet .legend span { white-space: nowrap; }
table.scores { border-collapse: collapse; width: 100%; font-size: 14px; font-variant-numeric: tabular-nums lining-nums; }
table.scores th, table.scores td { padding: 6px 7px; text-align: right; border-bottom: 1px solid color-mix(in srgb, currentColor 16%, transparent); white-space: nowrap; }
table.scores th[scope="row"], table.scores thead th:nth-child(1), table.scores td.place + th { text-align: left; }
table.scores th[scope="row"] { max-width: 9em; overflow: hidden; text-overflow: ellipsis; }
table.scores .now { background: color-mix(in srgb, var(--ink) 7%, transparent); }
table.scores td.total { font-weight: 800; }
table.scores td.total small, table.scores .outmark small { font-size: max(12px, .8em); font-weight: 400; color: var(--soft); }
table.scores tr.win th, table.scores tr.win td { color: var(--turn); font-weight: 800; }
table.scores td.place { text-align: left; font-weight: 700; color: var(--soft); }
table.contracts td:nth-child(2), table.contracts th:nth-child(2) { text-align: left; white-space: normal; }
.revealed { display: flex; flex-direction: column; gap: 10px; }
.revealrow { display: grid; grid-template-columns: 6.5em minmax(0, 1fr) auto; align-items: center; gap: 10px; }
.revealrow .cards { overflow-x: auto; padding-bottom: 2px; }
.revealname { font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* after a hand: how close everyone came (under the scores) */
.leftnote { font-size: var(--t-note); margin: -2px 0 10px; }
/* (cards a little smaller and closer than elsewhere, so a whole hand's
   melds and loose cards fit on one line) */
.leftovers { display: flex; flex-direction: column; gap: 12px; --cw-small: 40px; }
.leftovers .cards .card + .card { margin-left: calc(var(--cw-small) * -0.5); }
.leftrow { display: grid; grid-template-columns: 7.5em minmax(0, 1fr); gap: 12px; align-items: start; }
.leftwho { display: flex; flex-direction: column; gap: 1px; min-width: 0; font-size: var(--t-note); padding-top: 2px; }
.leftwho .who { font-size: 15px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.leftwho .leftshort { font-weight: 700; }
.leftcards { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 8px 14px; min-width: 0; }
.leftcards .wentout { font-weight: 700; padding-top: 2px; }
.leftcards .lefthead { font-size: var(--t-note); align-self: center; }
.lgroup { display: flex; flex-direction: column; gap: 3px; }
.lgroup .cards { display: flex; }
.lgroup .lcap { font-size: 12px; color: var(--soft); white-space: nowrap; }
.lgroup .lcap b { color: var(--ink); }
.lgroup.loose { border-left: 1.5px solid color-mix(in srgb, var(--ink) 22%, transparent); padding-left: 12px; }
.rulesheet ul, .rulesheet ol { padding-left: 1.2em; }
.field.inline { flex-direction: row; align-items: center; gap: 6px; font-size: 12px; }
.field.inline select { min-height: 34px; padding: 2px 6px; font-size: 13px; }

/* The tools and the moves share one row while they fit: the tool row
   needs up to 480px (its hidden slots keep their space, so its width
   never depends on the game) and the moves 528px, each wide enough for
   its longest label ("Discard the joker anyway?" with its key). A little
   short of that, the row tightens (no "Sort" label, smaller gaps), then
   the moves narrow to 220px each (a long label ends in "…"); below about
   920px the moves drop under the tools, at the right, never wider than
   260px each. Width alone decides, so nothing moves during play. */
.rummy .dock { container-type: inline-size; }
@container (max-width: 1060px) {
  .rummy .toolrow { gap: 8px; }
  .rummy .sorters .sortlabel { display: none; }
}
@container (max-width: 990px) {
  .rummy .actions { grid-template-columns: 220px 220px; }
}
@container (max-width: 920px) {
  .rummy .controls { flex-wrap: wrap; }
  .rummy .actions { grid-template-columns: repeat(2, minmax(0, 260px)); margin-left: auto; }
}
.rummy .tool, .rummy .tool .label { white-space: nowrap; }

/* phones (and phones on their side): the seats slide along a row of chips,
   from the player on your left round to you, and the tiles list who's down,
   in the order they went down, yours pinned at the foot over your hand */
@media (max-width: 640px), (max-height: 520px) {
  /* a chip's count is just the number ("10"; screen readers hear "10 cards") */
  .rummy .seat .downmark, .rummy .seat .youmark { display: none; }
  .rummy .seat .count .cw { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .rummy .board { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr) auto; gap: 6px; }
  .rummy .piles, .rummy .piles.across { width: auto; justify-content: center; padding: 6px; }
  .rummy .pile { width: auto; min-width: max(84px, calc(var(--cw) + 12px)); }
  /* (room above the first tile for its "Just went down" ribbon) */
  .rummy .tilewrap { padding: 12px 4px 4px; gap: 8px; }
  .rummy .staging { position: static; grid-column: 1; grid-row: 3; padding: 0; border: 0; border-radius: 0; background: none; box-shadow: none; }
  .rummy .tiles { gap: 6px; }
  /* (each other tile keeps what it raises, a ghost's "★ out" tag say, to
     itself, so nothing of theirs shows over yours pinned at the foot) */
  .rummy .tiles.list .tile:not(.me) { isolation: isolate; }
  .rummy .tiles.list .tile.me {
    position: sticky; bottom: 0; z-index: 2; box-shadow: 0 -8px 14px -6px rgb(0 0 0 / .45);
    background: linear-gradient(color-mix(in srgb, var(--ink) 9%, var(--panel)), color-mix(in srgb, var(--ink) 9%, var(--panel))), var(--room);
  }
  .rummy .spread { min-height: 60px; flex: none; }
}

/* mid-size windows: seats share the width */
@media (max-width: 900px) and (min-width: 641px) {
  .rummy .seat { flex: 1 1 0; width: auto; min-width: 160px; }
}

@media (max-width: 640px) {
  .introcard:has(.rintro) { padding: 16px 16px 46px; }
  .rintro .kicker { font-size: 13px; letter-spacing: .12em; white-space: nowrap; }
  .rintro .kicker .pip { margin: 0 .3em; }
  .rintro .headline, .rintro .headline.long { font-size: 30px; }
  .rintro .examples { gap: 14px; margin-top: 14px; }
  .rintro .fan { --cw: 34px; }
  .rintro .chipspot { bottom: -36px; width: 72px; height: 72px; margin-left: -36px; }
  .rintro .burst { inset: -26px; }
  .rintro .chip::before { inset: 12px; }
  .rintro .chip span { font-size: 12px; }
  .rintro .lastrule { font-size: 14px; }
  .felt.rummy { height: 100dvh; gap: 0; }
  .rummy .tablemain { gap: 8px; }
  /* Seats share the width (four fit without sliding); status shows on the
     initial rather than as a badge. */
  .rummy .seats { gap: 5px; }
  .rummy .seat { flex: 1 0 84px; width: auto; min-width: 84px; grid-template-columns: auto minmax(0, 1fr); min-height: 40px; padding: 3px 6px 3px 3px; gap: 5px; border-radius: 12px; }
  .rummy .seat .face { width: 28px; height: 28px; box-shadow: 0 0 0 2px var(--chip); }
  /* (the name over the glance's two figures: the count, then the score a size smaller) */
  .rummy .seat .who { font-size: 11px; line-height: 1.2; display: grid; grid-template-columns: auto auto; justify-content: start; align-items: baseline; column-gap: 7px; }
  .rummy .seat .who > .name { grid-column: 1 / -1; }
  .rummy .seat .count .house-figure { font-size: var(--t-label); }
  .rummy .seat .pts .house-figure { font-size: 13px; }
  /* (a list tile's header is one 13px line: its figures a size smaller, still the heaviest thing in it) */
  .rummy .tiles.list .tilehead .house-figure { font-size: var(--t-label); }
  .rummy .seat .pts .house-figure-noun { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .rummy .seat .name { font-size: 12px; }
  /* Six or more seats slide: yours, the last, stays at the row's end, the
     others passing under it (its shadow says there's more), and the turn
     scrolled to stays clear of it. */
  .rummy .seats { scroll-padding-inline-end: 96px; }
  .rummy .seats > .seat.me {
    position: sticky; right: 0; z-index: 2;
    background: linear-gradient(color-mix(in srgb, var(--ink) 10%, var(--chip)), color-mix(in srgb, var(--ink) 10%, var(--chip))), var(--room);
  }
  .rummy .seats:has(> .seat:nth-child(6)) > .seat.me { box-shadow: -14px 0 12px -6px rgb(0 0 0 / .7); }
  .rummy .seat .badge:not(button) { display: none; }
  .rummy .seat button.badge { grid-column: 1 / -1; width: 100%; }
  .rummy .seat.is-buying .face { box-shadow: 0 0 0 3px var(--turn); }
  .rummy .seat.is-deciding .face { box-shadow: 0 0 0 2px var(--chip), 0 0 0 4px color-mix(in srgb, var(--ink) 55%, transparent); }
  .rummy .seat.is-passed .face, .rummy .seat.is-away .face { opacity: .55; }
  /* (the top padding keeps the status clear of the timer bar on the edge) */
  .rummy .dock { padding: 10px 8px 8px; gap: 6px; }
  .rummy .status { grid-template-columns: minmax(0, 1fr); gap: 2px; }
  /* the buy timer: a thin bar over the dock's top edge, taking no row of its own */
  .rummy .dock { position: relative; }
  .rummy .timer {
    position: absolute; left: 14px; right: 14px; top: 0; transform: translateY(-60%); z-index: 3; width: auto; height: 22px;
    flex-direction: row; align-items: center; gap: 8px; padding: 0 10px; border-radius: 99px; font-size: var(--t-note);
    /* (a sheet's colors: its ink reads on it in every style) */
    background: var(--sheet); color: var(--ink); box-shadow: 0 0 0 1.5px var(--turn);
  }
  .rummy .timer :is(.soft, .clocktext) { color: var(--ink); }
  [data-theme="retro"] .rummy .timer { --ink: #000; color: #000; }
  .rummy .timer.off { display: none; }
  .rummy .timer .clock { flex: 1; flex-direction: row; align-items: center; gap: 8px; }
  .rummy .timer .clockbar { flex: 1; }
  .rummy .timer :is(.clocktext, .notimer) { min-height: 0; white-space: nowrap; min-width: 8.5em; text-align: right; }
  .rummy .timer .notimer { right: 10px; bottom: auto; top: 50%; transform: translateY(-50%); }
  /* two lines of the status's 14px, no more */
  .rummy .sayline { min-height: calc(2 * 1.45 * 14px); }
  .rummy .seat .face { width: 24px; height: 24px; }
  .rummy .seat .dealer { right: -5px; bottom: -5px; }
  .rummy .seat.is-ready .face { box-shadow: 0 0 0 2px var(--chip), 0 0 0 4px var(--good); }
  /* (a tab on the chip's bottom edge, in the row's spare padding: clear of
     the name, and right of the count, which is just a number) */
  .rummy .seat button.badge { position: absolute; right: 4px; bottom: -9px; width: auto; min-height: 0; height: 15px; padding: 0 5px; font-size: 9.5px; line-height: 1; z-index: 1; box-shadow: 0 1px 3px rgba(0, 0, 0, .4); }
  .rummy .seats { padding-bottom: 9px; }
  .rummy .seat .passfor .long { display: none; }
  .rummy .seat .passfor .short { display: inline; }
  .bar .more { min-height: 44px; min-width: 44px; }
  .rummy .tool { min-height: 40px; }
  .rummy .tool.mover { min-height: 40px; }
  table.scores th, table.scores td { padding: 6px 4px; font-size: 13px; }
  table.scores td.total, table.scores thead th:last-child { position: sticky; right: 0; background: var(--sheet); }
  /* every hand in view on a phone: a ring round the 0 says who went out
     (as on the chart), and how far behind is left to the chart */
  table.scores th, table.scores td { padding: 6px 3px; }
  table.scores th[scope="row"] { max-width: 5.5em; }
  table.scores td.place { font-size: 12px; }
  table.scores .outmark { display: inline-block; min-width: 1.5em; border: 1.5px solid currentColor; border-radius: 1em; text-align: center; line-height: 1.25; }
  table.scores .outmark small, table.scores td.total small { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .revealrow { grid-template-columns: 1fr auto; }
  .revealrow .cards { grid-column: 1 / -1; order: 3; }
  .leftrow { grid-template-columns: minmax(0, 1fr); gap: 6px; }
  .leftwho { flex-direction: row; flex-wrap: wrap; align-items: baseline; gap: 0 10px; }
  .leftcards { gap: 8px 10px; }
  .leftovers { --cw-small: 34px; }
  .rummy .say { font-size: 14px; }
  .rummy .controls { flex-direction: column; align-items: stretch; gap: 6px; }
  .rummy .toolrow { justify-content: space-between; gap: 6px; }
  /* no room for ‹ › beside the sort switch: they take its place (it's
     hidden, not removed, so nothing moves) while cards are picked */
  .rummy .sorters .sortlabel, .rummy .sorters kbd { display: none; }
  .rummy .sorters { position: relative; }
  .rummy .tool.mover { position: absolute; top: 0; min-width: 48px; }
  .rummy .tool.mleft { left: 0; }
  .rummy .tool.mright { left: 56px; }
  .rummy .dock.picking .sorters .seg { visibility: hidden; }
  .rummy .seg.small button { padding: 2px 8px; font-size: 12px; min-height: 38px; white-space: nowrap; }
  .rummy .tool.maker { min-width: 7.6em; }
  .rummy .gamelog.drawer { right: 10px; width: calc(100% - 20px); }
  .rummy .tgroup { gap: 4px; }
  .rummy .tool { padding: 4px 8px; font-size: 14px; min-height: 38px; }
  .rummy .act { font-size: 15px; }
  .rummy .actions { width: 100%; grid-template-columns: 1fr 1fr; margin-left: 0; }
  .scoresheet .legend { display: none; }
}

/* small phones: the tools a little tighter, so Make stays beside the sort switch */
@media (max-width: 400px) {
  .rummy .seg.small button { padding: 2px 6px; }
  .rummy .toolrow, .rummy .tgroup { gap: 4px; }
  .rummy .tool { padding: 4px 6px; }
  .rummy .tool.maker { min-width: 6.6em; }
  .rummy .act { font-size: 14px; padding-inline: 6px; }
}

/* phones upright: what you're building is a little tighter, so the last
   hand's three runs fit across (table.js shrinks their cards if need be) */
@media (max-width: 640px) {
  .rummy .staging { gap: 6px; }
  .rummy .staging .group { padding: 4px 6px 6px; gap: 4px; }
  .rummy .staging .grouphead { gap: 4px; font-size: 12px; }
  .rummy .staging .grouphead .btn.quiet { padding: 2px 4px; font-size: 12px; min-height: 28px; }
}

/* the narrowest phones (320px): smaller piles, no note on an empty table,
   and what you're building floats over the foot of the list, as on a
   phone on its side, so the list keeps its room */
@media (max-width: 340px) {
  /* (a chip holds the glance's two figures, so four seats slide here,
     yours pinned at the end, rather than squeeze them out) */
  .rummy .seat { flex-basis: 80px; min-width: 80px; }
  .rummy .seat .who { column-gap: 4px; }
  .rummy .seat .pts .house-figure { font-size: 12px; }
  .rummy .piles { --cw: 36px; gap: 8px; padding: 2px 6px; }
  .rummy .pile { min-width: 76px; }
  .rummy .spread:has(> .tablenote:only-child) { display: none; }
  .rummy .staging {
    position: absolute; grid-column: 1; grid-row: 2; left: 0; right: 0; bottom: 0; top: auto; width: auto; max-width: none; max-height: 74px; padding: 4px;
    border-radius: 10px; background: var(--sheet); border: var(--chip-edge); box-shadow: 0 -8px 20px rgba(0, 0, 0, .4);
  }
  .rummy .staging { gap: 4px; padding: 3px 2px; }
  .rummy .staging .group { padding: 3px 4px 4px; gap: 2px; }
  .rummy .staging .grouphead { gap: 3px; }
  .rummy .staging .grouphead .btn.quiet { min-height: 24px; padding-inline: 2px; }
}


/* the narrowest phones */
@media (max-width: 380px) {
  /* the score table's places go (the rows are in finishing order, the
     winners colored), so every hand fits */
  table.scores td.place, table.scores thead th:empty { display: none; }
}
/* (small phones: the score table a little closer set, so the seventh hand
   fits beside the total) */
@media (max-width: 430px) {
  table.scores th, table.scores td { padding: 6px 2px; font-size: 12px; letter-spacing: -.02em; }
  table.scores th[scope="row"] { max-width: 4.6em; }
}
@media (max-width: 340px) {
  table.scores th, table.scores td { padding-inline: 1px; }
}
/* phones: the total stays at the right edge as the hands scroll under it,
   with a shadow, so a hand tucked beneath it shows there's more */
@media (max-width: 640px) {
  table.scores td.total, table.scores thead th:last-child { box-shadow: -8px 0 8px -6px rgba(0, 0, 0, .45); }
}

/* short screens (phones on their side): one compact row of moves, the log
   behind the menu (L), and every spare pixel to the table */
@media (max-height: 520px) {
  body { --cw: 44px; --cw-small: 30px; }
  #app { padding: 0; }
  .felt.rummy { height: 100dvh; padding: 6px max(10px, env(safe-area-inset-right, 0px)) max(6px, env(safe-area-inset-bottom, 0px)) max(10px, env(safe-area-inset-left, 0px)); border: 0; border-radius: 0; gap: 0; }
  .rummy .tablemain { gap: 4px; }
  .rummy .bar .title { font-size: 14px; }
  .rummy .seat { flex: 0 0 132px; min-width: 132px; width: 132px; grid-template-columns: auto minmax(0, 1fr); min-height: 32px; padding: 2px 6px 2px 2px; }
  .rummy .seat .badge:not(button) { display: none; }
  /* the piles beside the list; what you're building floats over the list */
  .rummy .board { grid-template-columns: auto minmax(0, 1fr); grid-template-rows: minmax(0, 1fr); }
  .rummy .piles { grid-row: 1; flex-direction: row; justify-content: flex-start; }
  /* (as wide as the two piles and their words, so the tiles start after them) */
  .rummy .piles, .rummy .piles.across { width: auto; }
  .rummy .staging {
    position: absolute; grid-column: 2; grid-row: 1; left: 0; right: 0; bottom: 0; top: auto; width: auto; max-width: none; padding: 4px;
    border-radius: 10px; background: var(--sheet); border: var(--chip-edge); box-shadow: 0 -8px 20px rgba(0, 0, 0, .4);
  }
  .felt.rummy .bar .tools { display: none; }
  .felt.rummy .bar .more { display: inline-flex; min-height: 34px; }
  .rummy .staging { max-height: 70px; }
  .rummy .staging .group { padding: 3px 8px; gap: 2px; flex-direction: row; align-items: center; }
  .rummy .staging .grouphead { flex-direction: column; align-items: flex-start; gap: 0; }
  .rummy .staging .grouphead .btn.quiet { min-height: 24px; }
  .rummy .dock { padding: 4px 8px 6px; gap: 4px; }
  .rummy .sayline { min-height: 1.45em; }
  .rummy .say { -webkit-line-clamp: 1; font-size: 13px; }
  .rummy .status { grid-template-columns: minmax(0, 1fr) 120px; }
  .rummy .timer { width: 120px; flex-direction: row; gap: 6px; align-items: center; }
  .rummy .timer .clock { flex-direction: row; align-items: center; gap: 6px; }
  .rummy .timer .clockbar { flex: 1; }
  .rummy .controls { flex-wrap: nowrap; flex-direction: row; gap: 6px; }
  .rummy .actions { width: auto; grid-template-columns: 150px 150px; }
  .rummy .tool, .rummy .act { min-height: 36px; font-size: 14px; }
  .rummy .hand { min-height: calc(var(--cw) * 1.4 + 20px); padding-top: 12px; }
  /* no margin above the cards for the "new" tag: it sits in the card's empty corner */
  .rummy .hand .card.fresh::after { bottom: 3px; left: 3px; }
}
@media (max-height: 520px) and (max-width: 900px) {
  .rummy .sorters .sortlabel { display: none; }
  /* (room for "Discard anyway?") */
  .rummy .actions { grid-template-columns: 150px 150px; }
}
/* phones on their side: no room for the keys on the dock's buttons (they
   still work), and the tools a little tighter, so nothing overlaps */
@media (max-height: 520px) {
  .rummy .dock kbd { display: none; }
  .rummy .act { padding-inline: 6px; }
  .rummy .toolrow, .rummy .tgroup { gap: 4px; }
  .rummy .tool { padding: 4px 8px; }
  .rummy .tool.maker { min-width: 6.6em; }
  .rummy .seg.small button { padding: 2px 8px; }
  /* ‹ › take the sort switch's place while cards are picked, as on a phone */
  .rummy .sorters { position: relative; }
  .rummy .tool.mover { position: absolute; top: 0; min-width: 48px; }
  .rummy .tool.mleft { left: 0; }
  .rummy .tool.mright { left: 56px; }
  .rummy .dock.picking .sorters .seg { visibility: hidden; }
}
@media (max-height: 520px) and (max-width: 700px) {
  .rummy .actions { grid-template-columns: 140px 140px; gap: 6px; }
  .rummy .act { padding-inline: 3px; }
}
/* the smallest phones on their side: the moves get a row of their own */
@media (max-height: 520px) and (max-width: 660px) {
  .rummy .controls { flex-wrap: wrap; }
  .rummy .actions { width: 100%; grid-template-columns: 1fr 1fr; }
}
/* phones on their side, 400px tall or less: slightly smaller cards, so the piles fit beside the list;
   the board never spills onto the moves */
@media (max-height: 400px) {
  body { --cw: 40px; }
  .rummy .board { overflow: clip; }
  .rummy .piles { padding: 2px 6px; gap: 8px; }
}

/* the smallest screens on their side (an iPhone SE, 568×320): one row of
   moves, the sort switch in the ⋯ menu, smaller cards */
@media (max-height: 340px) {
  body { --cw: 36px; --cw-small: 26px; }
  .felt.rummy { padding: 4px 8px; }
  .rummy .tablemain { gap: 4px; }
  .felt.rummy .bar .more { min-height: 30px; }
  .rummy .seat { min-height: 28px; padding-block: 1px; }
  .rummy .seat .face { width: 22px; height: 22px; }
  .rummy .sorters { display: none; }
  .rummy .dock { padding: 3px 8px 4px; gap: 2px; }
  .rummy .controls { flex-wrap: nowrap; }
  .rummy .actions { width: auto; grid-template-columns: 128px 128px; margin-left: auto; }
  .rummy .tool, .rummy .act { min-height: 32px; }
  .rummy .hand { min-height: calc(var(--cw) * 1.4 + 18px); padding-top: 10px; }
  /* (the piles' words go: there's room for the cards alone; screen readers keep them) */
  .rummy .pile .count { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .rummy .piles { gap: 6px; padding: 2px 6px; }
}
/* touch screens: every control at least 44px tall */
@media (pointer: coarse) {
  .rummy .seg.small button, .rummy .tool, .rummy .tool.mover, .rummy .act { min-height: 44px; }
  .felt.rummy .bar .btn { min-height: 44px; }
  .bar .more { min-width: 44px; }
}
/* (phones on their side, 400px tall or less: 40px, so the table keeps its room) */
@media (pointer: coarse) and (max-height: 400px) {
  .rummy .tool, .rummy .tool.mover, .rummy .act, .rummy .seg.small button { min-height: 40px; }
}
@media (pointer: coarse) and (max-height: 340px) {
  .rummy .tool, .rummy .act, .felt.rummy .bar .btn { min-height: 40px; }
}
@media (prefers-reduced-motion: reduce) {
  .rummy .dock { transition: none; }
}
