/* Corona Bar Euchre.
   The palette, the type and the buttons all come from the parlor painting:
   mahogany and dark green, brass plaques, gold leaf lettering. */

/* Self-hosted so the game makes no outside requests and works on a LAN with no
   internet at all. Both faces are SIL Open Font License; the licenses ship
   alongside them in public/fonts/. `swap` means text paints immediately in the
   fallback serif and upgrades when the file lands. */
@font-face {
  font-family: "Playfair Display";
  src: url("/fonts/playfair-400.woff2") format("woff2");
  font-weight: 400 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Playfair Display";
  src: url("/fonts/playfair-700.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Playfair Display";
  src: url("/fonts/playfair-900.woff2") format("woff2");
  font-weight: 800 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Cinzel";
  src: url("/fonts/cinzel-600.woff2") format("woff2");
  font-weight: 500 700;
  font-style: normal;
  font-display: swap;
}

:root {
  /* The parlor's own palette: mahogany, dark green baize, brass and gold leaf. */
  --bg: #14100c;
  --wood: #2a1a0e;
  --wood-lit: #3d2714;
  --panel: #241609;
  --line: #4d3419;
  --line-lit: #7a5a2b;
  --text: #efe2c8;
  --muted: #a0906e;
  --gold: #e3c274;
  --gold-dim: #b2903f;
  --baize: #2f6b3f;
  --accent: #c9a44c;
  --warn: #d08a3f;
  --red: #b4342f;

  --display: "Playfair Display", "Palatino Linotype", "Book Antiqua", Palatino, Georgia, serif;
  --engraved: "Cinzel", "Trajan Pro", "Palatino Linotype", Georgia, serif;
  --body: "Palatino Linotype", "Book Antiqua", Palatino, Georgia, serif;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  padding: 1rem;
  font: 16px/1.55 var(--body);
  color: var(--text);
  -webkit-text-size-adjust: 100%;
  /* Dark panelled wood behind everything. */
  background:
    radial-gradient(ellipse at 50% 0%, rgba(120, 80, 30, .16), transparent 60%),
    linear-gradient(180deg, #1a120a 0%, #120d08 100%),
    var(--bg);
  background-attachment: fixed;
  min-height: 100vh;
}

h1 { font-family: var(--display); font-weight: 800; font-size: 1.8rem; margin: 0 0 .25rem; }
h2 {
  font-family: var(--engraved); font-size: .82rem; font-weight: 600;
  margin: 1.5rem 0 .6rem; color: var(--gold-dim);
  text-transform: uppercase; letter-spacing: .16em;
}
.sub { color: var(--muted); margin-top: 0; }
.muted { color: var(--muted); }
.hidden { display: none !important; }

.screen { max-width: 760px; margin: 0 auto; }

/* ------------------------------------------------------- brass plaque buttons

   Every button is a small engraved plate screwed to the wall: dark bevelled
   metal, gold lettering cut into it, a highlight along the top edge and a
   shadow underneath. Pressing one pushes it into the wood. */

button {
  font-family: var(--engraved);
  font-size: .84rem;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  padding: .6rem 1.1rem;
  border: 1px solid #6b4a20;
  border-radius: 4px;
  background: linear-gradient(180deg, #4a3218 0%, #33210f 52%, #241608 100%);
  color: var(--gold);
  cursor: pointer;
  text-shadow: 0 -1px 0 rgba(0, 0, 0, .9);
  box-shadow:
    inset 0 1px 0 rgba(226, 189, 116, .28),
    inset 0 -3px 8px rgba(0, 0, 0, .55),
    0 2px 6px rgba(0, 0, 0, .5);
  transition: filter .12s, transform .08s, box-shadow .12s;
}
button:hover:not(:disabled) {
  filter: brightness(1.28);
  border-color: var(--line-lit);
}
button:active:not(:disabled) {
  transform: translateY(1px);
  box-shadow: inset 0 2px 7px rgba(0, 0, 0, .8), 0 1px 2px rgba(0, 0, 0, .4);
}
button:disabled { opacity: .35; cursor: default; }

/* The one you're meant to press: polished brass rather than dark bronze. */
button.primary {
  background: linear-gradient(180deg, #e2c078 0%, #c39c47 45%, #96702a 100%);
  border-color: #8a6725;
  color: #2b1c06;
  text-shadow: 0 1px 0 rgba(255, 240, 200, .45);
  box-shadow:
    inset 0 1px 0 rgba(255, 244, 214, .75),
    inset 0 -3px 8px rgba(96, 66, 16, .5),
    0 3px 9px rgba(0, 0, 0, .55);
}

/* Quiet inline actions — no plaque, just gold text. */
button.link {
  background: none; border: none; box-shadow: none;
  color: var(--gold-dim);
  font-family: var(--body); font-size: .9rem;
  letter-spacing: normal; text-transform: none;
  text-decoration: underline; text-underline-offset: 3px;
  padding: 0; text-shadow: none;
}
button.link:hover:not(:disabled) { color: var(--gold); filter: none; }
button.link:active:not(:disabled) { transform: none; box-shadow: none; }

input {
  font-family: var(--body); font-size: 1rem;
  padding: .55rem .7rem;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: #0f0a05;
  color: var(--text);
  min-width: 0;
  box-shadow: inset 0 2px 6px rgba(0, 0, 0, .6);
}
input:focus { outline: none; border-color: var(--line-lit); }
input::placeholder { color: #7a6b50; }

.row { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; margin: .75rem 0; }

.status {
  position: fixed; top: 0; left: 0; right: 0;
  padding: .4rem 1rem;
  background: linear-gradient(180deg, #c98b3c, #a56a25);
  color: #1a1006;
  font-family: var(--body);
  font-size: .85rem;
  text-align: center;
  z-index: 50;
}
.status:empty { display: none; }

/* ------------------------------------------------------------- player list */

.player-list, .table-list { list-style: none; padding: 0; margin: 0; display: flex; flex-wrap: wrap; gap: .5rem; }
.player-list small, .table-list small { color: var(--muted); font-size: .75rem; }

/* Pick your name and your dog — each one a little framed portrait. */
.playercard {
  display: flex; align-items: center; gap: .8rem;
  padding: .45rem 1.1rem .45rem .45rem;
  min-width: 13.5rem;
  letter-spacing: normal;
  text-transform: none;
}
.playercard .label { display: flex; flex-direction: column; align-items: flex-start; line-height: 1.3; }
.playercard strong {
  font-family: var(--display); font-weight: 700; font-size: 1.25rem;
  color: var(--text); letter-spacing: .01em;
}
.playercard small { color: var(--muted); font-family: var(--body); letter-spacing: normal; }
.playercard small.presence { color: #7fc08c; }
.playercard.online .portrait { box-shadow: inset 0 0 0 1px rgba(226, 189, 116, .18), 0 0 0 2px #4f9a5f, 0 2px 5px rgba(0, 0, 0, .5); }
.portrait {
  border: 1px solid #6b4a20;
  box-shadow: inset 0 0 0 1px rgba(226, 189, 116, .18), 0 2px 5px rgba(0, 0, 0, .5);
}
.portrait {
  position: relative;
  width: 68px; height: 68px; flex: 0 0 68px;
  border-radius: 8px; overflow: hidden;
  background: #2a3630; color: var(--text);
  display: grid; place-items: center;
  font-size: 1.2rem; font-weight: 700;
}
/* The dog covers the initial; if the image is missing, the initial shows. */
.portrait img, .badge .avatar img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover; display: block;
}
.table-list { flex-direction: column; }
.table-list li {
  border: 1px solid var(--line);
  border-radius: 5px;
  padding: .65rem .9rem;
  display: flex; justify-content: space-between; align-items: center; gap: 1rem;
  background: linear-gradient(180deg, rgba(61, 39, 20, .55), rgba(26, 16, 8, .55));
  box-shadow: inset 0 1px 0 rgba(226, 189, 116, .12);
}
.table-list li > div > div:first-child { font-family: var(--display); font-weight: 700; }

/* ------------------------------------------------------------------- table */

.topbar {
  display: flex; justify-content: space-between; align-items: center;
  gap: 1rem; margin-bottom: 1rem;
  font-family: var(--display); font-size: 1.05rem;
}
.score { font-variant-numeric: tabular-nums; color: var(--muted); font-size: .85rem; }

.seats { display: grid; grid-template-columns: repeat(2, 1fr); gap: .5rem; margin-bottom: 1rem; }
.seat {
  border: 1px solid var(--line); border-radius: 5px; padding: .5rem .7rem; font-size: .9rem;
  background: linear-gradient(180deg, rgba(61, 39, 20, .5), rgba(26, 16, 8, .5));
}
.seat strong { font-family: var(--display); font-size: 1rem; }
.seat.you { border-color: var(--accent); }
.seat.turn { background: #23302a; }
.seat .role { color: var(--muted); font-size: .75rem; display: block; }
.seat .offline { color: var(--warn); }
.seat .sitting-out { color: var(--muted); font-style: italic; }

/* ------------------------------------------------------------------- felt */

/* A plain felt table. Seat positions below are symmetric about the middle, so
   unlike the old painted-room background they aren't tied to any image. The
   table edge and the pool of lamplight are drawn in CSS. */
.felt {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 10;
  max-height: 70vh;
  margin: 0 auto 1rem;
  border-radius: 14px;
  overflow: hidden;
  background-color: #2c6740;
  background-image:
    radial-gradient(ellipse 62% 58% at 50% 46%, rgba(130, 205, 150, .18), transparent 70%),
    url('/img/felt.webp');
  background-size: cover, cover;
  background-position: center, center;
  box-shadow:
    inset 0 0 0 3px rgba(58, 34, 16, .92),     /* the table edge */
    inset 0 0 0 6px rgba(150, 110, 55, .30),   /* brass bead inside it */
    inset 0 0 130px rgba(0, 0, 0, .6),         /* light falls off at the rails */
    0 10px 30px rgba(0, 0, 0, .5);
}

/* Trump stays visible for the whole hand, not just between tricks. */
.trumppill {
  position: absolute; top: 10px; left: 10px; z-index: 3;
  display: flex; align-items: center; gap: .45rem;
  padding: .35rem .8rem;
  border-radius: 999px;
  background: rgba(10, 14, 10, .82);
  border: 1px solid rgba(226, 189, 116, .4);
  box-shadow: 0 2px 8px rgba(0, 0, 0, .6);
  font-family: var(--engraved);
  font-size: .78rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--gold);
}
.trumppill b { font-size: 1.9rem; line-height: 1; color: #f0f0ea; }
.trumppill b.red { color: #ef6a60; }
.trumppill:empty { display: none; }

.scorebox {
  position: absolute; top: 8px; right: 8px;
  display: flex; flex-direction: column; gap: 2px;
  font-size: .7rem; text-align: center; z-index: 3;
}
.scorebox div {
  padding: .15rem .5rem; border-radius: 4px;
  display: flex; gap: .4rem; align-items: baseline; justify-content: space-between;
  min-width: 4.2rem;
}
.scorebox div { border: 1px solid rgba(226, 189, 116, .35); box-shadow: 0 2px 6px rgba(0,0,0,.6); }
.scorebox .us { background: linear-gradient(180deg, #245b9e, #163c6b); }
.scorebox .them { background: linear-gradient(180deg, #9e3a30, #6b201a); }
.scorebox span { font-family: var(--engraved); font-size: .62rem; letter-spacing: .1em; text-transform: uppercase; }
.scorebox span { opacity: .75; }
.scorebox b { font-size: 1rem; font-variant-numeric: tabular-nums; }

/* Seat badges. Position is relative to the viewer: you are always bottom. */
.badge {
  position: absolute; z-index: 3;
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  transform: translate(-50%, -50%);
  width: max-content;
}
/* The inner wrapper carries the team/turn classes, so these are descendant
   selectors rather than compound ones. */
.badge > div { display: flex; flex-direction: column; align-items: center; gap: 2px; }
.badge .chip {
  display: flex; align-items: center; gap: .35rem;
  padding: .2rem .45rem .2rem .2rem;
  border-radius: 8px; border: 2px solid var(--line);
  background: rgba(12, 18, 14, .82);
}
.badge .chip.portrait-only { padding: .25rem; }
.badge .them .chip { border-color: #c4483c; }
.badge .us .chip { border-color: #3d7fd1; }
.badge .turn .chip { box-shadow: 0 0 0 3px rgba(255, 214, 102, .85); }
.badge .out .chip { opacity: .4; }
.badge .avatar {
  position: relative;
  width: 68px; height: 68px; border-radius: 8px;
  background: #2a3630; color: var(--text);
  display: grid; place-items: center;
  font-size: 1.5rem; font-weight: 700;
  overflow: hidden;
}
.badge .tricks { font-size: 1.5rem; font-weight: 700; font-variant-numeric: tabular-nums; min-width: 1.2rem; text-align: center; }
.badge .who { font-family: var(--display); font-size: 1.05rem; font-weight: 700; text-shadow: 0 1px 3px rgba(0,0,0,.95), 0 0 10px rgba(0,0,0,.7); }
.badge .tag { font-size: .75rem; color: #d8e8dc; text-shadow: 0 1px 3px rgba(0,0,0,.95); }
.badge .tag.warn { color: #f0b27a; }
.badge .dealer {
  position: absolute; top: -9px; right: -13px;
  width: 26px; height: 26px; border-radius: 50%;
  background: #f2f0e8; color: #17181a;
  font-size: .8rem; font-weight: 800;
  display: grid; place-items: center;
  border: 2px solid #b9b4a3;
}

/* Evenly round the table, in the viewer's own orientation. */
.badge.pos-top    { top: 14%; left: 50%; }
.badge.pos-bottom { top: 86%; left: 50%; }
.badge.pos-left   { top: 50%; left: 13%; }
.badge.pos-right  { top: 50%; left: 87%; }

/* Cards played, pulled in toward the middle from each seat. */
.cardslot {
  position: absolute; z-index: 2;
  transform: translate(-50%, -50%);
}
/* Cards meet in the middle, one step in from each seat. */
.cardslot.pos-top    { top: 33%; left: 50%; }
.cardslot.pos-bottom { top: 67%; left: 50%; }
.cardslot.pos-left   { top: 50%; left: 32%; }
.cardslot.pos-right  { top: 50%; left: 68%; }
.cardslot .card { box-shadow: 0 4px 12px rgba(0, 0, 0, .6); }
.cardslot.won .card { outline: 3px solid #ffd666; }

.center {
  position: absolute; top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  z-index: 1;
  text-align: center;
  color: #d6e6da;
  font-size: .8rem;
  text-shadow: 0 1px 4px rgba(0, 0, 0, .9);
}
.center .trump { font-size: 1.5rem; font-weight: 800; line-height: 1.1; }
.center .trump.red { color: #ff7b72; }
.center .upcard { margin-bottom: .3rem; }

.prompt { min-height: 1.5rem; margin-bottom: .6rem; font-family: var(--display); font-size: 1.1rem; color: var(--text); }
.actions { display: flex; gap: .5rem; flex-wrap: wrap; margin-bottom: 1rem; }

.hand { display: flex; gap: .4rem; flex-wrap: wrap; justify-content: center; min-height: 4.4rem; }
.prompt, .actions { text-align: center; justify-content: center; }

.card {
  display: inline-flex; align-items: center; justify-content: center;
  width: 3rem; height: 4.2rem;
  border-radius: 6px;
  background: #f2f0e8; color: #17181a;
  font-size: 1.15rem; font-weight: 700;
  border: 1px solid #c9c5b6;
  cursor: default;
  user-select: none;
}
.card.red { color: var(--red); }
.card.playable { cursor: pointer; box-shadow: 0 0 0 2px var(--accent); }
.card.playable:hover { transform: translateY(-4px); }
.card.dim { opacity: .35; }
.card.facedown {
  background-image: url('/img/cardback.webp');
  background-size: cover;
  background-position: center;
  border-color: #4a2b22;
  color: transparent;
}

/* The pack, with the turned-up card resting on it. */
.kitty { position: relative; display: inline-block; }
.kitty .facedown { position: absolute; top: -5px; left: -7px; transform: rotate(-7deg); z-index: 0; }
.kitty .card:not(.facedown) { position: relative; z-index: 1; }

/* ------------------------------------------------------------ title screen */

.title { max-width: 860px; }

.titleart {
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: 14px;
  overflow: hidden;
  margin-bottom: 1.25rem;
  /* Stands in for the painting until title.webp exists. */
  background:
    radial-gradient(ellipse at 50% 60%, rgba(60, 130, 80, .5) 0%, transparent 60%),
    linear-gradient(180deg, #241a12 0%, #34251a 45%, #1a1410 100%);
  box-shadow: 0 12px 36px rgba(0, 0, 0, .5);
  display: grid; place-items: end center;
}
/* The title painting is already framed for this box, so show all of it. */
.titleart img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: center; }
/* Just enough shadow at the foot of the wall to seat the type. */
.titleart::after {
  content: ''; position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(180deg, transparent 0%, transparent 52%, rgba(4, 8, 5, .82) 100%);
}
.titlemark {
  position: relative; z-index: 2;
  width: 100%; padding: 2rem 1rem 1.4rem;
  text-align: center;
}
/* Painted gold lettering on the wainscoting — a gradient fill for the leaf,
   a hard dark edge underneath so it reads as applied to the wood. */
.titlemark h1 {
  margin: 0;
  font-family: var(--display);
  font-weight: 900;
  font-size: clamp(1.6rem, 6.2vw, 3.1rem);
  letter-spacing: .015em;
  line-height: 1.05;
  background: linear-gradient(178deg, #fdf0cd 0%, #e6c67e 42%, #b98f36 68%, #f0dca4 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  filter: drop-shadow(0 2px 1px rgba(0, 0, 0, .95)) drop-shadow(0 6px 18px rgba(0, 0, 0, .8));
}

.titlebuttons { display: grid; gap: .7rem; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); }
button.big { padding: 1rem 1rem; font-size: .95rem; letter-spacing: .13em; }

.corner {
  position: fixed; top: .6rem; z-index: 60;
  width: 2.1rem; height: 2.1rem; padding: 0;
  border-radius: 50%; font-size: .95rem; line-height: 1; letter-spacing: 0;
  opacity: .7;
}
.corner:hover { opacity: 1; }
.mute { right: .6rem; }
.full { right: 3.1rem; }
.mute.off { opacity: .4; text-decoration: line-through; }

/* --------------------------------------------------------------- standings */

.table-scroll { overflow-x: auto; }

table.stats { border-collapse: collapse; width: 100%; font-size: .9rem; white-space: nowrap; }
table.stats th, table.stats td { padding: .45rem .6rem; text-align: right; border-bottom: 1px solid var(--line); }
table.stats th:first-child, table.stats td:first-child { text-align: left; }
table.stats th {
  font-family: var(--engraved);
  color: var(--gold-dim); font-weight: 600; font-size: .68rem;
  text-transform: uppercase; letter-spacing: .1em;
  cursor: pointer; user-select: none; position: sticky; top: 0;
  background: #16100a;
  border-bottom: 1px solid var(--line);
}
table.stats th:hover { color: var(--gold); }
table.stats th.sorted { color: var(--gold); }
table.stats td:first-child { font-family: var(--display); font-weight: 700; }
table.stats tbody tr:hover { background: rgba(61, 39, 20, .5); }
table.stats td { font-variant-numeric: tabular-nums; }
table.stats tbody tr:hover { background: var(--panel); }
table.stats .thin { color: var(--muted); }

/* --------------------------------------------------------- shuffle and deal */

.deallayer { position: absolute; inset: 0; z-index: 4; pointer-events: none; }

.deallayer .deck {
  position: absolute; left: 50%; top: 50%;
  width: 3rem; height: 4.2rem; margin: -2.1rem 0 0 -1.5rem;
  animation: riffle .9s ease-in-out 1 both;
  box-shadow: 0 4px 14px rgba(0, 0, 0, .7);
}
/* The pack squares itself up before the first card goes out. */
@keyframes riffle {
  0%   { transform: rotate(-7deg) translateY(0) scale(1); }
  22%  { transform: rotate(6deg) translateY(-5px) scale(1.03); }
  44%  { transform: rotate(-5deg) translateY(3px) scale(.99); }
  66%  { transform: rotate(3deg) translateY(-2px) scale(1.01); }
  100% { transform: rotate(0deg) translateY(0) scale(1); }
}

.deallayer .dealt {
  position: absolute; left: 50%; top: 50%;
  width: 2.4rem; height: 3.4rem; margin: -1.7rem 0 0 -1.2rem;
  opacity: 0;
  animation: dealfly .55s cubic-bezier(.22, .7, .3, 1) both;
}
@keyframes dealfly {
  0%   { transform: translate(0, 0) rotate(0deg) scale(.7); opacity: 0; }
  12%  { opacity: 1; }
  85%  { opacity: 1; }
  100% { transform: translate(var(--dx), var(--dy)) rotate(var(--rot, 8deg)) scale(1); opacity: 0; }
}

/* Nothing to click while the cards are still in the air. */
.board.is-dealing .hand { opacity: .25; pointer-events: none; transition: opacity .3s; }

/* ------------------------------------------------- announcement placeholder */

.announce {
  position: fixed; inset: 0;
  display: grid; place-items: center;
  background: rgba(0, 0, 0, .55);
  z-index: 40;
  pointer-events: none;
}
.announce span {
  font-family: var(--display);
  font-size: clamp(2rem, 12vw, 5rem);
  font-weight: 900;
  color: var(--gold);
  text-transform: uppercase;
  letter-spacing: .02em;
  text-align: center;
  padding: 0 1rem;
}

@media (max-width: 480px) {
  .seats { grid-template-columns: 1fr; }
  .card { width: 2.6rem; height: 3.7rem; font-size: 1rem; }
  .playercard { min-width: 100%; }
  .titlebuttons { grid-template-columns: 1fr; }
}

/* ---------------------------------------------------------- phone, sideways

   A phone held horizontally is about 844x390. The felt keeps its aspect ratio
   and fills the height — letterboxed at the sides against the wood rather than
   stretched, so the badges stay on the painted chairs. The hand, the prompt and
   the buttons sit on top of the felt instead of below it, which is the only way
   they all fit. */
@media (orientation: landscape) and (max-height: 560px) {
  body { padding: 0; }
  .screen { max-width: none; }

  #screen-table .topbar { display: none; }

  #board { position: relative; height: 100vh; display: grid; place-items: center; }
  .felt {
    height: 100vh;
    max-height: 100vh;
    width: auto;
    max-width: 100%;
    aspect-ratio: 16 / 10;
    margin: 0;
    border-radius: 0;
  }

  /* Overlaid on the felt, anchored to the bottom of the screen. */
  .prompt, .actions, .hand {
    position: absolute; left: 0; right: 0; z-index: 6; margin: 0;
  }
  .prompt {
    bottom: 5.4rem; font-size: .8rem;
    min-height: 0; text-shadow: 0 2px 6px rgba(0, 0, 0, 1), 0 0 14px rgba(0, 0, 0, .9);
  }
  .actions { bottom: 3.5rem; gap: .3rem; }
  .actions button { padding: .3rem .65rem; font-size: .65rem; }
  .hand { bottom: .35rem; gap: .25rem; min-height: 0; }

  .badge .avatar { width: 46px; height: 46px; font-size: 1rem; }
  .badge .who { font-size: .78rem; }
  .badge .tag { font-size: .6rem; }
  .badge .tricks { font-size: 1.05rem; }
  .badge .dealer { width: 19px; height: 19px; font-size: .6rem; top: -7px; right: -10px; }
  /* Your own badge moves off the centre line so the prompt and your cards have
     it to themselves. You know your own name, so that comes off too. */
  .badge.pos-bottom { top: 84%; left: 15%; }
  .badge.pos-bottom .who { display: none; }

  .card { width: 2.2rem; height: 3.1rem; font-size: .9rem; border-radius: 4px; }
  .cardslot .card { width: 2rem; height: 2.8rem; font-size: .8rem; }

  .trumppill { padding: .18rem .45rem; font-size: .55rem; gap: .3rem; }
  .trumppill b { font-size: 1.2rem; }
  .scorebox { font-size: .55rem; gap: 1px; }
  .scorebox div { min-width: 3.4rem; padding: .1rem .35rem; }
  .scorebox b { font-size: .8rem; }

  /* Fixed to the viewport, clear of the letterboxed felt. */
  .corner { width: 1.7rem; height: 1.7rem; font-size: .72rem; top: .3rem; }
  .mute { right: .3rem; }
  .full { right: 2.2rem; }
  #btn-leave {
    display: block; position: fixed; top: .5rem; left: .5rem; z-index: 60;
    font-size: .7rem;
  }

  .announce span { font-size: clamp(1.6rem, 9vw, 3rem); }
}

/* A phone held upright can still play, but say what it's missing. */
@media (orientation: portrait) and (max-width: 560px) {
  .felt { max-height: 46vh; }
}
