:root {
  --felt: #0f5a3a;
  --felt-dark: #083826;
  --ink: #f4f1e8;
  --muted: #b9c9bf;
  --accent: #f2c14e;
  --red: #c8242f;
  --black: #1b1b1f;
  --cw: 68px;
  --ch: 96px;
  --mw: 40px;
  --mh: 56px;

  font-family:
    system-ui,
    -apple-system,
    'Segoe UI',
    Roboto,
    sans-serif;
}

* {
  box-sizing: border-box;
  -webkit-tap-highlight-color: transparent;
}

html {
  /* iOS Safari still needs the prefixed forms of text-size-adjust, user-select and touch-callout. */

  /* stylelint-disable-next-line property-no-vendor-prefix */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  margin: 0;
  min-height: 100vh;
  min-height: 100dvh; /* the mobile address bar collapses; vh alone would overflow */
  background: #062a1c;
  color: var(--ink);

  /* Keep clear of notches and home bars (the viewport uses viewport-fit=cover). */
  padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
}

/* No double-tap zoom or 300ms tap delay on controls. */
button,
select,
input,
.card {
  touch-action: manipulation;
}

@media (pointer: coarse) {
  button,
  select {
    min-height: 44px;
  }

  /* The round buttons (? and the dialog ×) are 36px circles; the 44px minimum height above would stretch them
     into ovals, so on a touch screen they grow to 44px in both directions and stay round. (The element in the
     selector is there so this beats their own width and height, which come later in the file.) */
  button.help-btn,
  button.dialog-x {
    width: 44px;
    height: 44px;
  }
}

button,
select {
  font: inherit;
  color: inherit;
  background: #1f6b4b;
  border: 1px solid #3c8a68;
  border-radius: 8px;
  padding: 7px 14px;
  cursor: pointer;
}

button:hover:not(:disabled) {
  background: #278059;
}

button:disabled {
  opacity: 0.4;
  cursor: default;
}

button.primary {
  background: var(--accent);
  color: #222;
  border-color: #d9a634;
  font-weight: 600;
}

button.primary:hover:not(:disabled) {
  background: #ffd36b;
}

button.ghost {
  background: transparent;
}

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 20px;
  background: #041d13;
  border-bottom: 1px solid #154a33;
}

.topbar h1 {
  margin: 0;
  line-height: 0;
}

.topbar h1 svg {
  display: block;
  height: 48px;
  width: auto;
}

.controls {
  display: flex;
  gap: 10px;
  align-items: center;
  margin-left: auto;
}

.controls label {
  display: flex;
  gap: 6px;
  align-items: center;
  color: var(--muted);
}

/* The How to play dialog: a long page that scrolls inside the dialog. */
.help {
  width: min(680px, calc(100% - 24px));
  max-height: calc(100dvh - 32px);
  overflow-y: auto;
}

/* A close cross that stays in view while a long dialog scrolls. */
.dialog-x {
  position: sticky;
  top: 0;
  z-index: 1;
  float: right;
  width: 36px;
  height: 36px;
  margin: -6px -10px 0 8px;
  padding: 0;
  font-size: 1.4rem;
  line-height: 1;
  background: #0b3a27;
  border-radius: 50%;
}

.help h2 {
  margin-top: 0;
  color: var(--accent);
}

.help h3 {
  margin: 18px 0 6px;
  font-size: 1rem;
}

.help p,
.help li {
  line-height: 1.45;
}

.help ul {
  padding-left: 20px;
}

.rates {
  width: 100%;
  margin: 8px 0;
  border-collapse: collapse;
}

.rates th,
.rates td {
  padding: 5px 10px;
  text-align: left;
  border-bottom: 1px solid #1f5a40;
}

.help-btn {
  width: 36px;
  height: 36px;
  margin-left: 10px;
  padding: 0;
  border-radius: 50%;
  font-weight: 700;
}

/* The current online game in the lobby: a short list of facts. */
.facts {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 6px 16px;
  margin: 10px 0 14px;
}

.facts dt {
  color: var(--muted);
}

.facts dd {
  margin: 0;
  overflow-wrap: anywhere;
}

/* The settings of the solo game, shown but not editable. */
.chip {
  padding: 5px 12px;
  color: var(--muted);
  font-size: 0.85rem;
  white-space: nowrap;
  border: 1px solid #2a6a4c;
  border-radius: 999px;
}

/* The account menu: your name, and what you can do with the account. */
.account {
  position: relative;
  margin-left: 10px;
}

.account > summary {
  display: block;
  padding: 7px 14px;
  color: var(--ink);
  background: transparent;
  border: 1px solid #3c8a68;
  border-radius: 8px;
  cursor: pointer;
  list-style: none;
  user-select: none;
}

/* Safari still draws its own triangle unless this is hidden. */

/* stylelint-disable-next-line selector-no-vendor-prefix */
.account > summary::-webkit-details-marker {
  display: none;
}

.account > summary::after {
  content: ' ▾';
  color: var(--muted);
}

.account[open] > summary,
.account > summary:hover {
  background: #1f6b4b;
}

.account .menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 30;
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 150px;
  padding: 6px;
  background: #0b2a1d;
  border: 1px solid #3c8a68;
  border-radius: 10px;
  box-shadow: 0 10px 30px rgb(0 0 0 / 50%);
}

.account .menu button {
  width: 100%;
  text-align: left;
}

.layout {
  display: grid;
  grid-template-columns: 1fr 270px;
  gap: 14px;
  padding: 14px;
  height: calc(100vh - 56px);
  height: calc(100dvh - 56px);
  min-height: 640px;
}

.table {
  position: relative;
  display: grid;
  grid-template:
    'north north north' auto
    'west center east' 1fr
    'me me me' auto
    / 200px 1fr 200px;
  gap: 10px;
  padding: 16px;
  border-radius: 22px;
  background: radial-gradient(ellipse at center, #17784f 0%, var(--felt) 45%, var(--felt-dark) 100%);
  box-shadow:
    inset 0 0 60px rgb(0 0 0 / 50%),
    0 0 0 8px #3b2414,
    0 0 0 10px #22140a;
  overflow: hidden;
}

.seat {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 8px;
  border-radius: 14px;
  transition: background 0.2s;
}

.seat-north {
  grid-area: north;
}

.seat-west {
  grid-area: west;
  justify-content: center;
}

.seat-east {
  grid-area: east;
  justify-content: center;
}

.seat.active,
.me.active {
  background: rgb(242 193 78 / 12%);
  box-shadow: 0 0 0 2px rgb(242 193 78 / 55%);
}

.seat-name {
  font-weight: 600;
  display: flex;
  gap: 8px;
  align-items: center;
}

.count {
  background: rgb(0 0 0 / 35%);
  border-radius: 999px;
  padding: 1px 9px;
  font-size: 0.85rem;
}

.count.low {
  background: var(--red);
  animation: pulse 1.2s infinite;
}

@keyframes pulse {
  50% {
    opacity: 0.6;
  }
}

/* Phones show a single card-back with the count on it instead of the whole row. */
.stack {
  display: none;
  position: relative;
  width: var(--mw);
  height: var(--mh);
}

.stack .back {
  position: absolute;
  inset: 0;
  width: auto;
  height: auto;
  box-shadow:
    3px 3px 0 -1px #5a1420,
    6px 6px 0 -2px #3e0e16,
    0 2px 6px rgb(0 0 0 / 45%);
}

.stack .num {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.15rem;
  font-weight: 800;
  color: #fff;
  text-shadow:
    0 1px 4px #000,
    0 0 6px #000;
}

.stack .num.low {
  color: #ff8d8d;
}

.backs {
  display: flex;
  height: var(--mh);
}

.backs .back + .back {
  margin-left: -30px;
}

.seat-west .backs .back + .back,
.seat-east .backs .back + .back {
  margin-left: -33px;
}

.back {
  width: var(--mw);
  height: var(--mh);
  border-radius: 5px;
  border: 2px solid #fff;
  background:
    repeating-linear-gradient(45deg, transparent 0 4px, rgb(255 255 255 / 14%) 4px 5px),
    repeating-linear-gradient(-45deg, transparent 0 4px, rgb(255 255 255 / 14%) 4px 5px), #8a2233;
  box-shadow:
    inset 0 0 0 2px #8a2233,
    inset 0 0 0 3px rgb(255 255 255 / 45%),
    0 1px 3px rgb(0 0 0 / 40%);
}

.action {
  min-height: calc(var(--mh) + 4px);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 3px;
  color: var(--muted);
  font-style: italic;
}

.action .label {
  font-style: normal;
  font-size: 0.75rem;
  margin-left: 6px;
}

.thinking::after {
  content: '';
  animation: dots 1.2s steps(4) infinite;
}

@keyframes dots {
  0% {
    content: '';
  }

  25% {
    content: '.';
  }

  50% {
    content: '..';
  }

  75% {
    content: '...';
  }
}

.center {
  grid-area: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
}

/* The play on the table gets a soft glow so it stands out from the seats. */
.trick-cards:not(:empty) {
  padding: 8px 14px;
  border-radius: 12px;
  background: rgb(255 255 255 / 5%);
  box-shadow:
    0 0 0 2px rgb(130 195 255 / 55%),
    0 0 22px rgb(130 195 255 / 40%);
}

.trick-cards {
  display: flex;
  gap: 6px;
  min-height: var(--ch);
}

.trick-cards .card {
  animation: drop 0.25s ease-out;
}

@keyframes drop {
  from {
    transform: translateY(-14px) scale(1.05);
    opacity: 0;
  }
}

.trick-label {
  font-size: 1.05rem;
  font-weight: 600;
  text-align: center;
  min-height: 1.4em;
}

.trick-label small {
  display: block;
  font-weight: 400;
  color: var(--muted);
  font-size: 0.85rem;
}

.status {
  color: var(--accent);
  min-height: 1.3em;
  text-align: center;
}

.me {
  grid-area: me;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 10px;
  border-radius: 14px;

  /* The card size and overlap live here so the highlight can be exactly as wide as a full
     14-card hand (plus its side padding), not as wide as the table. */
  --overlap: 18px;
  --px: 10px;

  width: min(100%, calc(14 * var(--cw) - 13 * var(--overlap) + 2 * var(--px)));

  /* ...but never narrower than its controls (online has an extra button), or they wrap. */
  min-width: min(100%, max-content);
  justify-self: center;
}

.me-head {
  display: flex;
  gap: 20px;
  align-items: center;
  min-height: 28px;
}

.my-action {
  color: var(--muted);
  font-style: italic;
}

.sel-info {
  font-size: 0.95rem;
}

.sel-info .ok {
  color: #8fe3a8;
}

.sel-info .bad {
  color: #ff9a9a;
}

.played-fan {
  --cw: 52px;
  --ch: 74px;

  display: flex;
  justify-content: center;
  min-height: calc(var(--ch) + 14px);
  padding-bottom: 14px;
}

.played-fan .card + .card {
  margin-left: -12px;
}

.hand {
  display: flex;
  padding: 44px 0 28px; /* headroom for lifted (selected) cards, room for the arc below */
  min-height: calc(var(--ch) + 72px);

  /* Taps and swipes on the hand are handled in JS; vertical page scrolling still works. */
  touch-action: pan-y;

  /* stylelint-disable-next-line property-no-vendor-prefix */
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}

.hand .card + .card {
  margin-left: calc(-1 * var(--hand-overlap, var(--overlap)));
}

.hand .card {
  cursor: pointer;
  transition:
    transform 0.14s ease,
    box-shadow 0.14s ease;
}

@media (hover: hover) {
  .hand .card:hover {
    --lift: -8px;
  }
}

/* A selected card is lifted out of the hand with a glow: about a third of the card's height on
   desktop. It keeps its place in the stacking order (and its size): the card to its right stays in
   front of it, as in a held fan. Raising it above its neighbours, or enlarging it, covered the
   rank and suit of the next card, so you could not see what you were picking next to it. */
.hand .card.selected {
  --lift: -34px;

  box-shadow:
    0 0 0 3px var(--accent),
    0 0 18px 4px rgb(242 193 78 / 60%),
    0 12px 18px rgb(0 0 0 / 50%);
}

.hand.disabled .card {
  cursor: default;
}

.actions {
  display: flex;
  gap: 8px;
}

/* Cards: the face is an inline SVG (see src/card-art.js) that fills the card. */
.card .face {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.card {
  position: relative;
  flex: none;
  width: var(--cw);
  height: var(--ch);
  border-radius: 7px;
  background: linear-gradient(160deg, #fff 0%, #f3efe6 100%);
  color: var(--black);
  box-shadow:
    0 0 0 1px rgb(0 0 0 / 28%),
    0 2px 5px rgb(0 0 0 / 40%);

  /* stylelint-disable-next-line property-no-vendor-prefix */
  -webkit-user-select: none;
  user-select: none;

  /* --a, --y: position on the fan arc; --lift: hover/selected raise. */
  transform: translateY(calc(var(--y, 0px) + var(--lift, 0px))) rotate(var(--a, 0deg)) scale(var(--s, 1));
}

.card.red {
  color: var(--red);
}

.card.joker {
  background: linear-gradient(160deg, #fffbe8 0%, #f6e7b0 100%);
}

.card.mini {
  width: var(--mw);
  height: var(--mh);
  border-radius: 5px;
}

/* Log (the side panel: the play log above, chat below) */
.log {
  display: flex;
  flex-direction: column;
  min-height: 0;
  background: #041d13;
  border: 1px solid #154a33;
  border-radius: 14px;
  padding: 12px 14px;
  overflow-y: auto;
}

.log h2 {
  margin: 0 0 8px;
  font-size: 0.95rem;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.log ol {
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: 0.85rem;
}

/* The play log folds away: the heading is its toggle, with a chevron. */
.log-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  min-height: 0; /* the heading row, not a 44px touch button: landscape has no height to spare */
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  cursor: pointer;
}

.log-toggle::after {
  content: '';
  width: 7px;
  height: 7px;
  margin-right: 3px;
  border: solid currentcolor;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg) translateY(-2px);
  transition: transform 0.15s ease;
}

.log.collapsed .log-toggle::after {
  transform: rotate(-45deg);
}

.log.collapsed > ol {
  display: none;
}

.log.collapsed > h2 {
  margin-bottom: 0;
}

.log li {
  padding: 5px 0;
  border-bottom: 1px solid rgb(255 255 255 / 6%);
}

.log li.you {
  color: var(--accent);
}

.log li.sys {
  color: var(--muted);
  font-style: italic;
}

.log .cards-txt {
  color: var(--muted);
  font-family: ui-monospace, Consolas, monospace;
  font-size: 0.8rem;
}

/* End overlay and dialogs */
.overlay {
  position: fixed;
  inset: 0;
  background: rgb(0 0 0 / 60%);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 10;
}

.overlay[hidden] {
  display: none;
}

.panel,
dialog {
  background: #0b3a27;
  color: var(--ink);
  border: 1px solid #3c8a68;
  border-radius: 16px;
  padding: 22px 26px;
  max-width: 760px;
  box-shadow: 0 20px 60px rgb(0 0 0 / 60%);
}

.panel h2 {
  margin-top: 0;
  color: var(--accent);
}

.end-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 8px 0;
}

.end-row .who {
  width: 110px;
  font-weight: 600;
}

.end-row .cards {
  display: flex;
  gap: 3px;
  flex-wrap: wrap;
}

dialog::backdrop {
  background: rgb(0 0 0 / 55%);
}

/* Online mode */
[hidden] {
  display: none !important;
}

body.online .solo-only,
body.solo .online-only {
  display: none !important;
}

.muted {
  color: var(--muted);
}

.bad {
  color: #ff9a9a;
  min-height: 1.2em;
  margin: 6px 0;
}

.row {
  display: flex;
  gap: 10px;
  align-items: center;
  flex-wrap: wrap;
  margin: 10px 0;
}

.mode {
  display: flex;
}

button.seg {
  border-radius: 0;
  background: transparent;
  padding: 5px 12px;
}

.mode .seg:first-child,
.row > button.seg:first-child {
  border-radius: 8px 0 0 8px;
}

.mode .seg:last-child,
.row > button.seg:last-child {
  border-radius: 0 8px 8px 0;
}

button.seg.active {
  background: var(--accent);
  color: #222;
  border-color: #d9a634;
  font-weight: 600;
}

.clock {
  font-variant-numeric: tabular-nums;
  color: var(--muted);
  min-height: 1.3em;
}

.clock.urgent {
  color: #ff9a9a;
  font-weight: 700;
}

.lobby {
  border-radius: 22px;
  padding: 22px;
  overflow: auto;
  background: radial-gradient(ellipse at center, #17784f 0%, var(--felt) 45%, var(--felt-dark) 100%);
  box-shadow:
    inset 0 0 60px rgb(0 0 0 / 50%),
    0 0 0 8px #3b2414,
    0 0 0 10px #22140a;
}

.lobby-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 16px;
}

.panel-card {
  background: rgb(4 29 19 / 82%);
  border: 1px solid #154a33;
  border-radius: 14px;
  padding: 16px 20px;
}

.panel-card h2 {
  margin: 0 0 6px;
  color: var(--accent);
}

.panel-card h3 {
  margin: 14px 0 6px;
  font-size: 0.95rem;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.list li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 7px 0;
  border-bottom: 1px solid rgb(255 255 255 / 7%);
}

table.lb,
table.ls {
  width: 100%;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
}

table.lb th,
table.lb td,
table.ls th,
table.ls td {
  text-align: right;
  padding: 5px 6px;
  border-bottom: 1px solid rgb(255 255 255 / 7%);
}

table.lb th:nth-child(2),
table.lb td:nth-child(2) {
  text-align: left;
}

table.ls th:first-child,
table.ls td:first-child {
  text-align: left;
}

/* The luck-and-skill table has wider cells than a phone has room for: it scrolls inside its card. */
.ls-scroll {
  overflow-x: auto;
}

table.ls td {
  white-space: nowrap;
}

/* On a phone, drop Wins and Expected wins (Wins vs expected says the same thing) so the rest fits without scrolling. */
@media (max-width: 700px) {
  table.ls th:nth-child(3),
  table.ls td:nth-child(3),
  table.ls th:nth-child(4),
  table.ls td:nth-child(4) {
    display: none;
  }

  table.ls th,
  table.ls td {
    padding: 5px 4px;
    font-size: 0.85rem;
  }
}

table.lb th,
table.ls th {
  color: var(--muted);
  font-weight: 500;
  font-size: 0.85rem;
}

.field {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 10px 0;
}

input {
  font: inherit;
  color: var(--ink);
  background: #06281b;
  border: 1px solid #3c8a68;
  border-radius: 8px;
  padding: 8px 10px;
}

.lobby.admin {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.lobby.admin .lobby-grid {
  width: 100%;
}

.check {
  display: flex;
  gap: 8px;
  align-items: center;
  margin: 8px 0;
}

table.users td {
  text-align: left;
}

table.users td.actions-cell {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  justify-content: flex-end;
}

table.users td.actions-cell button {
  padding: 3px 9px;
  font-size: 0.85rem;
}

.list li.muted {
  justify-content: flex-start;
}

button.ghost.active {
  background: rgb(242 193 78 / 20%);
  border-color: var(--accent);
}

/* Side panel: the play log above, chat below */
.log > ol {
  flex: 1;
  overflow-y: auto;
  min-height: 80px;
}

.chat {
  border-top: 1px solid #154a33;
  margin-top: 10px;
  padding-top: 8px;
}

.chat h2 {
  margin: 0 0 6px;
}

.chat ol {
  list-style: none;
  margin: 0 0 8px;
  padding: 0;
  max-height: 190px;
  min-height: 60px;
  overflow-y: auto;
  font-size: 0.88rem;
  overflow-wrap: anywhere;
}

.chat li {
  padding: 3px 0;
  border: 0;
}

.chat li b {
  color: var(--accent);
  margin-right: 2px;
}

.chat .row {
  margin: 0;
  flex-wrap: nowrap;
}

.chat input {
  flex: 1;
  min-width: 0;
}

.chat .bad {
  margin: 4px 0 0;
  min-height: 0;
}

.end-row .pts {
  margin-left: auto;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.pts.win {
  color: #8fe3a8;
}

.pts.loss {
  color: #ff9a9a;
}

/* Landscape phones: very little height, so shrink everything and drop the side panel. */
@media (orientation: landscape) and (max-height: 520px) {
  :root {
    --cw: 40px;
    --ch: 58px;
    --mw: 22px;
    --mh: 32px;
  }

  .topbar {
    padding: 2px 10px;
  }

  .topbar h1 svg {
    height: 30px;
  }

  .layout {
    grid-template-columns: 1fr;
    height: auto;
    min-height: 0;
    padding: 4px 6px;
  }

  .log {
    display: none;
  }

  .table {
    grid-template-columns: 110px 1fr 110px;
    grid-template-rows: auto 1fr auto;
    padding: 4px 6px;
    gap: 2px;
    min-height: 0;
    border-radius: 14px;
  }

  .seat {
    padding: 1px;
    gap: 1px;
  }

  .seat-name {
    font-size: 0.72rem;
    white-space: nowrap;
  }

  /* The count sits on one card-back, as on a portrait phone. */
  .backs,
  .count {
    display: none;
  }

  .stack {
    display: block;

    --mw: 24px;
    --mh: 34px;
  }

  .stack .num {
    font-size: 0.9rem;
  }

  .action {
    min-height: 0;
    font-size: 0.72rem;
  }

  .status {
    font-size: 0.78rem;
    min-height: 0;
  }

  .me-head {
    order: 1;
    min-height: 0;
    gap: 10px;
    font-size: 0.78rem;
  }

  .actions {
    order: 3;
    gap: 6px;
  }

  .hand {
    order: 4;
    padding: 30px 0 0;
    min-height: calc(var(--ch) + 30px - 24px);
    margin-bottom: -24px;
  }

  .card.mini {
    width: 20px;
    height: 29px;
  }

  .center {
    gap: 3px;
  }

  .trick-cards {
    --cw: 30px;
    --ch: 43px;
  }

  .trick-cards:not(:empty) {
    padding: 4px 8px;
  }

  .trick-label {
    font-size: 0.85rem;
  }

  /* "played by" shares the line with the hand's name: with all three last plays showing, a
     two-line label made the table 7px taller than the screen. */
  .trick-label small {
    display: inline;
    margin-left: 0.4em;
  }

  .played-fan {
    display: none;
  }

  .me {
    --cw: 46px;
    --ch: 66px;
    --overlap: 24px;
    --px: 0px;

    /* wide enough for the whole row of buttons, which now includes Log (it is not just the hand's width) */
    width: min(100%, 540px);
    padding: 2px 0 0;
    gap: 2px;
  }

  .hand .card.selected {
    --lift: -26px;
  }

  .my-action {
    display: none;
  }

  button,
  select {
    padding: 3px 10px;
    min-height: 34px;
  }

  .topbar button,
  .topbar select {
    min-height: 30px;
  }
}

/* Phones: a narrower table with smaller cards and stacked seat labels. */
@media (max-width: 700px) {
  :root {
    --cw: 44px;
    --ch: 64px;
    --mw: 26px;
    --mh: 38px;
  }

  body {
    overflow-x: hidden;
  }

  button,
  select {
    padding: 5px 9px;
    font-size: 0.85rem;
  }

  .topbar {
    flex-wrap: wrap;
    gap: 6px;
    padding: 8px 10px;
  }

  /* Logo and account share the first row; the mode and game controls take the second. */
  .help-btn {
    order: 2;
    margin-left: auto;
  }

  .account {
    order: 2;
    margin-left: 6px;
  }

  .topbar h1 svg {
    height: 34px;
  }

  .controls {
    flex-wrap: wrap;
    gap: 6px;
    order: 3;
    flex-basis: 100%;
    margin-left: 0;
  }

  .layout {
    padding: 8px;
    gap: 8px;
  }

  .table {
    grid-template-columns: 78px 1fr 78px;
    padding: 8px;
    gap: 6px;
    border-radius: 16px;
    min-width: 0;
  }

  .seat {
    padding: 3px;
    min-width: 0;
  }

  .seat-name {
    flex-direction: column;
    gap: 2px;
    font-size: 0.78rem;
    text-align: center;
  }

  .count {
    padding: 0 6px;
    font-size: 0.72rem;
  }

  .backs .back + .back {
    margin-left: -19px;
  }

  .seat-west .backs .back + .back,
  .seat-east .backs .back + .back {
    margin-left: -21px;
  }

  .action {
    flex-wrap: wrap;
    font-size: 0.75rem;
    min-height: calc(var(--mh) + 2px);
  }

  .card.mini {
    width: 24px;
    height: 34px;
    border-radius: 4px;
  }

  .trick-cards {
    --cw: 34px;
    --ch: 49px;
  }

  .trick-cards .card + .card {
    margin-left: -8px;
  }

  .trick-label {
    font-size: 0.9rem;
  }

  .status {
    font-size: 0.85rem;
  }

  .center {
    min-width: 0;
    gap: 6px;
  }

  .played-fan {
    --cw: 34px;
    --ch: 48px;

    order: 2;
    min-height: calc(var(--ch) + 8px);
    padding-bottom: 8px;
  }

  .played-fan .card + .card {
    margin-left: -8px;
  }

  /* The hand: one curved row tucked into the bottom edge of the table, so the
     cards can be wide enough to tap while only their tops show. Controls sit
     above it. A selected card rises well clear of the row. */
  .me {
    --cw: 54px;
    --ch: 78px;
    --overlap: 32px; /* 22px of each card stays exposed to the finger */
    --px: 2px;

    padding: 6px 2px;
    min-width: 0;
  }

  .me-head {
    order: 1;
    flex-wrap: wrap;
    justify-content: center;
    gap: 6px 12px;
    min-height: 0;
    text-align: center;
  }

  .actions {
    order: 3;
    flex-wrap: wrap;
    justify-content: center;
  }

  .hand {
    order: 4;
    padding: 46px 0 16px; /* room above for a lifted card, and below for the arc of the fan */
    min-height: calc(var(--ch) + 46px + 16px);
    max-width: 100%;
    touch-action: pan-y;
  }

  .hand .card.selected {
    --lift: -38px;
  }

  /* Seats: the count sits on one card-back. */
  .backs,
  .count {
    display: none;
  }

  .stack {
    display: block;

    --mw: 34px;
    --mh: 48px;
  }

  .lobby {
    padding: 10px;
    border-radius: 16px;
  }

  .lobby-grid {
    grid-template-columns: 1fr;
  }

  .panel-card {
    padding: 12px 14px;
    overflow-x: auto;
  }

  table.users td.actions-cell {
    justify-content: flex-start;
  }

  .panel,
  dialog {
    padding: 16px;
    max-width: calc(100vw - 24px);
  }

  .end-row {
    flex-wrap: wrap;
  }

  .end-row .who {
    width: 100%;
  }
}

@media (max-width: 1100px) {
  .layout {
    grid-template-columns: 1fr;
    height: auto;
  }

  .log {
    max-height: 220px;
  }

  :root {
    --cw: 56px;
    --ch: 80px;
  }
}

/* The sign-in page, shown instead of the game until you are signed in. */
.signin {
  width: min(440px, calc(100% - 32px));
  margin: 12vh auto 0;
}

.signin h1 {
  margin: 0 0 12px;
  font-size: 1.6rem;
}

/* Text for screen readers only (the logo above it is a picture). */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.signin .logo svg {
  display: block;
  width: min(300px, 100%);
  height: auto;
  margin: 0 auto;
}

/* A portrait phone: the table fills the screen under the header, so the spare height goes to the middle
   (where the played cards show) and your hand stays at the bottom, under your thumb. */
@media (max-width: 700px) and (orientation: portrait) {
  body {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    min-height: 100dvh;
  }

  .layout {
    flex: 1 1 auto;
    min-height: 0;
  }

  /* The side seats hug their cards: stretched to the taller middle row, their "thinking" highlight
     would become a tall empty box. */
  .seat-west,
  .seat-east {
    align-self: center;
  }
}

/* On a phone the play log and chat are a sheet over the table, opened by the Log button, so the
   table keeps the whole screen. (A landscape phone, too short for a side panel, does the same.) */
.compact-only {
  display: none;
}

@media (max-width: 700px), (orientation: landscape) and (max-height: 520px) {
  .compact-only {
    display: inline-block;
  }

  .log {
    display: none;
  }

  body.log-open {
    overflow: hidden;
  }

  body.log-open .log {
    position: fixed;
    inset: 0;
    z-index: 40;
    display: flex;
    max-height: none;
    padding: 14px 16px calc(14px + env(safe-area-inset-bottom));
    border-radius: 0;
  }

  body.log-open .log-toggle::after {
    content: '×';
    width: auto;
    height: auto;
    margin: 0;
    font-size: 1.9rem;
    line-height: 1;
    border: 0;
    transform: none;
  }

  .log-btn.unread::after {
    content: '';
    display: inline-block;
    width: 8px;
    height: 8px;
    margin-left: 6px;
    background: var(--accent);
    border-radius: 50%;
  }
}

/* ---- turn alerts ---- */

/* The one-tap offer under the header (phones that can have alerts, until they say "not now"). */
.banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
  margin: 0 12px 8px;
  padding: 8px 12px;
  border: 1px solid var(--line, rgb(255 255 255 / 18%));
  border-radius: 10px;
  background: rgb(224 180 60 / 12%);
}

.banner[hidden] {
  display: none;
}

.banner-actions {
  display: flex;
  gap: 8px;
}

dialog.alerts {
  max-width: min(520px, 94vw);
}

.alerts-status {
  font-weight: 600;
}

.alerts-help {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
}

.alerts-help:empty {
  display: none;
}

.alerts-trouble {
  margin: 12px 0;
}

.alerts-trouble li {
  margin: 6px 0;
}

.ios-steps {
  padding-left: 1.3em;
}

.ios-steps li {
  margin: 8px 0;
}

/* ---- my solo stats ---- */
table.solo-stats .section th {
  padding-top: 14px;
  color: var(--accent);
  text-align: left;
}

table.solo-stats .total td {
  font-weight: 700;
  border-top: 1px solid #2a6a4c;
}

table.solo-stats td:not(:first-child),
table.solo-stats th:not(:first-child) {
  text-align: right;
}

/* ---- the name of a test copy of the site ---- */
.site-label {
  align-self: center;
  padding: 2px 10px;
  color: #1c1400;
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  background: var(--accent);
  border-radius: 999px;
}

.site-label[hidden] {
  display: none;
}
