/* Game Night: the games' own site.
 *
 * The DM asked for the games to be "their own area, nothing to do with the
 * Forgotten Index or MHI", to "feel like a fully different website almost",
 * dark and easy on the eye, a little fun, cozy. And, after the first try:
 * no yellow on blue.
 *
 * So: warm charcoal (not the Index's green, not the generic purple), ONE
 * accent (marigold), Bricolage Grotesque for headings and Figtree for text.
 * Night in the werewolf room dims the lights; it does not turn the room blue.
 *
 * SHAPES, one rule used everywhere: panels and tiles 16px, inputs 12px,
 * buttons and chips fully rounded.
 *
 * Red and green appear only as STATE (a refusal, a werewolf, a win), never
 * as decoration.
 */

:root {
  --gn-bg: #121113;
  --gn-bg-night: #0c0b0d;
  --gn-raise: #1b191c;
  --gn-raise-2: #242125;
  --gn-raise-3: #2e2a2f;
  --gn-line: rgba(255, 240, 225, .08);
  --gn-line-2: rgba(255, 240, 225, .16);

  --gn-ink: #f3eee9;
  --gn-dim: #b3aba4;
  --gn-mute: #857d77;

  --gn-accent: #f4a25b;
  /* The yellow chair in the DM's Game Night picture: the top bar's colour. */
  --gn-chair: #d49b4b;
  --gn-accent-hi: #f7b77e;
  --gn-accent-ink: #1f1308;
  --gn-accent-soft: rgba(244, 162, 91, .13);
  --gn-accent-line: rgba(244, 162, 91, .42);

  --gn-good: #7cc49a;
  --gn-bad: #e8796b;
  --gn-bad-soft: rgba(232, 121, 107, .14);

  --gn-display: 'Bricolage Grotesque', 'Figtree', system-ui, sans-serif;
  --gn-body: 'Figtree', system-ui, 'Segoe UI', sans-serif;

  --gn-r-panel: 16px;
  --gn-r-input: 12px;
  --gn-shadow: 0 1px 0 rgba(255, 240, 225, .04) inset, 0 18px 40px -24px rgba(0, 0, 0, .7);
  --gn-ease: cubic-bezier(.16, 1, .3, 1);
}

/* ── The page ──────────────────────────────────────────────────────────── */
html { overflow-x: clip; }
body.gn-body {
  margin: 0; min-height: 100dvh; color: var(--gn-ink);
  font: 400 16px/1.55 var(--gn-body); -webkit-font-smoothing: antialiased;
  background-color: var(--gn-bg);
  /* One lamp in the corner of the room. */
  background-image: radial-gradient(1100px 700px at 0% -10%, rgba(244, 162, 91, .07), transparent 62%);
  background-attachment: fixed;
  transition: background-color .9s ease;
}
body.gn-body.is-night { background-color: var(--gn-bg-night); background-image: none; }

/* The night sky behind every page: small warm stars that twinkle, never
   blue. base_games.html scatters them once per page; they sit behind the
   panels, so they show only in the gaps. With reduced motion they stay
   still (the rule at the bottom of this file stops the animation). */
.gn-sky { position: fixed; inset: 0; z-index: -1; pointer-events: none; overflow: hidden; }
.gn-star {
  position: absolute; width: var(--s, 1.5px); height: var(--s, 1.5px); border-radius: 50%;
  background: #fff3e2; opacity: var(--o, .5);
  animation: gn-twinkle var(--d, 4s) ease-in-out var(--w, 0s) infinite alternate;
}
.gn-star.is-bright { box-shadow: 0 0 4px 1px rgba(255, 228, 196, .45); }
@keyframes gn-twinkle {
  from { opacity: var(--o, .5); }
  to { opacity: .08; }
}
body.gn-body a { color: inherit; }
body.gn-body ::selection { background: var(--gn-accent); color: var(--gn-accent-ink); }
body.gn-body :focus-visible { outline: 2px solid var(--gn-accent); outline-offset: 2px; }

/* Scrollbars. The rest of the app colours them in style.css, which this
   site does not load, so without these the browser's own grey shows in
   every panel and list. A thin marigold thumb on no track. Chrome, Edge
   and Firefox use scrollbar-color; the ::-webkit rules are for Safari. */
html:has(body.gn-body), body.gn-body, body.gn-body * {
  scrollbar-width: thin;
  scrollbar-color: var(--gn-accent-line) transparent;
}
/* No background on <html> here: the body's then paints the whole canvas,
   and the star sky and Werewolf's scene (z-index -1) show in front of it.
   With one on <html>, the body's own background covers them. */
body.gn-body ::-webkit-scrollbar, html:has(body.gn-body)::-webkit-scrollbar { width: 10px; height: 10px; }
body.gn-body ::-webkit-scrollbar-track, html:has(body.gn-body)::-webkit-scrollbar-track { background: transparent; }
body.gn-body ::-webkit-scrollbar-corner, html:has(body.gn-body)::-webkit-scrollbar-corner { background: transparent; }
body.gn-body ::-webkit-scrollbar-thumb, html:has(body.gn-body)::-webkit-scrollbar-thumb {
  background: var(--gn-accent-line); border-radius: 999px;
  border: 3px solid transparent; background-clip: padding-box;
}
body.gn-body ::-webkit-scrollbar-thumb:hover, html:has(body.gn-body)::-webkit-scrollbar-thumb:hover {
  background: var(--gn-accent); background-clip: padding-box;
}

.fx-main.gn-main {
  position: relative; max-width: 1360px; margin: 0 auto;
  padding: 32px clamp(16px, 4vw, 56px) 96px;
}

/* ── The masthead ──────────────────────────────────────────────────────── */
/* No bar: the logo, the way back and your picture sit straight on the night
   sky. With so little left in it, the DM found the strip didn't earn its
   place. It isn't sticky any more either: see-through, it would float over
   whatever scrolled under it. */
.gn-mast {
  position: relative; z-index: 100; height: 64px; box-sizing: border-box;
  display: flex; align-items: center; gap: 24px; padding: 0 clamp(16px, 4vw, 40px);
}
.gn-mark {
  display: flex; align-items: center; gap: 10px; text-decoration: none; white-space: nowrap;
  font: 700 20px/1 var(--gn-display); letter-spacing: -.02em; color: var(--gn-ink);
}
.gn-mark i { color: var(--gn-accent); font-size: 17px; }
/* The DM's logo, when there is one (static/games/mark.* and wordmark.*). */
.gn-mark-pic { display: block; height: 38px; width: auto; }
.gn-mark-word { display: block; height: 24px; width: auto; }
.gn-links { display: flex; align-items: center; gap: 14px; margin-right: auto; min-width: 0; }
/* The way back: a quiet pill. Hover turns it chair-yellow and nudges the
   arrow left. */
.gn-back {
  display: inline-flex; align-items: center; gap: 8px; flex: 0 0 auto;
  font: 600 14px/1 var(--gn-body); color: var(--gn-dim); text-decoration: none; white-space: nowrap;
  padding: 8px 14px; border: 1px solid var(--gn-line); border-radius: 999px;
  transition: color .25s ease, border-color .25s ease;
}
.gn-back i { font-size: 12px; transition: transform .35s cubic-bezier(.34, 1.56, .64, 1); }
.gn-back:hover, .gn-back:focus-visible { color: var(--gn-chair); border-color: var(--gn-chair); }
.gn-back:hover i, .gn-back:focus-visible i { transform: translateX(-3px); }
/* The page you're on: simply its name, in chair-yellow. */
.gn-here {
  font: 600 14.5px/1 var(--gn-body); color: var(--gn-chair);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0;
}

/* Your seal: your picture in a ring. It opens a small menu. */
.gn-me { position: relative; flex: 0 0 auto; }
.gn-seal {
  position: relative; width: 40px; height: 40px; padding: 0; border: none; background: none;
  border-radius: 50%; cursor: pointer; display: grid; place-items: center;
}
.gn-seal::before {
  content: ''; position: absolute; inset: 0; border-radius: 50%;
  border: 2px solid var(--gn-accent-line); transition: border-color .2s, transform .3s var(--gn-ease);
}
.gn-seal:hover::before, .gn-seal[aria-expanded="true"]::before { border-color: var(--gn-accent); transform: scale(1.06); }
.gn-face {
  width: 30px; height: 30px; border-radius: 50%; overflow: hidden; display: grid; place-items: center;
  background: var(--gn-raise-3); color: var(--gn-accent); font: 700 14px/1 var(--gn-display);
}
.gn-face img { width: 100%; height: 100%; object-fit: cover; display: block; }
.gn-face--lg { width: 44px; height: 44px; font-size: 18px; flex: 0 0 auto; box-shadow: 0 0 0 2px var(--gn-accent-line); }
.gn-menu {
  position: absolute; right: 0; top: calc(100% + 12px); z-index: 120; width: 264px;
  background: var(--gn-raise); border: 1px solid var(--gn-line-2); border-radius: var(--gn-r-panel);
  box-shadow: 0 24px 60px -20px rgba(0, 0, 0, .8); overflow: hidden;
  transform-origin: top right; animation: gn-pop .18s var(--gn-ease);
}
.gn-menu[hidden] { display: none; }
@keyframes gn-pop { from { opacity: 0; transform: scale(.96) translateY(-4px); } }
.gn-menu-id { display: flex; gap: 12px; align-items: center; padding: 16px; border-bottom: 1px solid var(--gn-line); }
.gn-menu-id b { display: block; font: 700 16px/1.2 var(--gn-display); color: var(--gn-ink); }
.gn-menu-id span { font-size: 13px; color: var(--gn-mute); }
.gn-menu a, .gn-menu button {
  display: flex; align-items: center; gap: 12px; width: 100%; box-sizing: border-box;
  padding: 12px 16px; font: 600 14px/1.2 var(--gn-body); color: var(--gn-dim); text-decoration: none;
  background: none; border: none; cursor: pointer; text-align: left;
}
.gn-menu a:hover, .gn-menu button:hover { background: var(--gn-raise-2); color: var(--gn-ink); }
.gn-menu i { width: 16px; text-align: center; color: var(--gn-mute); }
.gn-menu form { margin: 0; border-top: 1px solid var(--gn-line); }
/* Projects: MHI, the Index and Game Night side by side (_project_switch.html).
   Two classes deep so `.gn-menu a` does not flatten them into rows. */
.gn-menu .proj-switch { padding: 12px 12px 14px; border-bottom: 1px solid var(--gn-line); }
.gn-menu .proj-switch-label { display: block; padding: 0 2px 8px; font: 600 11px/1 var(--gn-body); letter-spacing: .08em; text-transform: uppercase; color: var(--gn-mute); }
.gn-menu .proj-switch-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.gn-menu .proj-switch-item {
  display: flex; flex-direction: column; align-items: center; gap: 6px; width: auto;
  padding: 10px 4px 9px; border-radius: 10px; border: 1px solid var(--gn-line);
  background: var(--gn-raise-2); font: 600 12px/1.2 var(--gn-body); color: var(--gn-dim);
  text-align: center; text-decoration: none; transition: border-color .16s, color .16s, transform .16s;
}
.gn-menu a.proj-switch-item:hover { border-color: var(--gn-accent-line); color: var(--gn-ink); transform: translateY(-2px); }
.gn-menu .proj-switch-item.is-here { border-color: var(--gn-accent); color: var(--gn-ink); }
.gn-menu .proj-switch-pic { width: 26px; height: 26px; display: grid; place-items: center; }
.gn-menu .proj-switch-pic img { max-width: 100%; max-height: 100%; object-fit: contain; }
.gn-menu .proj-switch-pic i { width: auto; font-size: 17px; }
.gn-menu .proj-switch-pic .proj-switch-fi { color: #d4af37; }
.gn-menu .proj-switch-pic .proj-switch-gn { color: var(--gn-accent); }

/* ── Type ──────────────────────────────────────────────────────────────── */
.gn-h1 {
  font: 700 clamp(30px, 4.2vw, 44px)/1.08 var(--gn-display); letter-spacing: -.025em;
  color: var(--gn-ink); margin: 0 0 10px;
}
.gn-h2 { font: 700 19px/1.25 var(--gn-display); letter-spacing: -.01em; color: var(--gn-ink); margin: 0 0 14px; }
.gn-lead { font-size: 17px; color: var(--gn-dim); max-width: 60ch; margin: 0 0 28px; }
.gn-note { font-size: 15px; color: var(--gn-dim); margin: 0 0 10px; max-width: 62ch; }
.gn-note b, .gn-lead b { color: var(--gn-ink); font-weight: 700; }
.gn-small { font-size: 13px; color: var(--gn-mute); }

/* ── Panels ────────────────────────────────────────────────────────────── */
.gn-panel {
  background: var(--gn-raise); border: 1px solid var(--gn-line); border-radius: var(--gn-r-panel);
  padding: 22px; box-shadow: var(--gn-shadow);
}
.gn-panel + .gn-panel { margin-top: 16px; }

/* ── Buttons ───────────────────────────────────────────────────────────── */
.gn-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px; white-space: nowrap;
  font: 700 14.5px/1 var(--gn-body); padding: 12px 20px; border-radius: 999px; cursor: pointer;
  border: 1px solid transparent; background: var(--gn-accent); color: var(--gn-accent-ink);
  text-decoration: none; transition: background .2s, transform .15s var(--gn-ease), opacity .2s;
}
.gn-btn:hover { background: var(--gn-accent-hi); }
.gn-btn:active { transform: scale(.97); }
.gn-btn:disabled { opacity: .45; cursor: default; transform: none; }
.gn-btn--quiet { background: var(--gn-raise-2); color: var(--gn-ink); border-color: var(--gn-line-2); }
.gn-btn--quiet:hover { background: var(--gn-raise-3); }
.gn-btn--ghost { background: transparent; color: var(--gn-dim); border-color: var(--gn-line-2); padding: 9px 15px; font-size: 13.5px; }
.gn-btn--ghost:hover { background: var(--gn-raise-2); color: var(--gn-ink); }
.gn-btn--danger { background: var(--gn-bad-soft); color: #ffd6cf; border-color: rgba(232, 121, 107, .45); }
.gn-btn--danger:hover { background: rgba(232, 121, 107, .24); }
.gn-row { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }

/* ── Inputs ────────────────────────────────────────────────────────────── */
.gn-field { display: grid; gap: 7px; margin-bottom: 16px; }
.gn-field label { font: 600 14px/1.2 var(--gn-body); color: var(--gn-ink); }
.gn-input, body.gn-body select {
  width: 100%; box-sizing: border-box; padding: 12px 14px; border-radius: var(--gn-r-input);
  border: 1px solid var(--gn-line-2); background: var(--gn-bg); color: var(--gn-ink);
  font: 400 16px/1.3 var(--gn-body); transition: border-color .2s, box-shadow .2s;
}
body.gn-body select { width: auto; padding: 9px 12px; font-size: 14.5px; }
.gn-input::placeholder { color: var(--gn-mute); }
.gn-input:focus, body.gn-body select:focus { outline: none; border-color: var(--gn-accent); box-shadow: 0 0 0 3px var(--gn-accent-soft); }
.gn-error { font-size: 14px; color: var(--gn-bad); margin: 0; }

/* A pill switch: one choice of a few. */
.gn-pills { display: inline-flex; gap: 4px; padding: 4px; border-radius: 999px; background: var(--gn-bg); border: 1px solid var(--gn-line); flex-wrap: wrap; }
.gn-pills button {
  font: 600 13.5px/1 var(--gn-body); padding: 9px 14px; border-radius: 999px; border: none;
  background: transparent; color: var(--gn-dim); cursor: pointer; transition: background .2s, color .2s;
}
.gn-pills button:hover:not(:disabled) { color: var(--gn-ink); }
.gn-pills button[aria-pressed="true"] { background: var(--gn-raise-3); color: var(--gn-ink); box-shadow: 0 0 0 1px var(--gn-accent-line); }
.gn-pills button:disabled { cursor: default; }

/* An on/off switch. */
.gn-switch { position: relative; width: 44px; height: 26px; flex: 0 0 auto; border-radius: 999px; border: none; cursor: pointer; background: var(--gn-raise-3); transition: background .2s; padding: 0; }
.gn-switch::after { content: ''; position: absolute; top: 3px; left: 3px; width: 20px; height: 20px; border-radius: 50%; background: var(--gn-dim); transition: transform .25s var(--gn-ease), background .2s; }
.gn-switch[aria-checked="true"] { background: var(--gn-accent); }
.gn-switch[aria-checked="true"]::after { transform: translateX(18px); background: var(--gn-accent-ink); }
.gn-switch:disabled { cursor: default; opacity: .6; }

/* ── Toast ─────────────────────────────────────────────────────────────── */
.gn-toast {
  position: fixed; left: 50%; bottom: 28px; transform: translateX(-50%); z-index: 500;
  padding: 12px 20px; border-radius: 999px; max-width: 90vw; box-sizing: border-box;
  background: var(--gn-raise-3); border: 1px solid var(--gn-line-2); color: var(--gn-ink);
  font: 600 14px/1.35 var(--gn-body); box-shadow: 0 18px 40px -12px rgba(0, 0, 0, .7);
  animation: gn-rise .3s var(--gn-ease);
}
.gn-toast.is-bad { background: #2a1714; border-color: rgba(232, 121, 107, .45); color: #ffd6cf; }
@keyframes gn-rise { from { opacity: 0; transform: translate(-50%, 8px); } }

/* ── "Are you sure?" (static/js/gn-ask.js) ─────────────────────────────────
   In place of the browser's grey box at the top of the screen. The room
   dims, and a card rises: in the middle on a computer, from the bottom on a
   phone, where the thumb already is. The question is the heading; what it
   costs is the small print. Red only when the answer loses something. */
.gn-ask {
  position: fixed; inset: 0; z-index: 600; display: grid; place-items: center; padding: 20px;
  background: rgba(8, 7, 9, .62); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  animation: gn-ask-dim .2s ease;
}
.gn-ask-card {
  position: relative; width: 100%; max-width: 400px; box-sizing: border-box; text-align: center;
  padding: 30px 26px 22px; border-radius: 22px;
  background: linear-gradient(180deg, var(--gn-raise-2), var(--gn-raise) 70%);
  border: 1px solid var(--gn-line-2);
  box-shadow: 0 1px 0 rgba(255, 240, 225, .06) inset, 0 30px 70px -20px rgba(0, 0, 0, .85);
  animation: gn-ask-in .34s var(--gn-ease);
}
/* A warm glow behind the badge, like the lamp in the corner of the page. */
.gn-ask-card::before {
  content: ''; position: absolute; left: 50%; top: 0; width: 220px; height: 120px; transform: translateX(-50%);
  background: radial-gradient(closest-side, var(--gn-accent-soft), transparent); pointer-events: none;
}
.gn-ask.is-danger .gn-ask-card::before { background: radial-gradient(closest-side, var(--gn-bad-soft), transparent); }
.gn-ask-icon {
  position: relative; display: inline-grid; place-items: center; width: 54px; height: 54px; margin-bottom: 14px;
  border-radius: 50%; font-size: 21px; color: var(--gn-accent);
  background: var(--gn-accent-soft); box-shadow: 0 0 0 1px var(--gn-accent-line), 0 0 0 7px rgba(244, 162, 91, .05);
}
.gn-ask.is-danger .gn-ask-icon {
  color: var(--gn-bad); background: var(--gn-bad-soft);
  box-shadow: 0 0 0 1px rgba(232, 121, 107, .45), 0 0 0 7px rgba(232, 121, 107, .05);
}
.gn-ask-title {
  position: relative; margin: 0; font: 700 22px/1.2 var(--gn-display); letter-spacing: -.015em;
  color: var(--gn-ink); text-wrap: balance; overflow-wrap: anywhere;
}
.gn-ask-detail { margin: 9px 0 0; font: 400 15px/1.5 var(--gn-body); color: var(--gn-dim); text-wrap: pretty; }
.gn-ask-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 24px; }
.gn-ask-row .gn-btn { width: 100%; padding: 14px 16px; font-size: 15px; white-space: normal; line-height: 1.2; }
/* Going ahead with a loss is a full red button, not the soft one. */
.gn-ask-row .gn-btn--danger { background: var(--gn-bad); border-color: var(--gn-bad); color: #2a0c07; }
.gn-ask-row .gn-btn--danger:hover { background: #f09082; }
.gn-ask.is-leaving { animation: gn-ask-dim .16s ease reverse forwards; }
.gn-ask.is-leaving .gn-ask-card { animation: gn-ask-out .16s ease forwards; }
@keyframes gn-ask-dim { from { opacity: 0; } }
@keyframes gn-ask-in { from { opacity: 0; transform: translateY(14px) scale(.96); } }
@keyframes gn-ask-out { to { opacity: 0; transform: translateY(8px) scale(.98); } }
@media (max-width: 560px) {
  .gn-ask { place-items: end center; padding: 0; }
  .gn-ask-card {
    max-width: none; border-radius: 24px 24px 0 0; border-bottom: none;
    padding: 26px 20px calc(18px + env(safe-area-inset-bottom));
    animation-name: gn-ask-up;
  }
  /* A grab bar, so it reads as a sheet that came up from below. */
  .gn-ask-card::after {
    content: ''; position: absolute; top: 9px; left: 50%; width: 38px; height: 4px; margin-left: -19px;
    border-radius: 999px; background: var(--gn-line-2);
  }
  .gn-ask-row { grid-template-columns: 1fr; }
  .gn-ask-row [data-yes] { order: -1; }
  .gn-ask.is-leaving .gn-ask-card { animation-name: gn-ask-down; }
}
@keyframes gn-ask-up { from { transform: translateY(100%); } }
@keyframes gn-ask-down { to { transform: translateY(100%); } }
@media (prefers-reduced-motion: reduce) {
  .gn-ask, .gn-ask-card, .gn-ask.is-leaving, .gn-ask.is-leaving .gn-ask-card { animation: none; }
}

/* The typed questions (mhiPrompt: naming a playlist, and so on) in the same
   card, not the Index's red one. */
body.gn-body .mhi-modal-overlay { z-index: 600; background: rgba(8, 7, 9, .62); backdrop-filter: blur(6px); }
body.gn-body .mhi-modal {
  width: min(400px, calc(100vw - 32px)); min-width: 0; box-sizing: border-box; padding: 22px 22px 18px;
  border-radius: 22px; border: 1px solid var(--gn-line-2);
  background: linear-gradient(180deg, var(--gn-raise-2), var(--gn-raise) 70%);
  box-shadow: 0 30px 70px -20px rgba(0, 0, 0, .85); animation: gn-ask-in .34s var(--gn-ease);
}
body.gn-body .mhi-modal-head { border: none; margin-bottom: 12px; padding: 0; }
body.gn-body .mhi-modal-title { font: 700 20px/1.2 var(--gn-display); letter-spacing: -.015em; text-transform: none; color: var(--gn-ink); }
body.gn-body .mhi-modal-x { color: var(--gn-mute); font-size: 15px; }
body.gn-body .mhi-modal-x:hover { color: var(--gn-ink); }
body.gn-body .mhi-modal-label, body.gn-body .mhi-modal-message { font: 400 15px/1.5 var(--gn-body); color: var(--gn-dim); }
body.gn-body .mhi-modal-input {
  padding: 12px 14px; border-radius: var(--gn-r-input); border: 1px solid var(--gn-line-2);
  background: var(--gn-bg); color: var(--gn-ink); font: 400 16px/1.3 var(--gn-body);
}
body.gn-body .mhi-modal-input:focus { border-color: var(--gn-accent); background: var(--gn-bg); box-shadow: 0 0 0 3px var(--gn-accent-soft); }
body.gn-body .mhi-modal-actions { border: none; margin-top: 18px; padding: 0; gap: 10px; }
body.gn-body .mhi-modal-cancel, body.gn-body .mhi-modal-confirm {
  height: auto; padding: 12px 20px; border-radius: 999px; font: 700 14.5px/1 var(--gn-body);
  letter-spacing: 0; text-transform: none;
}
body.gn-body .mhi-modal-cancel { background: var(--gn-raise-2); border: 1px solid var(--gn-line-2); color: var(--gn-ink); }
body.gn-body .mhi-modal-cancel:hover { background: var(--gn-raise-3); }
body.gn-body .mhi-modal-confirm { background: var(--gn-accent); border: 1px solid transparent; color: var(--gn-accent-ink); }
body.gn-body .mhi-modal-confirm:hover { background: var(--gn-accent-hi); }
body.gn-body .mhi-modal-confirm--danger { background: var(--gn-bad); color: #2a0c07; }

/* ── The shared table (static/js/gn-table.js) ─────────────────────────────
   Every game after Werewolf draws its news, seats and lobby with these. */
.gt [hidden] { display: none !important; }
.gt-grid { display: grid; gap: 16px; grid-template-columns: minmax(0, 1.5fr) minmax(300px, 1fr); align-items: start; }
@media (max-width: 920px) { .gt-grid { grid-template-columns: minmax(0, 1fr); } }
.gt-col { display: flex; flex-direction: column; gap: 16px; }
.gt-news { display: flex; align-items: center; flex-wrap: wrap; gap: 10px 16px; }
.gt-news-main { flex: 1 1 260px; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.gt-phase { font: 600 13px/1 var(--gn-body); color: var(--gn-mute); }
.gt-news p { margin: 0; font: 500 clamp(18px, 2vw, 22px)/1.35 var(--gn-display); color: var(--gn-ink); letter-spacing: -.01em; }
.gt-seats { display: grid; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(118px, 1fr)); }
.gt-seat {
  position: relative; display: flex; flex-direction: column; align-items: center; gap: 7px;
  padding: 18px 8px 14px; border-radius: var(--gn-r-panel); border: 1px solid var(--gn-line);
  background: var(--gn-raise-2); text-align: center; font: inherit; color: inherit;
}
button.gt-seat { cursor: pointer; transition: border-color .2s, transform .25s var(--gn-ease), background .2s; }
button.gt-seat:hover { border-color: var(--gn-accent-line); transform: translateY(-2px); background: var(--gn-raise-3); }
.gt-seat.is-picked { border-color: var(--gn-accent); box-shadow: 0 0 0 3px var(--gn-accent-soft); }
.gt-face {
  width: 56px; height: 56px; border-radius: 50%; overflow: hidden; display: grid; place-items: center;
  font: 700 21px/1 var(--gn-display); color: var(--gn-ink); background: var(--gn-raise-3);
  box-shadow: 0 0 0 2px var(--gn-line-2);
}
.gt-face img { width: 100%; height: 100%; object-fit: cover; display: block; }
.gt-seat.is-me .gt-face { box-shadow: 0 0 0 2px var(--gn-accent); }
.gt-who { font: 700 14.5px/1.2 var(--gn-body); color: var(--gn-ink); word-break: break-word; }
.gt-info { font: 600 12px/1.3 var(--gn-body); color: var(--gn-dim); }
.gt-info--hot { color: var(--gn-accent); }
.gt-badges { position: absolute; top: 8px; right: 10px; display: flex; gap: 6px; align-items: center; font: 600 11.5px/1 var(--gn-body); color: var(--gn-mute); }
.gt-badges i { color: var(--gn-accent); font-size: 12px; }
.gt-kick { position: absolute; top: 6px; left: 6px; width: 26px; height: 26px; border-radius: 50%; border: none; background: transparent; color: var(--gn-mute); cursor: pointer; font-size: 13px; }
.gt-kick:hover { background: var(--gn-bad-soft); color: var(--gn-bad); }
/* Taking somebody who has gone away out of a running game (gn-table.js). */
/* A small round icon in the seat's bottom corner -- clear of the vote count
   (top left) and the crown (top right). The words are in its tooltip. */
.gt-seat-box { position: relative; display: grid; }
.gt-drop { position: absolute; right: 6px; bottom: 6px; z-index: 1; width: 26px; height: 26px; border-radius: 50%; padding: 0;
  display: grid; place-items: center; cursor: pointer; border: none; background: transparent; color: var(--gn-mute); font-size: 11.5px;
  transition: background .15s, color .15s; }
.gt-drop:hover, .gt-drop:focus-visible { background: var(--gn-bad-soft); color: var(--gn-bad); }
.gt-drop.is-away { color: var(--gn-bad); }
.gt-away { display: block; margin-top: 4px; font: 700 11.5px/1.2 var(--gn-body); color: var(--gn-bad); letter-spacing: .04em; }
.gt-hint { margin: 16px 0 0; font: 600 14.5px/1.4 var(--gn-body); color: var(--gn-accent); }
.gt-setup { display: grid; gap: 18px; }
.gt-setup h3 { font: 700 15.5px/1.2 var(--gn-display); color: var(--gn-ink); margin: 0 0 10px; }
.gt-log ul { list-style: none; margin: 0; padding: 0; }
.gt-log li { padding: 9px 0; font-size: 15px; color: var(--gn-ink); border-bottom: 1px solid var(--gn-line); }
.gt-log li:last-child { border-bottom: none; }
/* A secret card: what only you are told. Face down until you tap it. */
.gt-secret { display: flex; gap: 18px; align-items: center; flex-wrap: wrap; }
.gt-card {
  width: 128px; aspect-ratio: 5/7; border-radius: 14px; flex: 0 0 auto; cursor: pointer;
  display: grid; place-items: center; text-align: center; padding: 12px; box-sizing: border-box;
  border: 1px solid var(--gn-accent-line); color: var(--gn-ink); font: 700 17px/1.2 var(--gn-display);
  background: repeating-linear-gradient(45deg, rgba(244, 162, 91, .05) 0 10px, transparent 10px 20px), #1d1a1e;
  box-shadow: 0 14px 30px -12px rgba(0, 0, 0, .8); transition: transform .3s var(--gn-ease);
}
.gt-card:hover { transform: translateY(-2px); }
.gt-card i { font-size: 34px; color: var(--gn-accent); }
.gt-card.is-up { background: radial-gradient(120% 70% at 50% 0%, rgba(244, 162, 91, .22), transparent 70%), #1d1a1e; }
.gt-card.is-bad { border-color: rgba(232, 121, 107, .55); background: radial-gradient(120% 70% at 50% 0%, rgba(232, 121, 107, .26), transparent 70%), #1d1a1e; }

/* Whose turn (gn-table.js turn()): the seat the game is waiting on glows in
   the chair's yellow. When everybody plays at once, it's who's still thinking. */
.gt-seat.is-turn { border-color: rgba(212, 155, 75, .55); background: radial-gradient(120% 90% at 50% 0%, rgba(212, 155, 75, .16), transparent 70%), var(--gn-raise-2); }
.gt-seat.is-turn .gt-face { box-shadow: 0 0 0 2px var(--gn-chair), 0 0 18px 2px rgba(212, 155, 75, .35); animation: gn-turn 2.4s ease-in-out infinite; }
@keyframes gn-turn { 50% { box-shadow: 0 0 0 2px var(--gn-chair), 0 0 6px 0 rgba(212, 155, 75, .15); } }

/* A card turning over (from Tarot's tt-flip). Put .gn-flip on a card that
   has just been turned -- only one nobody has seen yet, never on a refresh. */
.gn-flip { animation: gn-flip .5s ease both; }
@keyframes gn-flip { from { transform: perspective(900px) rotateY(90deg); opacity: .2; } to { transform: perspective(900px) rotateY(0); opacity: 1; } }
/* A card laid down on the table (from Blackjack's cz-deal). */
.gn-lay { animation: gn-lay .38s var(--gn-ease) both; }
@keyframes gn-lay { from { transform: translateY(-26px) scale(1.06) rotate(var(--lay-r, 0deg)); opacity: 0; } }

/* The table top: the middle of a game, where its pieces lie -- never the
   whole page. A dark felt with a fine grain; --felt tints it per game. */
.gn-table-top {
  --felt: #1c2620;
  position: relative; border-radius: 22px; padding: 22px;
  background:
    var(--gn-felt-img, none) center / 512px repeat,
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .07 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"),
    radial-gradient(120% 90% at 50% 35%, color-mix(in srgb, var(--felt) 94%, white), var(--felt) 55%, color-mix(in srgb, var(--felt) 65%, black));
  background-blend-mode: overlay, normal, normal; /* the felt picture lends grain, --felt keeps the colour */
  box-shadow: inset 0 0 0 1px rgba(255, 240, 225, .06), inset 0 10px 40px rgba(0, 0, 0, .45), 0 18px 40px -22px rgba(0, 0, 0, .9);
}

/* The empty table (gn-table.js renderFelt): before a game starts, the felt
   with chairs round its edge, the game's pieces lying on it, and one big
   button. The Players panel steps aside meanwhile -- the chairs are the players. */
[data-gt-mode="idle"] [data-t-news],
[data-gt-mode="idle"] .gn-panel:has(> [data-t-seats]),
[data-gt-mode="lobby"] .gn-panel:has(> [data-t-seats]) { display: none !important; }
/* With the Players panel gone, what is left is one column under the table. */
[data-gt-mode="idle"] .gt-grid, [data-gt-mode="lobby"] .gt-grid { grid-template-columns: minmax(0, 1fr); }
.gt-felt { display: grid; gap: 22px; justify-items: center; text-align: center; margin: 42px 0 16px; padding: 0 22px 28px; }
.gt-felt[hidden] { display: none; }
.gt-chairs { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px 20px; margin-top: -31px; }
.gt-chairs .gt-who:empty, .gt-chair.is-empty:not(.is-free) .gt-who { display: none; }
.gt-chair {
  position: relative; display: flex; flex-direction: column; align-items: center; gap: 7px; width: 76px;
  padding: 0; border: none; background: none; font: inherit; color: inherit;
}
.gt-chair .gt-face { width: 62px; height: 62px; box-shadow: 0 0 0 3px color-mix(in srgb, var(--felt) 70%, black), 0 10px 20px -8px rgba(0, 0, 0, .8); }
.gt-chair.is-me .gt-face { box-shadow: 0 0 0 3px var(--gn-accent), 0 10px 20px -8px rgba(0, 0, 0, .8); }
.gt-chair .gt-who { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; }
.gt-chair.is-empty .gt-face { background: rgba(0, 0, 0, .28); border: 2px dashed rgba(255, 240, 225, .2); box-sizing: border-box; color: rgba(255, 240, 225, .28); font-size: 19px; box-shadow: none; }
.gt-chair.is-free { cursor: pointer; }
.gt-chair.is-free .gt-who { color: var(--gn-dim); }
.gt-chair.is-free:hover .gt-face, .gt-chair.is-free:focus-visible .gt-face { border-color: var(--gn-accent); color: var(--gn-accent); }
.gt-chair.is-free:focus-visible { outline: none; }
.gt-chair-host { position: absolute; top: -8px; right: 4px; z-index: 1; color: var(--gn-chair); font-size: 14px; filter: drop-shadow(0 2px 3px rgba(0, 0, 0, .7)); }
.gt-chair .gt-kick { top: -8px; left: -2px; z-index: 1; background: var(--gn-raise-2); }
.gt-pieces { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 16px 22px; padding: 6px 0; pointer-events: none; }
.gt-pieces.is-new > * { animation: gn-lay .5s var(--gn-ease) both; }
.gt-pieces.is-new > :nth-child(2) { animation-delay: .08s; } .gt-pieces.is-new > :nth-child(3) { animation-delay: .16s; }
.gt-pieces.is-new > :nth-child(4) { animation-delay: .24s; } .gt-pieces.is-new > :nth-child(n+5) { animation-delay: .32s; }
.gt-felt-act { display: grid; gap: 12px; justify-items: center; }
.gt-felt-act p { margin: 0; max-width: 46ch; font: 500 14.5px/1.45 var(--gn-body); color: rgba(243, 238, 233, .7); }
.gt-leave { padding: 0; border: none; background: none; color: inherit; font: inherit; text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
.gt-leave:hover { color: var(--gn-ink); }
.gn-btn--big { padding: 17px 32px; font-size: 17px; box-shadow: 0 14px 32px -12px color-mix(in srgb, var(--gn-accent) 70%, transparent); }
@media (max-width: 640px) {
  .gt-felt { padding: 0 14px 22px; }
  .gt-chairs { gap: 10px 12px; }
  .gt-chair { width: 64px; }
  .gt-chair .gt-face { width: 54px; height: 54px; }
  .gt-felt-act, .gn-btn--big { width: 100%; }
}

/* ── The picture cropper (static/js/vtt-crop.js), in Game Night's colours ──
   The same tool the VTT uses for tokens; only its paint changes here. */
body.gn-body .vtt-crop-panel { background: var(--gn-raise); border-color: var(--gn-line-2); border-radius: var(--gn-r-panel); color: var(--gn-ink); font-family: var(--gn-body); }
body.gn-body .vtt-crop-title { font: 700 17px/1.2 var(--gn-display); }
body.gn-body .vtt-crop-ring { border-color: var(--gn-accent); }
body.gn-body .vtt-crop-hint { color: var(--gn-mute); }
body.gn-body .vtt-crop-slider { accent-color: var(--gn-accent); }
body.gn-body .vtt-crop-btn, body.gn-body .vtt-crop-zbtn { border-radius: 999px; background: var(--gn-raise-2); border-color: var(--gn-line-2); color: var(--gn-ink); font-family: var(--gn-body); }
body.gn-body .vtt-crop-btn:hover, body.gn-body .vtt-crop-zbtn:hover { background: var(--gn-raise-3); }
body.gn-body .vtt-crop-btn--primary, body.gn-body .vtt-crop-btn--primary:hover { background: var(--gn-accent); border-color: var(--gn-accent); color: var(--gn-accent-ink); }

@media (prefers-reduced-motion: reduce) {
  body.gn-body *, body.gn-body *::before, body.gn-body *::after { animation: none !important; transition: none !important; }
}
@media (max-width: 640px) {
  .gn-mast { gap: 12px; }
  .gn-mast:has(.gn-links) .gn-mark span, .gn-mast:has(.gn-links) .gn-mark-word { display: none; }
  .gn-links { gap: 10px; }
  .gn-back { padding: 7px 12px; font-size: 13.5px; }
}

/* A game's own logo in place of its page title (game_logo() in
   mhi/routes/tarot.py): the whole sticker, no box around it. */
.gn-h1.gn-logo-h1 { margin: 0 0 14px; line-height: 0; }
.gn-logo-h1 img { display: block; width: min(100%, 340px); height: auto; filter: drop-shadow(0 14px 22px rgba(0, 0, 0, .45)); }

/* ── The dice tray (static/js/gn-dice.js) ─────────────────────────────────
   A die in the corner of every page. The 3D throw draws on a stage over the
   whole window and never takes a click; the result cards stack above it. */
.gd-stage { position: fixed; inset: 0; z-index: 450; pointer-events: none; opacity: 0; transition: opacity .25s ease; }
.gd-stage.is-active { opacity: 1; }
.gd-stage canvas { width: 100vw !important; height: 100vh !important; display: block; }
.gd { position: fixed; right: 22px; bottom: 22px; z-index: 460; display: flex; flex-direction: column; align-items: flex-end; gap: 10px; }
.gd-open {
  width: 54px; height: 54px; border-radius: 50%; cursor: pointer;
  background: var(--gn-raise-2); border: 1px solid var(--gn-line-2); color: var(--gn-chair);
  font-size: 24px; display: grid; place-items: center; box-shadow: 0 14px 30px -12px rgba(0, 0, 0, .8);
  transition: transform .25s var(--gn-ease), color .2s, border-color .2s;
}
.gd-open:hover, .gd-open[aria-expanded="true"] { transform: rotate(-18deg) scale(1.06); color: var(--gn-accent); border-color: var(--gn-accent); }
.gd-panel {
  width: min(320px, calc(100vw - 32px)); box-sizing: border-box; padding: 14px;
  background: var(--gn-raise); border: 1px solid var(--gn-line-2); border-radius: 18px;
  box-shadow: 0 24px 50px -18px rgba(0, 0, 0, .85); animation: gn-rise .25s var(--gn-ease);
}
.gd-dice { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
.gd-die {
  position: relative; padding: 11px 0; border-radius: 12px; cursor: pointer;
  background: var(--gn-raise-2); border: 1px solid var(--gn-line); color: var(--gn-ink);
  font: 700 15px/1 var(--gn-display); transition: background .15s, border-color .15s, transform .15s;
}
.gd-die:hover { background: var(--gn-raise-3); border-color: var(--gn-chair); transform: translateY(-2px); }
.gd-die b {
  position: absolute; top: -7px; right: -5px; min-width: 20px; height: 20px; padding: 0 5px; box-sizing: border-box;
  border-radius: 999px; background: var(--gn-accent); color: var(--gn-accent-ink); font: 700 12px/20px var(--gn-body);
}
.gd-pool { margin: 12px 0 10px; font: 600 14px/1.35 var(--gn-body); color: var(--gn-ink); min-height: 19px; }
.gd-pool.is-empty { color: var(--gn-mute); font-weight: 500; }
.gd-row { display: flex; gap: 8px; align-items: center; }
.gd-row .gn-btn:last-child { margin-left: auto; }
.gd-mod { display: flex; align-items: center; gap: 6px; color: var(--gn-mute); font: 600 13px var(--gn-body); }
.gd-mod input {
  width: 58px; padding: 8px; border-radius: 10px; box-sizing: border-box;
  background: var(--gn-raise-2); border: 1px solid var(--gn-line-2); color: var(--gn-ink); font: 600 14px var(--gn-body);
}
.gd-look { display: block; margin-top: 12px; font: 500 12.5px var(--gn-body); color: var(--gn-dim); }
.gd-look:hover { color: var(--gn-chair); }
.gd-cards { position: fixed; right: 22px; bottom: 90px; z-index: 455; display: flex; flex-direction: column; gap: 8px; align-items: flex-end; pointer-events: none; }
.gd-card {
  display: flex; align-items: center; gap: 10px; padding: 8px 14px 8px 8px; max-width: min(340px, calc(100vw - 32px)); box-sizing: border-box;
  background: var(--gn-raise-2); border: 1px solid var(--gn-line-2); border-radius: 999px;
  box-shadow: 0 16px 34px -14px rgba(0, 0, 0, .85); animation: gn-card-in .35s var(--gn-ease);
  transition: opacity .5s, transform .5s;
}
.gd-card.is-mine { border-color: rgba(244, 162, 91, .45); }
.gd-card.is-out { opacity: 0; transform: translateX(16px); }
.gd-card-face {
  width: 34px; height: 34px; flex: 0 0 auto; border-radius: 50%; overflow: hidden; display: grid; place-items: center;
  background: var(--gn-raise-3); color: var(--gn-dim); font: 700 14px var(--gn-display);
}
.gd-card-face img { width: 100%; height: 100%; object-fit: cover; }
.gd-card-text { display: flex; flex-direction: column; min-width: 0; font: 500 12.5px/1.3 var(--gn-body); color: var(--gn-dim); }
.gd-card-text b { color: var(--gn-ink); font-weight: 700; font-size: 13.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gd-card-total { margin-left: auto; padding-left: 6px; font: 800 24px/1 var(--gn-display); color: var(--gn-chair); }
@keyframes gn-card-in { from { opacity: 0; transform: translateY(10px) scale(.96); } }
@media (max-width: 640px) {
  .gd { right: 14px; bottom: 14px; }
  .gd-open { width: 48px; height: 48px; font-size: 21px; }
  .gd-cards { right: 14px; bottom: 74px; }
}
@media (prefers-reduced-motion: reduce) {
  .gd-open, .gd-die, .gd-card { transition: none; animation: none; }
}

/* ── Music together (static/js/gn-music.js) ───────────────────────────────
   The VTT's shared YouTube player, bottom-left, opposite the dice. The
   round button matches the dice tray's; while the room is playing it wears
   a small dot (pulsing when you can hear it) so you can tell at a glance. */
.gm { position: fixed; left: 22px; bottom: 22px; z-index: 460; display: flex; flex-direction: column; align-items: flex-start; gap: 10px; }
.gm [hidden] { display: none !important; }
.gm-engine { position: absolute; width: 1px; height: 1px; overflow: hidden; opacity: 0; pointer-events: none; left: -9999px; }
.gm-open {
  position: relative; width: 54px; height: 54px; border-radius: 50%; cursor: pointer;
  background: var(--gn-raise-2); border: 1px solid var(--gn-line-2); color: var(--gn-chair);
  font-size: 21px; display: grid; place-items: center; box-shadow: 0 14px 30px -12px rgba(0, 0, 0, .8);
  transition: transform .25s var(--gn-ease), color .2s, border-color .2s;
}
.gm-open:hover, .gm-open[aria-expanded="true"] { transform: rotate(12deg) scale(1.06); color: var(--gn-accent); border-color: var(--gn-accent); }
.gm.is-playing .gm-open { border-color: var(--gn-accent-line); }
.gm.is-playing .gm-open::after {
  content: ''; position: absolute; top: 3px; right: 3px; width: 11px; height: 11px; border-radius: 50%;
  background: var(--gn-accent); border: 2px solid var(--gn-raise-2);
}
.gm.is-hearing .gm-open::after { animation: gm-pulse 1.6s ease-in-out infinite; }
@keyframes gm-pulse { 50% { transform: scale(.7); opacity: .6; } }

.gm-panel {
  width: min(360px, calc(100vw - 32px)); box-sizing: border-box; padding: 14px;
  background: var(--gn-raise); border: 1px solid var(--gn-line-2); border-radius: 18px;
  box-shadow: 0 24px 50px -18px rgba(0, 0, 0, .85); animation: gm-in .25s var(--gn-ease);
}
@keyframes gm-in { from { opacity: 0; transform: translateY(8px); } }

.gm-now { display: flex; align-items: center; gap: 12px; min-width: 0; }
.gm-now-tx { display: flex; flex-direction: column; min-width: 0; }
.gm-now-tx b { font: 700 15.5px/1.25 var(--gn-display); color: var(--gn-ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gm-now-tx span { font: 500 12.5px/1.35 var(--gn-body); color: var(--gn-mute); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Three bars that dance while the room plays, and stand still when it does not. */
.gm-eq { display: inline-flex; align-items: flex-end; justify-content: center; gap: 3px; height: 14px; }
.gm-eq i { display: block; width: 3px; height: 30%; border-radius: 2px; background: var(--gn-accent); }
.gm.is-playing .gm-eq i { animation: gm-bar .9s ease-in-out infinite; }
.gm.is-playing .gm-eq i:nth-child(2) { animation-delay: -.3s; }
.gm.is-playing .gm-eq i:nth-child(3) { animation-delay: -.6s; }
.gm-now > .gm-eq { flex: 0 0 auto; width: 40px; height: 40px; border-radius: 12px; background: var(--gn-accent-soft); padding: 11px 0; box-sizing: border-box; }
@keyframes gm-bar { 0%, 100% { height: 25%; } 50% { height: 100%; } }

.gm-transport { display: flex; align-items: center; gap: 8px; margin: 12px 0; }
.gm-btn {
  width: 38px; height: 38px; border-radius: 50%; cursor: pointer; display: grid; place-items: center;
  background: var(--gn-raise-2); border: 1px solid var(--gn-line); color: var(--gn-ink); font-size: 14px;
  transition: background .15s, border-color .15s, color .15s, transform .15s;
}
.gm-btn:hover:not(:disabled) { background: var(--gn-raise-3); border-color: var(--gn-chair); color: var(--gn-chair); }
.gm-btn:disabled { opacity: .4; cursor: default; }
.gm-btn--play { width: 46px; height: 46px; font-size: 16px; background: var(--gn-accent); color: var(--gn-accent-ink); border-color: transparent; }
.gm-btn--play:hover:not(:disabled) { background: var(--gn-accent-hi); color: var(--gn-accent-ink); border-color: transparent; }
.gm-btn--sm { width: 32px; height: 32px; font-size: 12.5px; flex: 0 0 auto; }
.gm-loop { margin-left: auto; color: var(--gn-mute); font-size: 13px; padding: 0 4px; }

.gm-plrow { display: flex; gap: 6px; align-items: center; }
body.gn-body .gm-select {
  flex: 1 1 auto; min-width: 0; padding: 7px 10px; border-radius: 10px; font: 600 13.5px var(--gn-body);
  background: var(--gn-raise-2); border: 1px solid var(--gn-line-2); color: var(--gn-ink);
}
body.gn-body .gm-select:disabled { opacity: 1; }

.gm-list { list-style: none; margin: 10px 0; padding: 0; max-height: min(300px, 42vh); overflow-y: auto; overscroll-behavior: contain; }
.gm-empty { padding: 14px 6px; color: var(--gn-mute); font: 500 13.5px var(--gn-body); text-align: center; }
.gm-item { border-radius: 12px; position: relative; }
.gm-item + .gm-item { margin-top: 2px; }
.gm-row { display: flex; align-items: center; gap: 6px; padding: 5px 4px 5px 2px; }
.gm-item:hover, .gm-item.is-open { background: var(--gn-raise-2); }
.gm-item.is-current { background: var(--gn-accent-soft); }
.gm-grip {
  flex: 0 0 auto; width: 20px; height: 32px; display: grid; place-items: center; color: var(--gn-mute);
  cursor: grab; touch-action: none; font-size: 12px;
}
.gm-grip:hover { color: var(--gn-chair); }
.gm-list.is-sorting, .gm-list.is-sorting * { cursor: grabbing; user-select: none; }
.gm-item.is-dragging { opacity: .45; }
.gm-item.drop-before::before, .gm-item.drop-after::after {
  content: ''; position: absolute; left: 6px; right: 6px; height: 3px; border-radius: 3px; background: var(--gn-accent);
}
.gm-item.drop-before::before { top: -2px; }
.gm-item.drop-after::after { bottom: -2px; }
.gm-tplay {
  flex: 0 0 auto; width: 30px; height: 30px; border-radius: 50%; cursor: pointer; display: grid; place-items: center;
  background: transparent; border: 1px solid var(--gn-line-2); color: var(--gn-dim); font-size: 10.5px;
}
.gm-tplay:hover { color: var(--gn-accent-ink); background: var(--gn-accent); border-color: transparent; }
.gm-item.is-current .gm-tplay { border-color: var(--gn-accent-line); color: var(--gn-accent); }
.gm-tname { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.gm-tname b { font: 600 13.5px/1.3 var(--gn-body); color: var(--gn-ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gm-item.is-current .gm-tname b { color: var(--gn-accent-hi); }
.gm-tname small { font: 500 11.5px/1.3 var(--gn-body); color: var(--gn-mute); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gm-more {
  flex: 0 0 auto; width: 30px; height: 30px; border-radius: 50%; cursor: pointer; display: grid; place-items: center;
  background: transparent; border: 0; color: var(--gn-mute); font-size: 13px;
}
.gm-more:hover, .gm-more[aria-expanded="true"] { color: var(--gn-ink); background: var(--gn-raise-3); }
.gm-acts { display: flex; flex-wrap: wrap; gap: 6px; padding: 2px 8px 9px 58px; }
.gm-acts button {
  padding: 6px 11px; border-radius: 999px; cursor: pointer; font: 600 12.5px/1 var(--gn-body);
  background: var(--gn-raise-3); border: 1px solid var(--gn-line-2); color: var(--gn-ink);
}
.gm-acts button:hover:not(:disabled) { border-color: var(--gn-chair); color: var(--gn-chair); }
.gm-acts button:disabled { opacity: .35; cursor: default; }
.gm-acts button.is-bad { color: #ffd6cf; border-color: rgba(232, 121, 107, .45); background: var(--gn-bad-soft); }

.gm-add { display: flex; flex-direction: column; gap: 8px; }
.gm-add-row { display: flex; gap: 8px; }
.gm-add input {
  flex: 1 1 auto; min-width: 0; padding: 9px 12px; border-radius: 12px; box-sizing: border-box;
  background: var(--gn-raise-2); border: 1px solid var(--gn-line-2); color: var(--gn-ink); font: 500 14px var(--gn-body);
}
.gm-add input:focus { outline: none; border-color: var(--gn-accent-line); }
.gm-add .gn-btn { padding: 9px 16px; font-size: 13.5px; }
/* What a pasted link is, before it goes on the list: its picture, and its
   name in a box you can change. */
.gm-preview { display: flex; gap: 10px; align-items: center; padding: 8px; border-radius: 12px; background: var(--gn-raise-2); border: 1px solid var(--gn-line); }
.gm-preview img { flex: 0 0 auto; width: 72px; height: 40px; border-radius: 8px; object-fit: cover; background: var(--gn-raise-3); }
.gm-name { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.gm-name span { font: 600 11.5px/1 var(--gn-body); color: var(--gn-mute); }
.gm-add .gm-name input { padding: 7px 10px; font-size: 13.5px; background: var(--gn-raise); }
/* Your own songs: click the name to change it in place. */
.gm-tname b.gm-editable { cursor: text; border-radius: 6px; margin: 0 -4px; padding: 0 4px; }
.gm-tname b.gm-editable:hover { background: var(--gn-raise-3); box-shadow: inset 0 -1px 0 var(--gn-accent-line); }
.gm-rename {
  width: 100%; box-sizing: border-box; padding: 4px 8px; border-radius: 8px; margin: -2px 0;
  background: var(--gn-bg); border: 1px solid var(--gn-accent-line); color: var(--gn-ink); font: 600 13.5px/1.3 var(--gn-body);
}
.gm-rename:focus { outline: none; border-color: var(--gn-accent); }
.gm-err { margin-top: 8px; padding: 8px 11px; border-radius: 10px; background: var(--gn-bad-soft); color: #ffd6cf; font: 500 12.5px/1.35 var(--gn-body); }

.gm-vol { display: flex; align-items: center; gap: 10px; margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--gn-line); }
.gm-vol input[type="range"] { flex: 1 1 auto; min-width: 0; accent-color: var(--gn-accent); }
.gm-seek { display: flex; align-items: center; gap: 8px; margin: 2px 0 10px; }
.gm-seek input[type="range"] { flex: 1 1 auto; min-width: 0; accent-color: var(--gn-accent); }
.gm-seek input[type="range"]:disabled { opacity: .4; }
.gm-time { min-width: 34px; font: 600 11.5px var(--gn-body); color: var(--gn-mute); font-variant-numeric: tabular-nums; }
.gm-time[data-gm-len] { text-align: right; }
.gm-volnum { width: 26px; text-align: right; font: 600 12px var(--gn-body); color: var(--gn-mute); }

@media (max-width: 640px) {
  .gm { left: 14px; bottom: 14px; }
  .gm-open { width: 48px; height: 48px; font-size: 19px; }
  .gm-list { max-height: 34vh; }
}
@media (prefers-reduced-motion: reduce) {
  .gm-open, .gm-panel { transition: none; animation: none; }
  .gm.is-playing .gm-eq i, .gm.is-hearing .gm-open::after { animation: none; }
}

/* ── Room for a finger ────────────────────────────────────────────────────
   On a touch screen the small round buttons (take out, skip, the music
   list's play / more / grip) get an invisible hit area of about 44px around
   them. The look doesn't change. The music rows only grow up and down, so a
   tap meant for the grip never lands on the play button next to it. */
@media (pointer: coarse) {
  .gm-btn--sm, .gm-tplay, .gm-more, .gm-grip { position: relative; }
  .gt-kick::before, .gt-drop::before { content: ''; position: absolute; inset: -9px; }
  .gm-btn--sm::before { content: ''; position: absolute; inset: -6px; }
  .gm-tplay::before, .gm-more::before, .gm-grip::before { content: ''; position: absolute; inset: -7px 0; }
}

/* ── In a game: the whole game in view (gn-table.js, data-gt-mode) ───────
   The DM's playtest: "the whole game needs to fit the screen", and with it
   spread down the page it was hard to tell whose turn it was. While a game
   is played (and at its end) the title shrinks to the logo, the news bar
   stays in sight saying whose turn it is, the players stand beside the
   table, "How to play" folds into a button, and the buttons that move the
   game on are big. */
.gt[data-gt-mode="play"] .gn-lead, .gt[data-gt-mode="over"] .gn-lead { display: none; }
.gt[data-gt-mode="play"] .gn-logo-h1, .gt[data-gt-mode="over"] .gn-logo-h1 { margin: 0 0 10px; }
.gt[data-gt-mode="play"] .gn-logo-h1 img, .gt[data-gt-mode="over"] .gn-logo-h1 img { width: auto; height: 56px; }
.gt[data-gt-mode="play"] .gn-h1:not(.gn-logo-h1), .gt[data-gt-mode="over"] .gn-h1:not(.gn-logo-h1) { font-size: 28px; margin: 0 0 10px; }
.gt[data-gt-mode="play"] [data-t-news] {
  position: sticky; top: 8px; z-index: 60; padding: 12px 16px 12px 20px;
  background: color-mix(in srgb, var(--gn-raise) 94%, transparent);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
}
.gt[data-gt-mode="play"] .gt-news p { font-size: clamp(16px, 1.6vw, 19px); }
.gt-turn {
  display: inline-flex; align-items: center; gap: 9px; padding: 7px 14px 7px 8px; border-radius: 999px;
  font: 700 14.5px/1.1 var(--gn-body); color: var(--gn-ink);
  background: rgba(212, 155, 75, .12); border: 1px solid rgba(212, 155, 75, .5);
}
.gt-turn > i { margin-left: 6px; color: var(--gn-chair); }
.gt-turn .gt-face { width: 28px; height: 28px; font-size: 12px; box-shadow: 0 0 0 2px var(--gn-chair); }
.gt-turn.is-mine {
  padding: 10px 18px; font-size: 16px; background: var(--gn-accent); color: var(--gn-accent-ink); border-color: transparent;
  animation: gt-mine 1.4s ease-out 2;
}
.gt-turn.is-mine > i { color: inherit; margin: 0; }
@keyframes gt-mine { from { box-shadow: 0 0 0 0 color-mix(in srgb, var(--gn-accent) 60%, transparent); } to { box-shadow: 0 0 0 14px transparent; } }
.gt-howbtn {
  display: inline-flex; align-items: center; gap: 7px; padding: 8px 12px; border-radius: 999px; cursor: pointer;
  font: 600 13px/1 var(--gn-body); color: var(--gn-dim); background: transparent; border: 1px solid var(--gn-line-2);
}
.gt-howbtn:hover { color: var(--gn-ink); border-color: var(--gn-accent-line); }
.gt-howbtn i { font-size: 15px; }
.gt[data-gt-mode="play"] .gt-how:not(.is-open), .gt[data-gt-mode="over"] .gt-how:not(.is-open) { display: none; }
.gt .gt-how.is-open {
  position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 450;
  width: min(560px, calc(100vw - 32px)); max-height: 80vh; overflow-y: auto; box-sizing: border-box;
  box-shadow: 0 0 0 100vmax rgba(8, 6, 8, .62), 0 30px 60px -20px rgba(0, 0, 0, .9);
}
@media (min-width: 921px) {
  .gt[data-gt-mode="play"] .gt-grid > .gt-col:last-child {
    position: sticky; top: 104px; max-height: calc(100vh - 116px); overflow-y: auto; overscroll-behavior: contain;
  }
}
.gt[data-gt-mode="play"] .gt-players .gt-seats, .gt[data-gt-mode="over"] .gt-players .gt-seats { grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 8px; }
.gt[data-gt-mode="play"] .gt-players .gt-seat, .gt[data-gt-mode="over"] .gt-players .gt-seat { padding: 12px 6px 10px; gap: 5px; }
.gt[data-gt-mode="play"] .gt-players .gt-face, .gt[data-gt-mode="over"] .gt-players .gt-face { width: 42px; height: 42px; font-size: 17px; }
.gt[data-gt-mode="play"] .gt-log ul { max-height: 220px; overflow-y: auto; }
/* The buttons that move the game on: big, and lit. */
.gt[data-gt-mode="play"] .gn-btn:not(.gn-btn--ghost):not(.gn-btn--quiet):not(.gn-btn--danger) {
  font-size: 16px; padding: 14px 24px;
  box-shadow: 0 10px 24px -10px color-mix(in srgb, var(--gn-accent) 75%, transparent), inset 0 0 0 1px rgba(255, 240, 225, .14);
}
.gt-nudge {
  position: fixed; left: 50%; bottom: 22px; transform: translateX(-50%); z-index: 470;
  display: inline-flex; align-items: center; gap: 9px; padding: 12px 22px; border-radius: 999px; cursor: pointer;
  font: 800 15px/1 var(--gn-body); color: var(--gn-accent-ink); background: var(--gn-accent); border: 0;
  box-shadow: 0 14px 30px -8px rgba(0, 0, 0, .8); animation: gt-nudge-in .4s var(--gn-ease) both;
}
.gt-nudge[hidden] { display: none; }
@keyframes gt-nudge-in { from { opacity: 0; transform: translate(-50%, 16px); } }
@media (max-width: 640px) {
  .gt[data-gt-mode="play"] .gn-logo-h1 img { height: 44px; }
  .gt[data-gt-mode="play"] [data-t-news] { padding: 10px 12px; }
  .gt-howbtn span { display: none; }
  .gt-nudge { bottom: 84px; }
}
@media (prefers-reduced-motion: reduce) {
  .gt-turn.is-mine, .gt-nudge { animation: none; }
}

/* ── The game on one screen (gn-table.js applyFit, gn-clock.js) ──────────
   The DM's playtest, on a PC monitor at full screen: "all the information
   that the game needs, you can see ... that everything has a place". A page
   that opts in (data-gt-fit) gets .is-fit on its .gt while a game is played
   or just over, and body.gn-fit, on a screen at least 1200x700. Then the
   page is exactly one window tall: the news bar across the top, and each
   game's own stylesheet places its panels in the grid below. Nothing
   scrolls but a list inside its own box (the log, a chat). Each game is laid
   out its own way; what is here is only what they all share. */
body.gn-fit .gn-mast { height: 52px; }
body.gn-fit .fx-main.gn-main { max-width: 1880px; padding: 0 20px 16px; }
.gt.is-fit {
  --fit-h: calc(100dvh - 68px);
  height: var(--fit-h); box-sizing: border-box; display: grid; gap: 14px;
  grid-template-columns: minmax(0, 1fr) 340px; grid-template-rows: auto minmax(0, 1fr);
  grid-template-areas: "status status" "stage side";
}
.gt.is-fit .gt-grid, .gt.is-fit .gt-col { display: contents; }
.gt.is-fit > :is(div, header):has(.gn-h1) { display: none; }
.gt.is-fit > *, .gt.is-fit .gt-col > * { min-width: 0; min-height: 0; margin: 0 !important; }
.gt.is-fit .gn-panel { padding: 16px 18px; overflow: auto; }
.gt.is-fit .gn-panel > .gn-h2:first-child { font-size: 16px; margin: 0 0 10px; }
.gt.is-fit .gt-felt { display: none; }
.gt.is-fit .gt-seatpanel { grid-area: side; }
.gt.is-fit [data-t-log] { grid-area: side; }

/* The news bar: the game's logo, what just happened, whose turn, the clock. */
.gt-news-body, .gt-news-tools { display: contents; }
.gt-news-clock { flex: 1 1 100%; }
.gt-news-logo, .gt-news-title { display: none; }
.gt.is-fit [data-t-news] { grid-area: status; position: relative; top: auto; z-index: 60; padding: 8px 12px 8px 14px; }
.gt.is-fit .gt-news { flex-wrap: nowrap; gap: 18px; }
.gt.is-fit .gt-news-body { display: flex; align-items: center; gap: 16px; flex: 1 1 auto; min-width: 0; }
.gt.is-fit .gt-news-tools { display: flex; gap: 8px; flex: 0 0 auto; }
.gt.is-fit .gt-news-clock { flex: 0 1 420px; min-width: 240px; }
.gt.is-fit .gt-news-clock[hidden] { display: none; }
.gt.is-fit .gt-news-logo { display: block; height: 46px; width: auto; flex: 0 0 auto; filter: drop-shadow(0 6px 10px rgba(0, 0, 0, .45)); }
.gt.is-fit .gt-news-title { display: block; flex: 0 0 auto; font: 700 20px/1 var(--gn-display); color: var(--gn-chair); }
.gt.is-fit .gt-news-main { flex: 1 1 auto; gap: 3px; }
.gt.is-fit .gt-news p { font-size: clamp(16px, 1.25vw, 20px); overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.gt.is-fit .gt-turn { flex: 0 0 auto; white-space: nowrap; }
.gt.is-fit .gt-turn.is-mine { padding: 11px 20px; font-size: 17px; animation: gt-mine 1.6s ease-out infinite; }
.gt-menubtn { padding: 8px 11px; }

/* "Leave / Stop" behind the ⋯ button, and "How to play", float over the game. */
.gt.is-fit [data-t-run]:not(.is-open) { display: none !important; }
.gt.is-fit [data-t-run].is-open {
  position: fixed; top: 132px; right: 26px; z-index: 460; width: 360px; box-sizing: border-box;
  box-shadow: 0 30px 60px -20px rgba(0, 0, 0, .9); border-color: var(--gn-line-2); animation: gn-pop .18s var(--gn-ease);
}
/* A game just ended: "Play again" waits at the bottom of the screen. */
.gt.is-fit[data-gt-mode="over"] [data-t-lobby] {
  position: fixed; left: 50%; bottom: 18px; transform: translateX(-50%); z-index: 80;
  display: flex; align-items: center; gap: 18px; padding: 12px 14px 12px 22px; border-radius: 999px;
  border-color: var(--gn-accent-line); box-shadow: 0 24px 50px -16px rgba(0, 0, 0, .9);
}
.gt.is-fit[data-gt-mode="over"] [data-t-lobby] .gn-h2 { margin: 0; font-size: 16px; white-space: nowrap; }
.gt.is-fit[data-gt-mode="over"] [data-t-lobby] .gn-note { display: none; }

/* The Players panel as a list: a row each, whose turn marked down the side. */
.gt.is-fit .gt-seatpanel { display: flex; flex-direction: column; }
.gt.is-fit .gt-seatpanel > [data-t-seats] { flex: 1 1 auto; min-height: 0; overflow-y: auto; margin: 0 -6px; padding: 0 6px; }
.gt.is-fit .gt-seatpanel .gt-seats { display: flex; flex-direction: column; gap: 6px; }
.gt.is-fit .gt-seatpanel .gt-seat {
  flex-direction: row; flex-wrap: wrap; align-items: center; gap: 1px 8px; min-height: 50px; box-sizing: border-box;
  padding: 7px 64px 7px 58px; text-align: left; border-radius: 12px;
}
.gt.is-fit .gt-seatpanel button.gt-seat:hover { transform: none; }
.gt.is-fit .gt-seatpanel .gt-face { position: absolute; left: 10px; top: 50%; margin-top: -18px; width: 36px; height: 36px; font-size: 15px; }
.gt.is-fit .gt-seatpanel .gt-who { flex: 1 1 100%; font-size: 14.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.gt.is-fit .gt-seatpanel .gt-badges { top: 50%; right: 12px; transform: translateY(-50%); }
.gt.is-fit .gt-seatpanel .gt-kick { top: 50%; left: auto; right: 38px; transform: translateY(-50%); }
.gt.is-fit .gt-seatpanel .gt-away { margin: 0; }
.gt.is-fit .gt-seatpanel .gt-drop { bottom: 50%; transform: translateY(50%); right: 40px; }
.gt.is-fit .gt-seatpanel .gt-seat.is-turn::before {
  content: ''; position: absolute; left: 0; top: 9px; bottom: 9px; width: 4px; border-radius: 0 4px 4px 0;
  background: var(--gn-chair); box-shadow: 0 0 12px 1px var(--gn-chair);
}
.gt-seat.is-thinking .gt-who::after { content: ' \2022\2022\2022'; letter-spacing: 1px; color: var(--gn-chair); animation: gt-think 1.4s ease-in-out infinite; }
@keyframes gt-think { 50% { opacity: .25; } }

/* The log fills its box and scrolls inside it; the newest line lights up. */
.gt.is-fit .gt-log { display: flex; flex-direction: column; overflow: hidden; }
.gt.is-fit .gt-log ul { flex: 1 1 auto; min-height: 0; max-height: none; overflow-y: auto; }
.gt.is-fit .gt-log li { padding: 7px 0; font-size: 14px; }
.gt-log li.is-new { animation: gt-log-new 2.6s ease-out; }
@keyframes gt-log-new { from { background: var(--gn-accent-soft); box-shadow: -10px 0 0 var(--gn-accent-soft), 10px 0 0 var(--gn-accent-soft); color: var(--gn-accent-hi); } }

/* Tabs: panels that share one box on the one-screen layout (gn-table.js). */
[data-gt-tabs] { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.gt-tabbar { display: none; }
.is-fit [data-gt-tabs] {
  gap: 0; overflow: hidden; background: var(--gn-raise); border: 1px solid var(--gn-line);
  border-radius: var(--gn-r-panel); box-shadow: var(--gn-shadow);
}
.is-fit [data-gt-tabs].is-empty { display: none; }
.is-fit .gt-tabbar { display: flex; flex: 0 0 auto; gap: 2px; padding: 6px 10px 0; border-bottom: 1px solid var(--gn-line); overflow-x: auto; }
.gt-tabbar button {
  position: relative; padding: 9px 11px 10px; border: 0; border-bottom: 2px solid transparent; background: none; cursor: pointer;
  font: 700 13.5px/1 var(--gn-body); color: var(--gn-mute); white-space: nowrap; transition: color .2s, border-color .2s;
}
.gt-tabbar button:hover { color: var(--gn-ink); }
.gt-tabbar button.is-on { color: var(--gn-ink); border-bottom-color: var(--gn-accent); }
.gt-tabdot { position: absolute; top: 5px; right: 2px; width: 7px; height: 7px; border-radius: 50%; background: var(--gn-accent); }
.is-fit [data-gt-tabs] > [data-gt-tab] {
  display: none; flex: 1 1 auto; min-height: 0; overflow: auto; margin: 0 !important;
  border: 0; border-radius: 0; box-shadow: none; background: none;
}
.is-fit [data-gt-tabs] > [data-gt-tab].is-on:not([hidden]) { display: flex; flex-direction: column; }
.is-fit [data-gt-tabs] > [data-gt-tab] > :is(.gn-h2, h2):first-child { display: none; }

/* ── The clock (gn-clock.js): a bar that drains, and the seconds ───────── */
.gn-clock { display: flex; align-items: center; gap: 12px; min-width: 0; }
.gn-clock[hidden] { display: none !important; }
.gn-clock-track {
  position: relative; flex: 1 1 auto; height: 12px; border-radius: 999px; overflow: hidden;
  background: rgba(255, 240, 225, .07); box-shadow: inset 0 0 0 1px var(--gn-line);
}
.gn-clock-fill {
  position: absolute; inset: 0; border-radius: inherit; transform-origin: left center;
  background: linear-gradient(90deg, var(--gn-chair), var(--gn-accent-hi));
  box-shadow: 0 0 12px rgba(244, 162, 91, .35); transition: transform .25s linear;
}
.gn-clock-num {
  flex: 0 0 auto; min-width: 2.4ch; text-align: right; font: 800 30px/1 var(--gn-display); letter-spacing: -.02em;
  color: var(--gn-ink); font-variant-numeric: tabular-nums; transition: color .3s;
}
.gn-clock.is-low .gn-clock-fill { background: linear-gradient(90deg, #d9772a, #f39a45); box-shadow: 0 0 14px rgba(243, 154, 69, .45); }
.gn-clock.is-low .gn-clock-num { color: #f5a55a; }
.gn-clock.is-urgent .gn-clock-fill { background: linear-gradient(90deg, #d8433f, #ff6d5c); box-shadow: 0 0 18px rgba(255, 90, 75, .6); }
.gn-clock.is-urgent .gn-clock-track { animation: gn-clock-throb 1s ease-in-out infinite; }
.gn-clock.is-urgent .gn-clock-num { color: #ff7a68; animation: gn-clock-beat 1s ease-in-out infinite; }
.gn-clock.is-out .gn-clock-num { color: var(--gn-bad); font-size: 22px; }
@keyframes gn-clock-beat { 0%, 100% { transform: scale(1); } 15% { transform: scale(1.22); } }
@keyframes gn-clock-throb { 50% { box-shadow: inset 0 0 0 1px rgba(255, 109, 92, .6), 0 0 16px 2px rgba(255, 90, 75, .35); } }
.gn-clock--thin { gap: 0; }
.gn-clock--thin .gn-clock-track { height: 5px; }

/* ── It needs you (gn-table.js attention, gn-clock.js GNTurn) ────────────
   What you have to press breathes a warm glow; while it is your turn the
   edge of the whole window glows too. --gn-turn changes the colour (Codenames
   uses the team's). */
.gn-attn { animation: gn-attn 1.8s ease-in-out infinite; }
@keyframes gn-attn {
  0%, 100% { box-shadow: 0 0 0 2px color-mix(in srgb, var(--gn-turn, var(--gn-accent)) 85%, transparent), 0 0 14px 2px color-mix(in srgb, var(--gn-turn, var(--gn-accent)) 30%, transparent); }
  50% { box-shadow: 0 0 0 4px color-mix(in srgb, var(--gn-turn, var(--gn-accent)) 55%, transparent), 0 0 32px 8px color-mix(in srgb, var(--gn-turn, var(--gn-accent)) 50%, transparent); }
}
body.gn-myturn::after {
  content: ''; position: fixed; inset: 0; z-index: 445; pointer-events: none;
  box-shadow: inset 0 0 0 3px color-mix(in srgb, var(--gn-turn, var(--gn-accent)) 80%, transparent),
    inset 0 0 70px 4px color-mix(in srgb, var(--gn-turn, var(--gn-accent)) 26%, transparent);
  animation: gn-frame 2.6s ease-in-out infinite;
}
@keyframes gn-frame { 50% { opacity: .4; } }

/* On one screen the dice and the music move up beside your picture, so the
   corners of the table stay clear. */
body.gn-fit .gd { top: 6px; bottom: auto; right: 94px; flex-direction: column-reverse; }
body.gn-fit .gm { top: 6px; bottom: auto; left: auto; right: 144px; flex-direction: column-reverse; align-items: flex-end; }
body.gn-fit .gd-open, body.gn-fit .gm-open { width: 40px; height: 40px; font-size: 18px; }
body.gn-fit .gd-cards { top: 64px; bottom: auto; }
.gt:not(.is-fit) .gt-menubtn { display: none; }

/* ── Somebody won (gn-win.js) ─────────────────────────────────────────── */
.gn-win {
  position: fixed; inset: 0; z-index: 95; display: grid; place-items: center; padding: 16px;
  background: radial-gradient(ellipse at center, rgba(12, 11, 13, .7), rgba(12, 11, 13, .9));
  cursor: pointer; animation: gn-win-fade .3s ease both;
}
.gn-win.is-out { animation: gn-win-out .3s ease both; }
.gn-win-card {
  position: relative; display: flex; flex-direction: column; align-items: center; gap: 14px;
  max-width: 560px; text-align: center; animation: gn-win-slam .6s cubic-bezier(.2, 1.35, .4, 1) both;
}
.gn-win-card h2 { margin: 0; font: 800 clamp(30px, 5.4vw, 54px)/1.05 var(--gn-display); letter-spacing: -.02em; color: var(--gn-ink); }
.gn-win.is-mine .gn-win-card h2 { color: var(--gn-accent); }
.gn-win-card p { margin: 0; font: 600 17px/1.4 var(--gn-body); color: var(--gn-dim); }
.gn-win-card small { font: 600 13px/1 var(--gn-body); color: var(--gn-mute); }
.gn-win-faces { display: flex; justify-content: center; flex-wrap: wrap; gap: 10px; }
.gn-win-face {
  width: 92px; height: 92px; border-radius: 50%; overflow: hidden; display: grid; place-items: center;
  background: var(--gn-raise-3); color: var(--gn-ink); font: 800 36px/1 var(--gn-display);
  box-shadow: 0 0 0 4px var(--gn-chair), 0 0 34px 6px rgba(212, 155, 75, .35);
}
.gn-win-faces:has(.gn-win-face:nth-child(3)) .gn-win-face { width: 70px; height: 70px; font-size: 28px; }
.gn-win-face img { width: 100%; height: 100%; object-fit: cover; display: block; }
.gn-win-face--icon { color: var(--gn-accent); font-size: 38px; }
.gn-win-burst { position: absolute; left: 50%; top: 46px; width: 0; height: 0; pointer-events: none; }
.gn-win-burst i {
  position: absolute; width: 9px; height: 14px; border-radius: 2px; background: var(--c);
  transform: rotate(var(--a)) translateY(0) scale(var(--s)); opacity: 0;
  animation: gn-win-bit 1.5s cubic-bezier(.15, .7, .4, 1) .15s both;
}
@keyframes gn-win-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes gn-win-out { to { opacity: 0; } }
@keyframes gn-win-slam { from { transform: scale(1.3) translateY(-18px); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes gn-win-bit {
  0% { opacity: 1; transform: rotate(var(--a)) translateY(0) scale(var(--s)); }
  100% { opacity: 0; transform: rotate(var(--a)) translateY(calc(var(--d) * -1)) rotate(220deg) scale(var(--s)); }
}
@media (prefers-reduced-motion: reduce) {
  .gn-win, .gn-win.is-out, .gn-win-card, .gn-win-burst i { animation: none; }
}
