/* Page chrome: everything that is NOT the HUD.
 *
 * Kept out of hud/ deliberately -- hud.css must stay portable, so it can drop
 * onto the real 3D scene without dragging a page layout with it.
 */

/* `hidden` is only a UA `display:none`, so any author `display` below beats it.
 * Both the bar and the lobby set one, and both start hidden -- without this
 * they render on top of the table. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  height: 100%;
  background: var(--ground);
  overflow: hidden;
  font-family: var(--sans);
  color: var(--text);
}

/* Where the Three.js canvas will live. Until it does, a lit backdrop so the
 * overlay is judged against something like the real ground, not black. */
.scene {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(120% 90% at 50% 8%, #1a1f25 0%, #0c0f13 55%, #06080a 100%);
}

.scene::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(90% 70% at 50% 46%, transparent 40%, rgba(0, 0, 0, 0.45) 100%);
}

.scene__note {
  position: absolute;
  left: 50%;
  top: 52%;
  transform: translate(-50%, -50%);
  text-align: center;
  font-weight: 800;
  font-size: 13px;
  letter-spacing: 0.42em;
  text-indent: 0.42em;
  color: rgba(232, 182, 74, 0.18);
}

.scene__note small {
  display: block;
  margin-top: 5px;
  font-size: 9px;
  letter-spacing: 0.34em;
  color: rgba(255, 255, 255, 0.10);
}

/* ----------------------------------------------------- between-hands title

   Shown over the wide establishing shot in the pause before a hand deals. It
   swipes in from the left, holds at centre, then swipes out to the right -- a
   broadcast lower-third's motion, minus the third. `pointer-events: none` so it
   never eats a click meant for the bar beneath it; z-index above the HUD but
   below the lobby, which replaces the whole view when open. The `.play` class
   (re-added per hand after a reflow) restarts the animation. */
.handcard {
  position: absolute;
  left: 0;
  right: 0;
  top: 36%;
  z-index: 25;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  pointer-events: none;
  opacity: 0;                /* resting: invisible until a hand is announced */
  will-change: transform, opacity;
}

.handcard.play {
  /* 4s -- the same window as broadcast.js HAND_INTRO_MS, so the card is gone by
     the time the deal cuts in. `both` holds the final (off-right, faded) frame
     rather than snapping back to centre when it ends. */
  animation: handcard 4s cubic-bezier(0.22, 0.61, 0.36, 1) both;
}

/* The TABLE-WINNER card. Swipes in like the hand card but HOLDS centred rather
   than wiping off, because the table is over -- it is the last thing on screen,
   and it tells the viewer they can move on. */
.handcard.final.play {
  animation: handcard-final 1.1s cubic-bezier(0.22, 0.61, 0.36, 1) both;
}
@keyframes handcard-final {
  0%   { transform: translateX(-62vw); opacity: 0; }
  100% { transform: translateX(0);     opacity: 1; }
}

/* The "NEW HAND" kicker over the big number, ruled in gold like the POT tab so
   the card belongs to the same broadcast. */
.handcard__eyebrow {
  font-family: var(--mono);
  font-weight: 700;
  font-size: 14px;
  letter-spacing: 0.5em;
  text-indent: 0.5em;        /* re-centre against the trailing letter-spacing */
  color: var(--gold);
  padding-bottom: 9px;
  border-bottom: 2px solid var(--gold);
  text-shadow: 0 2px 14px rgba(0, 0, 0, 0.65);
}

.handcard__title {
  font-family: var(--sans);
  font-weight: 800;
  font-size: clamp(48px, 9vw, 132px);
  line-height: 0.95;
  letter-spacing: 0.01em;
  color: var(--text);
  text-shadow: 0 4px 32px rgba(0, 0, 0, 0.7);
  text-align: center;
}

/* The "GAME OVER" line under the winner's name. Only the final card fills it. */
.handcard__subtitle {
  font-family: var(--mono);
  font-weight: 700;
  font-size: clamp(14px, 2vw, 20px);
  letter-spacing: 0.5em;
  text-indent: 0.5em;
  color: var(--gold);
  text-shadow: 0 2px 14px rgba(0, 0, 0, 0.65);
}

/* Empty eyebrow / subtitle take no room, so a card with only a title stays
   vertically centred rather than carrying a phantom gap. */
.handcard__eyebrow:empty,
.handcard__subtitle:empty { display: none; }

/* In from the left, hold, out to the right. The long middle is the hold, so the
   number is readable; the quick ends read as a wipe rather than a drift. Fades
   at both ends so nothing pops on or off screen. */
@keyframes handcard {
  0%   { transform: translateX(-62vw); opacity: 0; }
  16%  { transform: translateX(0);     opacity: 1; }
  74%  { transform: translateX(0);     opacity: 1; }
  100% { transform: translateX(62vw);  opacity: 0; }
}

/* Honour a reduced-motion preference: no swipe, just a gentle fade in and out
   over the same 4s so the card still announces the hand. */
@media (prefers-reduced-motion: reduce) {
  .handcard.play { animation: handcard-fade 4s ease both; }
  @keyframes handcard-fade {
    0%, 100% { opacity: 0; }
    16%, 74% { opacity: 1; }
  }
}

/* ------------------------------------------------------- play-by-play caption

   A WSOP-style lower third: the commentary line for the current beat, centred
   above the controls. Page chrome (not scaled with the 1920x1080 stage) so the
   text stays readable at any window size, and pointer-events off so it never
   eats a click. Grows upward from its bottom anchor as a line wraps. */
.caption {
  position: absolute;
  left: 50%;
  bottom: 70px;                 /* clears the controls bar (bottom: 14px) */
  transform: translateX(-50%);
  z-index: 15;
  max-width: min(78%, 1180px);
  padding: 12px 26px;
  border-radius: 12px;
  background: rgba(9, 11, 14, 0.82);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.08);
  backdrop-filter: blur(6px);
  font-weight: 800;
  font-size: 21px;
  letter-spacing: 0.01em;
  line-height: 1.35;
  color: var(--text);
  text-align: center;
  pointer-events: none;
}

/* A quick rise + fade each time the line changes, so a new beat reads as new. */
.caption.caption--in { animation: caption-in 0.32s ease both; }
@keyframes caption-in {
  from { opacity: 0; transform: translate(-50%, 9px); }
  to   { opacity: 1; transform: translate(-50%, 0); }
}

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

.bar {
  position: absolute;
  left: 50%;
  bottom: 14px;
  transform: translateX(-50%);
  z-index: 20;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 8px 10px;
  border-radius: 12px;
  background: rgba(9, 11, 14, 0.82);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.07);
  backdrop-filter: blur(6px);
}

.btn {
  appearance: none;
  border: 0;
  cursor: pointer;
  font-family: var(--sans);
  font-weight: 800;
  font-size: 13px;
  letter-spacing: 0.03em;
  color: var(--text);
  padding: 9px 15px;
  border-radius: 9px;
  background: linear-gradient(180deg, #20252b, #161a1e);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.08), 0 3px 8px -3px rgba(0, 0, 0, 0.6);
  transition: transform 0.08s ease, background 0.12s ease;
}

.btn:hover { background: linear-gradient(180deg, #262c33, #1a1f24); }
.btn:active { transform: translateY(1px); }
.btn:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.btn:disabled { opacity: 0.4; cursor: not-allowed; }

.btn--primary {
  background: linear-gradient(180deg, var(--gold), var(--gold-deep));
  color: #0c0f12;
  box-shadow: 0 4px 14px -4px rgba(232, 182, 74, 0.5), inset 0 0 0 1px rgba(255, 255, 255, 0.2);
}
.btn--primary:hover { filter: brightness(1.06); }
.btn[aria-pressed="true"] {
  box-shadow: inset 0 0 0 1px var(--gold), 0 0 0 2px rgba(232, 182, 74, 0.25);
}

.bar__note {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.04em;
  color: var(--text-faint);
  padding: 0 6px;
}

select.btn { padding-right: 10px; }

/* ------------------------------------------------- live indicator (bottom-left)
   The "on air" bug. Shown only while the table is still in progress, because the
   delayed broadcast can jump forward to the current hand when live play outruns
   the show -- this frames that skip as expected, not a glitch. Purely
   informational, so it never intercepts a click. */
.livetag {
  position: absolute;
  left: 16px;
  bottom: 16px;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 8px 13px;
  border-radius: 12px;
  background: rgba(9, 11, 14, 0.82);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.07);
  backdrop-filter: blur(6px);
  pointer-events: none;
}
/* The attribute must win over display:flex, or `hidden` would not hide it. */
.livetag[hidden] { display: none; }

.livetag__dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #e5484d;                          /* the standard on-air red */
  box-shadow: 0 0 9px rgba(229, 72, 77, 0.85);
  /* A slow, soft breathe -- a live light, not a blink that pulls the eye off the
     table. */
  animation: livetag-pulse 2.4s ease-in-out infinite;
}
.livetag__label {
  font-family: var(--mono);
  font-weight: 800;
  font-size: 12px;
  letter-spacing: 0.14em;
  color: #f2f4f5;
}
.livetag__note {
  font-family: var(--sans);
  font-size: 11px;
  letter-spacing: 0.02em;
  color: rgba(255, 255, 255, 0.42);
}

@keyframes livetag-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: 0.32; transform: scale(0.8); }
}

@media (prefers-reduced-motion: reduce) {
  .livetag__dot { animation: none; }
}

/* ------------------------------------------------------------ lobby picker */

.lobby {
  position: absolute;
  inset: 0;
  z-index: 30;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;   /* two lists need to scroll, not centre */
  gap: 14px;
  padding: 6vh 20px 48px;
  overflow-y: auto;
  background: rgba(6, 8, 10, 0.9);
  backdrop-filter: blur(4px);
}

.lobby__inner {
  width: min(640px, 94vw);
  display: flex;
  flex-direction: column;
  gap: 28px;
}

.lobby__title {
  font-weight: 800;
  font-size: 22px;
  letter-spacing: 0.2em;
  text-indent: 0.2em;
  color: var(--text-dim);
}

.lobby__section { display: flex; flex-direction: column; gap: 8px; }

.lobby__heading {
  margin: 0;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-dim);
}

.lobby__list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 2px;
}

.lobby__pager {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 2px;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--text-dim);
}
.lobby__pager button {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--text);
  cursor: pointer;
  background: transparent;
  border: 1px solid var(--panel-stroke, rgba(255, 255, 255, 0.14));
  border-radius: 6px;
  padding: 5px 12px;
}
.lobby__pager button:disabled { opacity: 0.4; cursor: default; }
.lobby__pager button:not(:disabled):hover { border-color: rgba(232, 182, 74, 0.5); }

.lobby__row {
  display: flex;
  align-items: center;
  gap: 16px;
  width: 100%;
  padding: 12px 16px;
  border-radius: 10px;
  cursor: pointer;
  text-align: left;
  background: linear-gradient(180deg, var(--panel-top), var(--panel-bottom));
  box-shadow: inset 0 0 0 1px var(--panel-stroke);
  color: var(--text);
  font-family: var(--sans);
  border: 0;
}

.lobby__row:hover { box-shadow: inset 0 0 0 1px rgba(232, 182, 74, 0.4); }

.lobby__name { flex: 1; font-weight: 800; font-size: 16px; }

.lobby__meta {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--text-dim);
}

.lobby__empty {
  font-size: 13px;
  color: var(--text-faint);
  max-width: 420px;
  text-align: center;
  line-height: 1.6;
}
