/*
 * Royal Baccarat.
 *
 * THE ONE IDEA IN THIS FILE
 *
 * Everything is sized in multiples of a single unit, --u. The unit is derived
 * from the viewport, so the whole table scales as one piece: the cards, the
 * chips, the lettering and the gaps all keep their relationships, and there is
 * no width at which two of them disagree about how big the table is.
 *
 * Flexible rows then absorb whatever vertical space is left over, which is what
 * makes a tall phone and a wide laptop both look deliberate rather than stretched.
 *
 * NOBODY IS ASKED TO TURN THEIR DEVICE. There is no portrait overlay and no rule
 * that hides the table at an aspect ratio. Both shapes are laid out, and the
 * short-and-wide case gets its own smaller unit so six rows still fit.
 */

/* ------------------------------------------------------------------ *
 * Faces
 * ------------------------------------------------------------------ */

@font-face {
  font-family: "Playfair Display";
  src: url("../assets/fonts/playfair-var.woff2") format("woff2-variations");
  font-weight: 400 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("../assets/fonts/inter-var.woff2") format("woff2-variations");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

/* ------------------------------------------------------------------ *
 * Ground rules
 * ------------------------------------------------------------------ */

:root {
  /*
   * The unit the whole table is built from.
   *
   * Two things decide it. vmin keeps a hand of three cards and a row of three
   * betting areas inside the width they have; vh keeps six rows on a screen
   * that is wider than it is tall. The floor is for a very small phone and the
   * ceiling is where a big monitor stops needing a bigger table.
   */
  --u: clamp(4.4px, min(1.95vmin, 1.15vh), 10.5px);

  --serif: "Playfair Display", Georgia, "Times New Roman", serif;
  --sans: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  --ink: #f3ecdc;
  --ink-soft: rgba(243, 236, 220, 0.74);
  --ink-dim: rgba(243, 236, 220, 0.46);
  --gold: #c9a24a;
  --gold-bright: #e6c078;
  --gold-deep: #8a6a24;

  --player: #4a86d8;
  --banker: #c8433a;
  --tie: #33a06a;

  --night: #080a09;
  --walnut: #35210f;
  --walnut-light: #5a3a1c;

  --radius: calc(var(--u) * 1.1);
  --shadow-card: 0 calc(var(--u) * 0.5) calc(var(--u) * 1.6) rgba(0, 0, 0, 0.55);

  --travel: 320ms;
  --flip: 260ms;
  --fade: 220ms;

  --safe-t: env(safe-area-inset-top, 0px);
  --safe-r: env(safe-area-inset-right, 0px);
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-l: env(safe-area-inset-left, 0px);
}

/* The animation setting, in one place, alongside the timings the script uses. */
html[data-motion="quick"] {
  --travel: 134ms;
  --flip: 109ms;
  --fade: 120ms;
}
html[data-motion="none"] {
  --travel: 0ms;
  --flip: 0ms;
  --fade: 0ms;
}
html[data-motion="none"] * {
  animation-duration: 0.001ms !important;
  animation-iteration-count: 1 !important;
  transition-duration: 0.001ms !important;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

/*
 * The hidden attribute has to win.
 *
 * The browser's own rule for [hidden] is a bare `display: none` at the lowest
 * specificity there is, so any class that sets display beats it, and the
 * round summary stayed on screen as an empty black bar after being hidden.
 * Anything this page hides is hidden by setting the attribute, so this is the
 * one place that has to be emphatic.
 */
[hidden] {
  display: none !important;
}

html,
body {
  margin: 0;
  padding: 0;
  height: 100%;
  overflow: hidden;
  background: var(--night);
  color: var(--ink);
  font-family: var(--sans);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overscroll-behavior: none;
}

body {
  /* A phone that is being tapped should not flash a blue box or select a label. */
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

#app {
  height: 100%;
  height: 100dvh;
}

.stage {
  height: 100%;
}

svg {
  display: block;
}

/*
 * Every drawing is wrapped in a span, so the wrapper is what carries the size
 * and the drawing fills it. Icons drawn at a fixed size bring their own width
 * and height and simply sit on the line.
 */
.svg {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.svg > svg {
  display: block;
}

.shoe-art > .svg,
.legend-chip > svg,
.rack-chip > svg,
.stack-chip > svg,
.lobby-balance-chip > svg {
  width: 100%;
  height: 100%;
}

button {
  font: inherit;
  color: inherit;
  border: 0;
  background: none;
  cursor: pointer;
}

:focus-visible {
  outline: calc(var(--u) * 0.32) solid var(--gold-bright);
  outline-offset: calc(var(--u) * 0.22);
  border-radius: calc(var(--u) * 0.4);
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ------------------------------------------------------------------ *
 * The lobby
 * ------------------------------------------------------------------ */

.lobby {
  position: relative;
  height: 100%;
  overflow-y: auto;
  overflow-x: hidden;
  background:
    radial-gradient(140% 90% at 50% -10%, rgba(201, 162, 74, 0.14) 0%, rgba(8, 10, 9, 0) 55%),
    radial-gradient(100% 70% at 50% 120%, rgba(19, 62, 44, 0.5) 0%, rgba(8, 10, 9, 0) 60%),
    var(--night);
  padding: calc(var(--u) * 2 + var(--safe-t)) calc(var(--u) * 3 + var(--safe-r)) calc(var(--u) * 2 + var(--safe-b))
    calc(var(--u) * 3 + var(--safe-l));
}

.lobby-sheen {
  position: fixed;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(120% 80% at 50% 50%, rgba(0, 0, 0, 0) 40%, rgba(0, 0, 0, 0.6) 100%);
}

.lobby-inner {
  position: relative;
  max-width: calc(var(--u) * 116);
  margin: 0 auto;
  min-height: 100%;
  display: flex;
  flex-direction: column;
  gap: calc(var(--u) * 2.4);
  /* Centred when it fits, top aligned when it does not. Plain `center` on an
     overflowing column puts the brand off the top of the scroll area, where no
     amount of scrolling reaches it. */
  justify-content: flex-start;
  justify-content: safe center;
  padding: calc(var(--u) * 1) 0;
}

.brand {
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(var(--u) * 0.5);
}

.brand-crown {
  color: var(--gold-bright);
  filter: drop-shadow(0 calc(var(--u) * 0.2) calc(var(--u) * 0.7) rgba(0, 0, 0, 0.6));
}

.brand-name {
  margin: 0;
  font-family: var(--serif);
  font-weight: 700;
  font-size: calc(var(--u) * 3.4);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink);
  text-shadow: 0 calc(var(--u) * 0.2) calc(var(--u) * 1.4) rgba(0, 0, 0, 0.7);
}

.brand-tagline {
  margin: 0;
  font-size: calc(var(--u) * 1.4);
  color: var(--ink-soft);
  letter-spacing: 0.02em;
}

.lobby-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: calc(var(--u) * 1.8);
}

@media (min-width: 820px) {
  .lobby-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

/*
 * Two cards from one markup. Narrow: a square of artwork beside its words, the
 * shape of a lobby list on a phone. Wide: the 16:9 artwork with the words laid
 * over its bottom edge. The picture is never the only place the name lives.
 */
.lobby-card {
  position: relative;
  display: grid;
  grid-template-columns: 36% 1fr;
  grid-template-areas: "art body";
  align-items: stretch;
  gap: calc(var(--u) * 1.2);
  padding: calc(var(--u) * 0.8);
  border-radius: var(--radius);
  border: 1px solid rgba(201, 162, 74, 0.22);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.045), rgba(255, 255, 255, 0.012));
  transition: transform var(--fade) ease, border-color var(--fade) ease, box-shadow var(--fade) ease;
  text-align: left;
}

.card-frame {
  grid-area: art;
}

.card-body {
  grid-area: body;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: calc(var(--u) * 0.3);
  min-width: 0;
}

.card-foot {
  display: none;
}

@media (min-width: 820px) {
  .lobby-card {
    grid-template-columns: 1fr;
    grid-template-areas: "art" "foot";
    gap: calc(var(--u) * 0.9);
  }
  .card-body {
    /* The same cell as the artwork, so the words sit on the picture. */
    grid-area: art;
    z-index: 2;
    align-self: end;
    justify-content: flex-end;
    padding: calc(var(--u) * 4) calc(var(--u) * 1.4) calc(var(--u) * 1.2);
    border-radius: 0 0 calc(var(--radius) * 0.8) calc(var(--radius) * 0.8);
    /* Deep and early. The thumbnail's cards land behind the title, and a title
       read across the pips of a nine of diamonds is a title nobody finishes. */
    background: linear-gradient(
      180deg,
      rgba(6, 9, 8, 0) 0%,
      rgba(6, 9, 8, 0.6) 26%,
      rgba(6, 9, 8, 0.92) 52%,
      rgba(6, 9, 8, 0.98) 100%
    );
  }
  .card-frame {
    aspect-ratio: 16 / 9;
  }
  .card-foot {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    padding: 0 calc(var(--u) * 0.5) calc(var(--u) * 0.2);
    font-size: calc(var(--u) * 1.06);
    color: var(--ink-dim);
  }
}

.lobby-card:hover,
.lobby-card:focus-visible {
  transform: translateY(calc(var(--u) * -0.5));
  border-color: rgba(230, 192, 120, 0.6);
  box-shadow: 0 calc(var(--u) * 1.4) calc(var(--u) * 3) rgba(0, 0, 0, 0.55), 0 0 calc(var(--u) * 2) rgba(201, 162, 74, 0.18);
}

.lobby-card:active {
  transform: translateY(0) scale(0.994);
}

.lobby-card.last {
  border-color: rgba(230, 192, 120, 0.4);
}

.card-frame {
  position: relative;
  border-radius: calc(var(--radius) * 0.8);
  overflow: hidden;
  aspect-ratio: 1 / 1;
  background: linear-gradient(150deg, #10231b, #0a0f0d);
  isolation: isolate;
}

@media (min-width: 820px) {
  .card-frame {
    aspect-ratio: 16 / 9;
  }
}

/* The loading state, before the picture has arrived. */
.card-frame::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, rgba(255, 255, 255, 0) 20%, rgba(255, 255, 255, 0.07) 50%, rgba(255, 255, 255, 0) 80%);
  transform: translateX(-100%);
  animation: shimmer 1.5s linear infinite;
}

.card-frame.loaded::before,
.card-frame.failed::before {
  display: none;
}

@keyframes shimmer {
  to {
    transform: translateX(100%);
  }
}

.card-picture,
.card-picture img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.card-picture img {
  opacity: 0;
  transition: opacity 420ms ease, transform 700ms cubic-bezier(0.2, 0.8, 0.3, 1);
}

.card-frame.loaded .card-picture img {
  opacity: 1;
}

.lobby-card:hover .card-picture img,
.lobby-card:focus-visible .card-picture img {
  transform: scale(1.035);
}

/* If the picture never arrives, the card is still a card: the name, the blurb
   and the Play button are all drawn by the page, not by the image. */
.card-frame.failed {
  background: linear-gradient(160deg, #14251d, #0a0f0d 70%);
}

.card-eyebrow {
  font-size: calc(var(--u) * 0.92);
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--gold-bright);
}

.card-title {
  font-family: var(--serif);
  font-weight: 700;
  font-size: calc(var(--u) * 3);
  line-height: 1;
  color: #fdfaf3;
  text-shadow: 0 calc(var(--u) * 0.2) calc(var(--u) * 1) rgba(0, 0, 0, 0.7);
}

.card-blurb {
  font-size: calc(var(--u) * 1.16);
  color: var(--ink-soft);
}

.card-play {
  margin-top: calc(var(--u) * 0.7);
  display: inline-flex;
  align-items: center;
  gap: calc(var(--u) * 0.5);
  align-self: flex-start;
  padding: calc(var(--u) * 0.55) calc(var(--u) * 1.3) calc(var(--u) * 0.55) calc(var(--u) * 1);
  border-radius: 999px;
  background: linear-gradient(180deg, var(--gold-bright), var(--gold));
  color: #221704;
  font-weight: 600;
  font-size: calc(var(--u) * 1.14);
  box-shadow: 0 calc(var(--u) * 0.3) calc(var(--u) * 0.9) rgba(0, 0, 0, 0.5);
  transition: transform var(--fade) ease;
}

.card-play-arrow {
  transform: rotate(180deg);
  display: inline-flex;
}

.lobby-card:hover .card-play,
.lobby-card:focus-visible .card-play {
  transform: translateX(calc(var(--u) * 0.3));
}

.card-limits {
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}

.lobby-notice {
  margin: 0;
  padding: calc(var(--u) * 0.9) calc(var(--u) * 1.2);
  border-radius: var(--radius);
  border: 1px solid rgba(201, 162, 74, 0.3);
  background: rgba(201, 162, 74, 0.07);
  color: var(--ink-soft);
  font-size: calc(var(--u) * 1.12);
  line-height: 1.5;
}

.lobby-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: calc(var(--u) * 1.4);
  flex-wrap: wrap;
  padding-top: calc(var(--u) * 0.6);
  border-top: 1px solid rgba(201, 162, 74, 0.16);
}

.lobby-balance {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--u) * 0.6);
}

.lobby-balance-label {
  font-size: calc(var(--u) * 1.05);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.lobby-balance-value {
  font-family: var(--serif);
  font-size: calc(var(--u) * 2.1);
  color: var(--gold-bright);
}

.lobby-balance-chip {
  display: inline-block;
  width: calc(var(--u) * 1.9);
  height: calc(var(--u) * 1.9);
}

.lobby-actions {
  display: flex;
  gap: calc(var(--u) * 0.6);
  flex-wrap: wrap;
}

.lobby-btn {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--u) * 0.45);
  padding: calc(var(--u) * 0.62) calc(var(--u) * 1.2);
  border-radius: 999px;
  border: 1px solid rgba(201, 162, 74, 0.3);
  color: var(--ink-soft);
  font-size: calc(var(--u) * 1.1);
  transition: background var(--fade) ease, color var(--fade) ease, border-color var(--fade) ease;
}

.lobby-btn:hover,
.lobby-btn:focus-visible {
  background: rgba(201, 162, 74, 0.14);
  border-color: rgba(230, 192, 120, 0.6);
  color: var(--ink);
}

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

.screen {
  position: relative;
  height: 100%;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.felt {
  position: relative;
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  padding: calc(var(--u) * 1 + var(--safe-t)) calc(var(--u) * 2 + var(--safe-r)) calc(var(--u) * 1.4 + var(--safe-b))
    calc(var(--u) * 2 + var(--safe-l));
  gap: calc(var(--u) * 1);
  background-color: #0c3a28;
  background-image: url("../assets/table/felt-emerald.webp");
  background-size: calc(var(--u) * 26) calc(var(--u) * 26);
  background-blend-mode: normal;
  overflow: hidden;
}

/* The room beyond the table, and the light coming down onto it. */
.felt-sheen {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(90% 62% at 50% 34%, rgba(255, 240, 200, 0.14) 0%, rgba(255, 240, 200, 0) 62%),
    radial-gradient(130% 100% at 50% 55%, rgba(0, 0, 0, 0) 34%, rgba(4, 6, 5, 0.86) 100%);
}

/*
 * The table's own marking, painted on the felt.
 *
 * A baccarat table has a swept arc inlaid across it, and drawing one here is
 * doing two jobs at once: it is the plainest way to say "this is a baccarat
 * table" without a word, and it gives the empty felt a shape. A tall phone has
 * more height than six rows need, and an unmarked expanse of green under the
 * cards reads as a hole rather than as felt.
 */
.felt::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  /* Two hairline rings, swept across the felt. Drawn as backgrounds rather
     than as bordered boxes so that one pseudo-element can hold both. */
  background-image:
    radial-gradient(circle closest-side, rgba(0, 0, 0, 0) 0 97.6%, rgba(230, 192, 120, 0.11) 97.6% 100%, rgba(0, 0, 0, 0) 100%),
    radial-gradient(circle closest-side, rgba(0, 0, 0, 0) 0 96%, rgba(230, 192, 120, 0.07) 96% 100%, rgba(0, 0, 0, 0) 100%);
  background-position: 50% 44%, 50% 44%;
  background-size:
    min(78%, calc(var(--u) * 68)) min(78%, calc(var(--u) * 68)),
    min(60%, calc(var(--u) * 52)) min(60%, calc(var(--u) * 52));
  background-repeat: no-repeat;
}

/* The walnut rail around the felt, drawn as an inset frame. */
.felt::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  border: calc(var(--u) * 0.62) solid transparent;
  border-image: linear-gradient(160deg, var(--walnut-light), var(--walnut) 45%, #1d1207) 1;
  opacity: 0.85;
}

.screen[data-table="vip"] .felt {
  background-color: #3a0c1a;
  background-image: url("../assets/table/felt-burgundy.webp");
}
.screen[data-table="vip"] .felt-sheen {
  background:
    radial-gradient(90% 62% at 50% 34%, rgba(255, 226, 214, 0.12) 0%, rgba(255, 226, 214, 0) 62%),
    radial-gradient(130% 100% at 50% 55%, rgba(0, 0, 0, 0) 30%, rgba(6, 2, 4, 0.88) 100%);
}
.screen[data-table="speed"] .felt {
  background-color: #0d3230;
}
.screen[data-table="speed"] .felt-sheen {
  background:
    radial-gradient(90% 62% at 50% 30%, rgba(214, 244, 255, 0.16) 0%, rgba(214, 244, 255, 0) 62%),
    radial-gradient(130% 100% at 50% 55%, rgba(0, 0, 0, 0) 34%, rgba(3, 6, 7, 0.86) 100%);
}

/* ---- the toolbar ---- */

.bar {
  position: relative;
  z-index: 4;
  display: flex;
  align-items: center;
  gap: calc(var(--u) * 1);
  min-height: calc(var(--u) * 3.4);
}

.back-btn {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--u) * 0.35);
  padding: calc(var(--u) * 0.5) calc(var(--u) * 1) calc(var(--u) * 0.5) calc(var(--u) * 0.6);
  border-radius: 999px;
  border: 1px solid rgba(230, 192, 120, 0.28);
  background: rgba(6, 10, 8, 0.42);
  color: var(--ink-soft);
  font-size: calc(var(--u) * 1.08);
}

.back-btn:hover,
.back-btn:focus-visible {
  color: var(--ink);
  border-color: rgba(230, 192, 120, 0.65);
}

.bar-id {
  display: flex;
  align-items: baseline;
  gap: calc(var(--u) * 0.7);
  min-width: 0;
  flex: 1;
}

.bar-table {
  font-family: var(--serif);
  font-size: calc(var(--u) * 1.5);
  color: var(--ink);
  white-space: nowrap;
}

.bar-round,
.bar-status {
  font-size: calc(var(--u) * 1.02);
  color: var(--ink-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.bar-status {
  color: var(--gold-bright);
}

.bar-beads {
  display: flex;
  gap: calc(var(--u) * 0.22);
  align-items: center;
}

.bar-beads .bead {
  width: calc(var(--u) * 1.32);
  height: calc(var(--u) * 1.32);
  font-size: calc(var(--u) * 0.82);
}

.bar-tools {
  display: flex;
  gap: calc(var(--u) * 0.3);
}

.icon-btn {
  width: calc(var(--u) * 3);
  height: calc(var(--u) * 3);
  display: grid;
  place-items: center;
  border-radius: 50%;
  color: var(--ink-soft);
  border: 1px solid rgba(230, 192, 120, 0.2);
  background: rgba(6, 10, 8, 0.38);
  transition: color var(--fade) ease, border-color var(--fade) ease, background var(--fade) ease;
}

.icon-btn:hover,
.icon-btn:focus-visible {
  color: var(--gold-bright);
  border-color: rgba(230, 192, 120, 0.6);
  background: rgba(201, 162, 74, 0.14);
}

/* ---- the shoe ---- */

.shoe {
  position: absolute;
  z-index: 3;
  /* Below the toolbar, never over it: the shoe is scenery and the toolbar is
     the only way back to the lobby. */
  top: calc(var(--u) * 6 + var(--safe-t));
  right: calc(var(--u) * 2.4 + var(--safe-r));
  width: calc(var(--u) * 4.2);
  height: calc(var(--u) * 4.8);
  filter: drop-shadow(0 calc(var(--u) * 0.4) calc(var(--u) * 0.8) rgba(0, 0, 0, 0.6));
}

.shoe-art {
  display: block;
  width: 100%;
  height: 100%;
}

.shoe-count {
  position: absolute;
  bottom: calc(var(--u) * -1.3);
  left: 0;
  right: 0;
  text-align: center;
  font-size: calc(var(--u) * 0.86);
  color: rgba(243, 236, 220, 0.5);
  letter-spacing: 0.08em;
}

/* ---- the hands ---- */

.main {
  position: relative;
  z-index: 2;
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  /* The hands and the areas are one group and stay together; a screen with
     height to spare splits its extra space above and below them, not between
     the two hands, which are a pair. */
  justify-content: center;
  gap: calc(var(--u) * 1);
}

/* Stacked until there is width for a table. See the wide rule near the bottom,
   which turns this into the row a real baccarat table seats. */
.hands {
  display: flex;
  flex-direction: column;
  gap: calc(var(--u) * 0.9);
}

.hand {
  display: flex;
  align-items: center;
  gap: calc(var(--u) * 1);
  padding: calc(var(--u) * 0.6) calc(var(--u) * 0.9);
  border-radius: var(--radius);
  transition: background var(--fade) ease, box-shadow var(--fade) ease;
}

/* Both hands centre on the felt when they are stacked. The Banker's row is
   mirrored, so its mark faces the Player's across the two rows and the cards of
   both hands land on the same centre line. */
.hand-player {
  justify-content: center;
}

.hand-banker {
  justify-content: center;
  flex-direction: row-reverse;
}

.hand-side {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(var(--u) * 0.3);
  min-width: calc(var(--u) * 5);
}

.hand-name {
  font-size: calc(var(--u) * 1.02);
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.hand-player .hand-side,
.hand-player .hand-name {
  color: var(--player);
}
.hand-banker .hand-side,
.hand-banker .hand-name {
  color: var(--banker);
}

.hand-score {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(var(--u) * 0.1);
  min-width: calc(var(--u) * 4);
  opacity: 0.42;
  transition: opacity var(--fade) ease;
}

.hand.dealt .hand-score {
  opacity: 1;
}

.hand-total-label {
  font-size: calc(var(--u) * 0.84);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.hand-total {
  font-family: var(--serif);
  font-weight: 700;
  font-size: calc(var(--u) * 3.4);
  line-height: 1;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.hand-cards {
  display: flex;
  align-items: center;
  min-height: calc(var(--u) * 17.5);
}

/* Each card sits slightly under the one before it, the way a dealt hand does.
   The inset is small on purpose: past about a quarter of a card the first card
   of a three-card hand disappears, and the suit and value along its top left
   edge are the whole reason a card is readable at all. */
.hand-cards .card-slot + .card-slot {
  margin-left: calc(var(--card-w) * -0.24);
}

.card-slot {
  --card-w: calc(var(--u) * 12.6);
  position: relative;
  width: var(--card-w);
  height: calc(var(--card-w) * 1.4);
  perspective: calc(var(--u) * 60);
  opacity: 0;
  transition: transform var(--travel) cubic-bezier(0.2, 0.85, 0.25, 1), opacity var(--travel) ease;
  will-change: transform;
}

.card-slot[data-state="travel"],
.card-slot[data-state="flip"],
.card-slot[data-state="face"] {
  opacity: 1;
}

.card-3d {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
  transform: rotateY(180deg);
  transition: transform var(--flip) cubic-bezier(0.45, 0.05, 0.35, 1);
}

.card-slot[data-state="flip"] .card-3d,
.card-slot[data-state="face"] .card-3d {
  transform: rotateY(0deg);
}

.card-face,
.card-back {
  position: absolute;
  inset: 0;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  border-radius: calc(var(--card-w) * 0.075);
  overflow: hidden;
  box-shadow: var(--shadow-card);
}

.card-face svg,
.card-back svg {
  width: 100%;
  height: 100%;
}

.card-back {
  transform: rotateY(180deg);
}

/* The winning hand, and the one that lost. */
.hand.won {
  background: radial-gradient(72% 92% at 50% 50%, rgba(230, 192, 120, 0.15), rgba(230, 192, 120, 0) 70%);
  /* A lit edge rather than a lit panel. Filled harder than this the winning
     hand stops being a hand at all and becomes a brown rectangle laid on the
     felt, with the cards sitting on top of it. */
  box-shadow:
    inset 0 0 calc(var(--u) * 2.4) rgba(230, 192, 120, 0.2),
    inset 0 0 0 1px rgba(230, 192, 120, 0.17);
}

.hand.won .hand-total {
  color: var(--gold-bright);
  text-shadow: 0 0 calc(var(--u) * 1.2) rgba(230, 192, 120, 0.6);
}

.hand.lost {
  opacity: 0.52;
}

.hand.pushed {
  background: radial-gradient(80% 100% at 50% 50%, rgba(51, 160, 106, 0.16), rgba(51, 160, 106, 0) 72%);
}

/* ---- the betting areas ---- */

.areas {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: calc(var(--u) * 0.9);
  /* Three areas stretched across a 1600 pixel felt become three long shallow
     trays with the chips lost in one corner of them. Capped and centred they
     stay the size they are at their busiest, on every screen. */
  width: 100%;
  max-width: calc(var(--u) * 86);
  margin: 0 auto;
}

.area {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: calc(var(--u) * 0.3);
  padding: calc(var(--u) * 0.9) calc(var(--u) * 0.9) calc(var(--u) * 0.7);
  border-radius: var(--radius);
  border: calc(var(--u) * 0.16) solid var(--edge, rgba(255, 255, 255, 0.16));
  background: linear-gradient(180deg, rgba(4, 8, 6, 0.56), rgba(4, 8, 6, 0.34));
  text-align: left;
  transition: transform 140ms ease, border-color var(--fade) ease, background var(--fade) ease, box-shadow var(--fade) ease;
  min-height: calc(var(--u) * 11);
  --edge: rgba(255, 255, 255, 0.2);
}

.area-player {
  --edge: rgba(74, 134, 216, 0.72);
  --tint: var(--player);
}
.area-banker {
  --edge: rgba(200, 67, 58, 0.72);
  --tint: var(--banker);
}
.area-tie {
  --edge: rgba(51, 160, 106, 0.72);
  --tint: var(--tie);
}

.area:disabled {
  cursor: default;
  opacity: 0.62;
}

.area:not(:disabled):hover,
.area:not(:disabled):focus-visible {
  border-color: var(--tint);
  background: linear-gradient(180deg, rgba(12, 20, 16, 0.72), rgba(6, 10, 8, 0.5));
}

.area:not(:disabled):active {
  transform: scale(0.985);
}

.area-head {
  display: flex;
  align-items: center;
  gap: calc(var(--u) * 0.5);
  color: var(--tint);
}

.area-mark {
  display: inline-flex;
  filter: drop-shadow(0 0 calc(var(--u) * 0.5) rgba(0, 0, 0, 0.5));
}

.area-name {
  font-family: var(--serif);
  font-weight: 700;
  font-size: calc(var(--u) * 1.72);
  letter-spacing: 0.02em;
  color: var(--ink);
}

.area-odds {
  font-size: calc(var(--u) * 1.06);
  letter-spacing: 0.06em;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}

/*
 * A stack of chips on a betting area.
 *
 * The height here is the stack's, not a chip's: four chips overlapping by a
 * little less than a fifth each need just over one and a half chip heights.
 * Everything is derived from --chip, so the stack, the chip in the rack and the
 * chip in the payout are one size at every screen.
 */
.area-chips {
  --chip: calc(var(--u) * 4.4);
  position: relative;
  height: calc(var(--chip) * 1.62);
  margin-top: calc(var(--u) * 0.3);
}

.stack {
  position: absolute;
  inset: 0;
}

.stack-chip {
  position: absolute;
  left: 0;
  width: var(--chip);
  height: var(--chip);
}

.stack-chip:nth-child(1) {
  bottom: 0;
  z-index: 4;
}
.stack-chip:nth-child(2) {
  bottom: calc(var(--chip) * 0.18);
  z-index: 3;
}
.stack-chip:nth-child(3) {
  bottom: calc(var(--chip) * 0.36);
  z-index: 2;
}
.stack-chip:nth-child(4) {
  bottom: calc(var(--chip) * 0.54);
  z-index: 1;
}

.stack-chip svg {
  width: 100%;
  height: 100%;
}

.stack-more {
  position: absolute;
  left: calc(var(--chip) + var(--u) * 0.3);
  bottom: 0;
  font-size: calc(var(--u) * 1);
  color: var(--ink-soft);
}

.area-foot {
  display: flex;
  align-items: baseline;
  gap: calc(var(--u) * 0.7);
  margin-top: auto;
}

.area-stake-label {
  font-size: calc(var(--u) * 0.86);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.area-stake {
  font-family: var(--serif);
  font-size: calc(var(--u) * 1.5);
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.area-note {
  /* Reserved even when empty. Only one area usually carries a settlement note,
     and without the room set aside its STAKE line sits lower than the other
     two and the row reads as though it were misaligned. */
  min-height: calc(var(--u) * 2.7);
  font-size: calc(var(--u) * 0.98);
  line-height: 1.35;
  color: var(--ink-soft);
  margin: calc(var(--u) * 0.2) 0 0;
}

.area.staked {
  background: linear-gradient(180deg, rgba(14, 22, 18, 0.78), rgba(6, 10, 8, 0.56));
  box-shadow: inset 0 0 calc(var(--u) * 1.4) rgba(0, 0, 0, 0.4);
}

.area.win {
  border-color: var(--gold-bright);
  box-shadow: 0 0 calc(var(--u) * 2.4) rgba(230, 192, 120, 0.45), inset 0 0 calc(var(--u) * 2) rgba(230, 192, 120, 0.2);
}

.area.lose {
  opacity: 0.5;
}

.area.push {
  border-color: rgba(51, 160, 106, 0.9);
}

.area.flash {
  animation: area-flash 420ms ease;
}

@keyframes area-flash {
  0% {
    transform: scale(1);
  }
  35% {
    transform: scale(1.045);
  }
  100% {
    transform: scale(1);
  }
}

.area.refused {
  animation: refuse 400ms ease;
  border-color: var(--banker);
}

@keyframes refuse {
  0%,
  100% {
    transform: translateX(0);
  }
  20% {
    transform: translateX(calc(var(--u) * -0.6));
  }
  50% {
    transform: translateX(calc(var(--u) * 0.5));
  }
  80% {
    transform: translateX(calc(var(--u) * -0.25));
  }
}

/* ---- the console ---- */

.console {
  position: relative;
  z-index: 3;
  display: flex;
  flex-direction: column;
  gap: calc(var(--u) * 0.6);
}

.console-betting {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-areas: "rack tools" "deal deal";
  gap: calc(var(--u) * 0.7);
  align-items: center;
}

.console[data-mode="dealing"] .console-betting,
.console[data-mode="settled"] .console-betting {
  display: none;
}

.rack {
  grid-area: rack;
  display: flex;
  gap: calc(var(--u) * 0.4);
}

.rack-chip {
  width: calc(var(--u) * 4.2);
  height: calc(var(--u) * 4.2);
  border-radius: 50%;
  padding: 0;
  position: relative;
  transition: transform 140ms cubic-bezier(0.3, 1.4, 0.5, 1), opacity var(--fade) ease;
}

.rack-chip svg {
  width: 100%;
  height: 100%;
}

.rack-chip:hover:not(:disabled),
.rack-chip:focus-visible:not(:disabled) {
  transform: translateY(calc(var(--u) * -0.45));
}

.rack-chip.selected {
  transform: translateY(calc(var(--u) * -0.7));
  filter: drop-shadow(0 0 calc(var(--u) * 0.9) rgba(230, 192, 120, 0.85));
}

.rack-chip.selected::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: calc(var(--u) * -0.7);
  width: calc(var(--u) * 0.7);
  height: calc(var(--u) * 0.7);
  border-radius: 50%;
  background: var(--gold-bright);
  transform: translateX(-50%);
}

.rack-chip:disabled {
  opacity: 0.26;
  cursor: not-allowed;
}

.tools {
  grid-area: tools;
  display: flex;
  gap: calc(var(--u) * 0.35);
  justify-content: flex-end;
}

.tool {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--u) * 0.35);
  padding: calc(var(--u) * 0.6) calc(var(--u) * 0.9);
  border-radius: 999px;
  border: 1px solid rgba(230, 192, 120, 0.24);
  background: rgba(6, 10, 8, 0.45);
  color: var(--ink-soft);
  font-size: calc(var(--u) * 1.02);
  transition: color var(--fade) ease, border-color var(--fade) ease, opacity var(--fade) ease;
}

.tool:hover:not(:disabled),
.tool:focus-visible:not(:disabled) {
  color: var(--gold-bright);
  border-color: rgba(230, 192, 120, 0.62);
}

.tool:disabled {
  opacity: 0.34;
  cursor: not-allowed;
}

.console-deal {
  grid-area: deal;
  display: flex;
  align-items: center;
  gap: calc(var(--u) * 1);
}

.balance {
  display: flex;
  flex-direction: column;
  line-height: 1.1;
}

.balance-label {
  font-size: calc(var(--u) * 0.84);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.balance-value {
  font-family: var(--serif);
  font-size: calc(var(--u) * 1.9);
  color: var(--gold-bright);
  font-variant-numeric: tabular-nums;
}

.stakes {
  font-size: calc(var(--u) * 1.02);
  color: var(--ink-soft);
  flex: 1;
  min-width: 0;
}

.deal-btn {
  appearance: none;
  padding: calc(var(--u) * 1.15) calc(var(--u) * 3.8);
  border-radius: 999px;
  background: linear-gradient(180deg, var(--gold-bright), var(--gold) 62%, var(--gold-deep));
  color: #241804;
  font-family: var(--serif);
  font-weight: 700;
  font-size: calc(var(--u) * 1.7);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  box-shadow: 0 calc(var(--u) * 0.4) calc(var(--u) * 1.1) rgba(0, 0, 0, 0.55), inset 0 1px 0 rgba(255, 255, 255, 0.5);
  transition: transform 140ms ease, filter var(--fade) ease;
}

.deal-btn:hover:not(:disabled),
.deal-btn:focus-visible:not(:disabled) {
  transform: translateY(calc(var(--u) * -0.25));
  filter: brightness(1.06);
}

.deal-btn:active:not(:disabled) {
  transform: translateY(0);
}

.deal-btn:disabled {
  background: linear-gradient(180deg, rgba(201, 162, 74, 0.3), rgba(138, 106, 36, 0.3));
  color: rgba(36, 24, 4, 0.55);
  cursor: not-allowed;
  box-shadow: none;
}

/* ---- the round summary, in place of the controls ---- */

.summary {
  display: flex;
  flex-direction: column;
  gap: calc(var(--u) * 0.7);
  padding: calc(var(--u) * 1) calc(var(--u) * 1.2);
  border-radius: var(--radius);
  border: 1px solid rgba(230, 192, 120, 0.36);
  background: linear-gradient(180deg, rgba(8, 14, 11, 0.9), rgba(5, 8, 7, 0.84));
  box-shadow: 0 calc(var(--u) * 0.6) calc(var(--u) * 2) rgba(0, 0, 0, 0.55);
  animation: summary-in 320ms cubic-bezier(0.2, 0.9, 0.3, 1);
}

@keyframes summary-in {
  from {
    opacity: 0;
    transform: translateY(calc(var(--u) * 1.2));
  }
}

/* One column, as wide as the betting areas above it and centred the same way.
   The three blocks of the summary then share an edge, instead of the lines
   indented in the middle with the outcome and the house notes out at the
   corners of a band twice as wide as anything in it. */
.sum-head,
.sum-lines,
.sum-notes,
.sum-actions {
  width: 100%;
  max-width: calc(var(--u) * 86);
  margin-inline: auto;
}

.sum-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: calc(var(--u) * 1);
  flex-wrap: wrap;
}

.sum-outcome {
  font-family: var(--serif);
  font-weight: 700;
  font-size: calc(var(--u) * 2.1);
}

.outcome-player {
  color: var(--player);
}
.outcome-banker {
  color: var(--banker);
}
.outcome-tie {
  color: var(--tie);
}

.sum-score {
  font-size: calc(var(--u) * 1.14);
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}

.sum-lines {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(calc(var(--u) * 27), 1fr));
  gap: calc(var(--u) * 0.18) calc(var(--u) * 1.6);
}

.sum-line {
  display: flex;
  align-items: baseline;
  /* The key and its value are one phrase and stay together. Pushed to opposite
     ends of a cell they read as two columns of a table that has lost its rows:
     "Player" here, "40" over there, and the result floating in between. */
  justify-content: flex-start;
  gap: calc(var(--u) * 0.7);
  font-size: calc(var(--u) * 1.04);
  padding: calc(var(--u) * 0.14) 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.sum-key {
  color: var(--ink-dim);
}

.sum-val {
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.sum-win .sum-val,
.sum-val.sum-win {
  color: var(--gold-bright);
}
.sum-loss .sum-val {
  color: rgba(243, 236, 220, 0.6);
}
.sum-fee .sum-val {
  color: var(--ink-soft);
}
.sum-win .sum-key,
.sum-win .sum-val {
  color: var(--gold-bright);
}
.sum-loss .sum-key,
.sum-loss .sum-val {
  color: rgba(243, 236, 220, 0.55);
}

.sum-notes {
  display: flex;
  flex-wrap: wrap;
  gap: calc(var(--u) * 0.2) calc(var(--u) * 1.2);
}

.sum-note {
  margin: 0;
  font-size: calc(var(--u) * 0.98);
  color: var(--ink-dim);
  line-height: 1.4;
}

.sum-actions {
  display: flex;
  justify-content: flex-end;
}

.next-btn {
  font-size: calc(var(--u) * 1.42);
}

/* ---- the floating net ---- */

.payout-float {
  position: absolute;
  z-index: 6;
  right: calc(var(--u) * 2);
  /* Above the console, not on top of it: the summary rises into the console's
     own space, and a net figure floating over it hides the same figure twice. */
  bottom: calc(100% + var(--u) * 0.5);
  font-family: var(--serif);
  font-weight: 700;
  font-size: calc(var(--u) * 2.6);
  pointer-events: none;
  animation: float-up 900ms cubic-bezier(0.2, 0.8, 0.3, 1) forwards;
  text-shadow: 0 calc(var(--u) * 0.2) calc(var(--u) * 1.2) rgba(0, 0, 0, 0.8);
}

.payout-float.up {
  color: var(--gold-bright);
}
.payout-float.down {
  color: rgba(243, 236, 220, 0.65);
}
.payout-float.flat {
  color: var(--ink-soft);
}

.payout-float.gone {
  transition: opacity 400ms ease;
  opacity: 0;
}

@keyframes float-up {
  from {
    opacity: 0;
    transform: translateY(calc(var(--u) * 1.6));
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* ------------------------------------------------------------------ *
 * Dialogs
 * ------------------------------------------------------------------ */

.dlg {
  position: fixed;
  inset: 0;
  z-index: 40;
  display: grid;
  place-items: center;
  padding: calc(var(--u) * 1.6 + var(--safe-t)) calc(var(--u) * 1.6 + var(--safe-r)) calc(var(--u) * 1.6 + var(--safe-b))
    calc(var(--u) * 1.6 + var(--safe-l));
}

.dlg-scrim {
  position: absolute;
  inset: 0;
  background: rgba(4, 6, 5, 0.72);
  backdrop-filter: blur(3px);
  opacity: 0;
  transition: opacity var(--fade) ease;
}

.dlg[data-open="true"] .dlg-scrim {
  opacity: 1;
}

.dlg-panel {
  position: relative;
  width: min(100%, calc(var(--u) * 62));
  max-height: 100%;
  display: flex;
  flex-direction: column;
  border-radius: calc(var(--radius) * 1.2);
  border: 1px solid rgba(230, 192, 120, 0.3);
  background: linear-gradient(180deg, #101713, #0a0f0c);
  box-shadow: 0 calc(var(--u) * 1.6) calc(var(--u) * 4) rgba(0, 0, 0, 0.7);
  opacity: 0;
  transform: translateY(calc(var(--u) * 1.6)) scale(0.985);
  transition: opacity var(--fade) ease, transform var(--fade) cubic-bezier(0.2, 0.9, 0.3, 1);
  overflow: hidden;
}

.dlg[data-open="true"] .dlg-panel {
  opacity: 1;
  transform: none;
}

.dlg-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: calc(var(--u) * 1);
  padding: calc(var(--u) * 1.3) calc(var(--u) * 1.6);
  border-bottom: 1px solid rgba(230, 192, 120, 0.18);
}

.dlg-title {
  margin: 0;
  font-family: var(--serif);
  font-weight: 700;
  font-size: calc(var(--u) * 1.9);
  letter-spacing: 0.02em;
}

.dlg-close {
  width: calc(var(--u) * 2.6);
  height: calc(var(--u) * 2.6);
  display: grid;
  place-items: center;
  border-radius: 50%;
  color: var(--ink-soft);
  border: 1px solid rgba(230, 192, 120, 0.2);
}

.dlg-close:hover,
.dlg-close:focus-visible {
  color: var(--gold-bright);
  border-color: rgba(230, 192, 120, 0.6);
}

.dlg-body {
  padding: calc(var(--u) * 1.4) calc(var(--u) * 1.6) calc(var(--u) * 1.8);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
}

.panel-lede {
  margin: 0 0 calc(var(--u) * 1.2);
  font-size: calc(var(--u) * 1.16);
  line-height: 1.6;
  color: var(--ink-soft);
}

.panel-section {
  margin-top: calc(var(--u) * 1.6);
}

.panel-heading {
  margin: 0 0 calc(var(--u) * 0.5);
  font-family: var(--serif);
  font-size: calc(var(--u) * 1.5);
  color: var(--gold-bright);
  letter-spacing: 0.02em;
}

.panel-subheading {
  margin: calc(var(--u) * 0.8) 0 calc(var(--u) * 0.3);
  font-size: calc(var(--u) * 1.16);
  color: var(--ink);
}

.panel-p {
  margin: 0 0 calc(var(--u) * 0.6);
  font-size: calc(var(--u) * 1.1);
  line-height: 1.62;
  color: var(--ink-soft);
}

.panel-warn {
  color: #f0c98a;
}

.panel-note {
  font-size: calc(var(--u) * 0.98);
  color: var(--ink-dim);
  line-height: 1.5;
}

.panel-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: calc(var(--u) * 0.7);
  margin-top: calc(var(--u) * 0.8);
}

.panel-btn {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--u) * 0.45);
  padding: calc(var(--u) * 0.68) calc(var(--u) * 1.3);
  border-radius: 999px;
  border: 1px solid rgba(230, 192, 120, 0.34);
  color: var(--ink);
  font-size: calc(var(--u) * 1.08);
  transition: background var(--fade) ease, border-color var(--fade) ease;
}

.panel-btn:hover,
.panel-btn:focus-visible {
  background: rgba(201, 162, 74, 0.16);
  border-color: rgba(230, 192, 120, 0.7);
}

.panel-btn.danger {
  border-color: rgba(200, 67, 58, 0.45);
  color: #efb4ae;
}

.panel-btn.danger:hover,
.panel-btn.danger:focus-visible {
  background: rgba(200, 67, 58, 0.18);
  border-color: rgba(200, 67, 58, 0.8);
}

/* ---- paytable ---- */

.paytable {
  display: flex;
  flex-direction: column;
  gap: calc(var(--u) * 0.5);
  margin-bottom: calc(var(--u) * 1);
}

.paytable-row {
  display: grid;
  grid-template-columns: auto auto auto 1fr;
  align-items: center;
  gap: calc(var(--u) * 0.8);
  padding: calc(var(--u) * 0.8) calc(var(--u) * 1);
  border-radius: var(--radius);
  border: 1px solid rgba(255, 255, 255, 0.1);
  background: rgba(255, 255, 255, 0.025);
}

.paytable-mark {
  display: inline-flex;
  color: var(--ink-soft);
}

.pay-player .paytable-mark {
  color: var(--player);
}
.pay-banker .paytable-mark {
  color: var(--banker);
}
.pay-tie .paytable-mark {
  color: var(--tie);
}

.push-mark {
  width: calc(var(--u) * 1.4);
  text-align: center;
  font-weight: 700;
  font-size: calc(var(--u) * 1.4);
}

.paytable-name {
  font-family: var(--serif);
  font-size: calc(var(--u) * 1.32);
}

.paytable-odds {
  font-variant-numeric: tabular-nums;
  color: var(--gold-bright);
  font-size: calc(var(--u) * 1.14);
}

.paytable-blurb {
  font-size: calc(var(--u) * 1.02);
  color: var(--ink-dim);
  line-height: 1.45;
}

@media (max-width: 560px) {
  .paytable-row {
    grid-template-columns: auto 1fr auto;
    grid-template-areas: "mark name odds" "blurb blurb blurb";
  }
  .paytable-mark {
    grid-area: mark;
  }
  .paytable-name {
    grid-area: name;
  }
  .paytable-odds {
    grid-area: odds;
  }
  .paytable-blurb {
    grid-area: blurb;
  }
}

/* ---- bead plate and history ---- */

.bead-plate {
  display: flex;
  gap: calc(var(--u) * 0.24);
  padding: calc(var(--u) * 0.8);
  border-radius: var(--radius);
  background: rgba(0, 0, 0, 0.32);
  border: 1px solid rgba(255, 255, 255, 0.08);
  overflow-x: auto;
  margin-bottom: calc(var(--u) * 1);
}

.bead-col {
  display: flex;
  flex-direction: column;
  gap: calc(var(--u) * 0.24);
  flex: 0 0 auto;
}

.bead {
  width: calc(var(--u) * 1.9);
  height: calc(var(--u) * 1.9);
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: calc(var(--u) * 1.06);
  font-weight: 700;
  color: #0a0d0b;
  font-family: var(--sans);
}

.bead-player {
  background: var(--player);
}
.bead-banker {
  background: var(--banker);
  color: #fdeeec;
}
.bead-tie {
  background: var(--tie);
}

.bead-empty-cell {
  background: rgba(255, 255, 255, 0.045);
}

.bead-empty {
  color: var(--ink-dim);
  margin: 0;
}

.counts {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: calc(var(--u) * 0.7);
  margin-bottom: calc(var(--u) * 1);
}

.count {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-areas: "mark num" "mark label";
  align-items: center;
  gap: 0 calc(var(--u) * 0.7);
  padding: calc(var(--u) * 0.7) calc(var(--u) * 0.9);
  border-radius: var(--radius);
  border: 1px solid rgba(255, 255, 255, 0.1);
  background: rgba(255, 255, 255, 0.025);
}

.count-mark {
  grid-area: mark;
  display: inline-flex;
}
.count-player .count-mark {
  color: var(--player);
}
.count-banker .count-mark {
  color: var(--banker);
}
.count-tie .count-mark {
  color: var(--tie);
}

.count-num {
  grid-area: num;
  font-family: var(--serif);
  font-size: calc(var(--u) * 1.9);
  line-height: 1;
}

.count-label {
  grid-area: label;
  font-size: calc(var(--u) * 0.94);
  color: var(--ink-dim);
}

.count-share {
  grid-column: 2;
  font-size: calc(var(--u) * 0.9);
  color: var(--ink-dim);
}

.stats-row {
  display: flex;
  flex-wrap: wrap;
  gap: calc(var(--u) * 0.7);
  margin-bottom: calc(var(--u) * 1);
}

.stat {
  flex: 1 1 calc(var(--u) * 8);
  display: flex;
  flex-direction: column;
  padding: calc(var(--u) * 0.6) calc(var(--u) * 0.9);
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.07);
}

.stat-value {
  font-family: var(--serif);
  font-size: calc(var(--u) * 1.6);
  font-variant-numeric: tabular-nums;
}

.stat-label {
  font-size: calc(var(--u) * 0.9);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

.stat-good .stat-value {
  color: var(--gold-bright);
}
.stat-bad .stat-value {
  color: #d98d85;
}

.recent {
  display: flex;
  flex-direction: column;
  gap: calc(var(--u) * 0.2);
  border-radius: var(--radius);
  background: rgba(0, 0, 0, 0.24);
  border: 1px solid rgba(255, 255, 255, 0.07);
  padding: calc(var(--u) * 0.7);
}

.recent-head,
.recent-row {
  display: grid;
  grid-template-columns: calc(var(--u) * 3) 1fr auto auto auto;
  align-items: center;
  gap: calc(var(--u) * 0.6);
  font-size: calc(var(--u) * 1);
}

.recent-head {
  color: var(--ink-dim);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-size: calc(var(--u) * 0.86);
  padding-bottom: calc(var(--u) * 0.3);
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

.recent-row {
  padding: calc(var(--u) * 0.34) 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}

.recent-seq {
  color: var(--ink-dim);
  font-variant-numeric: tabular-nums;
}

.recent-cards {
  display: flex;
  gap: calc(var(--u) * 0.8);
  flex-wrap: wrap;
}

.recent-hand {
  display: inline-flex;
  align-items: center;
  gap: calc(var(--u) * 0.16);
}

.mini-card {
  display: inline-grid;
  place-items: center;
  min-width: calc(var(--u) * 1.5);
  padding: 0 calc(var(--u) * 0.2);
  height: calc(var(--u) * 2);
  border-radius: calc(var(--u) * 0.3);
  background: #f5f0e2;
  color: #17171c;
  font-size: calc(var(--u) * 0.94);
  font-weight: 600;
}

.recent-total {
  font-style: normal;
  color: var(--gold-bright);
  font-family: var(--serif);
  font-size: calc(var(--u) * 1.24);
  margin-left: calc(var(--u) * 0.2);
}

.recent-result {
  font-size: calc(var(--u) * 1);
}
.outcome-player .recent-result {
  color: var(--player);
}
.outcome-banker .recent-result {
  color: var(--banker);
}
.outcome-tie .recent-result {
  color: var(--tie);
}

.recent-stake,
.recent-net {
  font-variant-numeric: tabular-nums;
  text-align: right;
}

.recent-net.good {
  color: var(--gold-bright);
}
.recent-net.bad {
  color: #d98d85;
}

@media (max-width: 640px) {
  .recent-head,
  .recent-row {
    grid-template-columns: calc(var(--u) * 2.4) 1fr auto;
    grid-template-areas: "seq cards result" "seq cards net";
  }
  .recent-seq {
    grid-area: seq;
  }
  .recent-cards {
    grid-area: cards;
  }
  .recent-result {
    grid-area: result;
    text-align: right;
  }
  .recent-stake {
    display: none;
  }
  .recent-net {
    grid-area: net;
  }
  .recent-head span:nth-child(4) {
    display: none;
  }
}

/* ---- settings controls ---- */

.choices {
  display: flex;
  flex-direction: column;
  gap: calc(var(--u) * 0.5);
  margin: calc(var(--u) * 0.6) 0;
}

.choice {
  display: flex;
  align-items: flex-start;
  gap: calc(var(--u) * 0.8);
  padding: calc(var(--u) * 0.8) calc(var(--u) * 1);
  border-radius: var(--radius);
  border: 1px solid rgba(255, 255, 255, 0.1);
  background: rgba(255, 255, 255, 0.025);
  cursor: pointer;
}

.choice.selected {
  border-color: rgba(230, 192, 120, 0.6);
  background: rgba(201, 162, 74, 0.1);
}

.choice input {
  margin-top: calc(var(--u) * 0.3);
  accent-color: var(--gold);
  width: calc(var(--u) * 1.6);
  height: calc(var(--u) * 1.6);
}

.choice-body {
  display: flex;
  flex-direction: column;
  gap: calc(var(--u) * 0.12);
}

.choice-label {
  font-size: calc(var(--u) * 1.14);
}

.choice-blurb {
  font-size: calc(var(--u) * 1);
  color: var(--ink-dim);
  line-height: 1.45;
}

.switch {
  display: flex;
  align-items: flex-start;
  gap: calc(var(--u) * 0.8);
  width: 100%;
  padding: calc(var(--u) * 0.7) 0;
  text-align: left;
}

.switch:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.switch-track {
  flex: 0 0 auto;
  width: calc(var(--u) * 3.6);
  height: calc(var(--u) * 2);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.14);
  border: 1px solid rgba(255, 255, 255, 0.2);
  position: relative;
  transition: background var(--fade) ease, border-color var(--fade) ease;
}

.switch.on .switch-track {
  background: rgba(201, 162, 74, 0.55);
  border-color: rgba(230, 192, 120, 0.8);
}

.switch-knob {
  position: absolute;
  top: 50%;
  left: calc(var(--u) * 0.22);
  width: calc(var(--u) * 1.4);
  height: calc(var(--u) * 1.4);
  border-radius: 50%;
  background: var(--ink);
  transform: translateY(-50%);
  transition: left var(--fade) cubic-bezier(0.3, 1.3, 0.5, 1);
}

.switch.on .switch-knob {
  left: calc(var(--u) * 1.9);
}

.switch-body {
  display: flex;
  flex-direction: column;
  gap: calc(var(--u) * 0.1);
}

.switch-label {
  font-size: calc(var(--u) * 1.12);
}

.switch-blurb {
  font-size: calc(var(--u) * 0.98);
  color: var(--ink-dim);
}

.volume {
  display: flex;
  align-items: center;
  gap: calc(var(--u) * 0.9);
  padding: calc(var(--u) * 0.5) 0;
}

.volume-label {
  font-size: calc(var(--u) * 1.08);
  min-width: calc(var(--u) * 6);
}

.slider {
  flex: 1;
  accent-color: var(--gold);
  height: calc(var(--u) * 1.6);
}

.link-row {
  display: flex;
  gap: calc(var(--u) * 0.6);
  align-items: center;
  flex-wrap: wrap;
}

.link-field {
  flex: 1 1 calc(var(--u) * 20);
  min-width: 0;
  padding: calc(var(--u) * 0.7) calc(var(--u) * 0.9);
  border-radius: calc(var(--radius) * 0.7);
  border: 1px solid rgba(255, 255, 255, 0.16);
  background: rgba(0, 0, 0, 0.35);
  color: var(--ink-soft);
  font-size: calc(var(--u) * 1);
  font-family: var(--sans);
}

/* ---- credits ---- */

.credits {
  display: flex;
  flex-direction: column;
  gap: calc(var(--u) * 0.5);
  margin-bottom: calc(var(--u) * 1);
}

.credit {
  padding: calc(var(--u) * 0.8) calc(var(--u) * 1);
  border-radius: var(--radius);
  border: 1px solid rgba(255, 255, 255, 0.08);
  background: rgba(255, 255, 255, 0.02);
}

.credit-what {
  font-size: calc(var(--u) * 1.14);
  color: var(--ink);
  margin-bottom: calc(var(--u) * 0.2);
}

.credit-detail {
  font-size: calc(var(--u) * 1.02);
  color: var(--ink-dim);
  line-height: 1.5;
  margin-bottom: calc(var(--u) * 0.3);
}

.credit-licence {
  font-size: calc(var(--u) * 0.96);
  color: var(--gold);
}

.chip-legend {
  display: flex;
  gap: calc(var(--u) * 0.7);
  margin: calc(var(--u) * 0.5) 0 calc(var(--u) * 0.7);
}

.legend-chip {
  display: inline-block;
  width: calc(var(--u) * 3.4);
  height: calc(var(--u) * 3.4);
}

.legend-chip svg {
  width: 100%;
  height: 100%;
}

/* ------------------------------------------------------------------ *
 * Messages
 * ------------------------------------------------------------------ */

.toasts {
  position: fixed;
  z-index: 60;
  left: 50%;
  /* Clear of the console. Anchored to the bottom of the window a notice lands
     on top of the rack and the Deal button, which are the two things the player
     is looking at when the notice appears and the two things it explains. */
  bottom: calc(var(--u) * 12 + var(--safe-b));
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  gap: calc(var(--u) * 0.5);
  align-items: center;
  pointer-events: none;
  width: max-content;
  max-width: min(92vw, calc(var(--u) * 54));
}

.toast {
  padding: calc(var(--u) * 0.85) calc(var(--u) * 1.4);
  border-radius: 999px;
  font-size: calc(var(--u) * 1.06);
  line-height: 1.4;
  text-align: center;
  background: rgba(10, 15, 12, 0.94);
  border: 1px solid rgba(230, 192, 120, 0.4);
  color: var(--ink);
  box-shadow: 0 calc(var(--u) * 0.6) calc(var(--u) * 1.6) rgba(0, 0, 0, 0.6);
  opacity: 0;
  transform: translateY(calc(var(--u) * 0.8));
  transition: opacity var(--fade) ease, transform var(--fade) ease;
}

.toast.in {
  opacity: 1;
  transform: none;
}

.toast-warn {
  border-color: rgba(200, 67, 58, 0.55);
}

/* ------------------------------------------------------------------ *
 * Shape adjustments
 * ------------------------------------------------------------------ */

/* Wide enough for the rail to sit beside the table. The height guard keeps a
   phone held sideways out of this layout, where there is no room for it. */
@media (min-width: 900px) and (min-height: 620px) {
  .screen {
    flex-direction: row;
    align-items: stretch;
  }
  .felt {
    flex: 1;
  }
  .areas {
    gap: calc(var(--u) * 1.2);
  }
  .area {
    min-height: calc(var(--u) * 12.5);
  }
  .console-betting {
    grid-template-columns: auto 1fr auto;
    grid-template-areas: "rack tools deal";
  }
  /* On one row the tools belong in the middle: pinned to the right of their
     column they crowd the balance and the Deal button into one clump at the
     corner, and the console reads as though something fell over. */
  .tools {
    justify-content: center;
  }
  .console-deal {
    justify-content: flex-end;
    gap: calc(var(--u) * 1.8);
  }
  .main {
    gap: calc(var(--u) * 1.2);
  }
  /* A table, not a list. With the width to spare the Player's hand takes the
     left and the Banker's the right, which is where they sit on a real baize,
     and both read at once instead of one above the other. */
  .hands {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: calc(var(--u) * 2);
    /* The same column the betting areas below use. Sent to the felt's own edges
       instead, an empty hand is a mark and a nought marooned in a corner with
       four hundred pixels of nothing beside it, and the table stops looking
       like one table. */
    width: 100%;
    max-width: calc(var(--u) * 86);
    margin: 0 auto;
  }
  /* Sized to its own cards rather than to half the felt. Stretched, the panel
     behind a winning hand becomes a wide empty band with the cards huddled at
     one end of it, and the highlight stops reading as a highlight. */
  .hand {
    flex: 0 1 auto;
    min-width: 0;
  }
  /* Player left, Banker right, as on a real baize, and it puts each hand's
     mark on the outside edge: read from the left, the Player's mark then its
     cards then its total, and the Banker's mirrored to answer it. */
  .hand-player {
    order: 1;
    justify-content: flex-start;
  }
  /* row-reverse, so flex-start is the right hand edge. */
  .hand-banker {
    order: 2;
    justify-content: flex-start;
  }
}

/* Short and wide: a phone held sideways, or a small laptop window. Everything
   tightens and the hand rows sit beside each other rather than stacked. */
@media (max-height: 620px) and (min-width: 640px) {
  :root {
    --u: clamp(3.6px, 1.6vh, 7.4px);
  }
  .felt {
    padding-top: calc(var(--u) * 0.8 + var(--safe-t));
    padding-bottom: calc(var(--u) * 0.9 + var(--safe-b));
    gap: calc(var(--u) * 0.6);
  }
  .bar {
    min-height: calc(var(--u) * 3);
  }
  .shoe {
    width: calc(var(--u) * 3.4);
    height: calc(var(--u) * 3.9);
    top: calc(var(--u) * 3.6 + var(--safe-t));
  }
  .main {
    gap: calc(var(--u) * 0.9);
  }
  .hands {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: calc(var(--u) * 1.6);
  }
  .hand {
    flex: 0 1 auto;
    min-width: 0;
  }
  /* Player left, Banker right, mirrored so both marks sit on the outside edge. */
  .hand-player {
    order: 1;
  }
  .hand-banker {
    order: 2;
    justify-content: flex-start;
  }
  .card-slot {
    --card-w: calc(var(--u) * 10.4);
  }
  .areas {
    gap: calc(var(--u) * 0.7);
  }
  .area {
    min-height: calc(var(--u) * 9);
    padding: calc(var(--u) * 0.6) calc(var(--u) * 0.7) calc(var(--u) * 0.5);
  }
  .area-name {
    font-size: calc(var(--u) * 1.5);
  }
  .area-chips {
    display: none;
  }
  .sum-notes {
    display: none;
  }
}

/* Very narrow: the rack and the tools share one line and scroll if they must. */
@media (max-width: 400px) {
  .tool-label {
    display: none;
  }
  .tool {
    padding: calc(var(--u) * 0.6);
  }
  .bar-beads {
    display: none;
  }
  .console-betting {
    gap: calc(var(--u) * 0.55);
  }
}

@media (max-width: 340px) {
  .hand-name,
  .hand-total-label {
    display: none;
  }
}

/* A lap-sized window in portrait: give the table a little more room. */
@media (min-width: 700px) and (min-height: 900px) {
  :root {
    --u: clamp(5.4px, 1.15vmin, 10.5px);
  }
}
