* { box-sizing: border-box; margin: 0; padding: 0; }

:root {
  --brand: #6366f1;
  --brand-2: #818cf8;
  --p1: #6366f1;
  --p2: #ec4899;
  --bg: #f1f5f9;
  --panel: #ffffff;
  --ink: #0f172a;
  --muted: #64748b;
  --faint: #94a3b8;
  --line: #e2e8f0;
  --chip: #eef2ff;
  --ok: #16a34a;
  --bad: #ef4444;
  --shadow: 0 8px 30px rgba(15, 23, 42, .08);
}
html.dark {
  --bg: #171717;
  --panel: #262626;
  --ink: #f8fafc;
  --muted: #a1a1aa;
  --faint: #71717a;
  --line: #3f3f46;
  --chip: #312e81;
  --shadow: 0 8px 30px rgba(0, 0, 0, .45);
}

body {
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  background: var(--bg);
  color: var(--ink);
  min-height: 100vh;
  transition: background .25s ease, color .25s ease;
}

.hidden { display: none !important; }
/* hides an element while keeping the space it occupies (no layout shift) */
.is-invisible { visibility: hidden !important; }

/* ---------- app shell ---------- */
#app { min-height: 100vh; display: flex; flex-direction: column; }

/* LEVELKANA AD — compact chip inline in the header row (scoreboard).
   Fixed short copy, nowrap, never flex-grows and never wraps, so it can
   NEVER add vertical space or push the scores around. Full copy in tooltip. */
.lk-ad {
  flex: 0 1 auto;
  min-width: 0;
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  font-size: .78rem;
  font-weight: 600;
  line-height: 1;
  color: var(--brand);
  text-decoration: none;
  white-space: nowrap;
  overflow: hidden;
  padding: .3rem .35rem .3rem .45rem;
  border: 1px solid transparent;
  border-radius: 999px;
  background: #eef2ff;
  border-color: #e0e7ff;
  background: color-mix(in srgb, var(--brand) 8%, transparent);
  border-color: color-mix(in srgb, var(--brand) 18%, transparent);
  cursor: pointer;
  transition: background .15s ease, border-color .15s ease, transform .15s ease;
}
.lk-ad:hover {
  background: #e0e7ff;
  background: color-mix(in srgb, var(--brand) 15%, transparent);
  border-color: color-mix(in srgb, var(--brand) 40%, transparent);
  transform: translateY(-1px);
}
.lk-badge { font-size: .85rem; line-height: 1; }
.lk-text {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--muted);
  font-weight: 600;
}
.lk-text b { color: var(--brand); font-weight: 800; }
.lk-cta {
  flex: none;
  background: var(--brand);
  color: #fff;
  font-weight: 800;
  font-size: .7rem;
  letter-spacing: .01em;
  padding: .22rem .5rem;
  border-radius: 999px;
}
html.dark .lk-ad {
  background: rgba(99, 102, 241, .14);
  border-color: rgba(99, 102, 241, .35);
}
html.dark .lk-ad:hover {
  background: rgba(99, 102, 241, .24);
  border-color: #818cf8;
}
html.dark .lk-text b { color: #a5b4fc; }
html.dark .lk-cta { background: #6366f1; color: #fff; }

/* screens fill the space below the header */
.screens { flex: 1; min-height: 0; display: flex; flex-direction: column; }

.screen { max-width: 1100px; margin: 0 auto; padding: 1rem; }

/* round screen: full-height flex column so the disks can GROW to fill the
   available space, and the sign-off zone below keeps a FIXED height so the
   layout never jumps when the reveal/award/next elements appear. */
#screen-round {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  width: 100%;
  /* let the round screen use the full width so the two disks can be big */
  max-width: min(100%, 1700px);
}

/* ---------- branding ---------- */
.brand { display: flex; flex-direction: column; align-items: center; gap: .6rem; }
/* brand is a link to levelkana.com — reset anchor defaults */
a.brand, a.brand-mini { text-decoration: none; color: inherit; cursor: pointer; }
a.brand:hover, a.brand-mini:hover { opacity: .8; }
.brand-logo { width: 74px; height: auto; }
.logo {
  font-size: 2.6rem; font-weight: 900; letter-spacing: -.02em;
  color: var(--ink);
}
.logo .logo-sub { color: var(--brand); }
.brand-mini { display: flex; align-items: center; gap: .45rem; }
.brand-logo-sm { width: 30px; height: auto; }
.brand-name { font-weight: 900; font-size: 1rem; white-space: nowrap; }
.brand-name .logo-sub { color: var(--brand); }

.theme-toggle {
  position: fixed; top: .9rem; right: .9rem; z-index: 50;
  width: 44px; height: 44px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--panel);
  font-size: 1.2rem; cursor: pointer; box-shadow: var(--shadow);
}
.scoreboard .theme-toggle { position: static; width: 38px; height: 38px; font-size: 1rem; }
.theme-toggle.card-toggle { position: absolute; top: .9rem; right: .9rem; }
.start-card { position: relative; }

/* ---------- start / final ---------- */
.start-card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 20px;
  box-shadow: var(--shadow);
  padding: 2.5rem 2rem;
  text-align: center;
  max-width: 640px;
  margin: 5vh auto;
}
.tagline { font-size: 1.15rem; margin: 1rem 0 1.25rem; }
.rules { font-size: .9rem; color: var(--muted); margin: 1rem 0 1.5rem; line-height: 1.5; }
.names { display: flex; gap: 1rem; justify-content: center; flex-wrap: wrap; margin-bottom: .5rem; }
.names label { font-weight: 600; display: flex; flex-direction: column; gap: .3rem; text-align: left; }
.names input {
  font-size: 1rem; padding: .55rem .8rem; border: 2px solid var(--line);
  border-radius: 10px; width: 180px; background: var(--bg); color: var(--ink);
}
.names input:focus { outline: none; border-color: var(--brand); }
.deck-info { margin-top: 1rem; font-size: .85rem; color: var(--faint); }
.final-result { font-size: 1.6rem; font-weight: 700; margin: 1rem 0 .4rem; }
.final-scores { color: var(--muted); margin-bottom: 1.5rem; }

button.big {
  font-size: 1.25rem; font-weight: 700;
  background: linear-gradient(90deg, var(--brand), var(--brand-2));
  color: #fff; border: none; border-radius: 14px;
  padding: .9rem 2.2rem; cursor: pointer;
  box-shadow: 0 4px 14px rgba(99, 102, 241, .35);
  transition: transform .08s ease;
}
button.big:active { transform: scale(.97); }
/* disabled while the icons preload — the game can't start without them */
button.big:disabled { opacity: .5; cursor: progress; }
button.big:disabled:active { transform: none; }

/* ---------- scoreboard ---------- */
.scoreboard {
  display: flex; align-items: center; justify-content: space-between;
  gap: .6rem; background: var(--panel); border: 1px solid var(--line);
  border-radius: 14px;
  padding: .55rem 1rem; margin-bottom: .6rem;
  box-shadow: var(--shadow);
}
.player { display: flex; align-items: center; gap: .6rem; font-weight: 700; font-size: 1.05rem; }
.pscore {
  background: var(--chip); color: var(--brand);
  border-radius: 999px; min-width: 2.2rem;
  text-align: center; padding: .15rem .5rem; font-size: 1.1rem;
}
.player.p1 { color: var(--p1); }
.player.p2 { color: var(--p2); }
.round-info { color: var(--faint); font-weight: 600; }

.hint {
  text-align: center; font-weight: 600; font-size: 1rem;
  color: var(--brand); padding: .4rem; margin-bottom: .5rem;
}

/* ---------- disks ----------
   .disks is the flex-grow region: it takes ALL leftover vertical space and
   centers the disks in it. Disk size is capped by BOTH the width and the
   available height, so the disks use as much space as possible and still fit
   without scrolling (no scrollbar → no reflow). The high-res 1024px source
   stays crisp at any of these sizes. */
.disks {
  flex: 1 1 auto;
  min-height: 0;
  display: flex; align-items: center; justify-content: center;
  gap: 1.25rem;
}
.disk-wrap {
  /* fill as much of the measured .disks region (--avail) as possible,
     capped by width and a sane max (the 2048px source stays crisp well beyond).
     --avail is set by JS via ResizeObserver. */
  width: min(49vw, 900px, calc(var(--avail, 60vh) - 10px));
}
/* square box: the hotspots overlay must map 1:1 onto the 2048x2048 disk image.
   No caption/label below the disk, so the overlay stays aligned. */
.disk-box { position: relative; aspect-ratio: 1 / 1; }
.disk-img {
  width: 100%; height: 100%; display: block;
  background: transparent;
  filter: drop-shadow(0 8px 24px rgba(0,0,0,.16));
}
html.dark .disk-img { filter: drop-shadow(0 8px 24px rgba(0,0,0,.55)); }
.vs {
  font-weight: 800; font-size: 1.5rem; color: var(--faint);
}

/* ---------- hotspots ---------- */
.hotspots { position: absolute; inset: 0; }
.hotspot {
  position: absolute; border: none; background: transparent;
  cursor: pointer; border-radius: 12px; min-width: 44px; min-height: 44px;
  transition: background .1s, box-shadow .1s;
}
.hotspot:hover { background: rgba(99, 102, 241, .14); }
.hotspot:focus-visible { outline: 3px solid var(--brand); outline-offset: 2px; }
.hotspot.shared {
  box-shadow: inset 0 0 0 4px var(--ok), 0 0 0 3px var(--ok);
  background: rgba(22, 163, 74, .18);
  animation: pulse 1s ease-in-out infinite;
}
.hotspot.pick-ok { box-shadow: inset 0 0 0 4px var(--ok); background: rgba(22, 163, 74, .2); }
.hotspot.pick-bad { box-shadow: inset 0 0 0 4px var(--bad); background: rgba(239, 68, 68, .15); }

@keyframes pulse { 50% { background: rgba(22, 163, 74, .34); } }

/* ---------- bottom bar (always visible) ----------
   A fixed-height bar at the bottom that ALWAYS shows: the result text (empty
   until the answer is revealed) + the score buttons + the Next button. The
   score buttons are disabled (greyed) until the answer is given. Because the
   bar's height never changes, the disks keep their exact size — no jump. */
.bottombar {
  flex: 0 0 auto;
  min-height: 108px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: .5rem;
  padding: .5rem 1rem .9rem;
}
.bb-row { display: flex; flex-direction: column; align-items: center; gap: .5rem; }
/* ---------- round-result notification (floating, non-blocking) ----------
   position:fixed so it never affects the round screen layout. No dimmed
   overlay and pointer-events:none, so it never blocks the score buttons. */
.result-toast {
  position: fixed;
  top: 4.4rem;
  left: 50%;
  transform: translateX(-50%) translateY(-10px);
  z-index: 100;
  max-width: 90vw;
  padding: .7rem 1.5rem;
  border-radius: 999px;
  font-weight: 800;
  font-size: 1.1rem;
  color: #fff;
  text-align: center;
  box-shadow: 0 12px 34px rgba(0, 0, 0, .28);
  opacity: 0;
  pointer-events: none;
  transition: opacity .2s ease, transform .2s ease;
}
.result-toast:not(.hidden) { opacity: 1; transform: translateX(-50%) translateY(0); }
.result-toast.ok { background: var(--ok); }
.result-toast.bad { background: var(--bad); }

.score-btns { display: flex; gap: .8rem; justify-content: center; flex-wrap: wrap; }
.score-btn {
  font-size: 1.05rem; font-weight: 700; padding: .7rem 1.4rem;
  border: none; border-radius: 12px; cursor: pointer; color: #fff;
  background: #52525b;
  transition: transform .08s ease, opacity .15s ease, filter .15s ease;
}
.score-btn.s1 { background: var(--p1); }
.score-btn.s2 { background: var(--p2); }
.score-btn.draw { background: #71717a; }
.score-btn:active:not(:disabled) { transform: scale(.97); }
.score-btn:disabled {
  cursor: not-allowed;
  opacity: .4;
  filter: grayscale(.5);
}
/* Next: always visible, sits next to Player 2 with a bit of space.
   Distinct outline style so it reads as "advance" rather than "award". */
.score-btn.next {
  margin-left: .7rem;
  color: var(--brand);
  background: transparent;
  border: 2px solid var(--brand);
}
.score-btn.next:disabled {
  color: var(--brand);
  border-color: var(--brand);
  opacity: .35;
  filter: none;
}
.score-btn.next:not(:disabled) { background: var(--brand); color: #fff; }

/* ---------- congrats / game-over toast ----------
   A floating notification. position:fixed + high z-index means it overlays
   the round screen WITHOUT affecting its layout (disks keep their size). */
.toast {
  position: fixed;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%) scale(.96);
  z-index: 100;
  min-width: min(88vw, 380px);
  padding: 1.6rem 1.8rem 1.5rem;
  border-radius: 18px;
  background: var(--panel);
  border: 1px solid var(--line);
  box-shadow: 0 20px 60px rgba(0, 0, 0, .35);
  text-align: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity .2s ease, transform .2s ease;
}
.toast:not(.hidden) { opacity: 1; pointer-events: auto; transform: translate(-50%, -50%) scale(1); }
/* dim the game behind the toast (also non-layout-affecting) */
body:has(.toast:not(.hidden))::after {
  content: "";
  position: fixed; inset: 0;
  background: rgba(0, 0, 0, .45);
  z-index: 99;
}
.toast-close {
  position: absolute; top: .5rem; right: .6rem;
  border: none; background: transparent;
  font-size: 1.1rem; color: var(--muted); cursor: pointer;
  padding: .2rem .4rem; border-radius: 8px;
}
.toast-close:hover { background: var(--line); color: var(--ink); }
.toast-title { font-size: 1.7rem; font-weight: 800; margin-bottom: .4rem; }
.toast-result { font-size: 1.3rem; font-weight: 700; color: var(--brand); margin: 0 0 .3rem; }
.toast-scores { font-size: 1rem; color: var(--muted); margin: 0 0 1.1rem; }
.toast .big { min-width: 180px; }

/* ---------- mobile ---------- */
@media (max-width: 700px) {
  .disks { flex-direction: column; align-items: center; gap: .6rem; }
  /* stacked: each disk capped by width AND by half the available height */
  .disk-wrap { width: min(86vw, 420px, calc((100vh - 400px) / 2 * 0.96)); }
  .logo { font-size: 2rem; }
  /* header ad: chip shrinks to just the icon + CTA on narrow screens */
  .lk-text { display: none; }
  .lk-ad { flex: none; font-size: .7rem; padding: .28rem .32rem .28rem .42rem; }
  .scoreboard { font-size: .85rem; flex-wrap: wrap; justify-content: center; }
  .brand-name { display: none; }
  .bottombar { min-height: 150px; }
}
