:root {
  --bg: #0f1117;
  --panel: #171a23;
  --panel-2: #1e2230;
  --text: #e8eaf0;
  --muted: #8b91a3;
  --accent: #6c8cff;
  --accent-hover: #88a1ff;
  --green: #4ade80;
  --red: #f87171;
  --radius: 12px;

  /* hand card size: grows with the viewport, capped so 12 cards + overlap
     fit even on a ~320px phone, and kept short on landscape screens so the
     deck never eats the whole height */
  --card-w: clamp(2rem, min(4vw + 1.3rem, 10.5vh), 6rem);
  /* vertical space the fixed deck occupies (card + deck paddings + hover lift) */
  --deck-clear: calc(var(--card-w) * 1.86);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  min-height: 100vh;
  background: var(--bg);
  color: var(--text);
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
}

button {
  font: inherit;
  color: inherit;
  background: var(--panel-2);
  border: 1px solid #2c3145;
  border-radius: var(--radius);
  padding: 0.6rem 1.2rem;
  cursor: pointer;
  transition: background 0.15s, transform 0.05s;
}
button:hover:not(:disabled) { background: #262b3d; }
button:active:not(:disabled) { transform: scale(0.97); }
button:disabled { opacity: 0.4; cursor: default; }
button.primary { background: var(--accent); border-color: var(--accent); color: #0b0e1a; font-weight: 600; }
button.primary:hover:not(:disabled) { background: var(--accent-hover); }
button.big { padding: 0.9rem 2rem; font-size: 1.1rem; width: 100%; }
button.ghost { background: transparent; border-color: transparent; color: var(--muted); font-size: 0.9rem; }
button.ghost:hover { color: var(--text); background: var(--panel-2); }

input[type="text"] {
  font: inherit;
  color: inherit;
  background: var(--panel-2);
  border: 1px solid #2c3145;
  border-radius: var(--radius);
  padding: 0.7rem 1rem;
  text-align: center;
  letter-spacing: 0.1em;
}
input[type="text"]:focus { outline: 2px solid var(--accent); border-color: transparent; }

/* --- landing / join pages --- */

.center-page {
  display: grid;
  place-items: center;
  min-height: 100vh;
  padding: 1rem;
}

.card-panel {
  background: var(--panel);
  border-radius: 16px;
  padding: 2.5rem 2rem;
  width: 100%;
  max-width: 380px;
  text-align: center;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.4);
}

.card-panel h1 { margin: 0 0 0.5rem; font-size: 1.8rem; }
.tagline { color: var(--muted); margin: 0 0 1.8rem; line-height: 1.5; }
.card-panel form { display: flex; flex-direction: column; gap: 0.7rem; }

.divider {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  color: var(--muted);
  font-size: 0.85rem;
  margin: 1.4rem 0;
}
.divider::before, .divider::after {
  content: "";
  flex: 1;
  border-top: 1px solid #2c3145;
}

.join-form { flex-direction: row !important; }
.join-form input { flex: 1; text-transform: uppercase; min-width: 0; }

.error { color: #f87171; }

/* --- room page --- */

.room-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem 1rem;
  padding: 1rem 1.5rem;
  border-bottom: 1px solid #232738;
}

/* deck switcher: the active deck gets the accent, others stay quiet */
.deck-switcher { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.deck-btn { padding: 0.35rem 0.8rem; font-size: 0.85rem; color: var(--muted); }
.deck-btn.active {
  border-color: var(--accent);
  color: var(--accent);
  font-weight: 600;
}
.room-code-label { color: var(--muted); margin-right: 0.5rem; }
.room-code {
  font-family: ui-monospace, monospace;
  font-size: 1.3rem;
  letter-spacing: 0.25em;
  color: var(--accent);
}

/* joined room: full-height column — header on top, table area filling the
   rest, hand fixed at the bottom */
body.room-page {
  display: flex;
  flex-direction: column;
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
}

.room-page .room-header { flex: none; }

.room-main {
  flex: 1;
  min-height: 0;
  display: grid;
  place-items: center;
  padding: 1rem 1rem var(--deck-clear); /* bottom clearance for the fixed hand */
  /* size container, so the table can size itself against this box (cqw/cqh) */
  container-type: size;
}

/* the table: a round felt with players seated around it, re-rendered over SSE.
   It fills the room-main box, staying centered between header and hand. */
.poker-table {
  --size: min(88vw, 62vh); /* fallback without container query support */
  --size: min(94cqw, 92cqh);
  /* seat inset grows with the table so chips keep their proportions */
  --orbit: calc(var(--size) / 2 - clamp(2.6rem, calc(var(--size) * 0.07), 4.5rem));
  position: relative;
  width: var(--size);
  height: var(--size);
}

/* soft ambient glow pooling under the table (painted below felt + seats) */
.poker-table::before {
  content: "";
  position: absolute;
  inset: 2%; /* reach just past the felt's rim so the halo stays visible */
  border-radius: 50%;
  background: radial-gradient(circle at 50% 42%, rgba(74, 222, 128, 0.13), rgba(74, 222, 128, 0) 64%);
  filter: blur(12px);
  pointer-events: none;
}

.felt {
  position: absolute;
  inset: 17%;
  border-radius: 50%;
  /* the border is transparent: the wooden rim is painted by the border-box
     background layers, so it can be a gradient (border-color can't) */
  border: 0.55rem solid transparent;
  background:
    /* felt: top light over a green radial, both clipped inside the rim */
    radial-gradient(circle at 50% 30%, rgba(255, 255, 255, 0.10), rgba(255, 255, 255, 0) 55%) padding-box,
    radial-gradient(circle at 50% 40%, #3f9a70, #2b6a4d 58%, #1a4330) padding-box,
    /* rim: fine grain over a wood radial, painted under the border */
    repeating-linear-gradient(115deg, rgba(0, 0, 0, 0.14) 0 3px, rgba(255, 255, 255, 0.04) 3px 6px, rgba(0, 0, 0, 0) 6px 11px) border-box,
    radial-gradient(circle at 32% 26%, #7a5b3c, #553f2b 48%, #38291b) border-box;
  box-shadow:
    0 1.5rem 4rem rgba(0, 0, 0, 0.55),
    inset 0 0.25rem 0.7rem rgba(0, 0, 0, 0.5), /* bevel just inside the rim */
    inset 0 0 3.5rem rgba(0, 0, 0, 0.4);
  display: grid;
  place-items: center;
  text-align: center;
  padding: 1rem;
}

/* the dashed betting ring on the felt, like on a real poker table */
.felt::before {
  content: "";
  position: absolute;
  inset: 9%;
  border-radius: 50%;
  border: 2px dashed rgba(255, 255, 255, 0.15);
  pointer-events: none;
}

.felt-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.9rem;
  color: #eaf6ef;
  font-size: clamp(0.9rem, calc(var(--size) * 0.028), 1.05rem);
}
.empty { color: #b9d6c7; margin: 0; }
/* names of visitors (watching via the 👀 card), shown on the felt */
.visitors { margin: 0; color: #b9d6c7; font-size: 0.85em; }
.round-status { margin: 0; color: #cfe8da; }
.round-status strong { color: #ffd166; font-size: 1.3em; }

/* A seat is a zero-size arm reaching out from the table center, rotated into
   place; the (upright) player chip is centered on the end of the arm. */
.seat {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: rotate(calc(var(--i) * 1turn / var(--n))) translateY(calc(-1 * var(--orbit)));
}
.seat .player {
  position: absolute;
  top: 0;
  left: 0;
  /* center on the arm end and undo the arm's rotation to stay upright
     (--i/--n are custom properties, so they inherit into the chip) */
  transform: translate(-50%, -50%) rotate(calc(var(--i) * -1turn / var(--n)));
}

.player {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4rem;
  /* chips scale with the table, within sane bounds */
  width: clamp(3.8rem, calc(var(--size) * 0.13), 7rem);
}
.player.away { opacity: 0.45; }
.player-card {
  display: grid;
  place-items: center;
  width: 66%;
  aspect-ratio: 5 / 7;
  border-radius: 8px;
  border: 2px dashed #3d445f;
  background: linear-gradient(180deg, #181c29, #12151f);
  color: var(--muted);
  font-size: clamp(1rem, calc(var(--size) * 0.036), 1.7rem);
  font-weight: 700;
  box-shadow: 0 0.35rem 0.9rem rgba(0, 0, 0, 0.35);
}
/* voted but hidden: a card back — sheen stripes + a pale inset frame,
   like the patterned back of a real deck */
.player-card.filled:not(.open) {
  border-style: solid;
  border-color: #8fa3ff;
  color: rgba(255, 255, 255, 0.95);
  background:
    repeating-linear-gradient(45deg, rgba(255, 255, 255, 0.16) 0 5px, rgba(255, 255, 255, 0) 5px 10px),
    linear-gradient(155deg, #829dff, #4d63d8);
  box-shadow:
    inset 0 0 0 3px rgba(255, 255, 255, 0.22),
    0 0 0.9rem rgba(108, 140, 255, 0.4);
}
/* revealed: a white playing card with dark ink */
.player-card.filled.open {
  border-style: solid;
  border-color: #f4f6fc;
  background: linear-gradient(180deg, #ffffff, #dfe4f2);
  color: #171c2e;
  box-shadow: 0 0.4rem 1rem rgba(0, 0, 0, 0.45);
}
/* revealed but voteless ("—"): fade the empty slot back */
.player-card.open:not(.filled) { opacity: 0.55; }
/* revealed extremes: the card stays white; the lowest gets a green frame
   and glow, the highest red */
.player-card.open.low { border-color: var(--green); color: #189a54; box-shadow: 0 0 1.1rem rgba(74, 222, 128, 0.55); }
.player-card.open.high { border-color: var(--red); color: #d4483b; box-shadow: 0 0 1.1rem rgba(248, 113, 113, 0.55); }
/* ▼/▲ flags next to the names of the extreme voters */
.flag { margin-left: 0.25rem; font-size: 0.85em; }
.flag-low { color: var(--green); }
.flag-high { color: var(--red); }
/* the name: a small dark pill, readable over both the page and the rim;
   wider than the card column (it stays centered), so long names still fit */
.player-name {
  font-size: clamp(0.75rem, calc(var(--size) * 0.026), 0.95rem);
  max-width: 11rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  background: rgba(10, 13, 22, 0.78);
  border: 1px solid #2c3145;
  border-radius: 999px;
  padding: 0.1rem 0.5rem;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.35);
}
.player-name small { color: var(--muted); }

/* voted indicator next to the name */
.dot {
  display: inline-block;
  width: 0.45rem;
  height: 0.45rem;
  margin-right: 0.3rem;
  border-radius: 50%;
  border: 1px solid var(--muted);
  vertical-align: baseline;
}
.dot.on {
  background: var(--green);
  border-color: var(--green);
  box-shadow: 0 0 6px var(--green);
}

.stats {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.25rem;
  color: #cfe8da;
}
.stats .avg strong { color: #ffd166; font-size: 1.6em; margin-left: 0.25rem; text-shadow: 0 1px 6px rgba(0, 0, 0, 0.5); }
.stats .dist { letter-spacing: 0.06em; }

.controls {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.8rem;
}
/* lift the buttons off the felt */
.controls button { box-shadow: 0 3px 10px rgba(0, 0, 0, 0.35); }

/* the hand: fixed to the bottom of the screen, fanned out like a TCG hand.
   Card size comes from --card-w, so the whole hand scales with the viewport. */
.deck {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 10;
  display: flex;
  justify-content: center;
  align-items: flex-end;
  padding: calc(var(--card-w) * 0.3) 0.5rem calc(var(--card-w) * 0.15);
  background: linear-gradient(to top, rgba(8, 10, 16, 0.95) 55%, rgba(8, 10, 16, 0));
}
.card {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  line-height: 1;
  width: var(--card-w);
  height: calc(var(--card-w) * 1.41);
  font-size: calc(var(--card-w) * 0.38);
  font-weight: 700;
  background: var(--panel);
  border: 2px solid #39405a;
  box-shadow: 0 0.4rem 1.2rem rgba(0, 0, 0, 0.45);
  transform: rotate(var(--r, 0deg));
  transform-origin: 50% 115%;
  transition: transform 0.15s ease, border-color 0.15s, color 0.15s;
}
.card + .card { margin-left: calc(var(--card-w) * -0.25); }
/* the hand is fanned around a point below the deck via the inline --r
   rotation the template computes per card (symmetric for any deck size) */
/* hover / picked: straighten and draw the card from the hand */
.card:hover:not(:disabled),
.card.selected {
  border-color: var(--accent);
  color: var(--accent);
  transform: rotate(0deg) translateY(calc(var(--card-w) * -0.22));
  z-index: 2;
}
.card.cancel { border-style: dashed; color: var(--muted); }
.card.cancel:hover:not(:disabled) { border-color: #f87171; color: #f87171; }
/* the visitor card: dashed like cancel, but keeps the accent hover */
.card.visitor { border-style: dashed; color: var(--muted); }

/* --- action feedback: spinners, reveal animation, loading overlay --- */

/* pending: the click is in flight (or its SSE confirmation is on the way) */
button.pending { position: relative; color: transparent !important; pointer-events: none; }
button.pending::after {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  width: 1em;
  height: 1em;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.35);
  border-top-color: #fff;
  animation: vp-spin 0.7s linear infinite;
}
button.primary.pending::after {
  border-color: rgba(11, 14, 26, 0.3);
  border-top-color: #0b0e1a;
}
@keyframes vp-spin { to { transform: rotate(1turn); } }

/* the reveal: freshly flipped cards turn over one by one around the table
   (--i is the seat index, so the flip ripples clockwise), stats follow */
.just-revealed .player-card.open {
  animation: vp-flip 0.5s cubic-bezier(0.2, 0.7, 0.35, 1.15) backwards;
  animation-delay: calc(var(--i) * 70ms);
}
@keyframes vp-flip {
  from { transform: rotateY(95deg) scale(0.85); opacity: 0.3; }
  to { transform: rotateY(0) scale(1); opacity: 1; }
}
.just-revealed .stats { animation: vp-rise 0.45s 0.35s ease backwards; }
@keyframes vp-rise {
  from { transform: translateY(8px); opacity: 0; }
  to { transform: none; opacity: 1; }
}

/* live connection dot in the room header */
.conn {
  display: inline-block;
  width: 0.55rem;
  height: 0.55rem;
  margin-left: 0.6rem;
  border-radius: 50%;
  background: var(--red);
  animation: vp-pulse 1.2s ease-in-out infinite;
  vertical-align: middle;
}
.conn.on {
  background: var(--green);
  box-shadow: 0 0 6px var(--green);
  animation: none;
}
@keyframes vp-pulse { 50% { opacity: 0.35; } }

/* full-screen loading state for slow page loads (cold starts) */
.loading-overlay {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 1.1rem;
  background: rgba(8, 10, 16, 0.85);
  backdrop-filter: blur(3px);
  opacity: 0;
  transition: opacity 0.25s;
}
.loading-overlay.show { opacity: 1; }
.loading-card { font-size: 3.2rem; animation: vp-deal 1.1s ease-in-out infinite; }
@keyframes vp-deal {
  0% { transform: rotateY(0) translateY(0); }
  50% { transform: rotateY(180deg) translateY(-10px); }
  100% { transform: rotateY(360deg) translateY(0); }
}
.loading-overlay p { color: var(--muted); margin: 0; animation: vp-pulse 1.4s ease-in-out infinite; }

@media (prefers-reduced-motion: reduce) {
  .just-revealed .player-card.open,
  .just-revealed .stats,
  .loading-card { animation: none; }
}
