/* Daily QuizNine — shared styles for the offline mock (mock_question.html) and
   the live, API-backed page (index.html). */
:root{
  --bg:#f4f6f8;
  --card:#ffffff;
  --ink:#1c2430;
  --ink-soft:#5b6675;
  --line:#e6eaef;
  --accent:#4A90E2;            /* set per-question from category color */
  --accent-soft:#eaf2fc;
  --you:#e8863b;               /* highlight for the player's own bar in the
                                  "how everyone did today" histogram */
  --sub-alt:#1b5aa6;           /* every other subcategory in the "how to play"
                                  category lists — a saturated dark blue, set in
                                  bold so it reads clearly against the near-black
                                  rows (the two differ mainly in HUE, which is a
                                  weak signal on its own; weight does the work).
                                  Still ~7:1 on white, so it stays legible —
                                  a brighter blue would fail contrast at 14px. */
  --correct:#2e9e5b;
  --correct-soft:#e7f6ee;
  --wrong:#d8453c;
  --wrong-soft:#fbeceb;
  --radius:16px;
  --shadow:0 6px 24px rgba(28,36,48,.08);
}
*{box-sizing:border-box}
html,body{margin:0}
body{
  font-family:system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  background:var(--bg); color:var(--ink);
  min-height:100vh; display:flex; align-items:flex-start; justify-content:center;
  padding:32px 20px;
}
.app{width:100%; max-width:1000px}
.screen{display:none}
.screen.active{display:block}

/* ---- top bar ---- */
.topbar{position:relative; display:flex; align-items:center; justify-content:space-between; margin-bottom:14px}
.brand{font-weight:700; letter-spacing:.2px}
.brand span{color:var(--accent)}
/* "Day N" — same font AND colour as "Daily", sitting just after the brand on the
   same line. Two classes, so it beats `.brand span`'s accent colour. */
.brand .day{color:var(--ink)}
.navlinks{display:flex; gap:14px; align-items:center}
.navlinks a{cursor:pointer; font-size:14px; font-weight:600; color:var(--ink-soft);
  text-decoration:none; padding:4px 2px; border-bottom:2px solid transparent}
@media (hover:hover){.navlinks a:hover{color:var(--accent); border-bottom-color:var(--accent)}}
/* icon-only nav links (Statistics / Log in / Back) */
.navlinks a.navicon{display:flex; align-items:center; justify-content:center;
  width:38px; height:38px; padding:0; border:1px solid var(--line); border-radius:10px;
  color:var(--ink-soft); background:var(--card)}
.navlinks a.navicon svg{width:20px; height:20px; display:block}
@media (hover:hover){.navlinks a.navicon:hover{color:var(--accent); border-color:var(--accent)}}
/* ---- progress pips (also the round's navigation) ----
   Each pip is a button that jumps to its question, and carries that question's
   OUTCOME once answered — so the header doubles as an at-a-glance scorecard.
   A pip past the frontier is disabled: you can look back freely, but you still
   have to answer to go forward. */
.progress{display:flex; gap:6px; align-items:center}
.pip{position:relative; width:22px; height:6px; border-radius:99px; background:var(--line);
  border:0; padding:0; margin:0; appearance:none; -webkit-appearance:none;
  flex:0 0 auto; cursor:pointer; transition:transform .12s, background .12s}
/* The bar is 6px tall — far below a usable touch target — so grow the HIT area
   vertically without changing the layout. */
.pip::before{content:""; position:absolute; left:0; right:0; top:-13px; bottom:-13px}
.pip:disabled{cursor:default}
.pip.ok{background:var(--correct)}
.pip.no{background:var(--wrong)}
.pip.done{background:var(--accent)}
/* The current pip is marked by HEIGHT, so the colour stays free to carry the
   outcome. scaleY rather than a real height: no layout shift, no reflow. */
.pip.current{transform:scaleY(1.9)}
.pip.current:not(.ok):not(.no){background:var(--accent); opacity:.55}
.pip:focus-visible{outline:2px solid var(--accent); outline-offset:4px}
@media (hover:hover){.pip:not(:disabled):hover{background:var(--accent)}}

.pipnav{display:flex; align-items:center; justify-content:center;
  min-width:22px; height:26px; border:0; padding:0; margin:0; background:none;
  appearance:none; -webkit-appearance:none; flex:0 0 auto; cursor:pointer;
  font-size:19px; line-height:1; color:var(--ink-soft)}
.pipnav:disabled{opacity:.25; cursor:default}
.pipnav:focus-visible{outline:2px solid var(--accent); outline-offset:2px; border-radius:6px}
@media (hover:hover){.pipnav:not(:disabled):hover{color:var(--accent)}}
.count{font-size:13px; color:var(--ink-soft); margin-left:8px}

.card{background:var(--card); border-radius:var(--radius); box-shadow:var(--shadow); overflow:hidden}

/* ---- category banner (wide, short) ---- */
.banner{display:flex; gap:10px; padding:12px 16px; border-bottom:1px solid var(--line); background:linear-gradient(0deg,#fff, var(--accent-soft))}
.crumb{display:flex; align-items:center; gap:10px; padding:6px 14px 6px 7px; background:#fff; border:1px solid var(--line); border-radius:14px}
.crumb img{width:46px; height:46px; border-radius:9px; object-fit:cover; display:block}
.crumb .v{font-size:15px; font-weight:600; line-height:1.25}
.crumb-sep{align-self:center; color:var(--ink-soft); font-size:18px}
/* difficulty crumb: same size/shape as the category crumbs, pinned to the far
   right of the banner row (same row as the category breadcrumbs). */
.crumb-diff{margin-left:auto}

/* ---- question body: image | question ---- */
.body{display:grid; grid-template-columns:45% 55%}
.media{position:relative; background:#0e1420; min-height:380px}
.media img{width:100%; height:100%; object-fit:cover; display:block; position:absolute; inset:0; box-sizing:border-box}
/* "No crop" (contain) images: a small breathing margin so an outline that reaches
   the edge of its viewBox doesn't touch the box border and read as cropped. */
.media img.no-crop{padding:6px}
.media .tag{position:absolute; left:12px; bottom:12px; z-index:2;
  background:rgba(14,20,32,.62); color:#fff; font-size:11px; padding:4px 10px; border-radius:99px; backdrop-filter:blur(3px)}

.qa{padding:28px 30px; display:flex; flex-direction:column}
.prompt{font-size:24px; line-height:1.3; font-weight:650; margin:4px 0 22px}

.answers{display:flex; flex-direction:column; gap:12px}
.answer{
  position:relative; overflow:hidden;
  display:flex; align-items:flex-start; gap:14px; width:100%; text-align:left; line-height:1.4;
  background:#fff; border:2px solid var(--line); border-radius:12px;
  padding:14px 16px; font-size:16px; color:var(--ink); cursor:pointer;
  transition:border-color .12s, background .12s, transform .05s;
}
/* ⚠️ EVERY :hover rule in this file is wrapped in `@media (hover:hover)`, and
   this one is why. A beta tester on an iPhone (in an in-app browser, not
   Safari) reported the BOTTOM answer looking pre-selected on arrival — still
   answerable, but confusing. It was this rule: iOS WebKit applies :hover to
   whatever element sits under the LAST touch point, and the buttons the player
   taps to get here ("Play today's nine", "Next →") sit low on the screen, so
   after the re-render the bottom answer lands under that point and inherits
   hover until the next touch. The tint is `--accent`, which is set per
   question from the category colour, which is why the report showed an amber
   highlight on a Lifestyle & Everyday Life question.

   `(hover:hover)` is false on touch devices, so the rule simply never applies
   there. The same shape would have hit `.report-reason` (the report modal's
   option list) and `.diff` (the difficulty tiles) identically, which is why
   the guard is applied to all of them rather than just this one.
   ⚠️ `:focus-visible` rules are deliberately NOT wrapped — that pseudo-class
   already declines to match touch and mouse input, and gating it would remove
   the keyboard focus ring. */
@media (hover:hover){.answer:hover:not(:disabled){border-color:var(--accent); background:var(--accent-soft)}}
.answer:active:not(:disabled){transform:translateY(1px)}
.answer > *{position:relative; z-index:1}
.answer .key{
  flex:0 0 auto; width:28px; height:28px; border-radius:8px; display:grid; place-items:center;
  font-size:13px; font-weight:700; background:var(--accent-soft); color:var(--accent);
}
.answer .txt{flex:1}
.answer .mark{flex:0 0 auto; font-size:18px; opacity:0}
.answer.correct{border-color:var(--correct); background:var(--correct-soft)}
.answer.correct .key{background:var(--correct); color:#fff}
.answer.correct .mark{opacity:1; color:var(--correct)}
.answer.wrong{border-color:var(--wrong); background:var(--wrong-soft)}
.answer.wrong .key{background:var(--wrong); color:#fff}
.answer.wrong .mark{opacity:1; color:var(--wrong)}
.answer.dim{opacity:.55}
.answer:disabled{cursor:default}

/* ---- post-answer notes (revealed under the question) ---- */
.qnotes{display:none}
.qnotes.show{
  display:flex; gap:12px; align-items:flex-start; margin:0; padding:16px 30px 20px;
  border-top:1px solid var(--line); background:#fbfcfd;
  font-size:14.5px; line-height:1.55; color:var(--ink-soft);
}
.qnotes-icon{
  flex:0 0 auto; margin-top:1px;
  display:inline-flex; align-items:center; justify-content:center;
  width:22px; height:22px; border-radius:50%;
  background:var(--accent); color:#fff;
  font-family:Georgia,"Times New Roman",serif; font-style:italic; font-weight:700;
  font-size:14px; line-height:1;
}
.qnotes-body{flex:1}

/* ---- live answer distribution (% of today's players who picked each) ---- */
.answer .fill{
  position:absolute; left:0; top:0; bottom:0; width:0; z-index:0;
  background:rgba(28,36,48,.07); transition:width .45s ease;
}
.answer.correct .fill{background:rgba(46,158,91,.16)}
.answer.wrong   .fill{background:rgba(216,69,60,.14)}
.answer .pct{
  flex:0 0 auto; align-self:center; min-width:46px; text-align:right;
  font-size:13px; font-weight:700; color:var(--ink-soft); opacity:0; transition:opacity .25s;
}
.answer.revealed .pct{opacity:1}

/* Wrap onto two rows rather than squeezing report-btn's text when the note +
   report button + Next/See-results button don't all fit on one line (mobile). */
.footer{display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; margin-top:22px; min-height:44px; gap:14px}
.result-note{font-size:14px; font-weight:600; opacity:0; transition:opacity .15s; white-space:nowrap}
/* empty now on every normal answer (text dropped as redundant) — collapse it so
   it contributes no flex gap, only appearing when choose() writes an error */
.result-note:empty{display:none}
.result-note.show{opacity:1}
.result-note.ok{color:var(--correct)}
.result-note.no{color:var(--wrong)}
.foot-meta{display:flex; align-items:center; gap:16px; flex:1}
.footer .next{flex-shrink:0}
.report-btn{
  font:inherit; font-size:13px; font-weight:600; color:var(--ink-soft); text-align:center;
  background:#fff; border:1px solid var(--line); border-radius:10px;
  padding:12px 18px; cursor:pointer; white-space:nowrap; flex-shrink:0;
  display:inline-flex; align-items:center; justify-content:center;
  transition:border-color .12s, color .12s, background .12s;
}
@media (hover:hover){.report-btn:hover{color:var(--accent); border-color:var(--accent); background:var(--accent-soft)}}
.report-btn:focus-visible{outline:2px solid var(--accent); outline-offset:2px}

.btn{
  background:var(--accent); color:#fff; border:none; border-radius:10px;
  padding:12px 26px; font-size:15px; font-weight:650; cursor:pointer; transition:filter .12s, opacity .15s;
}
@media (hover:hover){.btn:hover{filter:brightness(1.05)}}
/* A disabled primary button must not look live. The merge dialog opens with its
   confirm disabled until a side is picked, and at full accent it read as a
   button that simply did nothing when clicked. */
.btn:disabled{opacity:.45; cursor:default; filter:none}
@media (hover:hover){.btn:disabled:hover{filter:none}}
.btn.ghost{background:#fff; color:var(--ink); border:1px solid var(--line)}
.next{opacity:0; pointer-events:none}
.next.show{opacity:1; pointer-events:auto}

/* ---- start / difficulty screen ---- */
.start{padding:40px 36px; text-align:center}
.start h1{margin:0 0 6px; font-size:30px}
.start h1 span{color:var(--accent)}
.start .sub{color:var(--ink-soft); margin:0 0 28px; font-size:15px}
.diffs{display:grid; grid-template-columns:repeat(3,1fr); gap:16px; margin:0 auto 28px; max-width:640px}
.diff{
  position:relative;
  background:#fff; border:2px solid var(--line); border-radius:14px; padding:18px 14px; cursor:pointer;
  display:flex; flex-direction:column; align-items:center; gap:12px; transition:border-color .12s, transform .06s, box-shadow .12s;
}
/* green check badge, shown when that difficulty is already completed today */
.diff .diff-check{
  position:absolute; top:10px; right:10px; display:none;
  width:26px; height:26px; border-radius:50%; background:var(--correct); color:#fff;
  align-items:center; justify-content:center; font-size:15px; font-weight:800;
  box-shadow:0 1px 4px rgba(0,0,0,.18);
}
.diff.done .diff-check{display:flex}
@media (hover:hover){.diff:hover{border-color:var(--accent); transform:translateY(-2px)}}
.diff img{width:104px; height:104px; object-fit:contain}
.diff .name{font-weight:700; font-size:17px}
.diff .desc{font-size:12.5px; color:var(--ink-soft); line-height:1.4}
.diff.selected{border-color:var(--accent); background:var(--accent-soft); box-shadow:0 4px 16px rgba(74,144,226,.18)}
.start .startbtn{padding:14px 40px; font-size:16px; opacity:.5; pointer-events:none}
.start .startbtn.ready{opacity:1; pointer-events:auto}
.start .note{margin-top:18px; font-size:12px; color:var(--ink-soft)}
.start .note a{color:var(--accent); cursor:pointer}
.start .yest{margin-top:10px; font-size:13px}
.start .yest a{color:var(--accent); cursor:pointer; text-decoration:none; font-weight:600}
@media (hover:hover){.start .yest a:hover{text-decoration:underline}}
/* yesterday page: the date under the title */
.yest-date{margin:0 0 8px; text-align:center; font-size:14px; color:var(--ink-soft)}

/* ---- site footer (persists across screens) ---- */
.sitefoot{display:flex; flex-wrap:wrap; align-items:center; justify-content:center;
  gap:8px; margin-top:28px; padding-top:16px; border-top:1px solid var(--line);
  font-size:12px; color:var(--ink-soft)}
.sitefoot a{color:var(--ink-soft); cursor:pointer; text-decoration:none}
@media (hover:hover){.sitefoot a:hover{color:var(--accent)}}
.sitefoot .dot{opacity:.5}

/* ---- help / how-to-play modal ---- */
.modal-backdrop{position:fixed; inset:0; z-index:50; display:flex; align-items:center;
  justify-content:center; padding:20px; background:rgba(20,26,34,.5)}
.modal-backdrop[hidden]{display:none}
.modal{position:relative; width:100%; max-width:440px; background:var(--card);
  border-radius:var(--radius); box-shadow:var(--shadow); padding:26px 28px 24px; text-align:left}
.modal h2{margin:0 0 14px; font-size:22px}
.modal .modal-x{position:absolute; top:12px; right:12px; width:32px; height:32px;
  border:none; background:transparent; color:var(--ink-soft); font-size:16px;
  cursor:pointer; border-radius:8px; line-height:1}
@media (hover:hover){.modal .modal-x:hover{background:var(--line); color:var(--ink)}}
.howto{margin:0 0 22px; padding-left:20px; display:flex; flex-direction:column; gap:11px}
.howto li{font-size:14px; line-height:1.5; color:var(--ink)}
.howto b{color:var(--ink)}
.modal .btn{width:100%; justify-content:center}
.modal-sub{margin:0 0 16px; font-size:14px; color:var(--ink-soft)}

/* ---- log in / account ---- */
.loginform{display:flex; flex-direction:column; gap:10px; margin:0 0 14px}
.loginform[hidden]{display:none}
.loginlabel{font-size:13px; color:var(--ink-soft)}
.logininput{width:100%; box-sizing:border-box; padding:12px 14px; font:inherit;
  font-size:15px; color:var(--ink); background:#fff; border:1px solid var(--line);
  border-radius:10px; transition:border-color .12s, box-shadow .12s}
.logininput::placeholder{color:#a9b2be}
.logininput:focus{outline:none; border-color:var(--accent);
  box-shadow:0 0 0 3px var(--accent-soft)}
/* The code is read off one screen and typed into another, so digit shape and
   grouping matter more than they would in ordinary copy: monospaced (so 1/l
   and 0/O cannot be confused), large, and widely tracked. */
.codeinput{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  font-size:26px; font-weight:700; letter-spacing:10px; text-align:center;
  padding:14px 10px}
.codeinput::placeholder{letter-spacing:10px; color:#cdd4dd; font-weight:400}
.loginerr{font-size:13px; color:var(--wrong); line-height:1.45}
.loginerr[hidden]{display:none}
.loginbig{margin:0 0 18px; font-size:16px; font-weight:600; color:var(--ink);
  word-break:break-all}
.loginfoot{margin:0; font-size:12px; color:var(--ink-soft); line-height:1.5}
.loginwarn{margin:0 0 4px; font-size:13px; color:var(--ink-soft); line-height:1.5}
/* A text-only control for the secondary actions ("delete my account",
   "cancel"), so the dialog never shows three equally loud buttons. */
.linkbtn{display:block; width:100%; margin:12px 0 0; padding:6px; border:none;
  background:none; font:inherit; font-size:13px; color:var(--ink-soft);
  cursor:pointer; text-decoration:underline; text-underline-offset:3px}
@media (hover:hover){.linkbtn:hover{color:var(--ink)}}
.linkbtn.danger{color:var(--wrong); opacity:.85}
@media (hover:hover){.linkbtn.danger:hover{opacity:1}}
.btn.danger{background:var(--wrong); border-color:var(--wrong)}
@media (hover:hover){.btn.danger:hover{filter:brightness(.94)}}

/* ---- "which progress do you want to keep?" ---- */
.modal.modal-wide{max-width:560px}
.mergegrid{display:grid; grid-template-columns:1fr 1fr; gap:12px; margin:0 0 16px}
.mergecard{text-align:left; background:#fff; border:2px solid var(--line);
  border-radius:12px; padding:14px 16px; cursor:pointer; font:inherit;
  color:var(--ink); transition:border-color .12s, background .12s}
@media (hover:hover){.mergecard:hover{border-color:var(--accent)}}
.mergecard.selected{border-color:var(--accent); background:var(--accent-soft)}
.mergecard-h{font-weight:700; font-size:14px; margin:0 0 10px}
.mergestats{margin:0; display:flex; flex-direction:column; gap:6px}
.mergestats>div{display:flex; justify-content:space-between; gap:10px; font-size:13px}
.mergestats dt{color:var(--ink-soft)}
.mergestats dd{margin:0; font-variant-numeric:tabular-nums; font-weight:600}
/* One column on a narrow phone: two 13px stat lists side by side wrap into an
   unreadable mess well before the viewport gets genuinely small. */
@media (max-width:520px){ .mergegrid{grid-template-columns:1fr} }

/* ---- report-a-problem modal ---- */
.report-reasons{display:flex; flex-direction:column; gap:8px}
.report-reasons[hidden]{display:none}
.report-reason{
  text-align:left; width:100%; background:#fff; border:1px solid var(--line); border-radius:10px;
  padding:11px 14px; font-size:14px; color:var(--ink); cursor:pointer; transition:border-color .12s, background .12s;
}
@media (hover:hover){.report-reason:hover:not(:disabled){border-color:var(--accent); background:var(--accent-soft)}}
.report-reason:disabled{opacity:.5; cursor:default}
.report-thanks{margin:0; font-size:14px; color:var(--correct); font-weight:600}

/* ---- results screen ---- */
.results{padding:40px 36px; text-align:center}
.results .label{color:var(--ink-soft); font-size:15px; letter-spacing:.3px; margin:0}
.results .score{font-size:64px; font-weight:800; line-height:1.05; margin:6px 0 2px}
.results .score small{font-size:30px; color:var(--ink-soft); font-weight:700}
.results .resimg{width:230px; height:230px; object-fit:contain; margin:14px auto 6px; display:block}
.results .blurb{font-size:16px; font-weight:600; margin:0 0 24px}
/* wrap: three buttons no longer fit one phone-width row. */
.results .actions{display:flex; gap:12px; justify-content:center; flex-wrap:wrap}

/* Last-resort share box: only ever shown when BOTH clipboard paths fail, so
   the player can still select the text by hand. Hidden until then. */
.share-fallback{max-width:420px; margin:16px auto 0; text-align:left}
.share-fallback[hidden]{display:none}
.share-fallback p{margin:0 0 6px; font-size:13px; color:var(--ink-soft)}
.share-fallback textarea{width:100%; box-sizing:border-box; padding:10px 12px;
  border:1px solid var(--line); border-radius:10px; background:#fff;
  color:var(--ink); font:inherit; font-size:14px; line-height:1.5; resize:vertical}

/* ---- per-question recap (results screen) ---- */
.qstats{max-width:560px; margin:0 auto 26px; text-align:left}
.qstats:empty{display:none}
.qstats h3{font-size:12px; text-transform:uppercase; letter-spacing:.6px; color:var(--ink-soft); margin:18px 0 10px; text-align:center}
.qs-hint{font-size:12px; color:var(--ink-soft); text-align:center; margin:0 0 8px}
.qs-list{border:1px solid var(--line); border-radius:12px; overflow:hidden; background:#fff}
/* A row is a button (it reopens its question), so the button chrome has to be
   reset back to the plain row it was. */
.qs-row{display:flex; align-items:center; gap:10px; padding:8px 12px;
  border:0; border-bottom:1px solid var(--line); width:100%; background:none;
  font:inherit; color:inherit; text-align:left; cursor:pointer;
  appearance:none; -webkit-appearance:none}
.qs-row:last-child{border-bottom:none}
.qs-row:focus-visible{outline:2px solid var(--accent); outline-offset:-2px}
@media (hover:hover){.qs-row:hover{background:var(--accent-soft)}}
.qs-go{flex:0 0 auto; font-size:17px; line-height:1; color:var(--ink-soft)}
.qs-mark{flex:0 0 auto; width:20px; height:20px; border-radius:50%; display:inline-flex;
  align-items:center; justify-content:center; font-size:13px; font-weight:800; color:#fff}
.qs-row.ok .qs-mark{background:var(--correct)}
.qs-row.no .qs-mark{background:var(--wrong)}
.qs-ic{flex:0 0 auto; width:28px; height:28px; border-radius:7px; object-fit:contain; display:block}
.qs-q{flex:1 1 auto; min-width:0; font-size:14px; line-height:1.3; color:var(--ink);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.qs-cmp{flex:0 0 auto; font-size:12.5px; font-weight:700; font-variant-numeric:tabular-nums; white-space:nowrap}
.qs-cmp.easy{color:var(--ink-soft)}
.qs-cmp.mid{color:#b8860b}
.qs-cmp.hard{color:var(--wrong)}

/* ---- "how everyone did today" histogram (results screen) ---- */
/* Reuses the stats-page histogram classes (.hrow/.hbars/.hb/.bar/.n); only the
   extras are here: the difficulty icon, the player-bar highlight, and the
   floating "you" marker. */
.todaystats{max-width:560px; margin:0 auto 26px; text-align:left}
.todaystats:empty{display:none}
.todaystats h3{font-size:12px; text-transform:uppercase; letter-spacing:.6px; color:var(--ink-soft); margin:18px 0 10px; text-align:center}
.todaystats .today-dic{width:52px; height:52px; object-fit:contain; display:block; margin:0 0 6px}
/* few-players note (first finisher / handful so far) */
.today-first{display:flex; flex-direction:column; align-items:center; text-align:center; gap:8px; margin:0 0 6px}
.today-first .today-dic.big{width:64px; height:64px; margin:0}
.today-note{margin:0 auto; max-width:420px; font-size:14px; line-height:1.5; color:var(--ink-soft)}
/* headroom above the bars so the "you" marker over a full-height bar isn't clipped */
.todaystats .hrow{padding-top:26px}
/* .hbars in the selector so this outranks the equal-specificity
   `.hbars .hb.has .bar` that would otherwise keep the player bar blue */
.todaystats .hbars .hb.you .bar{background:var(--you); position:relative}
.todaystats .hbars .hb.you .n{color:var(--you); font-weight:800}
.youtag{position:absolute; bottom:100%; left:50%; transform:translateX(-50%);
  display:flex; flex-direction:column; align-items:center; line-height:1;
  color:var(--you); font-weight:800; white-space:nowrap}
.youtag .l{font-size:10px; letter-spacing:.3px}
.youtag .a{font-size:12px; margin-top:-1px}

/* ---- category ratings table (results screen) ---- */
.ratings{max-width:520px; margin:0 auto 26px; text-align:left}
.ratings h3{font-size:12px; text-transform:uppercase; letter-spacing:.6px; color:var(--ink-soft); margin:18px 0 10px; text-align:center}
/* ---- streak chip (results screen) ---- */
/* Two columns, no rules or borders between them: labels right-aligned, values
   left-aligned, so they meet in the middle and every stat lines up. `auto auto`
   sizes each column to its widest cell and `width:max-content` shrinks the box
   to fit, so the pair stays optically centred whatever the labels say. */
.streak{display:grid; grid-template-columns:auto auto; gap:5px 10px;
  width:max-content; margin:0 auto 16px; padding:12px 18px;
  font-size:15px; color:var(--ink);
  border:1px solid var(--line); border-radius:14px; background:#fff}
.streak:empty{display:none}
.streak-label{color:var(--ink-soft); text-align:right}
.streak-val{text-align:left}
.streak b{font-size:17px; font-variant-numeric:tabular-nums}
.streak-flame{font-size:16px}

/* table-layout:fixed forces the table to exactly its container width (never wider),
   so on a narrow phone the rating/delta columns can't push the table off-screen and
   get clipped by the card's overflow:hidden. The name column takes what's left. */
.rtable{width:100%; border-collapse:collapse; table-layout:fixed}
.rtable .rname{overflow-wrap:anywhere}
.rtable td{padding:5px 8px; border-bottom:1px solid var(--line); vertical-align:middle}
.rtable tr:last-child td{border-bottom:none}
/* icon column — at least the play-screen crumb size (46px) */
.rtable .ricon{width:52px; padding-right:0}
.rtable .ricon img{display:block; width:46px; height:46px; max-width:46px; max-height:46px; object-fit:contain; border-radius:8px}
.rtable .rname{font-weight:600; font-size:14.5px; line-height:1.2}
.rprov{margin-left:7px; font-size:10px; font-weight:700; text-transform:uppercase; letter-spacing:.4px; color:var(--ink-soft); vertical-align:middle}
.rtable .rval{width:56px; text-align:right; font-weight:800; font-size:17px; font-variant-numeric:tabular-nums; white-space:nowrap}
.rtable .rdelta{text-align:right; width:66px; white-space:nowrap}
.rd{font-size:12.5px; font-weight:700; font-variant-numeric:tabular-nums}
.rd.up{color:var(--correct)}
.rd.down{color:var(--wrong)}
.rd.flat{color:var(--ink-soft)}
.rnew{font-size:11px; font-weight:800; letter-spacing:.5px; color:var(--accent)}
/* Overall row — emphasised header line */
.rtable .roverall td{border-bottom:2px solid var(--line); background:#fafbfc}
.rtable .roverall .rname{font-weight:800}
.rtable .roverall .rval{font-size:18px}

/* ---- statistics page ---- */
.stats-page{padding:32px 30px; text-align:center}   /* breathing room round the figures + above the title */
.stats-page h2{margin:0 0 4px; font-size:30px}  /* one heading size across all pages (matches the front-page title) */
.stats-empty{color:var(--ink-soft); font-size:15px; margin:24px auto; max-width:420px}
/* one statistics section (Overall, or a difficulty) */
.stats-sec{max-width:600px; margin:0 auto; padding:22px 0; text-align:left; border-top:1px solid var(--line)}
.stats-sec:first-of-type{border-top:none}
/* Difficulty section header: big centered icon with the name below (like start screen) */
.stats-dhead{display:flex; flex-direction:column; align-items:center; gap:4px; margin:0 0 14px}
.stats-dhead img.stats-dic{width:84px; height:84px; object-fit:contain; display:block}
.stats-dhead .stats-dname{font-size:17px; font-weight:700}
.stats-sec .streak{margin:0 auto 16px}          /* centered within the section */
.stats-line{color:var(--ink-soft); font-size:14px; margin:6px 0 2px; text-align:center}

/* ---- "want more?" page ---- */
.more-lead{max-width:520px; margin:0 auto 4px; font-size:15px; line-height:1.55; color:var(--ink); text-align:center}
.more-modes{display:flex; flex-direction:column; gap:10px; max-width:520px; margin:0 auto}
.more-mode{display:flex; gap:13px; align-items:flex-start; text-align:left;
  background:#fff; border:1px solid var(--line); border-radius:12px; padding:12px 15px}
.more-mode .mm-ic{font-size:22px; line-height:1.25; flex:0 0 auto}
.more-mode b{font-size:15px}
.more-mode .mm-desc{font-size:13px; color:var(--ink-soft); line-height:1.45; margin-top:2px}
.more-support{max-width:520px; margin:0 auto 16px; font-size:14px; line-height:1.5; color:var(--ink-soft); text-align:center}
.games{display:grid; grid-template-columns:1fr 1fr; gap:16px; max-width:640px; margin:0 auto}
.game-card{display:flex; flex-direction:column; text-decoration:none; color:inherit;
  background:#fff; border:1px solid var(--line); border-radius:14px; overflow:hidden;
  transition:border-color .12s, box-shadow .12s, transform .08s}
@media (hover:hover){.game-card:hover{border-color:var(--accent); box-shadow:0 6px 18px rgba(74,144,226,.16); transform:translateY(-2px)}}
.game-card img{width:100%; aspect-ratio:616/353; object-fit:cover; display:block; background:#0e1420}
.game-body{display:flex; flex-direction:column; gap:8px; padding:14px 15px 15px; text-align:left; flex:1}
.game-name{font-weight:700; font-size:16px}
.game-desc{font-size:13px; color:var(--ink-soft); line-height:1.45; flex:1}
.game-btn{align-self:stretch; text-align:center; margin-top:2px}

/* ---- info / how-to-play page ---- */
/* One tight type scale on this page: 15px for bold names, 14px for body text,
   13px for the uppercase section labels — no other sizes. */
.info-page{text-align:left}
.info-page h2{text-align:center}
.info-h3{margin:0 0 14px; font-size:13px; text-transform:uppercase; letter-spacing:.5px; color:var(--ink-soft); text-align:center}
.info-diffs{display:grid; grid-template-columns:repeat(3,1fr); gap:14px; max-width:560px; margin:0 auto 16px}
.info-diff{background:#fff; border:1px solid var(--line); border-radius:14px; padding:14px 12px; text-align:center}
.info-diff img{width:64px; height:64px; object-fit:contain; display:block; margin:0 auto 8px}
.info-diff .name{font-weight:700; font-size:15px}
.info-difflist{max-width:560px; margin:0 auto; padding-left:20px; display:flex; flex-direction:column; gap:8px}
.info-difflist li{font-size:14px; line-height:1.5; color:var(--ink)}
.info-difflist b{color:var(--ink)}
.info-cats{display:grid; grid-template-columns:repeat(3,1fr); gap:14px}
.info-cat{background:#fff; border:1px solid var(--line); border-top:4px solid var(--cat-color); border-radius:12px; padding:14px}
.info-cat-head{display:flex; align-items:center; gap:10px; margin:0 0 10px}
.info-cat-head img{width:34px; height:34px; object-fit:contain; border-radius:7px; display:block}
.info-cat-head .name{font-weight:700; font-size:15px; line-height:1.25}
.info-subs{margin:0; padding:0; list-style:none; display:flex; flex-direction:column; gap:3px}
/* Alternating colours so a subcategory that wraps onto two lines is still easy to
   tell apart from the next one. Both tones are dark enough to read as body text
   (the accent blue would not be); tweak --sub-alt to taste. */
.info-subs li{font-size:14px; line-height:1.4}
.info-subs li:nth-child(odd){color:var(--ink); font-weight:400}
.info-subs li:nth-child(even){color:var(--sub-alt); font-weight:625}
.info-more{text-align:center; margin:26px 0 4px}

.hrow{display:flex; align-items:flex-end; gap:16px; margin:0 0 18px}
.hrow .hmeta{width:140px; flex:0 0 auto}
.hrow .hname{font-weight:700; font-size:15px}
.hrow .hsub{font-size:12px; color:var(--ink-soft); line-height:1.5}
.hbars{flex:1; display:flex; align-items:flex-end; gap:3px; height:70px}
/* padding-bottom reserves the digit's row so it doesn't eat into the bar's
   height; the bar must NOT flex-shrink, or tall bars all get squeezed to the
   same height (e.g. a 4-count and a 5-count bar rendering identically). */
.hbars .hb{flex:1; position:relative; display:flex; flex-direction:column; align-items:center; justify-content:flex-end; height:100%; padding-bottom:14px}
.hbars .hb .bar{width:100%; background:var(--accent-soft); border-radius:3px 3px 0 0; min-height:2px; flex-shrink:0; transition:height .3s}
.hbars .hb.has .bar{background:var(--accent)}
.hbars .hb .n{position:absolute; bottom:0; left:0; right:0; text-align:center; font-size:9px; color:var(--ink-soft)}

/* ---- banners for states (live page) ---- */
.notice{margin:0 0 14px; padding:12px 16px; border-radius:12px; font-size:14px}
.notice.err{background:var(--wrong-soft); color:#8a2b25; border:1px solid #f1c3bf}
.notice.info{background:var(--accent-soft); color:#2c5b8f; border:1px solid #cfe1f6}

/* ---- responsive ---- */
@media (max-width:720px){
  /* Let the brand and the nav wrap rather than squash on a narrow phone. */
  .topbar{flex-wrap:wrap}
  .body{grid-template-columns:1fr}
  .media{min-height:300px; max-height:320px}
  .qa{padding:22px}
  .prompt{font-size:21px}
  .banner{flex-wrap:wrap}
  .diffs{grid-template-columns:1fr; max-width:360px}
  .diff{flex-direction:row; justify-content:flex-start; text-align:left}
  .diff img{width:64px; height:64px}
  .info-diffs{grid-template-columns:1fr; max-width:360px}
  .info-diff{display:flex; align-items:center; gap:12px; text-align:left; padding:10px 14px}
  .info-diff img{width:48px; height:48px; margin:0}
  .info-cats{grid-template-columns:repeat(2,1fr)}
  .games{grid-template-columns:1fr; max-width:400px}
}
/* The two nav arrows cost the progress row ~44px, which a narrow phone does not
   have to spare beside the brand — take it back off the pips, whose hit area is
   set by the ::before overlay and so is unaffected. */
@media (max-width:480px){
  .progress{gap:5px}
  .pip{width:15px}
  .pipnav{min-width:18px; font-size:17px}
  .count{margin-left:6px}
}
/* ---- phones: get the category banner down from three rows to two ----
   The three chips (main > sub, then difficulty) cannot share ONE row, and the
   arithmetic is not close: at 375px the banner has ~331px of content width,
   while three chips carry ~177px of icon + padding + border chrome BEFORE any
   text, and the labels themselves want 300px+. So the target is two rows —
   the two category chips together on row one, difficulty on row two — reached
   by shrinking the icon and capping the label so it wraps to two lines
   instead of forcing the chip as wide as its longest label.

   ⚠️ THE FONT SIZE IS WHAT MAKES TWO LINES POSSIBLE, not the cap — this was
   got wrong first, at 13px with a 92px cap, which forced a third line on nine
   of the 54 real main/subcategory pairs (at 375px as much as at 360px, so it
   was never only a narrow-phone problem). Measured over the real taxonomy in
   Segoe UI Semibold, the cap needed for every label to fit on two lines is
   102px at 13px but only 89px at 12px, driven by "Psychology & Human
   Behavior".

   ⚠️ 13px was rejected for FRAGILITY, not because it cannot be made to fit —
   worth stating precisely, because the obvious experiment succeeds and is
   misleading. A 102px cap does fit at both 360px and 375px with a 30px icon
   (measured: 0 overflow, 0 three-line, 7px slack at 360px). But 102px is a
   *Segoe UI* figure, and Segoe is what a Windows browser's device-emulation
   mode uses. Real phones render this in SF Pro (iOS) or Roboto (Android),
   ~8-10% wider, which lifts the requirement to ~110px — and that does not
   fit. So 13px would look correct in DevTools and wrap to three lines on the
   actual hardware. At 12px the requirement is 89px against a 92px cap, and
   the layout survives text measured 15% wider.

   The cap is 92px: above the 89px needed for two lines, and well above the
   longest single WORD (75px at 12px), so a label never breaks mid-word.

   Wrapping is left to the browser rather than forced at the "&": a forced
   break would put "& the Living World" on one line and blow the cap, whereas
   natural wrapping balances it. The chip is then shrunk back to its longest
   rendered line by fitLabel() in index.html — CSS alone cannot do that, so a
   label wider than the cap would otherwise occupy the full 92px however short
   its wrapped lines are.

   Verified over all 54 real main/subcategory pairs, with text measured at
   1.0x / 1.08x / 1.15x width to stand in for iOS (SF Pro) and Android
   (Roboto): zero rows overflow and zero three-line labels at 375px (31px
   slack) and 360px (16px slack). At 1.15x some labels take a third line, but
   still nothing overflows.

   ⚠️ ~320px phones (iPhone SE 1st gen) are NOT solved and deliberately so:
   the row there has 280px against two chips, and closing that needs either an
   18px icon or a cap below the two-line threshold. They fall back to the
   three-row banner via min-width:0 — today's behaviour, so no regression. */
@media (max-width:600px){
  .banner{gap:6px; padding:10px}
  /* min-width:0 is the safety net: if a row still cannot fit (a very wide
     font, a very narrow phone), the chip shrinks and the label wraps further
     instead of overflowing the card. Worst case degrades to the three-row
     banner rather than to a broken layout. */
  .crumb{gap:6px; padding:5px 8px 5px 5px; border-radius:12px; min-width:0}
  .crumb img{width:32px; height:32px; border-radius:8px}
  .crumb .v{font-size:12px; line-height:1.3; max-width:92px}
  .crumb-sep{font-size:15px}
  /* ⚠️ No difficulty chip on phones (DECIDED). Measured over all 54 real
     main/subcategory pairs, the full chip (icon + "Normal") shares the row in
     1 case out of 54 at both 360px and 375px — so keeping it costs a whole
     second banner row to display one word the player chose seconds earlier
     and sees again on the results screen.

     An adaptive ladder (full -> icon-only -> hidden, measured per question)
     was built and removed: icon-only would have fitted 19/54 at 360px and
     37/54 at 375px, but that means the icon appears for some questions and
     vanishes for others inside a single round, which reads as a glitch
     rather than as a fit. Showing it only where BOTH icon and text fit is the
     calmer rule. */
  .crumb-diff{display:none}
}

/* phones: trim the generous desktop padding so the ratings/recap fit, and make the
   ratings table a touch more compact (the icon column shrinks, freeing the name) */
@media (max-width:480px){
  body{padding:16px 10px}
  .results{padding:28px 16px}
  .stats-page{padding:26px 20px}   /* keep side + top white space on phones */
  .rtable .ricon{width:42px}
  .rtable .ricon img{width:36px; height:36px; max-width:36px; max-height:36px}
  .rtable .rname{font-size:13.5px}
  .rtable .rval{width:48px; font-size:16px}
  .rtable .rdelta{width:64px}
  .rd{font-size:11.5px}
  /* one category column, so the subcategories can use two columns again */
  .info-cats{grid-template-columns:1fr}
  .info-subs{display:grid; grid-template-columns:1fr 1fr; gap:3px 8px}
  /* Two columns fill row-wise, so plain odd/even would tint the COLUMNS and
     stack same-coloured items vertically. Band by pairs instead, so the colour
     still changes from one visual row to the next. */
  /* weight is reset explicitly: the base `even` rule bolds items 2/4/6, which
     land in DIFFERENT visual rows once the list is two columns wide */
  .info-subs li:nth-child(4n+1), .info-subs li:nth-child(4n+2){color:var(--ink); font-weight:400}
  .info-subs li:nth-child(4n+3), .info-subs li:nth-child(4n+4){color:var(--sub-alt); font-weight:700}
}
