/* Liar's Bar.
 *
 * A back room late at night: smoke-dark walls, one lamp, a green felt table
 * with a wooden rail, cream cards and blued steel. Everything is drawn here or
 * in inline SVG; nothing comes off the network, fonts included.
 *
 * Every size and colour is a custom property up here, so the rules below read
 * as layout rather than as numbers.
 */

:root {
  --ink: #efe6d6;
  --muted: #a39684;
  --ground: #120e0c;
  --lamp: #4a2f1466;
  --smoke: #2b333a55;
  --panel: #1d1714;
  --raised: #2a211c;
  --line: #43362d;
  --accent: #d9a441;
  --accent-ink: #1a1206;
  --danger: #d9473f;
  --danger-ink: #fff4f0;
  --safe: #5dbb73;
  --focus: #8fd0ff;

  --felt: #1f5c3d;
  --felt-light: #2d7a52;
  --felt-dark: #123524;
  --felt-line: #ffffff22;
  --wood: #4a2c17;
  --wood-light: #6b4423;
  --chair: #0d1a13cc;
  --shade: #000000aa;

  --card-face: #f3ead7;
  --card-sheen: #fffaf0;
  --card-edge: #b9ab8c;
  --pip-red: #b3261e;
  --pip-black: #1c1a17;
  --pip-joker: #6b3fa0;
  --back-a: #7a1f1f;
  --back-b: #5c1515;

  --steel-light: #8d949c;
  --steel: #5a6068;
  --steel-dark: #2c3036;
  --brass: #c9a24a;
  --brass-dark: #7d6125;
  --bore: #0c0d0f;

  --page: 1180px;
  --gap: 16px;
  --gap-small: 8px;
  --gap-large: 28px;
  --radius: 10px;
  --radius-small: 6px;
  --border: 1px;
  --thick: 3px;
  --hairline: 2px;
  --sliver: 4px;
  --glow: 8px;
  --glow-wide: 24px;
  --dim: 0.55;
  --faint: 0.45;

  --small: 13px;
  --text: 16px/1.5;
  --title: clamp(28px, 5vw, 48px);
  --timer: clamp(24px, 5vw, 36px);
  --code: clamp(32px, 7vw, 56px);
  --stamp: clamp(26px, 6vw, 40px);
  --tracking: 0.12em;
  --mono: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  --serif: Georgia, "Times New Roman", serif;

  --scroller: 60vh;
  --prose: 60ch;
  --form: 520px;
  --field: 160px;
  --aside: 240px;
  --column-wide: 280px;
  --column-narrow: 140px;

  /* The table's furniture. A card is sized by --card-size wherever it lies,
     and everything printed on it is a share of that. */
  --card-size: var(--card-mid);
  --card-large: clamp(48px, 13vw, 76px);
  --card-mid: clamp(40px, 10vw, 56px);
  --card-open: 30px;
  --card-small: 22px;
  --card-ratio: 5 / 7;
  --card-corner: 0.1;
  --index-scale: 0.26;
  --index-inset: 7%;
  --pip-share: 46%;
  --weave: 3px;
  --overlap: -0.55;
  --overlap-pile: -0.8;
  --overlap-open: -0.3;
  --fan-turn: 3deg;
  --lift: 14px;
  --rail: 10px;
  --felt-radius: 36px;
  --chair-width: 88px;
  --chair-open: 150px;
  --chair-max: 220px;
  --cylinder: 44px;
  --orbit: -0.3;
  --chamber-share: 0.24;
  --pin-inset: 42%;
  --tilt: -4deg;
  --stamp-from: 2.4;

  /* How a showdown plays out: each card turns over a beat after the last,
     then the verdict lands, then -- after a breath -- the trigger. */
  --flip: 380ms;
  --stagger: 220ms;
  --suspense: 500ms;
  --pulse: 900ms;
}

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

html {
  scroll-behavior: smooth;
}

body {
  min-height: 100vh;
  margin: 0;
  background:
    radial-gradient(ellipse at 50% -10%, var(--lamp) 0, transparent 55%),
    radial-gradient(ellipse at 15% 110%, var(--smoke) 0, transparent 50%),
    var(--ground);
  background-attachment: fixed;
  color: var(--ink);
  font:
    var(--text) system-ui,
    sans-serif;
}

main {
  max-width: var(--page);
  margin: 0 auto;
  padding: var(--gap);
}

h1,
h2,
h3 {
  line-height: 1.2;
  margin: 0 0 var(--gap-small);
}

h1 {
  font-family: var(--serif);
}

a {
  color: var(--accent);
}

.status,
.hint {
  color: var(--muted);
}

.hint {
  font-size: var(--small);
  margin: var(--gap-small) 0;
}

.eyebrow {
  display: block;
  margin: 0;
  color: var(--muted);
  font-size: var(--small);
  font-weight: 700;
  letter-spacing: var(--tracking);
  text-transform: uppercase;
}

.refusal {
  margin: var(--gap-small) 0;
  padding: var(--gap-small) var(--gap);
  border: var(--border) solid var(--danger);
  border-radius: var(--radius-small);
  color: var(--danger);
}

.code {
  font-family: var(--mono);
  letter-spacing: var(--tracking);
}

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

button,
.button {
  display: inline-block;
  padding: var(--gap-small) var(--gap);
  border: var(--border) solid var(--line);
  border-radius: var(--radius-small);
  background: var(--raised);
  color: var(--ink);
  font: inherit;
  text-decoration: none;
  cursor: pointer;
  touch-action: manipulation;
}

button:hover:not(:disabled),
.button:hover {
  border-color: var(--accent);
}

button:focus-visible,
.button:focus-visible,
input:focus-visible,
a:focus-visible {
  outline: var(--thick) solid var(--focus);
  outline-offset: var(--hairline);
}

button:disabled {
  cursor: default;
  opacity: var(--dim);
}

button.primary {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--accent-ink);
  font-weight: 700;
}

button.danger {
  border-color: var(--danger);
  background: var(--danger);
  color: var(--danger-ink);
  font-weight: 700;
}

button.quiet {
  background: transparent;
}

input {
  padding: var(--gap-small);
  border: var(--border) solid var(--line);
  border-radius: var(--radius-small);
  background: var(--ground);
  color: var(--ink);
  font: inherit;
}

input[type="number"] {
  width: 6em;
}

input[type="checkbox"] {
  accent-color: var(--accent);
}

label {
  color: var(--muted);
  font-size: var(--small);
}

.panel {
  padding: var(--gap);
  border: var(--border) solid var(--line);
  border-radius: var(--radius);
  background: var(--panel);
}

.columns,
.choices {
  display: grid;
  grid-template-columns: repeat(
    auto-fit,
    minmax(min(var(--column-wide), 100%), 1fr)
  );
  gap: var(--gap);
  margin: var(--gap) 0;
}

/* A grid child is as wide as its widest word unless told otherwise, and a
   table of cards is wider than a phone. */
.columns > *,
.choices > * {
  min-width: 0;
}

.actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--gap);
  margin: var(--gap) 0;
}

.row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap-small) var(--gap);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* ---- masthead ----------------------------------------------------------- */

.masthead,
.masthead nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--gap);
}

.masthead {
  justify-content: space-between;
  margin-bottom: var(--gap);
  padding-bottom: var(--gap-small);
  border-bottom: var(--border) solid var(--line);
}

.masthead form {
  margin: 0;
}

.brand {
  color: var(--accent);
  font: 700 1.2em var(--serif);
  letter-spacing: var(--tracking);
  text-decoration: none;
  text-transform: uppercase;
}

/* ---- door and lobby ----------------------------------------------------- */

.lede {
  max-width: var(--prose);
  color: var(--muted);
}

.door form.panel {
  display: grid;
  gap: var(--gap-small);
  align-content: start;
}

input.code {
  min-width: 0;
  font-size: 1.4em;
  text-transform: uppercase;
}

.invitation {
  text-align: center;
}

.invitation .code {
  margin: 0;
  color: var(--accent);
  font-size: var(--code);
  font-weight: 700;
}

.invitation .link {
  display: flex;
  gap: var(--gap-small);
  max-width: var(--form);
  margin: 0 auto;
}

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

.members {
  display: grid;
  gap: var(--gap-small);
  margin: 0 0 var(--gap);
  padding: 0;
  list-style: none;
}

.member {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--gap-small);
}

.member.away a {
  color: var(--muted);
}

.tag {
  padding: 0 var(--gap-small);
  border: var(--border) solid var(--line);
  border-radius: var(--radius);
  color: var(--muted);
  font-size: var(--small);
  white-space: nowrap;
}

.tag.host {
  border-color: var(--accent);
  color: var(--accent);
}

.tag.away {
  border-color: var(--danger);
  color: var(--danger);
}

.fields {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: var(--gap-small) var(--gap);
  margin-bottom: var(--gap);
}

.check {
  display: flex;
  align-items: center;
  gap: var(--gap-small);
  color: var(--ink);
  font-size: inherit;
}

.summary {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--gap-small) var(--gap);
  margin: 0;
}

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

.summary dd {
  margin: 0;
}

/* ---- a card ------------------------------------------------------------- */

.card {
  position: relative;
  display: inline-grid;
  flex: none;
  place-items: center;
  width: var(--card-size);
  aspect-ratio: var(--card-ratio);
  padding: 0;
  border: var(--border) solid var(--card-edge);
  border-radius: calc(var(--card-size) * var(--card-corner));
  background: linear-gradient(160deg, var(--card-sheen), var(--card-face));
  box-shadow: 0 var(--hairline) var(--sliver) var(--shade);
  color: var(--pip-black);
  font: 700 calc(var(--card-size) * var(--index-scale)) / 1 var(--serif);
}

.card[data-card="King"],
.card[data-card="Queen"] {
  color: var(--pip-red);
}

.card[data-card="Joker"] {
  color: var(--pip-joker);
}

.card .index {
  position: absolute;
  top: var(--index-inset);
  left: var(--index-inset);
}

.card .index.low {
  inset: auto var(--index-inset) var(--index-inset) auto;
  transform: rotate(0.5turn);
}

.card .pip {
  width: var(--pip-share);
  fill: currentColor;
}

.card.back {
  border: var(--hairline) solid var(--card-face);
  background: repeating-linear-gradient(
    45deg,
    var(--back-a) 0 var(--weave),
    var(--back-b) var(--weave) calc(var(--weave) * 2)
  );
}

/* Cards held together, each tucked under the last and turned a little. */
.fan {
  --card-size: var(--card-small);
  display: inline-flex;
  min-height: calc(var(--card-size) / (var(--card-ratio)));
}

.fan .card {
  transform: rotate(
    calc((var(--index) - (var(--count) - 1) / 2) * var(--fan-turn))
  );
}

.fan .card + .card,
.open-hand .dealt + .dealt {
  margin-left: calc(var(--card-size) * var(--overlap));
}

.dealt {
  display: inline-flex;
}

.open-hand {
  --card-size: var(--card-open);
  --overlap: var(--overlap-open);
  display: inline-flex;
}

/* ---- a revolver's cylinder ---------------------------------------------- */

.cylinder {
  position: relative;
  display: inline-block;
  flex: none;
  width: var(--cylinder);
  aspect-ratio: 1;
  border: var(--hairline) solid var(--steel-dark);
  border-radius: 50%;
  background: radial-gradient(
    circle,
    var(--steel-light),
    var(--steel) 60%,
    var(--steel-dark)
  );
  box-shadow: 0 var(--hairline) var(--sliver) var(--shade);
}

.cylinder::after {
  content: "";
  position: absolute;
  inset: var(--pin-inset);
  border-radius: 50%;
  background: var(--steel-dark);
}

/* A chamber nobody has tried may be the one: brass. One that has been tried
   is an empty hole, and the one that went off stays lit. */
.chamber {
  position: absolute;
  top: 50%;
  left: 50%;
  width: calc(var(--cylinder) * var(--chamber-share));
  aspect-ratio: 1;
  margin: calc(var(--cylinder) * var(--chamber-share) / -2);
  border: var(--border) solid var(--brass-dark);
  border-radius: 50%;
  background: var(--brass);
  transform: rotate(calc(1turn * var(--index) / var(--chambers)))
    translateY(calc(var(--cylinder) * var(--orbit)));
}

.chamber.tried {
  border-color: var(--steel-dark);
  background: var(--bore);
}

.chamber.fatal {
  border-color: var(--danger);
  background: var(--danger);
  box-shadow: 0 0 var(--glow) var(--danger);
}

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

.rail {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--gap-small) var(--gap);
  margin-bottom: var(--gap);
  padding: var(--gap-small) var(--gap);
  border: var(--border) solid var(--line);
  border-radius: var(--radius);
  background: var(--panel);
}

.rail p {
  margin: 0;
}

.round {
  color: var(--muted);
  font-size: var(--small);
  font-weight: 700;
  letter-spacing: var(--tracking);
  text-transform: uppercase;
}

.turn {
  min-width: 0;
  overflow-wrap: anywhere;
}

.turn.yours {
  color: var(--accent);
}

.timer {
  font: 700 var(--timer) / 1 var(--mono);
  font-variant-numeric: tabular-nums;
}

.timer.urgent {
  color: var(--danger);
  animation: pulse var(--pulse) ease-in-out infinite;
}

.banner {
  margin: 0 0 var(--gap);
  padding: var(--gap-small) var(--gap);
  border: var(--border) solid var(--accent);
  border-left-width: var(--sliver);
  border-radius: var(--radius-small);
  background: var(--panel);
}

.banner.out {
  border-color: var(--danger);
}

.table .columns {
  margin-top: 0;
}

.felt {
  display: grid;
  gap: var(--gap);
  min-width: 0;
  padding: var(--gap-large) var(--gap);
  border: var(--rail) solid var(--wood);
  border-radius: var(--felt-radius);
  outline: var(--border) solid var(--wood-light);
  outline-offset: calc(var(--rail) * -1);
  background: radial-gradient(
    ellipse at center,
    var(--felt-light),
    var(--felt) 55%,
    var(--felt-dark)
  );
  box-shadow:
    inset 0 0 var(--glow-wide) var(--shade),
    0 var(--sliver) var(--glow-wide) var(--shade);
}

.chairs {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--gap-small);
}

/* Nobody at the near side -- somebody watching -- is no row at all. */
.chairs:empty {
  display: none;
}

.chair {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  flex: 1 1 var(--chair-width);
  gap: var(--gap-small);
  justify-items: center;
  min-width: 0;
  max-width: var(--chair-max);
  padding: var(--gap-small);
  border: var(--hairline) solid transparent;
  border-radius: var(--radius);
  background: var(--chair);
  text-align: center;
}

.chairs.open .chair {
  flex-basis: var(--chair-open);
}

.chair[data-turn="true"] {
  border-color: var(--accent);
  box-shadow: 0 0 var(--glow-wide) var(--accent);
}

.chair[data-state="shot"],
.chair[data-state="left"] {
  opacity: var(--dim);
}

.chair[data-state="shot"] .name,
.chair[data-state="left"] .name {
  text-decoration: line-through;
}

.who {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--sliver);
  max-width: 100%;
  margin: 0;
}

.who .name {
  max-width: 100%;
  overflow: hidden;
  font-weight: 700;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.gun {
  display: flex;
  align-items: center;
  gap: var(--gap-small);
}

.pulls,
.holding .count {
  color: var(--muted);
  font: var(--small) var(--mono);
}

.holding {
  display: grid;
  gap: var(--sliver);
  justify-items: center;
  max-width: 100%;
}

.centre {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--gap) var(--gap-large);
  padding: var(--gap) 0;
  border-block: var(--border) dashed var(--felt-line);
  text-align: center;
}

.asked,
.laid {
  display: flex;
  align-items: center;
  gap: var(--gap);
}

.asked p,
.laid p {
  margin: 0;
  text-align: left;
}

.centre strong {
  display: block;
  font: 700 var(--title) / 1 var(--serif);
}

.centre .rank {
  color: var(--accent);
  letter-spacing: var(--tracking);
}

.laid .fan {
  --overlap: var(--overlap-pile);
  --fan-turn: 0deg;
}

.claim {
  flex-basis: 100%;
  margin: 0;
  color: var(--muted);
}

.claim.standing {
  color: var(--ink);
  font-weight: 700;
}

/* How the last round ended. It stays where it is until the next one does. */
.showdown {
  display: grid;
  gap: var(--gap-small);
  justify-items: center;
  padding: var(--gap);
  border: var(--hairline) solid var(--accent);
  border-radius: var(--radius);
  background: var(--chair);
  text-align: center;
}

.showdown[data-verdict="lie"] {
  border-color: var(--danger);
}

.showdown[data-verdict="truth"] {
  border-color: var(--safe);
}

.showdown p {
  margin: 0;
}

.revealed {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--gap-small);
  perspective: var(--aside);
}

.revealed:empty {
  display: none;
}

.dealt.lie .card {
  outline: var(--thick) solid var(--danger);
  transform: rotate(var(--tilt));
}

.ruling {
  color: var(--accent);
  font: 700 var(--stamp) / 1 var(--serif);
  letter-spacing: var(--tracking);
  transform: rotate(var(--tilt));
}

.showdown[data-verdict="lie"] .ruling {
  color: var(--danger);
}

.showdown[data-verdict="truth"] .ruling {
  color: var(--safe);
}

.shot {
  font-weight: 700;
}

.shot[data-shot="bang"] {
  color: var(--danger);
}

.showdown .dealt {
  animation: turn-over var(--flip) both;
  animation-delay: calc(var(--index) * var(--stagger));
}

.showdown .ruling {
  animation: land var(--flip) both;
  animation-delay: calc(var(--count) * var(--stagger) + var(--flip));
}

.showdown .shot {
  animation: arrive var(--flip) both;
  animation-delay: calc(
    var(--count) * var(--stagger) + var(--flip) * 2 + var(--suspense)
  );
}

@keyframes turn-over {
  from {
    opacity: 0;
    transform: rotateY(0.25turn);
  }
}

@keyframes land {
  from {
    opacity: 0;
    transform: rotate(var(--tilt)) scale(var(--stamp-from));
  }
}

@keyframes arrive {
  from {
    opacity: 0;
    transform: translateY(var(--gap-small));
  }
}

@keyframes pulse {
  50% {
    opacity: var(--faint);
  }
}

@media (prefers-reduced-motion: reduce) {
  .showdown .dealt,
  .showdown .ruling,
  .showdown .shot,
  .timer.urgent {
    animation: none;
  }
}

.mine-hand {
  display: grid;
  gap: var(--gap-small);
  justify-items: center;
}

.mine-hand .actions {
  justify-content: center;
  margin: 0;
}

.mine-hand .hint {
  max-width: var(--prose);
  margin: 0;
  color: var(--ink);
  opacity: var(--dim);
  text-align: center;
}

.hand {
  --card-size: var(--card-large);
  display: flex;
  justify-content: center;
  gap: var(--gap-small);
  padding-top: var(--lift);
}

.hand .card {
  cursor: pointer;
  transition: transform var(--flip);
}

.hand .card:hover:not(:disabled) {
  border-color: var(--accent);
}

.hand .card.chosen {
  outline: var(--thick) solid var(--accent);
  transform: translateY(calc(var(--lift) * -1));
}

.side {
  min-width: 0;
  padding: var(--gap);
  border: var(--border) solid var(--line);
  border-radius: var(--radius);
  background: var(--panel);
}

.feed,
.captions {
  display: grid;
  gap: var(--gap-small);
  margin: var(--gap-small) 0 0;
  padding: 0;
  list-style: none;
}

.feed {
  max-height: var(--scroller);
  overflow-y: auto;
  color: var(--muted);
  font-size: var(--small);
}

.feed li:first-child {
  color: var(--ink);
  font-size: 1rem;
}

.captions {
  margin: 0;
  text-align: center;
}

.company {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--gap);
  margin-top: var(--gap);
  padding-top: var(--gap);
  border-top: var(--border) solid var(--line);
}

.company .members {
  display: flex;
  flex: 1;
  margin: 0;
}

/* ---- debrief, profile, replay ------------------------------------------- */

.outcome {
  color: var(--accent);
  font-size: var(--title);
}

.debrief {
  display: grid;
  gap: var(--gap);
}

.debrief .actions {
  margin: 0;
}

.results {
  display: grid;
  gap: var(--gap-small);
  margin: 0;
  padding: 0;
  list-style: none;
}

.result {
  --cylinder: var(--card-open);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--gap-small) var(--gap);
  padding: var(--gap-small) var(--gap);
  border-left: var(--thick) solid var(--danger);
  background: var(--raised);
}

.result[data-state="alive"] {
  border-left-color: var(--safe);
}

.result a {
  font-weight: 700;
}

.result .pulls {
  margin-left: auto;
}

.profile {
  display: grid;
  gap: var(--gap);
}

.inline {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--gap-small);
}

.inline input {
  min-width: 0;
}

.stats {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--column-narrow), 1fr));
  gap: var(--gap);
  margin: 0;
}

.stats dt {
  color: var(--muted);
  font-size: var(--small);
}

.stats dd {
  margin: 0;
  font: 700 1.6em/1.2 var(--mono);
}

.history {
  display: grid;
  gap: var(--gap-small);
  margin: 0;
  padding: 0;
  list-style: none;
}

.entry {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--gap-small) var(--gap);
  padding: var(--gap-small) var(--gap);
  border-left: var(--thick) solid var(--danger);
  background: var(--raised);
}

.entry.won {
  border-left-color: var(--safe);
}

.entry .result {
  display: inline;
  padding: 0;
  border: 0;
  background: none;
  font-weight: 700;
}

.entry .with a {
  margin-right: var(--gap-small);
}

.entry time {
  margin-left: auto;
  color: var(--muted);
  font-size: var(--small);
}

.transport {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--gap-small);
  margin: var(--gap) 0;
}

.transport input[type="range"] {
  flex: 1;
  min-width: var(--field);
  padding: 0;
  accent-color: var(--accent);
}

.columns.wide-left {
  grid-template-columns: minmax(0, 2fr) minmax(var(--aside), 1fr);
  align-items: start;
}

/* A media query cannot read a custom property, so this one width is written
   out. */
@media (max-width: 800px) {
  .columns.wide-left {
    grid-template-columns: minmax(0, 1fr);
  }
}

.moments {
  display: grid;
  gap: var(--hairline);
  max-height: var(--scroller);
  margin: 0;
  padding: 0;
  overflow-y: auto;
  list-style: none;
}

.moment {
  display: flex;
  gap: var(--gap-small);
  width: 100%;
  border-color: transparent;
  background: transparent;
  font-size: var(--small);
  text-align: left;
}

.moment time {
  color: var(--muted);
  font-family: var(--mono);
}

.moment .lines {
  display: grid;
  gap: var(--sliver);
  min-width: 0;
}

.moment.current {
  border-color: var(--accent);
  background: var(--raised);
}
