/*
 * LAST CALL — shared design system.
 *
 * Every surface (TV, tablet, host) pulls its colour, type, spacing and motion
 * from the tokens below, so the room reads as one product: the purple a player
 * sees on their tablet is the same purple on the TV behind the bar.
 *
 * Body and display type are deliberately system-only. The venue runs on a LAN
 * with no guaranteed internet, so a webfont would mean a first-question flash of
 * fallback type on every tablet. The one exception is the hand-lettered face
 * below, which is served off this machine rather than off Google's -- it is used
 * on one unhurried screen, and nothing is waiting on it.
 */

/* Henny Penny (SIL Open Font License, see brand/fonts/HennyPenny-OFL.txt): the
   wobbly hand-drawn face the strange facts are titled in. */
@font-face {
  font-family: "Henny Penny";
  src: url("/shared/brand/fonts/HennyPenny-Regular.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}

:root {
  /* --- brand --- */
  --brand: #7c3aed;
  --brand-bright: #a855f7;
  --brand-deep: #4c1d95;
  --brand-ink: #2a1055;
  --brand-glow: rgba(168, 85, 247, 0.45);

  /* Complements, chosen to sit against purple without competing with it:
     aqua for neutral/informational accents, gold reserved for winning. */
  --accent: #22d3ee;
  --gold: #f5b33c;
  --silver: #c8d0de;
  --bronze: #cd8a5a;

  --correct: #22c55e;
  --incorrect: #f43f5e;

  /* One colour per answer letter, used identically on the TV and on every
     tablet: a player glancing up matches "the aqua one, B" instantly instead
     of re-reading four lines of text. */
  --choice-a: #8b5cf6;
  --choice-b: #22d3ee;
  --choice-c: #f472b6;
  --choice-d: #f5b33c;

  /* --- surfaces --- */
  --bg: #0b0714;
  --surface: #16102a;
  --surface-2: #1f1740;
  --surface-3: #2b2059;
  --line: rgba(168, 85, 247, 0.18);
  --line-strong: rgba(168, 85, 247, 0.4);

  --text: #f6f3ff;
  --muted: #a79bc8;
  --on-brand: #ffffff;
  --on-gold: #2b1a00;

  /* --- shape --- */
  --r-sm: 8px;
  --r-md: 14px;
  --r-lg: 22px;
  --r-pill: 999px;

  --shadow-1: 0 2px 10px rgba(0, 0, 0, 0.35);
  --shadow-2: 0 18px 50px rgba(0, 0, 0, 0.5);
  --shadow-brand: 0 0 0 1px var(--line), 0 14px 40px rgba(124, 58, 237, 0.25);

  /* --- type --- */
  --font: "Inter", "Segoe UI Variable Text", "Segoe UI", Roboto, system-ui, -apple-system, Arial, sans-serif;
  --font-display: "Inter", "Segoe UI Variable Display", "Segoe UI", Roboto, system-ui, -apple-system, Arial, sans-serif;
  /* Hand-lettered, for the one screen that is allowed to be silly. */
  --font-funky: "Henny Penny", "Chalkboard SE", "Comic Sans MS", "Segoe Print", cursive;

  /* --- motion --- */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --ease-pop: cubic-bezier(0.34, 1.56, 0.64, 1);
  --t-fast: 140ms;
  --t-base: 260ms;
  --t-slow: 520ms;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  color: var(--text);
  font-family: var(--font);
  background:
    radial-gradient(1200px 700px at 12% -8%, rgba(124, 58, 237, 0.3), transparent 60%),
    radial-gradient(900px 600px at 100% 0%, rgba(34, 211, 238, 0.12), transparent 55%),
    radial-gradient(900px 800px at 50% 120%, rgba(76, 29, 149, 0.35), transparent 60%),
    var(--bg);
  background-attachment: fixed;
}

.hidden { display: none !important; }
.muted { color: var(--muted); }

/* ---------------------------------------------------------------- brand --- */

.brand-lockup { display: flex; align-items: center; gap: 12px; }
.brand-mark { display: block; width: 44px; height: 44px; border-radius: 12px; box-shadow: var(--shadow-1); }
.brand-name {
  font-family: var(--font-display);
  font-weight: 900;
  letter-spacing: 0.14em;
  line-height: 0.98;
  text-transform: uppercase;
  font-size: 20px;
}
.brand-name .brand-name-second { color: var(--brand-bright); }
.brand-sub {
  display: block;
  font-size: 0.5em;
  font-weight: 700;
  letter-spacing: 0.34em;
  color: var(--muted);
  margin-top: 4px;
}

/* Stacked lockup used on the big idle/lobby screens. */
.brand-lockup.brand-stacked { flex-direction: column; gap: 22px; text-align: center; }
.brand-lockup.brand-stacked .brand-mark { width: 132px; height: 132px; border-radius: 32px; }
.brand-lockup.brand-stacked .brand-name { font-size: 86px; letter-spacing: 0.1em; }

/* --------------------------------------------------------------- pieces --- */

.panel {
  background: linear-gradient(180deg, var(--surface-2), var(--surface));
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-1);
}

/* Shared button, for the player and TV pages (the host panel styles bare
   `button` elements instead, since it is dense and form-like). */
.btn {
  background: linear-gradient(180deg, var(--surface-3), var(--surface-2));
  color: var(--text);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  font-family: inherit;
  font-size: 16px;
  font-weight: 800;
  padding: 12px 18px;
  cursor: pointer;
  transition: filter var(--t-fast) ease, transform var(--t-fast) var(--ease-out);
}
.btn:active { transform: scale(0.98); }
.btn:hover:not(:disabled) { filter: brightness(1.15); }
.btn:disabled { opacity: 0.4; cursor: not-allowed; }
.btn-primary {
  background: linear-gradient(180deg, var(--brand-bright), var(--brand));
  color: var(--on-brand);
  border-color: transparent;
  box-shadow: 0 8px 28px var(--brand-glow);
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  padding: 6px 14px;
  font-weight: 700;
  font-size: 14px;
}
.chip-brand { background: linear-gradient(135deg, var(--brand-deep), var(--brand)); border-color: transparent; color: var(--on-brand); }
.chip-gold { background: var(--gold); color: var(--on-gold); border-color: transparent; }
.chip-correct { background: rgba(34, 197, 94, 0.16); border-color: rgba(34, 197, 94, 0.5); color: var(--correct); }
.chip-incorrect { background: rgba(244, 63, 94, 0.16); border-color: rgba(244, 63, 94, 0.5); color: var(--incorrect); }

/* ----------------------------------------------------------------- icons --- */
/*
 * Line glyphs from web_shared/icons.js. They inherit colour and scale with the
 * type around them, so the same category icon works in a 14px host-panel chip
 * and in a 90px title card on the TV.
 */
.lc-icon { width: 1.15em; height: 1.15em; flex: none; display: block; }

/*
 * The rendered version of the same icons (web_shared/icons3d), for the places
 * the icon is the size of a coaster and gets to be the artwork rather than a
 * label. It is a raster image, so it can't take `currentColor` — anywhere a
 * state change recolours an icon, the line glyph is still the right one.
 */
.lc-art {
  width: 1.35em; height: 1.35em; flex: none; display: block; object-fit: contain;
  filter: drop-shadow(0 6px 14px rgba(0, 0, 0, 0.55));
}

/*
 * A pack's own artwork, dropped into web_shared/pack_art by whoever owns this
 * machine. Unlike a glyph it is a wordmark: wide, its own colours, and it says
 * the pack's name by itself, so whatever shows one gives it a strip and drops
 * the label. It never gets a square slot — letterboxing a logo looks broken.
 */
.lc-logo {
  display: block; max-width: 100%; max-height: 100%; object-fit: contain;
  filter: drop-shadow(0 6px 16px rgba(0, 0, 0, 0.6));
}

/* ------------------------------------------------------------ title card --- */
/*
 * The "here comes a game" moment, shared by the TV (full screen) and the
 * tablet (scaled down): the game's own glyph on a brand-gradient tile, its
 * name, and the rules the room needs before question 1. A glyph, never
 * letters -- "HM" in a purple box says nothing to a room.
 */
.title-card { display: flex; flex-direction: column; align-items: center; gap: 18px; text-align: center; }
.game-crest {
  display: grid;
  place-items: center;
  background: linear-gradient(135deg, var(--brand-deep), var(--brand) 55%, var(--brand-bright));
  border-radius: 28%;
  box-shadow: 0 18px 60px var(--brand-glow), inset 0 0 0 2px rgba(255, 255, 255, 0.14);
  position: relative;
}
/* With the pack's own artwork there is no tile: a brand-purple square around
   somebody else's logo reads as a mistake, and the logo is the crest. */
.game-crest.is-logo {
  background: none; box-shadow: none; border-radius: 0; width: auto;
}

/* The pack's own glyph, filling the tile it used to be badged onto. */
.game-crest-icon {
  display: grid;
  place-items: center;
  color: var(--on-brand);
  line-height: 0;
}
.game-title {
  font-family: var(--font-display);
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin: 0;
}
.game-tagline { color: var(--muted); margin: 0; }

.rules-list { display: flex; flex-direction: column; gap: 10px; margin: 0; padding: 0; list-style: none; text-align: left; }
.rules-list li {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  background: linear-gradient(90deg, var(--surface-2), var(--surface));
  border: 1px solid var(--line);
  border-left: 4px solid var(--brand-bright);
  border-radius: var(--r-md);
  padding: 12px 18px;
  font-weight: 600;
}
.rules-list li::before {
  content: "";
  flex: none;
  width: 0.5em;
  height: 0.5em;
  margin-top: 0.5em;
  border-radius: 50%;
  background: var(--brand-bright);
}

/* Category strip: what tonight is made of, as icons plus names. */
.cat-strip { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; }

/* ------------------------------------------------------------- countdown --- */
/*
 * The between-things clock. Anywhere the room is waiting (rules card, gap
 * between questions) it gets one of these rather than a static "30s" that
 * gives no clue whether anything is still happening.
 */
.countdown { display: inline-flex; align-items: center; gap: 14px; font-weight: 800; }
.countdown-ring { position: relative; display: grid; place-items: center; flex: none; }
.countdown-ring svg { transform: rotate(-90deg); display: block; width: 100%; height: 100%; }
.countdown-ring .ring-track { stroke: var(--line-strong); }
.countdown-ring .ring-fill {
  stroke: var(--brand-bright);
  transition: stroke-dashoffset 240ms linear;
}
.countdown-ring.urgent .ring-fill { stroke: var(--gold); }
.countdown-num {
  position: absolute;
  font-family: var(--font-display);
  font-weight: 900;
  font-variant-numeric: tabular-nums;
}
.countdown-label { color: var(--muted); font-weight: 700; letter-spacing: 0.04em; }

.status-pill {
  position: fixed;
  top: 12px;
  right: 12px;
  padding: 5px 12px;
  border-radius: var(--r-pill);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  z-index: 100;
}
.status-connected { background: rgba(34, 197, 94, 0.18); color: var(--correct); box-shadow: inset 0 0 0 1px rgba(34, 197, 94, 0.45); }
.status-connecting { background: rgba(245, 179, 60, 0.18); color: var(--gold); box-shadow: inset 0 0 0 1px rgba(245, 179, 60, 0.45); }
.status-disconnected { background: rgba(244, 63, 94, 0.2); color: var(--incorrect); box-shadow: inset 0 0 0 1px rgba(244, 63, 94, 0.5); }

/* -------------------------------------------------------------- avatars --- */
/*
 * A player's look: a solid colour disc with the transparent character on top,
 * so two tables can wear the same face in different colours. Sized by --av so
 * every surface (board row, chip, podium, picker) sets one number. The art is
 * drawn a touch over the circle's edge so the head fills it rather than
 * floating in the middle.
 */

.av-c {
  --av: 40px;
  position: relative; flex: 0 0 auto; display: inline-block;
  width: var(--av); height: var(--av); border-radius: 50%;
  background: var(--av-bg, #3a4152);
  border: calc(var(--av) * 0.065) solid rgba(255, 255, 255, 0.85);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.45);
  overflow: hidden; vertical-align: middle;
}
.av-c img {
  position: absolute; left: -2%; top: 2%; width: 104%; height: 104%;
  object-fit: contain; pointer-events: none;
}
/* The guest look: one stock face on a neutral grey, the same for everyone
   without a PIN. */
.av-c.av-default { background: #6b7280; }
/* A table's pair, the right one over the left by a tenth: joined, not two
   neighbours. Always the width of a pair, so a solo row's name starts on the
   same line as a table's. */
.av-group {
  --av: 40px;
  display: inline-flex; align-items: center; flex: 0 0 auto;
  width: calc(var(--av) * 1.9);
}
.av-group .av-c { --av: inherit; }
.av-group .av-c + .av-c { margin-left: calc(var(--av) * -0.1); position: relative; z-index: 1; }

/* ---------------------------------------------------------- leaderboard --- */
/*
 * One leaderboard component, used on the TV between questions and (compact)
 * in the host panel, so the standings the host reads out are pixel-identical
 * to the ones the room is looking at.
 */

.leaderboard { display: flex; flex-direction: column; gap: 10px; }

.lb-row {
  display: grid;
  grid-template-columns: auto 1fr auto auto;
  align-items: center;
  gap: 18px;
  padding: 14px 22px;
  border-radius: var(--r-md);
  background: linear-gradient(90deg, var(--surface-2), var(--surface));
  border: 1px solid var(--line);
  /* Rows are re-ordered between questions; transform is what makes a team
     visibly climb past another instead of teleporting. */
  transition: transform var(--t-slow) var(--ease-out), background var(--t-base) var(--ease-out),
    border-color var(--t-base) var(--ease-out);
}
.lb-rank {
  font-family: var(--font-display);
  font-weight: 900;
  font-variant-numeric: tabular-nums;
  color: var(--muted);
  min-width: 1.6em;
  text-align: right;
}
/* A row with faces on it: one more column, fixed width, between the rank and
   the name. */
.lb-row.has-av { grid-template-columns: auto auto 1fr auto auto; }
.lb-row .lb-av { --av: 34px; }
.lb-team { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.lb-name { font-weight: 800; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lb-meta { color: var(--muted); font-weight: 600; display: flex; align-items: center; gap: 10px; }
.lb-score { font-family: var(--font-display); font-weight: 900; font-variant-numeric: tabular-nums; }
.lb-delta {
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  border-radius: var(--r-pill);
  padding: 4px 12px;
  min-width: 4.5em;
  text-align: center;
  background: var(--surface-3);
  color: var(--muted);
}
.lb-delta.gain { background: rgba(34, 197, 94, 0.18); color: var(--correct); }
.lb-delta.loss { background: rgba(244, 63, 94, 0.18); color: var(--incorrect); }

/* Podium treatment for the top three — the only place gold is allowed. */
.lb-row.rank-1 { background: linear-gradient(90deg, rgba(245, 179, 60, 0.22), var(--surface-2)); border-color: rgba(245, 179, 60, 0.55); }
.lb-row.rank-1 .lb-rank, .lb-row.rank-1 .lb-score { color: var(--gold); }
.lb-row.rank-2 { border-color: rgba(200, 208, 222, 0.35); }
.lb-row.rank-2 .lb-rank { color: var(--silver); }
.lb-row.rank-3 { border-color: rgba(205, 138, 90, 0.35); }
.lb-row.rank-3 .lb-rank { color: var(--bronze); }

/* A knocked-out team stays on every board — the room wants to see how far they
   got — but it stops competing for attention with the teams still playing. */
.lb-row.knocked-out { opacity: 0.45; filter: saturate(0.4); }

/* "That's you" highlight on a tablet's own row. */
.lb-row.is-you { border-color: var(--brand-bright); box-shadow: 0 0 0 1px var(--brand-bright), 0 0 30px var(--brand-glow); }

.lb-move { font-weight: 800; font-variant-numeric: tabular-nums; }
.lb-move.up { color: var(--correct); }
.lb-move.down { color: var(--incorrect); }
.lb-move.flat { color: var(--muted); }

.streak-flame { color: var(--gold); font-weight: 800; }

/* ------------------------------------------------------------- motion --- */

@keyframes lc-rise-in {
  from { opacity: 0; transform: translateY(28px); }
  to { opacity: 1; transform: none; }
}
@keyframes lc-pop {
  0% { transform: scale(0.85); opacity: 0; }
  60% { transform: scale(1.06); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}
@keyframes lc-pulse {
  0%, 100% { box-shadow: 0 0 0 0 var(--brand-glow); }
  50% { box-shadow: 0 0 34px 6px var(--brand-glow); }
}

.rise-in { animation: lc-rise-in var(--t-slow) var(--ease-out) both; }
.pop-in { animation: lc-pop var(--t-base) var(--ease-pop) both; }

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 1ms !important; transition-duration: 1ms !important; }
}

/*
 * The confirm card (web_shared/lc-dialog.js): every "are you sure" on every
 * page. Sized for a thumb on a phone and a D-pad on the TV; the confirming
 * button is brand, or red when the thing it does throws something away.
 */
.lc-dialog {
  position: fixed; inset: 0; z-index: 400;
  display: flex; align-items: center; justify-content: center; padding: 24px;
  background: rgba(6, 4, 12, 0.78);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  animation: lc-dialog-fade var(--t-fast) ease both;
}
.lc-dialog-card {
  position: relative; width: 100%; max-width: 440px; padding: 26px 24px 22px;
  background: linear-gradient(180deg, var(--surface-2), var(--surface));
  border: 1px solid var(--line-strong); border-radius: var(--r-lg);
  box-shadow: var(--shadow-2), 0 0 0 1px rgba(0, 0, 0, 0.5);
  text-align: center; overflow: hidden;
  animation: lc-pop var(--t-base) var(--ease-pop) both;
}
.lc-dialog-card::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 4px;
  background: linear-gradient(90deg, var(--brand), var(--brand-bright), var(--gold));
}
.lc-dialog-mark {
  display: block; width: 52px; height: 52px; margin: 0 auto 12px; border-radius: 16px;
  box-shadow: 0 8px 24px var(--brand-glow);
}
.lc-dialog-title {
  margin: 0 0 6px; font-family: var(--font-display); font-size: 22px; font-weight: 900;
  letter-spacing: -0.01em; color: var(--text);
}
.lc-dialog-text { margin: 0; font-size: 16px; line-height: 1.45; color: var(--muted); }
.lc-dialog-actions { display: flex; gap: 12px; margin-top: 22px; }
.lc-dialog-btn {
  flex: 1 1 0; min-height: 50px; padding: 12px 16px;
  border-radius: var(--r-md); border: 1px solid var(--line-strong);
  background: linear-gradient(180deg, var(--surface-3), var(--surface-2));
  color: var(--text); font-family: inherit; font-size: 16px; font-weight: 800;
  cursor: pointer; transition: filter var(--t-fast) ease, transform var(--t-fast) var(--ease-out);
}
.lc-dialog-btn:hover { filter: brightness(1.15); }
.lc-dialog-btn:active { transform: scale(0.98); }
.lc-dialog-yes {
  background: linear-gradient(180deg, var(--brand-bright), var(--brand));
  color: var(--on-brand); border-color: transparent; box-shadow: 0 8px 24px var(--brand-glow);
}
.lc-dialog-yes.is-danger {
  background: linear-gradient(180deg, #f43f5e, #be123c);
  box-shadow: 0 8px 24px rgba(244, 63, 94, 0.35);
}
.lc-dialog-btn:focus-visible, .lc-dialog-btn:focus {
  outline: 3px solid var(--gold); outline-offset: 2px;
}
@keyframes lc-dialog-fade { from { opacity: 0; } to { opacity: 1; } }
