/* Mobile-first: base rules target a narrow portrait phone. The single @media (min-width)
   block near the bottom is the ONLY place desktop/tablet layout is widened -- everything
   above must look right on its own with no media query applied. */

:root {
  --bg:#fbfbfa; --fg:#1c1b19; --muted:#6b6862; --line:#e2dfd8;
  --card:#fff; --accent:#7a5c3e; --us:#2f6f9f; --cn:#b4453c; --ru:#7a5c3e;
  --good:#3a8a5c; --bad:#b4453c;
}
@media (prefers-color-scheme: dark) {
  :root { --bg:#16151a; --fg:#eceaf0; --muted:#9a96a3; --line:#2c2a33;
    --card:#1d1c22; --accent:#c9a227; --us:#7ab4dd; --cn:#e8877e; --ru:#d8b45e;
    --good:#6fbf8f; --bad:#e8877e; }
}
:root[data-theme="dark"] { --bg:#16151a; --fg:#eceaf0; --muted:#9a96a3; --line:#2c2a33;
    --card:#1d1c22; --accent:#c9a227; --us:#7ab4dd; --cn:#e8877e; --ru:#d8b45e;
    --good:#6fbf8f; --bad:#e8877e; }
:root[data-theme="light"] { --bg:#fbfbfa; --fg:#1c1b19; --muted:#6b6862; --line:#e2dfd8;
    --card:#fff; --accent:#7a5c3e; --us:#2f6f9f; --cn:#b4453c; --ru:#7a5c3e;
    --good:#3a8a5c; --bad:#b4453c; }

* { box-sizing:border-box; }
html, body { margin:0; height:100%; }
body {
  background:var(--bg); color:var(--fg);
  font:16px/1.5 ui-serif, Georgia, "Iowan Old Style", serif;
  overscroll-behavior-y:contain;
}
.app { max-width:480px; margin:0 auto; padding:18px 16px 40px; }

.mute-toggle { position:fixed; top:12px; right:12px; z-index:40; width:38px; height:38px;
  border-radius:50%; border:1px solid var(--line); background:var(--card); color:var(--fg);
  display:flex; align-items:center; justify-content:center; cursor:pointer;
  -webkit-tap-highlight-color:transparent; }
.mute-toggle .mute-slash { display:none; }
.mute-toggle.muted .mute-waves { opacity:.3; }
.mute-toggle.muted .mute-slash { display:block; }
h1 { font-size:1.5rem; line-height:1.2; margin:0 0 .5em; letter-spacing:-.01em; }
h2 { font-size:1.1rem; margin:1.4em 0 .5em; }
.hidden { display:none !important; }
.center-title { text-align:center; }

/* ---- title splash (prologue screen 1) ----
   Breaks out of .app's 480px column and padding to sit full-bleed against the viewport --
   it's cover art, and letterboxing it inside the normal text column would look like a
   mistake. The 100vw/50% trick re-centres it on the viewport rather than the column.
   Uses dvh, not vh, so mobile browser chrome appearing/disappearing doesn't crop it. */
/* position:fixed rather than breaking out of .app with negative margins -- it's a
   full-screen splash, so it should ignore the column's width AND its 18px/40px vertical
   padding (which otherwise leaves pale strips above and below the art). z-index sits below
   .mute-toggle's 40 so the player can still mute before the narration starts. */
#screen-title {
  position:fixed; inset:0; z-index:30;
  display:flex; align-items:center; justify-content:center;
  overflow:hidden; cursor:pointer; -webkit-tap-highlight-color:transparent;
  /* Fixed dark backdrop, deliberately NOT var(--bg): this screen is full-bleed artwork,
     not a themed UI surface, and in light mode a near-white --bg turns the letterboxing
     (see the aspect-ratio rule below) into bright bars either side of very dark art. This
     tone is picked to sit close to the poster's own edges so the bars read as intentional. */
  background:#0c1018;
}
/* The art is 2:3 portrait (0.667). On a phone (~0.46) `cover` trims a little off each side
   and fills the screen edge to edge, which is what a splash should do. */
.titleart { width:100%; height:100%; object-fit:cover; object-position:center;
  user-select:none; -webkit-user-drag:none; }
/* Once the viewport is WIDER than the art itself, `cover` stops trimming a little off the
   sides and starts zooming hard into the middle -- on a desktop window it crops away the
   globe, flags and silhouettes and leaves nothing but oversized lettering. Past that point
   show the whole poster instead and let the page background letterbox it; the art's own
   background is dark, so it reads as deliberate rather than as bars. */
@media (min-aspect-ratio: 2/3) {
  .titleart { object-fit:contain; }
}
/* Only shown when audio was blocked and a tap is genuinely needed (see app.js). */
.titlehint {
  position:absolute; left:50%; bottom:9%; transform:translateX(-50%);
  display:flex; align-items:center; gap:8px; padding:10px 16px; border-radius:999px;
  background:rgba(0,0,0,.62); color:#fff; border:1px solid rgba(255,255,255,.25);
  font:600 .95rem/1 ui-sans-serif, system-ui, sans-serif; white-space:nowrap;
  backdrop-filter:blur(4px); animation:titlehintpulse 1.8s ease-in-out infinite;
}
@keyframes titlehintpulse {
  0%, 100% { opacity:.75; transform:translateX(-50%) scale(1); }
  50%      { opacity:1;   transform:translateX(-50%) scale(1.045); }
}
@media (prefers-reduced-motion: reduce) {
  .titlehint { animation:none; opacity:1; }
}

.lede { color:var(--muted); font-size:.95rem; margin:0 0 1.2em; }

.btn {
  display:block; width:100%; padding:13px 18px; border-radius:11px; border:0;
  font:600 1rem/1.2 ui-sans-serif, system-ui, sans-serif; cursor:pointer;
  -webkit-tap-highlight-color:transparent;
}
.btn-primary { background:var(--accent); color:#fff; }
.btn-primary:active { opacity:.85; }
.btn-primary:disabled { opacity:.45; cursor:not-allowed; }
.btn-secondary { background:transparent; color:var(--accent); border:1.5px solid var(--line); margin-top:14px; }
.btnrow { display:flex; gap:10px; }
.btnrow .btn { flex:1 1 0; margin-top:0; }
/* "Play as <name>" carries a player-supplied name of up to nameMaxLen characters, which is
   easily wider than a phone -- clip it rather than letting the button grow or wrap. */
#startBtn { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* Sharing the row unequally: "Play as <someone's name>" is variable-length and is the
   action almost every tap wants, while "New player" is fixed and rare, so give the primary
   button the larger share instead of splitting 50/50 and truncating names needlessly. */
.introbtns #startBtn { flex:1.7 1 0; }
.introbtns #newPlayerBtn { flex:1 1 0; white-space:nowrap; }

/* colour semantics reused across the guess readout, reveal rows and result list --
   blue=USA favoured, red=rival favoured, neutral=dead even. */
.us-lean { color:var(--us); }
.rival-lean { color:var(--bad); }
.neutral { color:var(--fg); }

/* ---- intro ----
   (The name field that used to sit here is gone: players are auto-named server-side and
   rename themselves from the leaderboard afterwards, so nothing is typed before playing.) */
.weightcard { background:var(--card); border:1px solid var(--line); border-radius:12px;
  padding:16px; margin:0 0 20px; }
.weightrow { display:flex; align-items:center; gap:10px;
  font:600 .85rem/1 ui-sans-serif, system-ui, sans-serif; }
.weightrow b { white-space:nowrap; }
.lbl-cn { color:var(--cn); } .lbl-ru { color:var(--ru); }
#weightSlider { flex:1 1 auto; width:100%; height:6px; }
.weighthint { font:.8rem/1.5 ui-sans-serif, system-ui, sans-serif; color:var(--muted); margin:10px 0 0; }

input[type="range"] { -webkit-appearance:none; appearance:none; background:transparent; }
input[type="range"]::-webkit-slider-runnable-track { height:6px; border-radius:3px;
  background:linear-gradient(to right, var(--cn), var(--muted), var(--us)); }
input[type="range"]::-moz-range-track { height:6px; border-radius:3px;
  background:linear-gradient(to right, var(--cn), var(--muted), var(--us)); }
input[type="range"]::-webkit-slider-thumb { -webkit-appearance:none; width:22px; height:22px;
  border-radius:50%; background:var(--fg); border:3px solid var(--card);
  box-shadow:0 0 0 1px var(--fg); margin-top:-8px; cursor:pointer; }
input[type="range"]::-moz-range-thumb { width:22px; height:22px; border-radius:50%;
  background:var(--fg); border:3px solid var(--card); box-shadow:0 0 0 1px var(--fg); cursor:pointer; }
#weightSlider::-webkit-slider-runnable-track { background:linear-gradient(to right, var(--cn), var(--ru)); }
#weightSlider::-moz-range-track { background:linear-gradient(to right, var(--cn), var(--ru)); }
/* guess slider: left=USA favoured, right=rival favoured (see app.js's guessFromSlider) */
#guessSlider::-webkit-slider-runnable-track { background:linear-gradient(to right, var(--us), var(--muted), var(--bad)); }
#guessSlider::-moz-range-track { background:linear-gradient(to right, var(--us), var(--muted), var(--bad)); }

/* ---- round ---- */
.roundhead { text-align:center; margin:0 0 12px; }
.roundnum { display:block; font:600 .72rem/1 ui-sans-serif, system-ui, sans-serif;
  letter-spacing:.09em; text-transform:uppercase; color:var(--muted); margin:0 0 4px; }
.countryname { display:block; font-size:1.6rem; font-weight:600; }

.globewrap { position:relative; width:100%; aspect-ratio:900/700; border-radius:12px;
  overflow:hidden; background:#0e1116; margin:0 0 16px; border:1px solid var(--line); }
.globewrap iframe { position:absolute; inset:0; width:100%; height:100%; border:0; }
.globeloading { position:absolute; inset:0; display:flex; align-items:center; justify-content:center;
  color:#9a96a3; font:.85rem ui-sans-serif, system-ui, sans-serif; pointer-events:none; }

.guesscard, .revealcard { background:var(--card); border:1px solid var(--line);
  border-radius:12px; padding:16px; margin:0 0 14px; }

.timerwrap { display:flex; align-items:center; gap:10px; margin:0 0 14px; }
.timertrack { flex:1 1 auto; height:6px; border-radius:3px; background:var(--line); overflow:hidden; }
/* Colour is set inline per-tick from app.js (green -> yellow -> orange -> red as time runs
   out, see timerColorForFraction()) rather than a fixed CSS colour -- a continuous gradient
   isn't expressible as a static background. */
.timerfill { height:100%; border-radius:3px; background:hsl(140, 60%, 40%); }
.timertext { flex:0 0 auto; min-width:2.2em; text-align:right; font:700 .85rem/1 ui-sans-serif, system-ui, sans-serif;
  font-variant-numeric:tabular-nums; color:var(--muted); }
.timertext.urgent { color:var(--bad); }

.guesslabel { margin:0 0 10px; font:600 .88rem/1.4 ui-sans-serif, system-ui, sans-serif; }
.guessreadout { text-align:center; font-size:2rem; font-weight:700; font-variant-numeric:tabular-nums;
  margin:0 0 10px; }
#guessSlider { width:100%; margin:6px 0; }
.guessscale { display:flex; justify-content:space-between; font:.68rem/1 ui-sans-serif, system-ui, sans-serif;
  color:var(--muted); margin:0 0 16px; }

.revealrow { display:flex; justify-content:space-between; align-items:baseline;
  font:.95rem/1.6 ui-sans-serif, system-ui, sans-serif; }
.revealrow b { font-size:1.2rem; font-variant-numeric:tabular-nums; }

.comparebar { margin:16px 0 6px; }
.comparetrack { position:relative; height:8px; border-radius:4px;
  background:linear-gradient(to right, var(--us), var(--muted), var(--bad)); margin:0 0 5px; }
.comparemark { position:absolute; top:50%; width:15px; height:15px; border-radius:50%;
  transform:translate(-50%, -50%); box-sizing:border-box; }
.comparemark.guess { background:transparent; border:3px solid var(--fg); }
.comparemark.actual { background:var(--fg); border:2.5px solid var(--card); box-shadow:0 0 0 1px var(--fg); }
.comparelabels { display:flex; justify-content:space-between;
  font:.68rem/1 ui-sans-serif, system-ui, sans-serif; color:var(--muted); }

.revealpoints { text-align:center; font:700 1.4rem/1 ui-sans-serif, system-ui, sans-serif;
  color:var(--accent); margin:14px 0 16px; }

/* ---- summary ---- */
.commentary { color:var(--muted); font-size:.95rem; }
.commentary-line { display:block; font-weight:700; }
.commentary-line + .commentary-line { margin-top:4px; }
.resultlist { list-style:none; margin:0 0 20px; padding:0; }
.resultlist li { display:flex; justify-content:space-between; align-items:center; gap:10px;
  padding:10px 0; border-bottom:1px solid var(--line);
  font:.92rem/1.4 ui-sans-serif, system-ui, sans-serif; }
.resultlist li { transition:transform .5s ease; }
.resultlist .rname { font-weight:600; font-family:ui-serif, Georgia, serif; }
.resultlist .rratio { font-variant-numeric:tabular-nums; text-align:right; white-space:nowrap; }

.scorecard { display:flex; justify-content:space-between; align-items:baseline;
  background:var(--card); border:1px solid var(--line); border-radius:12px; padding:16px 18px;
  margin:0 0 18px; }
.scorelabel { font:600 .8rem/1 ui-sans-serif, system-ui, sans-serif; text-transform:uppercase;
  letter-spacing:.06em; color:var(--muted); }
.scoreval { font-size:2rem; font-weight:700; font-variant-numeric:tabular-nums; }

/* Rank is an explicit column now (server-supplied, see serve_game.py:_leaderboard_around),
   not a CSS counter -- once the list can have a gap, position-in-list no longer equals
   position-on-the-leaderboard, which a plain counter-increment would get wrong. */
.leaderlist { list-style:none; margin:0; padding:0; }
.leaderlist li { display:flex; align-items:baseline; gap:10px; padding:7px 0;
  border-bottom:1px solid var(--line); font:.92rem/1.4 ui-sans-serif, system-ui, sans-serif; }
.leaderlist .lrank { flex:0 0 1.8em; color:var(--muted); font-variant-numeric:tabular-nums; }
.leaderlist .lname { flex:1 1 auto; font-weight:400; }
.leaderlist .lscore { font-variant-numeric:tabular-nums; }
.leaderlist li.own-result, .leaderlist li.own-result * { font-weight:700; }
.leaderlist li.gap { justify-content:center; color:var(--muted); letter-spacing:.3em;
  padding:4px 0; border-bottom:0; }

/* ---- inline rename: your own name in the list IS the control ---- */
.leaderlist .lname.editable { cursor:pointer; -webkit-tap-highlight-color:transparent;
  /* dotted underline + pencil are the only affordance -- enough to read as tappable
     without turning a leaderboard row into a form. */
  text-decoration:underline dotted currentColor 1px; text-underline-offset:3px; }
.leaderlist .lpencil { margin-left:6px; opacity:.55; font-size:.85em; }
.leaderlist .lname.editable:hover .lpencil,
.leaderlist .lname.editable:focus-visible .lpencil { opacity:1; }
/* Sized to sit in the row without shifting the rank/score columns. 16px font because
   anything smaller makes iOS zoom the whole page when the field takes focus. */
.lnameinput { flex:1 1 auto; min-width:0; padding:2px 6px; margin:-3px 0;
  border-radius:6px; border:1.5px solid var(--accent); background:var(--bg); color:var(--fg);
  font:700 16px/1.4 ui-sans-serif, system-ui, sans-serif; }

/* ---- leaderboard modal ---- */
.modal-overlay { position:fixed; inset:0; background:rgba(0,0,0,.5);
  display:flex; align-items:flex-end; justify-content:center; z-index:50; }
/* max-height sized so all 15 leaderboard rows fit without scrolling on typical phone
   screens (verified down to a 375x667 viewport) -- overflow-y stays on as a safety net
   for unusually short screens or larger text-zoom, not because scrolling is expected. */
.modal-card { position:relative; background:var(--card); width:100%; max-width:480px;
  max-height:94vh; overflow-y:auto; border-radius:16px 16px 0 0;
  padding:18px 18px calc(18px + env(safe-area-inset-bottom, 0px)); }
.modal-head { text-align:center; margin:0 0 8px; }
.modal-head h2 { margin:0; }
.modal-close { position:absolute; top:12px; right:12px; background:none; border:0;
  padding:4px 8px; font-size:1.6rem; line-height:1; color:var(--muted); cursor:pointer;
  -webkit-tap-highlight-color:transparent; }

/* ---- wider viewports: desktop/tablet ---- */
@media (min-width: 700px) {
  .app { max-width:640px; padding-top:36px; }
  h1 { font-size:2rem; }
  .countryname { font-size:2rem; }
  .modal-overlay { align-items:center; }
  .modal-card { border-radius:16px; max-width:420px; }
}
