  /* Base. This used to sit in the page wrapper; with many pages it belongs
     with the stylesheet, or [hidden] stops meaning hidden and the invisible
     sheets swallow every tap aimed at the wheel. */
  *, *::before, *::after { box-sizing:border-box; }
  [hidden] { display:none !important; }
  img, svg { max-width:100%; }
  :root { color-scheme: light; }

/* Layout: one screen, no scroll — carnival wheel fills the stage, its hub is the letter display, controls sit beneath. Single dark "game show" world by design. */
  :root {
    /* Kitchen table: printed board game. Warm paper, ink outlines, flat colour.
       Nothing glows; depth comes from hard offset shadows, as on a printed box. */
    --bg:#F3E7D3; --bg-2:#FFFBF2; --bg-3:#E8DCC4;
    --ink:#20190F; --muted:#7A6A55;
    --brass:#C2341F; --coral:#C2341F; --teal:#2E7D63; --grape:#3C62A6;
    --butter:#E8B33C;
    --dim:#20190F; --good:#2E7D63;
    --faint:#8A7A64;          /* the quietest readable ink on paper */
    --onInk:#FFFBF2;          /* text sitting on a dark/solid fill */
    --brass-ink:#C2341F;      /* the accent when it is TEXT; a skin whose accent is a pale button colour sets a darker one */
    --line:#20190F;           /* outlines; a skin can soften these without touching text */
    --hub:#FFFBF2; --hub-ink:#20190F;
    color-scheme: light;
    /* No webfont download: these all ship on the phone, so the game keeps its
       face in a car with no signal. iOS lands on Superclarendon, Windows on
       Bookman Old Style, Linux on URW Bookman; everything else gets Georgia. */
    --display:"Superclarendon","Bookman Old Style","URW Bookman","TeX Gyre Bonum",
              "Rockwell",Georgia,serif;
    --body:"Iowan Old Style","Charter","Bitstream Charter","TeX Gyre Schola",
           "Century Schoolbook",Georgia,serif;
    --ko:"Apple SD Gothic Neo","Malgun Gothic","Noto Sans KR",sans-serif;
  }
  html { scroll-behavior:smooth; }
  body {
    margin:0; background:var(--bg);
    /* a faint laid-paper grain, not a glow */
    background-image:repeating-linear-gradient(0deg,
      rgba(32,25,15,.022) 0 1px, rgba(32,25,15,0) 1px 3px);
    color:var(--ink); font-family:var(--body);
    -webkit-text-size-adjust:100%;
    padding-top:env(safe-area-inset-top, 0px);
    padding-bottom:env(safe-area-inset-bottom, 0px);
  }
  .app {
    /* One full screen for the game, whatever is written below it. svh so the
       phone's disappearing address bar does not resize the wheel mid-spin. */
    /* min-height, not height+max-height. With the height locked, content that
       did not fit had nowhere to go: on a 320x568 phone the panel outgrew the
       box, the stage collapsed to zero and the wheel — floored at 100px — was
       painted UNDER the panel and stopped taking taps. min-height keeps the
       fill-the-screen behaviour (the stage still takes the slack) and lets the
       page scroll on the rare screen where everything genuinely cannot fit. */
    min-height:100svh; display:flex; flex-direction:column; gap:8px;
    padding-inline:16px; padding-block:10px 14px;
    max-width:560px; margin-inline:auto; box-sizing:border-box;
  }
  header { display:flex; align-items:center; gap:7px; flex-wrap:wrap; }
  /* One word since 15 Oct (was the three-word "Wheels Go Play"), so this has
     more room than it used to — but it is still tuned to stay on one line with
     the buttons beside it. Let the header wrap and it costs the wheel ~50px on
     a phone. tests/wmfit.mjs and tests/headwrap.mjs guard that. */
  /* A <p>, not an <h1>: every game page already has an <h1> naming its own
     category, and a second one repeating the site name on all 143 pages was
     the weaker of the two signals. Nothing styles it by tag. */
  .wordmark { margin:0; font-family:var(--display); font-size:clamp(13px,3.6vw,20px);
              color:var(--brass-ink); margin:0; line-height:1; white-space:nowrap;
              letter-spacing:-.005em; }
  .spacer { flex:1 1 auto; }
  .icon-btn {
    appearance:none; border:2px solid var(--line); background:var(--bg-2); color:var(--ink);
    font:inherit; font-size:12px; font-weight:700; padding:9px 14px;
    border-radius:999px; cursor:pointer; min-height:44px; min-width:44px; white-space:nowrap;
  }
  .icon-btn:hover { background:var(--bg-3); }
  .icon-btn:focus-visible { outline:2px solid var(--brass); outline-offset:2px; }

  /* The compact header, on every phone rather than only the smallest. Adding
     the game family to the wordmark pushed "New round" onto a second row at
     390 and 412 too, which cost the wheel about a hundred pixels on a Galaxy.
     A phone-width header has to stay one row; the wheel is the game. */
  @media (max-width: 440px) {
    header { gap:5px; }
    .wordmark { font-size:12.5px; }
    .icon-btn { padding:8px 9px; font-size:11px; min-width:38px; }
    .catbtn { padding:7px 11px; }
    .catbtn .ic { font-size:17px; }
    .catbtn-rule { font-size:10px; line-height:1.25; }
    /* 16px on the field stays: anything smaller makes iOS zoom on focus. */
    input[type="text"] { padding:9px 11px; }
    .panel { gap:5px; }
    .app { gap:6px; }
  }

  /* current-category button */
  .catbtn {
    appearance:none; width:100%; display:flex; align-items:center; gap:9px;
    border:2.5px solid var(--ink); background:var(--bg-2); color:var(--ink);
    font:inherit; font-size:15px; font-weight:700;
    padding:9px 14px; border-radius:10px; cursor:pointer; min-height:44px;
    box-shadow:3px 3px 0 var(--line);
  }
  .catbtn .ic { font-size:19px; line-height:1; flex:0 0 auto; }
  .catbtn-tx { flex:1 1 auto; min-width:0; display:flex; flex-direction:column; gap:1px; text-align:left; }
  .catbtn-rule { font-size:10.5px; font-weight:400; line-height:1.3; color:var(--muted); }
  /* The right-hand end has to read as a button. A small muted caret did not:
     people took the whole bar for a label and never found the language, mode,
     theme or category choices behind it (reported 14 Oct). */
  .catbtn-over { font-size:9.5px; font-weight:700; letter-spacing:.11em; text-transform:uppercase;
                 color:var(--brass-ink); line-height:1.1; }
  .catbtn-label { font-size:15px; font-weight:700; line-height:1.2; }
  .catbtn-cta { margin-left:auto; flex:0 0 auto; display:inline-flex; align-items:center; gap:4px;
                background:var(--brass); color:var(--onInk); font-size:12px; font-weight:700;
                letter-spacing:.02em; border-radius:999px; padding:6px 11px; white-space:nowrap;
                border:1.5px solid var(--ink); }
  .catbtn:hover .catbtn-cta { transform:translateY(-1px); }
  /* One-time nudge on a first visit, then never again. */
  @keyframes ctaNudge { 0%,100%{transform:none} 30%{transform:scale(1.11)} 60%{transform:scale(.98)} }
  .catbtn.nudge .catbtn-cta { animation:ctaNudge 1.1s ease-in-out 3; }
  @media (prefers-reduced-motion: reduce) { .catbtn.nudge .catbtn-cta { animation:none; } }
  .catbtn:hover { background:var(--bg-3); }
  /* Locked while a round runs. It keeps showing what is being played, so it
     should read as a label — no pointer, no hover, and NOT the faded look of a
     disabled control, which would say "broken" rather than "not now". */
  .catbtn.locked { cursor:default; opacity:1; }
  .catbtn.locked:hover { background:var(--bg-2); }
  .catbtn.locked .catbtn-cta { display:none; }
  .catbtn:active { transform:translate(2px,2px); box-shadow:1px 1px 0 var(--ink); }
  .catbtn:focus-visible { outline:2px solid var(--brass); outline-offset:2px; }

  /* category sheet */
  .sheet {
    position:fixed; inset:0; z-index:20;
    background:rgba(32,25,15,.42);
    display:flex; align-items:flex-end; justify-content:center;
  }
  .sheet-panel {
    width:100%; max-width:560px; box-sizing:border-box;
    background:var(--bg-2); border:1px solid var(--dim); border-bottom:none;
    border-radius:18px 18px 0 0;
    padding:14px 16px calc(18px + env(safe-area-inset-bottom, 0px));
    max-height:82vh; overflow-y:auto;
    box-shadow:0 -4px 0 rgba(32,25,15,.10);
  }
  .sheet-head { display:flex; align-items:center; gap:10px; margin-bottom:12px; }
  /* Four tabs have to fit a 360px phone without 한국어 breaking across two
     lines, so they share the width rather than each taking what they want. */
  .langtabs { display:flex; gap:3px; background:var(--bg); border:1px solid var(--dim);
              border-radius:999px; padding:3px; min-width:0; flex:1 1 auto; }
  .langtabs button {
    appearance:none; border:none; background:transparent; color:var(--muted);
    font:inherit; font-size:12.5px; font-weight:700; white-space:nowrap;
    flex:1 1 0; min-width:0; padding:6px 8px; border-radius:999px; cursor:pointer; min-height:32px;
  }
  @media (max-width:360px) { .langtabs button { font-size:11.5px; padding:6px 5px; } }

  /* On a 320px phone the Change chip takes width from the rule text, which
     then wrapped to four lines and stole 40px from the wheel. Cap the rule at
     two lines and tighten the chip; the bar stays the height it always was. */
  @media (max-width:360px) {
    .catbtn { padding:7px 9px; gap:7px; }
    /* the chip alone carries the message here; the overline costs 11px of wheel */
    .catbtn-over { display:none; }
    .catbtn-cta { padding:5px 8px; font-size:11px; }
    .catbtn-rule { display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
  }
  .langtabs button[aria-pressed="true"] { background:var(--brass); color:var(--onInk); }
  .langtabs button:focus-visible { outline:2px solid var(--brass); outline-offset:2px; }
  .sheet-x {
    appearance:none; margin-left:auto; border:1px solid var(--dim); background:transparent;
    color:var(--muted); font:inherit; font-size:14px; line-height:1;
    width:34px; height:34px; border-radius:50%; cursor:pointer;
  }
  .sheet-x:hover { color:var(--ink); border-color:var(--grape); }
  .sheet-x:focus-visible { outline:2px solid var(--brass); outline-offset:2px; }
  .catgrid { display:grid; grid-template-columns:repeat(auto-fill, minmax(210px, 1fr)); gap:8px; }
  .catgrid button, .catgrid a {
    appearance:none; display:flex; align-items:center; gap:9px; text-align:left;
    border:1px solid var(--dim); background:var(--bg-3); color:var(--ink);
    font:inherit; font-size:14px; font-weight:600;
    padding:11px 12px; border-radius:12px; cursor:pointer; min-height:48px; align-items:flex-start;
  }
  .catgrid button .ic, .catgrid a .ic { font-size:20px; line-height:1; flex:0 0 auto; margin-top:1px; }
  .catgrid a { text-decoration:none; }
  .catgrid button:hover, .catgrid a:hover { border-color:var(--grape); }
  .catgrid button[aria-pressed="true"], .catgrid a[aria-pressed="true"] { border-color:var(--brass-ink); background:var(--brass); color:var(--onInk); }
  .catgrid button .tx, .catgrid a .tx { flex:1 1 auto; min-width:0; display:flex; flex-direction:column; gap:2px; }
  .catgrid button .nm, .catgrid a .nm { font-weight:600; }
  .catgrid button .rule, .catgrid a .rule { font-size:10.5px; font-weight:400; line-height:1.35; color:var(--muted); }
  .catgrid button[aria-pressed="true"] .rule, .catgrid a[aria-pressed="true"] .rule { color:var(--onInk); opacity:.75; }
  .rv-rule { margin:2px 0 0; font-size:12px; line-height:1.45; color:var(--muted); max-width:46ch; }
  .catgrid button .band, .catgrid a .band {
    flex:0 0 auto; align-self:flex-start; font-size:9.5px; font-weight:700; letter-spacing:.06em; text-transform:uppercase;
    padding:2px 6px; border-radius:5px; border:1px solid currentColor; opacity:.75;
  }
  .catgrid button .band.Easy, .catgrid a .band.Easy { color:var(--good); }
  .catgrid button .band.Medium, .catgrid a .band.Medium { color:var(--brass-ink); }
  .catgrid button .band.Hard, .catgrid a .band.Hard { color:var(--coral); }
  .catgrid button[aria-pressed="true"] .band, .catgrid a[aria-pressed="true"] .band { color:var(--onInk); opacity:.65; }
  .catgrid button:focus-visible, .catgrid a:focus-visible { outline:2px solid var(--brass); outline-offset:2px; }

  /* end-of-round answer reveal */
  .rv-title { font-family:var(--display); font-size:18px; color:var(--brass-ink); margin:0 0 4px; }
  .rv-stat { margin:0 0 9px; font-size:11.5px; letter-spacing:.05em;
             text-transform:uppercase; color:var(--muted); }
  .rv-stat i { font-style:normal; color:var(--brass-ink); }
  .rv-stat.early i { color:#8A6A3C; }
  .rv-score { margin:0 0 12px; }
  .rv-h { display:block; font-family:var(--display); font-size:clamp(19px,5.4vw,24px);
          color:var(--ink); line-height:1.2; }
  .rv-h b { color:var(--brass-ink); font-weight:400; }
  .rv-sub { display:block; margin-top:4px; font-size:12.5px; color:var(--muted); line-height:1.5; }
  .rv-best { color:var(--brass-ink); }
  .rv-rest { display:block; margin-top:9px; font-size:13px; color:var(--muted); line-height:1.5; }
  .rv-score b { color:var(--ink); }
  .rv-rows { display:flex; flex-direction:column; gap:7px; }
  .rrow { display:flex; gap:7px; align-items:baseline; font-size:13px; line-height:1.5; }
  .rrow > b {
    flex:0 0 1.4em; font-family:var(--display); font-weight:400;
    color:var(--brass-ink); font-size:15px;
  }
  .rrow.ko > b { font-family:var(--ko); font-weight:700; }
  .rrow .ws { display:flex; flex-wrap:wrap; gap:4px 7px; min-width:0; }
  .rrow .ws span { color:var(--muted); }
  .rrow .ws span.got { color:var(--good); font-weight:700; }
  .rrow .ws span.got::before { content:"✓ "; }
  .rv-extra {
    margin-top:14px; padding-top:11px; border-top:1px solid var(--dim);
    font-size:13px; line-height:1.6; color:var(--muted);
  }
  .rv-extra b { color:var(--ink); }
  .rv-extra .ws { color:var(--teal); font-weight:700; }
  .rv-mine .ws { color:var(--brass-ink); font-weight:700; }
  .linky {
    appearance:none; background:none; border:none; padding:6px 0 0; margin:0;
    font:inherit; font-size:12px; color:var(--muted); text-decoration:underline;
    cursor:pointer; display:block; min-height:32px;
  }
  .linky:hover { color:var(--coral); }
  .linky:focus-visible { outline:2px solid var(--brass); outline-offset:2px; }
  .codebox { margin-top:14px; padding-top:13px; border-top:1px solid var(--dim); }
  .codebox label { display:block; font-size:12px; color:var(--muted); margin-bottom:7px; }
  .coderow { display:flex; gap:6px; }
  .coderow input {
    flex:1 1 auto; min-width:0; font:inherit; font-size:16px; letter-spacing:.12em;
    text-transform:uppercase; padding:11px 13px; border-radius:12px;
    border:1px solid var(--dim); background:var(--bg); color:var(--ink);
  }
  .coderow input::placeholder { color:var(--faint); letter-spacing:.12em; }
  .coderow input:focus-visible { outline:2px solid var(--brass); outline-offset:1px; }
  .codemsg { margin:7px 0 0; font-size:12px; line-height:1.45; color:var(--coral); min-height:1em; }
  .codemsg.ok { color:var(--good); }

  .rv-stats { color:var(--muted); font-weight:400; white-space:nowrap; }
  .rv-top { margin-top:14px; padding:10px 12px; border-radius:12px;
            background:var(--bg-3); border:1px solid var(--dim); }
  .rv-top-t { font-size:11.5px; letter-spacing:.05em; text-transform:uppercase;
              color:var(--muted); margin-bottom:7px; }
  .rv-top-r { display:flex; align-items:baseline; gap:8px; font-size:13px;
              line-height:1.7; color:var(--muted); }
  .rv-top-r > b { font-family:var(--display); color:var(--faint); width:1.1em; flex:0 0 auto; }
  .rv-top-r .n { color:var(--ink); font-weight:700; flex:0 0 auto; }
  .rv-top-r .m { flex:1 1 auto; min-width:0; font-size:12px; }
  .rv-top-r .d { flex:0 0 auto; font-size:11px; color:var(--faint); font-variant-numeric:tabular-nums; }
  .rv-top-r.mine > b, .rv-top-r.mine .n { color:var(--brass-ink); }
  .rv-top-r.mine .m { color:var(--ink); }
  .rv-top-e { font-size:12.5px; color:var(--muted); line-height:1.5; }
  .rv-code { margin-top:14px; padding:11px 12px; border-radius:12px;
             background:var(--bg-3); border:1px solid var(--dim); }
  .rv-code-l { font-size:12px; color:var(--muted); margin-bottom:7px; }
  .rv-code-row { display:flex; align-items:center; gap:8px; }
  .rv-code-row code {
    flex:1 1 auto; font-family:var(--display); font-size:clamp(17px,5vw,22px);
    letter-spacing:.1em; color:var(--brass-ink);
  }
  .rv-code-n { margin:8px 0 0; font-size:11.5px; line-height:1.45; color:var(--faint); }
  .rv-note { margin-top:12px; font-size:11.5px; color:var(--faint); line-height:1.5; }
  .rv-fact {
    margin-top:12px; padding:9px 11px; border-radius:10px;
    background:var(--bg-3); border:1px solid var(--dim);
    font-size:12.5px; color:var(--ink); line-height:1.5;
  }
  .rv-fact b { color:var(--brass-ink); }

  .stage {
    /* basis 0, not auto: the stage is purely the space left over. With basis
       auto it sized to its content — and its content is the wheel, whose size
       we set from the stage. Watching it then ratcheted the wheel smaller on
       every pass, down to 113px on a small phone. */
    /* min-height matches the floor sizeCanvas() refuses to go below (100px
       plus padding). Without it the stage could shrink past the wheel and
       the next sibling would be laid out on top of it. */
    flex:1 1 0; min-height:116px; display:grid; place-items:center;
    position:relative; touch-action:manipulation; overflow:hidden;
  }
  .wheel-wrap {
    position:relative; aspect-ratio:1; max-width:100%; max-height:100%;
    display:grid; place-items:center; cursor:pointer; user-select:none;
    -webkit-tap-highlight-color:transparent;
  }
  canvas { display:block; width:100%; height:100%; border-radius:50%; }
  .hub {
    position:absolute; width:42%; aspect-ratio:1; border-radius:50%;
    background:var(--hub);
    border:4px solid var(--line);
    box-shadow:0 0 0 5px var(--hub), 0 0 0 9px var(--line);
    display:grid; place-items:center; text-align:center; padding:6px; box-sizing:border-box;
  }
  .hub-letter { font-family:var(--display); font-size:min(14vh,17vw,92px); line-height:.9; color:var(--hub-ink); text-shadow:none; }
  .hub-letter.ko { font-family:var(--ko); font-weight:700; }
  .hub-prompt { font-size:clamp(11px,3vw,14px); font-weight:700; letter-spacing:.1em; text-transform:uppercase; color:var(--hub-ink); line-height:1.5; }
  .pointer {
    position:absolute; top:-2px; width:0; height:0;
    border-left:13px solid transparent; border-right:13px solid transparent;
    border-top:26px solid var(--ink); z-index:2;
  }

  .panel {
    display:flex; flex-direction:column; gap:7px;
    flex:0 0 auto; position:relative; z-index:1;
  }
  .cue { text-align:center; font-size:clamp(13px,3.6vw,15px); color:var(--muted); min-height:1.3em; margin:0; }
  .cue b { color:var(--ink); font-weight:700; }

  /* Floats over the wheel rather than sitting under it — on a small phone a
     box in the layout squeezed the wheel from 190px to 123px. Taps pass
     straight through to the wheel, and the first spin dismisses it for good.

     But "floats over" only looked right while the wheel was short of the
     bottom of the stage. On a laptop the wheel grows to fill the stage and the
     note landed across the bottom letters. So while the note is on screen the
     stage reserves room for it, and the wheel sizes itself into what is left.
     The height comes from JS (--fr-h) because the box wraps to two or three
     lines depending on width; the fallback covers the moment before JS runs.

     Only above 640px tall. On a small phone reserving the space took the wheel
     down to 111px, which is far worse than a note resting on the bottom rim,
     so below that it keeps the old floating behaviour. */
  @media (min-height: 640px) {
    .stage:has(.firstrun:not([hidden])) { padding-bottom: var(--fr-h, 72px); }
  }
  .firstrun {
    position:absolute; left:8px; right:8px; bottom:4px; z-index:3;
    pointer-events:none; text-align:center;
    font-size:clamp(11.5px,3.2vw,13px); line-height:1.45; color:var(--ink);
    background:var(--bg-2); border:2px solid var(--line);
    border-radius:12px; padding:8px 11px;
    box-shadow:3px 3px 0 var(--line);
  }
  /* Short and wide — a landscape phone. There is no room below the wheel, but
     plenty beside it, so the note becomes a right-hand column and the stage
     reserves width instead of height. The wheel then keeps its full height. */
  @media (orientation: landscape) and (max-height: 560px) {
    .stage:has(.firstrun:not([hidden])) { padding-bottom:0; padding-right:40%; }
    .firstrun {
      left:auto; right:10px; bottom:auto; top:50%; transform:translateY(-50%);
      width:36%; max-width:290px;
    }
  }

  .firstrun p { margin:0; color:var(--muted); }
  .firstrun p + p { margin-top:3px; }
  .firstrun b { color:var(--brass-ink); }

  .how { font-size:13.5px; line-height:1.6; color:var(--muted); }
  .how p { margin:0 0 11px; }
  .how b { color:var(--ink); }
  .how-lead { font-size:15px; color:var(--ink); font-weight:600; }
  .how ol { margin:0 0 14px; padding-left:20px; }
  .how li { margin-bottom:5px; }
  .how-box {
    background:var(--bg-3); border:1px solid var(--brass); border-radius:12px;
    padding:11px 13px; margin:0 0 13px;
  }
  .how-box-t { font-family:var(--display); font-size:15px; color:var(--brass-ink); margin:0 0 6px !important; }
  .how-box p { margin:0 !important; color:var(--ink); }
  .how-sub {
    font-family:var(--display); font-size:14px; color:var(--brass-ink);
    margin:16px 0 8px !important;
  }
  .how-fine { font-size:11.5px; color:var(--faint); }

  /* The clue: one quiet line under the cue. The description of one answer
     and its length — the letters themselves go into the answer box. */
  /* The clue has to be noticed the moment it lands — Rick's kids did not see it
     at 13px muted grey, which is the same treatment as the category rule above.
     The weight, the accent colour and the entrance do the work; the size grows
     only where there is room (clamp), so a 320px phone is barely affected and
     the wheel keeps its space. */
  .clue {
    text-align:center; font-size:clamp(13.5px, 3.8vw, 15.5px); line-height:1.3;
    font-weight:600; color:var(--brass-ink);
    margin:-4px 0 0; padding:0 4px;
  }
  /* The length is reference, not the hook: let the description own the eye. */
  .clue .len { font-weight:400; color:var(--muted); }
  .clue[hidden] { display:none; }
  /* Plays once as each clue arrives, which is the moment that was being missed. */
  @keyframes clueIn { from { opacity:0; transform:translateY(-4px); } to { opacity:1; transform:none; } }
  .clue.in { animation:clueIn .34s ease-out; }
  @media (prefers-reduced-motion: reduce) { .clue.in { animation:none; } }

  .entry { display:flex; gap:6px; }
  input[type="text"] {
    flex:1 1 auto; min-width:0; font:inherit; font-size:16px;
    padding:11px 13px; border-radius:10px;
    border:2px solid var(--line); background:var(--bg-2); color:var(--ink);
  }
  input[type="text"].wrong { border-color:var(--coral); }
  input[type="text"]::placeholder { color:var(--faint); }
  input[type="text"]:focus-visible { outline:2px solid var(--brass); outline-offset:3px; }
  .entry.shake { animation:shake .35s; }
  @keyframes shake {
    0%,100%{transform:translateX(0)} 20%{transform:translateX(-7px)}
    40%{transform:translateX(7px)} 60%{transform:translateX(-4px)} 80%{transform:translateX(4px)}
  }

  .btn {
    appearance:none; border:none; font:inherit; font-weight:700; font-size:14px;
    padding:11px 14px; border-radius:12px; cursor:pointer; white-space:nowrap; min-height:44px;
  }
  .btn-hint { background:var(--brass); color:var(--onInk); border:2px solid var(--line);
              box-shadow:2px 2px 0 var(--ink); }
  .btn-hint:active:not(:disabled) { transform:translate(2px,2px); box-shadow:none; }
  .btn-hint:disabled { background:var(--bg-3); color:var(--faint); box-shadow:none; }
  @media (prefers-reduced-motion: reduce) { .entry.shake{animation:none} }

  /* Phone on its side: stack the wheel and the controls side by side
     instead of on top of each other, so neither gets squeezed flat. */
  @media (orientation: landscape) and (max-height: 540px) {
    .app {
      display:grid; max-width:none; column-gap:16px; row-gap:6px;
      grid-template-columns:1fr 1fr;
      grid-template-rows:auto auto 1fr;
      grid-template-areas:"head panel" "cat panel" "stage panel";
    }
    header { grid-area:head; }
    .catbtn { grid-area:cat; }
    .stage  { grid-area:stage; }
    .panel  { grid-area:panel; overflow-y:auto; justify-content:center; }
    .catbtn-rule { display:none; }
    .catbtn-cta { padding:5px 9px; font-size:11.5px; }
    .log-body { max-height:30vh; }
  }
  .btn:disabled { opacity:.4; cursor:default; }
  .btn:focus-visible { outline:2px solid var(--brass); outline-offset:2px; }

  .status { display:flex; align-items:center; gap:10px; flex-wrap:wrap; font-size:12.5px; color:var(--muted); }
  .modebox { margin:0 0 13px; padding-bottom:12px; border-bottom:1px solid var(--dim); }
  .modetabs { display:flex; gap:4px; background:var(--bg); border:1px solid var(--dim);
              border-radius:999px; padding:3px; }
  .modetabs button {
    appearance:none; flex:1 1 0; border:none; background:transparent; color:var(--muted);
    font:inherit; font-size:12.5px; font-weight:700; padding:8px 6px;
    border-radius:999px; cursor:pointer; min-height:40px; white-space:nowrap;
  }
  .modetabs button[aria-pressed="true"] { background:var(--brass); color:var(--onInk); }
  .modetabs button:focus-visible { outline:2px solid var(--brass); outline-offset:2px; }
  .modenote { margin:8px 2px 0; font-size:12px; line-height:1.45; color:var(--muted); }
  .blitzlen { display:flex; align-items:center; gap:9px; margin-top:9px; }
  .blitzlen > span { font-size:12px; color:var(--muted); }
  .lenbtns { display:flex; gap:5px; }
  .lenbtns button {
    appearance:none; border:1px solid var(--dim); background:var(--bg-2); color:var(--muted);
    font:inherit; font-size:12.5px; font-weight:700; padding:0 11px; height:36px;
    border-radius:9px; cursor:pointer;
  }
  .lenbtns button[aria-pressed="true"] { border-color:var(--brass-ink); color:var(--brass-ink); }
  .lenbtns button:focus-visible { outline:2px solid var(--brass); outline-offset:2px; }

  .clock {
    font-family:var(--display); font-size:17px; color:var(--brass-ink);
    font-variant-numeric:tabular-nums; letter-spacing:.02em;
  }
  .clock.low { color:var(--coral); }
  .status .count { font-variant-numeric:tabular-nums; color:var(--ink); font-weight:700; }

  .finishbtn {
    appearance:none; border:2px solid var(--line); background:var(--bg-2); color:var(--teal);
    font:inherit; font-size:12px; font-weight:700;
    padding:8px 14px; border-radius:999px; cursor:pointer; min-height:40px; white-space:nowrap;
  }
  .finishrow { margin-top:14px; padding-top:10px; border-top:1px dashed var(--faint); }
  .finishbtn.arm { background:var(--coral); color:var(--onInk); border-color:var(--coral); }
  .finishbtn:hover { background:var(--teal); color:var(--onInk); }
  .finishbtn:focus-visible { outline:2px solid var(--brass); outline-offset:2px; }

  /* hints stepper — sets the budget before the round, tops up during it */
  .stepper { display:flex; align-items:center; gap:4px; }
  .stepper .lbl { margin-right:4px; }
  .stepper button {
    appearance:none; border:1px solid var(--dim); background:var(--bg-2); color:var(--brass-ink);
    font:inherit; font-size:15px; font-weight:700; line-height:1;
    width:40px; height:40px; border-radius:9px; cursor:pointer; padding:0;
  }
  .stepper button:hover:not(:disabled) { border-color:var(--brass-ink); }
  .stepper button:disabled { opacity:.35; cursor:default; }
  .stepper button:focus-visible { outline:2px solid var(--brass); outline-offset:2px; }
  .stepper .num {
    min-width:20px; text-align:center;
    font-variant-numeric:tabular-nums; color:var(--ink); font-weight:700; font-size:13px;
  }
  .said { display:flex; gap:6px; flex-wrap:wrap; }
  .said span {
    background:var(--bg-2); border:1px solid var(--dim); color:var(--ink);
    border-radius:8px; padding:3px 9px; font-size:12.5px;
  }
  /* An answer the game recognised, versus one it simply took your word for.
     They used to look identical, which read as "checked and approved". */
  .said span.known { border-color:var(--dim); }
  .said span.known::before { content:"\2713\00a0"; color:var(--good); font-weight:700; }
  .said span.unknown { border-style:dashed; color:var(--muted); }
  .said span.unknown::before { content:"?\00a0"; color:var(--brass-ink); font-weight:700; }
  .said span.fresh { border-color:var(--good); }
  .said span.unknown.fresh { border-color:var(--brass-ink); }

  details.log summary { cursor:pointer; font-size:12.5px; color:var(--muted); list-style:none; padding:3px 0; }
  details.log summary::-webkit-details-marker { display:none; }
  details.log summary::after { content:" ▾"; }
  details.log[open] summary::after { content:" ▴"; }
  .log-body {
    max-height:22vh; overflow-y:auto; font-size:13px; line-height:1.7;
    color:var(--muted); border-top:1px solid var(--dim); padding-top:8px;
  }
  .log-body b { color:var(--brass-ink); font-weight:700; margin-right:6px; }

  .toast { text-align:center; font-size:12.5px; font-weight:600; min-height:2.1em; line-height:1.35; color:var(--muted); margin:0; word-break:break-word; }
  .toast b { font-weight:700; }
  .toast.bad { color:var(--coral); }
  .toast.ok { color:var(--good); }
  .toast .err {
    color:var(--onInk); background:var(--coral); border-radius:3px;
    padding:0 3px; margin:0 1px; font-style:normal;
  }

  /* ---- the written page under the game -------------------------------- */
  .page-copy {
    max-width:640px; margin:0 auto; padding:30px 20px 60px;
    font-size:15.5px; line-height:1.65; color:var(--ink);
  }
  .page-copy h1 {
    font-family:var(--display); font-size:clamp(25px,7vw,34px);
    line-height:1.1; margin:0 0 14px; color:var(--brass-ink);
  }
  .page-copy h2 {
    font-family:var(--display); font-size:19px; margin:30px 0 10px; color:var(--ink);
  }
  .page-copy p { margin:0 0 14px; }
  .page-copy a { color:var(--brass-ink); text-underline-offset:2px; }
  .cat-links {
    list-style:none; margin:0; padding:0;
    display:grid; grid-template-columns:repeat(auto-fill, minmax(150px,1fr)); gap:4px 14px;
  }
  .cat-links a { display:block; padding:5px 0; }
  .copy-fine { margin-top:26px; font-size:13px; color:var(--muted); }
  .doc-page { padding-top:44px; }
  .page-copy .pending { color:var(--muted); font-style:italic; }

  /* ---- the written pages (how to play, about, privacy, contact) -------- */
  .doc-page { padding-top:34px; }
  .doc-page .crumb { margin:0 0 20px; font-size:13px; }
  .page-copy .lead { font-size:17.5px; line-height:1.55; color:var(--ink); margin-bottom:18px; }
  .page-copy h3 { font-family:var(--display); font-size:16.5px; margin:22px 0 6px; color:var(--brass-ink); }
  .page-copy ol, .page-copy ul { margin:0 0 16px; padding-left:22px; }
  .page-copy li { margin-bottom:6px; }
  .page-copy strong { font-weight:700; }
  .page-copy hr { border:0; border-top:2px solid var(--dim); margin:28px 0; }

  /* ---- the reward at the end of a finished round ---------------------- */
  .rv-unlock {
    margin-top:16px; padding:13px; border-radius:10px;
    background:var(--bg-3); border:2px solid var(--line); text-align:center;
  }
  .btn-full {
    width:100%; background:var(--teal); color:var(--onInk);
    border:2px solid var(--line); box-shadow:2px 2px 0 var(--ink);
  }
  .btn-full:active { transform:translate(2px,2px); box-shadow:none; }
  .rv-unlock-n { margin:9px 0 0; font-size:11.5px; line-height:1.5; color:var(--muted); }
  .full-lead { margin:0 0 14px; font-size:13px; line-height:1.55; color:var(--muted); }
  .full-lead b { color:var(--ink); }

  /* ---- the full word list on a category page -------------------------- */
  .wordlist { margin:0 0 10px; }
  .wl-row { display:flex; gap:10px; padding:7px 0; border-top:1px solid var(--bg-3); }
  .wl-row > b {
    flex:0 0 1.3em; font-family:var(--display); font-size:16px;
    color:var(--brass-ink); line-height:1.5;
  }
  .wl-ws { flex:1 1 auto; min-width:0; font-size:14px; line-height:1.7; color:var(--muted); }
  /* Each entry is one unbreakable unit carrying its own separator, so lines
     break BETWEEN answers. A plain space-dot-space let the line break at the
     space and start with a stray bullet; gluing the dot on with a hard space
     fixed that but let "Banana split" break across two lines instead. */
  .wl-ws span { display:inline-block; white-space:nowrap; }
  .wl-ws span::after { content:"\00b7"; color:var(--faint); margin:0 .18em 0 .42em; }
  .wl-ws span:last-child::after { content:""; }

  .page-copy .signoff {
    margin-top:30px; padding-top:16px; border-top:2px solid var(--dim);
    font-family:var(--display); font-size:15px; color:var(--brass-ink);
  }

/* ---- installed app: the game, and nothing under it ----------------------
   The copy below the wheel exists for somebody who arrived from a search
   result. Once the site is installed to a home screen it is an app, and an
   app should not have an article beneath it — so in standalone display mode
   the footer is gone entirely and the game owns the whole screen. */
@media (display-mode: standalone), (display-mode: fullscreen), (display-mode: minimal-ui) {
  .game-foot, .brandline { display: none !important; }
  /* overflow-y auto, not hidden: an installed app that cannot scroll is an
     installed app whose wheel can end up behind the panel on a short screen. */
  html, body { overflow-x: hidden; overflow-y: auto; height: 100%; }
}

/* The brand line at the foot of every page. Quiet on purpose — it is a
   signature, not a slogan, and it sits under copy that already said what
   the game is. */
.brandline {
  text-align:center; font-size:11.5px; line-height:1.5; color:var(--faint);
  margin:22px 0 14px; padding:0 16px; letter-spacing:.01em;
}

/* The one deliberate way into the answer list from the game page. */
.spoiler-link { margin-top: 1.1em; }
.spoiler-link a { font-weight: 600; }

/* ---- the reference page: a list you can study ---------------------------
   Built after a child scrolled the animal list, hit a name she had never
   heard of, and had to pick up a second phone to find out what it was. The
   answer belongs here, next to the name. */
/* Sticky, so it is still there three hundred names down — but it sits on top
   of the page, so it has to stay short. Two compact rows at phone width; the
   letter headings carry a matching scroll-margin so they land below it. */
.wl-jump {
  display:flex; flex-wrap:wrap; gap:3px; margin:0 0 18px;
  padding:5px 6px; border:2px solid var(--line); border-radius:10px;
  background:var(--bg-2); box-shadow:2px 2px 0 var(--ink);
  position:sticky; top:4px; z-index:4;
}
.wl-jump a {
  flex:1 0 auto; min-width:22px; padding:3px 0; text-align:center;
  font-family:var(--display); font-size:13.5px; line-height:1.4;
  text-decoration:none; color:var(--ink); border-radius:5px;
}
.wl-jump a:hover, .wl-jump a:focus { background:var(--brass); color:var(--onInk); }

.wl-warn { font-size:13px; color:var(--muted); margin:0 0 18px; }

.wl-letter { margin:0 0 26px; }
.wl-l {
  font-family:var(--display); font-size:30px; color:var(--brass-ink);
  margin:0 0 6px; padding-bottom:4px; border-bottom:3px solid var(--ink);
  scroll-margin-top:78px;   /* clears the sticky jump bar */
}
.wl-defs { margin:0; }
.wl-def { padding:9px 0; border-bottom:1px solid var(--bg-3); }
.wl-def dt {
  font-weight:700; color:var(--ink); font-size:15.5px;
  display:flex; align-items:baseline; gap:7px;
}
.wl-def dd { margin:2px 0 0; color:var(--muted); font-size:14.5px; line-height:1.55; }
.wl-pic { font-size:17px; line-height:1; }
.wl-def.bare dt { color:var(--muted); font-weight:600; }

/* ---- the in-game list, when the category explains itself -----------------
   Same content as the reference page, but offline and inside the app, so a
   curious player never has to leave the game to find out what a Newt is. */
.rv-rows.explain .fsec { margin:0 0 16px; }
.rv-rows.explain .fsec-l {
  font-family:var(--display); font-size:21px; color:var(--brass-ink);
  margin:0 0 2px; padding-bottom:3px; border-bottom:2px solid var(--ink);
}
.rv-rows.explain .fdef { padding:7px 0; border-bottom:1px solid var(--bg-3); }
.rv-rows.explain .fdef-w { margin:0; font-weight:700; font-size:14px; color:var(--ink); }
.rv-rows.explain .fdef-c { margin:1px 0 0; font-size:13px; line-height:1.5; color:var(--muted); }
.rv-rows.explain .fdef.got .fdef-w { color:var(--good); }
.rv-rows.explain .fdef.got .fdef-w::before { content:"\2713\00a0"; }

/* The way in to the guide for someone who is just curious, not mid-round. */
.how-guide {
  margin:0 0 14px; padding:11px 12px; border:2px solid var(--line);
  border-radius:12px; background:var(--bg-3); box-shadow:3px 3px 0 var(--line);
}
.how-guide-t { margin:0 0 2px; font-weight:700; color:var(--brass-ink); font-size:14px; }
.how-guide p { margin:0; }
.how-guide-b {
  margin-top:9px; width:100%; padding:9px 12px; font:inherit; font-weight:700;
  border:2px solid var(--line); border-radius:10px; cursor:pointer;
  background:var(--brass); color:var(--onInk);
}

/* ---- push-to-talk microphone --------------------------------------------
   State is never carried by colour alone. Roughly one man in twelve has some
   colour vision deficiency, and red/green is the pair they confuse — so ON
   and OFF differ in FOUR ways at once: fill, label text, border weight, and
   motion. Someone who cannot tell the two hues apart still cannot mistake a
   pulsing solid button for a flat outlined one.

   OFF is deliberately inert — outlined, cream, quiet. It has to look like a
   switch at rest, because that is what makes ON look dramatic by contrast.
   ON is the camera-and-tape-recorder red everyone already reads as "this is
   recording", at full fill, with a halo that breathes. */
.mic {
  display:flex; align-items:center; justify-content:center; gap:9px;
  width:100%; margin-top:7px; padding:11px 14px;
  font:inherit; font-size:15px; font-weight:700; letter-spacing:.01em;
  border:2px solid var(--line); border-radius:12px; cursor:pointer;
  background:var(--bg-2); color:var(--ink);
  box-shadow:3px 3px 0 var(--line);
  transition:background .12s, color .12s;
}
.mic-dot {
  width:13px; height:13px; border-radius:50%; flex:0 0 auto;
  background:var(--bg-3); border:2px solid var(--line);
}
.mic:active:not(:disabled) { transform:translate(2px,2px); box-shadow:none; }
.mic:disabled { opacity:.4; cursor:default; box-shadow:none; }

.mic.on {
  background:var(--brass); color:var(--onInk);
  border-width:3px; padding:10px 13px;      /* keeps the button the same size */
  box-shadow:3px 3px 0 var(--ink), 0 0 0 0 rgba(194,52,31,.55);
  animation:micPulse 1.25s ease-out infinite;
}
.mic.on .mic-dot { background:var(--onInk); border-color:var(--onInk); }

@keyframes micPulse {
  0%   { box-shadow:3px 3px 0 var(--ink), 0 0 0 0   rgba(194,52,31,.55); }
  70%  { box-shadow:3px 3px 0 var(--ink), 0 0 0 13px rgba(194,52,31,0); }
  100% { box-shadow:3px 3px 0 var(--ink), 0 0 0 0   rgba(194,52,31,0); }
}

/* The box tells you too, so the state is clear even when you are looking at
   where the words will land rather than at the button. */
.entry.listening input { border-color:var(--brass-ink); box-shadow:0 0 0 3px rgba(194,52,31,.22); }

/* Someone who has asked the system for less motion still gets the fill, the
   label and the heavier border — three signals is plenty. */
@media (prefers-reduced-motion: reduce) {
  .mic.on { animation:none; box-shadow:3px 3px 0 var(--line); }
}

/* No connection: the mic physically cannot work, so it says so rather than
   sitting there looking tappable. Dimmed, but still legible. */
.mic.offline { background:var(--bg-3); color:var(--faint); box-shadow:none; }
.mic.offline .mic-dot { background:var(--bg-3); border-color:var(--faint); }

/* The installed app's only way out to About, Privacy and Contact. */
.how-links { margin-top:10px; }
.how-links a { color:var(--brass-ink); }

/* ---- reference page with pictures ---------------------------------------
   A 64px square, not a big photo: 349 full-width images would make the page
   enormous to scroll and heavy to load. At this size you can still tell an
   axolotl from a newt, which is the whole job. The slot is the same size
   whether a photo is there or not, so nothing shifts as they load. */
.wl-def { padding:9px 0; border-bottom:1px solid var(--bg-3); }
.wl-def.haspic { display:flex; gap:11px; align-items:flex-start; }
.wl-text { flex:1 1 auto; min-width:0; }
.wl-shot {
  flex:0 0 auto; width:64px; height:64px; border-radius:9px;
  border:2px solid var(--line); background:var(--bg-3);
  object-fit:cover; display:grid; place-items:center;
}
.wl-shot-none { font-size:28px; line-height:1; color:var(--muted); }
/* Credit is required by most Commons licences — small, but never absent. */
.wl-credit { margin:3px 0 0; font-size:11px; color:var(--faint); line-height:1.4; }

/* The name is the way out to Wikipedia. Styled as a link but quietly — 349
   loud links would make the page look like a search results listing. The
   little arrow says it leaves the site, which the underline alone does not. */
/* Beats .page-copy a, which would paint all 349 of these brass and turn the
   page into something that looks like a list of search results. The name
   stays ink; only the underline and the arrow say it is a link. */
.page-copy .wl-look { color:var(--ink); text-decoration:underline;
  text-decoration-color:var(--bg-3); text-underline-offset:3px; }
.page-copy .wl-look:hover, .page-copy .wl-look:focus {
  color:var(--brass-ink); text-decoration-color:var(--brass-ink); }
.wl-out { font-size:.72em; margin-left:3px; color:var(--faint); vertical-align:super; }
.wl-look:hover .wl-out, .wl-look:focus .wl-out { color:var(--brass-ink); }

/* Same lookup link inside the game's own guide. */
.rv-rows.explain .fdef-a { color:inherit; text-decoration:underline;
  text-decoration-color:var(--faint); text-underline-offset:3px; }
.rv-rows.explain .fdef-out { font-size:.72em; margin-left:3px; color:var(--faint); vertical-align:super; }

/* The game family, after the wordmark: one brand, several games under it.
   Quieter and smaller than the brand so the eye reads "Coroplay" first
   and "Names" as the qualifier. */
.wordmark .fam { color:var(--muted); font-weight:400; font-size:.82em; letter-spacing:0; }
/* On the smallest phones there is no room for it beside three buttons — it
   wrapped the header and took the wheel down to 100px. The brand still reads
   correctly without it, and the bar underneath already says which game you
   are in, so this is the one place the family name gives way. */
@media (max-width: 345px) { .wordmark .fam { display:none; } }
/* "Palabras" and "Nouvelle partie" are each twice the width of their English
   counterparts and wrapped the header at 360px (Galaxy A-series, older
   iPhones), so on French and Spanish pages the label gives way sooner and the
   buttons tighten a notch on the smallest screens. */
@media (max-width: 375px) { html[lang="es"] .wordmark .fam, html[lang="fr"] .wordmark .fam { display:none; } }
@media (max-width: 345px) {
  html[lang="es"] .icon-btn, html[lang="fr"] .icon-btn { padding:8px 6px; font-size:10px; min-width:32px; letter-spacing:0; }
}

/* ---- 초성게임 landing: the Korean wheels as tiles ------------------------- */
.ko-tiles { list-style:none; margin:0 0 18px; padding:0; display:grid; gap:9px; }
.ko-tiles a {
  display:grid; grid-template-columns:34px 1fr; grid-template-rows:auto auto; column-gap:10px;
  padding:11px 13px; border:2px solid var(--line); border-radius:12px;
  background:var(--bg-2); color:var(--ink); text-decoration:none; box-shadow:3px 3px 0 var(--line);
}
.ko-tiles a:hover, .ko-tiles a:focus { background:var(--bg-3); }
.ko-tiles .ko-ic { grid-row:1 / span 2; font-size:26px; line-height:1; align-self:center; }
.ko-tiles b { font-size:17px; }
.ko-tiles .ko-rule { font-size:13px; color:var(--muted); line-height:1.4; }

/* English → Korean cross-link under the wheel. */
.ko-xlink { margin:14px 0 0; padding:10px 12px; border:1px solid var(--dim); border-radius:10px;
            background:var(--bg-2); font-size:14px; }
.ko-xlink a { font-weight:700; }
.ko-rom { color:var(--muted); }

/* ---- skin picker, in the ? sheet. Ten swatches in a row you can scroll;
   each is the skin's own wheel colours on its own background, so the chip
   IS the preview. Tap applies at once, behind the sheet. ---------------- */
.skins { margin:0 0 16px; }
.skins-t { margin:0 0 8px; font-weight:700; font-size:14px; color:var(--brass-ink); }
.skins:not(.skins-sheet) .skins-t::before { content:"\1F3A8 "; }
/* Wraps instead of scrolling sideways. The old row hid its scrollbar, which
   works with a thumb but leaves a mouse with no way to reach skin 8, 9 or 10
   (reported 14 Oct: nothing past Newsprint on desktop). Wrapping shows every
   skin on every device, so there is nothing to discover. */
.skin-row { display:grid; grid-template-columns:repeat(auto-fit,minmax(70px,1fr)); gap:10px 6px; padding:4px 2px 8px; }
.skin { width:auto; border:0; background:none; padding:0; cursor:pointer; font:inherit; color:var(--ink); text-align:center; }
.skin-chip { display:block; width:56px; height:56px; margin:0 auto 5px; box-sizing:border-box; border-radius:50%; border:3px solid var(--line); position:relative;
  background:conic-gradient(var(--c1) 0 25%, var(--c2) 25% 50%, var(--c3) 50% 75%, var(--c4) 75% 100%); box-shadow:0 0 0 4px var(--sbg); }
.skin-chip::after { content:""; position:absolute; inset:16px; border-radius:50%; background:var(--sbg); border:2px solid var(--line); }
.skin-n { display:block; font-size:10.5px; line-height:1.2; font-weight:700; }
.skin[aria-pressed="true"] .skin-chip { box-shadow:0 0 0 4px var(--sbg), 0 0 0 7px var(--brass); }
.skin:focus-visible { outline:2px solid var(--brass); outline-offset:2px; border-radius:8px; }
.skins-sheet { margin:4px 0 12px; padding:10px 12px 4px; border:2px solid var(--line); border-radius:12px;
  background:var(--bg-3); box-shadow:3px 3px 0 var(--line); }
.skins-sheet .skins-t { font-family:var(--display); font-size:15px; color:var(--brass-ink); margin:0 0 6px; display:flex; align-items:center; gap:8px; }
.skins-sheet .skins-t::before { content:"\1F3A8"; font-size:17px; }
.skins-sheet .skin-row { padding-bottom:6px; }
.skins-sheet .skin-row { grid-template-columns:repeat(auto-fit,minmax(62px,1fr)); }
.skins-sheet .skin-chip { width:46px; height:46px; }
.skins-sheet .skin-chip::after { inset:13px; }

/* ---- the blog. Shares the .page-copy shell with About and How to play;
   these are only the bits a list of posts needs. ---------------------- */
.post-list { list-style:none; margin:22px 0 0; padding:0; }
.post-card { padding:16px 0 18px; border-top:1.5px solid var(--dim); }
.post-card:first-child { border-top:0; padding-top:4px; }
.post-card h2, .post-card h3 { margin:4px 0 6px; font-size:21px; line-height:1.25; }
.post-card h3 { font-size:18px; }
.post-card h2 a, .post-card h3 a { text-decoration:none; }
.post-card h2 a:hover, .post-card h3 a:hover { text-decoration:underline; }
.post-card p { margin:0; color:var(--muted); }
.post-list.small .post-card { padding:12px 0; }
.post-meta { margin:0 0 10px; font-size:13px; color:var(--muted);
             display:flex; align-items:center; gap:9px; flex-wrap:wrap; }
.post-tag { font-weight:700; font-size:11.5px; letter-spacing:.08em; text-transform:uppercase;
            color:var(--onInk); background:var(--brass); border-radius:999px; padding:3px 9px; }
.post h2 { margin-top:30px; }
.post h3 { margin-top:22px; font-size:18px; }
.post hr { border:0; border-top:1.5px solid var(--dim); margin:28px 0; }
.post .post-note { color:var(--muted); font-style:italic; }
.post-table { width:100%; border-collapse:collapse; margin:16px 0; font-size:15px; }
.post-table th, .post-table td { text-align:left; padding:8px 10px 8px 0; border-bottom:1.5px solid var(--dim); vertical-align:top; }
.post-table th { font-weight:700; }
@media (max-width:420px){ .post-table { font-size:14px; } .post-card h2 { font-size:19px; } }

/* The first-run note's pointer at the top bar. Quieter than the two lines
   above it, but it is the line that makes the bar discoverable. */
.fr-bar { margin-top:8px !important; padding-top:8px; border-top:1.5px dashed var(--line);
          font-size:13px; color:var(--muted); }

/* The letter heading carries the phrase people actually search for, with the
   letter itself still doing the visual work of marking the block. */
.wl-l { display:flex; align-items:baseline; gap:10px; flex-wrap:wrap; }
.wl-l b { font-weight:inherit; }
.wl-l span { font-family:var(--body); font-size:14.5px; font-weight:400; color:var(--muted);
             letter-spacing:0; }
@media (max-width:420px){ .wl-l span { font-size:13.5px; } }

/* ---- skins (generated from src/skins.mjs) ---- */
@font-face{font-family:"Bonum";font-weight:400;font-style:normal;font-display:swap;src:url(/fonts/bonum-regular.woff2?v=acd7cf46) format("woff2");}
@font-face{font-family:"Bonum";font-weight:700;font-style:normal;font-display:swap;src:url(/fonts/bonum-bold.woff2?v=acd7cf46) format("woff2");}
@font-face{font-family:"Schola";font-weight:400;font-style:normal;font-display:swap;src:url(/fonts/schola-regular.woff2?v=acd7cf46) format("woff2");}
@font-face{font-family:"Schola";font-weight:700;font-style:normal;font-display:swap;src:url(/fonts/schola-bold.woff2?v=acd7cf46) format("woff2");}
@font-face{font-family:"Adventor";font-weight:700;font-style:normal;font-display:swap;src:url(/fonts/adventor-bold.woff2?v=acd7cf46) format("woff2");}
@font-face{font-family:"Heros";font-weight:400;font-style:normal;font-display:swap;src:url(/fonts/heros-regular.woff2?v=acd7cf46) format("woff2");}
@font-face{font-family:"Heros";font-weight:700;font-style:normal;font-display:swap;src:url(/fonts/heros-bold.woff2?v=acd7cf46) format("woff2");}
@font-face{font-family:"HerosCn";font-weight:400;font-style:normal;font-display:swap;src:url(/fonts/heroscn-regular.woff2?v=acd7cf46) format("woff2");}
@font-face{font-family:"HerosCn";font-weight:700;font-style:normal;font-display:swap;src:url(/fonts/heroscn-bold.woff2?v=acd7cf46) format("woff2");}
@font-face{font-family:"Poppins";font-weight:400;font-style:normal;font-display:swap;src:url(/fonts/poppins-regular.woff2?v=acd7cf46) format("woff2");}
@font-face{font-family:"Poppins";font-weight:700;font-style:normal;font-display:swap;src:url(/fonts/poppins-bold.woff2?v=acd7cf46) format("woff2");}
@font-face{font-family:"Lora";font-weight:400;font-style:normal;font-display:swap;src:url(/fonts/lora-regular.woff2?v=acd7cf46) format("woff2");}
@font-face{font-family:"Lora";font-weight:700;font-style:normal;font-display:swap;src:url(/fonts/lora-bold.woff2?v=acd7cf46) format("woff2");}
@font-face{font-family:"Inter";font-weight:400;font-style:normal;font-display:swap;src:url(/fonts/inter-regular.woff2?v=acd7cf46) format("woff2");}
@font-face{font-family:"Inter";font-weight:700;font-style:normal;font-display:swap;src:url(/fonts/inter-bold.woff2?v=acd7cf46) format("woff2");}
html[data-skin="kitchen"]{--bg:#F3E7D3;--bg-2:#FFFBF2;--bg-3:#E8DCC4;--ink:#20190F;--muted:#7A6A55;--faint:#8A7A64;--brass:#C2341F;--brass-ink:#C2341F;--coral:#C2341F;--teal:#2E7D63;--grape:#3C62A6;--butter:#E8B33C;--dim:#20190F;--good:#2E7D63;--onInk:#FFFBF2;--line:#20190F;--hub:#FFFBF2;--hub-ink:#20190F;color-scheme:light;--display:"Bonum","Bookman Old Style","Iowan Old Style",Georgia,serif;--body:"Schola","Bookman Old Style","Iowan Old Style",Georgia,serif;}
html[data-skin="gameshow"]{--bg:#0F1F4B;--bg-2:#1B2D63;--bg-3:#1B2D63;--ink:#FFFFFF;--muted:#B8C2E6;--faint:#8F9BCC;--brass:#FFC627;--brass-ink:#FFC627;--coral:#FFC627;--teal:#2BB3C0;--grape:#FF7A1A;--butter:#FFC627;--dim:#FFFFFF;--good:#2BB3C0;--onInk:#0F1F4B;--line:#4A5C9C;--hub:#0F1F4B;--hub-ink:#FFC627;color-scheme:dark;--display:"Adventor","Helvetica Neue",Arial,sans-serif;--body:"Heros","Helvetica Neue",Arial,sans-serif;}
html[data-skin="gameshow"] body{background-image:none;}
html[data-skin="gameshow"] .wordmark,html[data-skin="gameshow"] .catbtn-label{text-transform:uppercase;letter-spacing:.06em;}
html[data-skin="riso"]{--bg:#F2EBDD;--bg-2:#FBF7EE;--bg-3:#F2EBDD;--ink:#14213D;--muted:#5B6378;--faint:#7A8296;--brass:#FF4F1F;--brass-ink:#FF4F1F;--coral:#FF4F1F;--teal:#1F4FBF;--grape:#F2EBDD;--butter:#F2EBDD;--dim:#14213D;--good:#1F4FBF;--onInk:#FFFFFF;--line:#14213D;--hub:#FBF7EE;--hub-ink:#14213D;color-scheme:light;--display:"HerosCn","Helvetica Neue",Arial,sans-serif;--body:"HerosCn","Helvetica Neue",Arial,sans-serif;}
html[data-skin="riso"] .wordmark,html[data-skin="riso"] .catbtn-label{text-transform:uppercase;letter-spacing:.06em;}
html[data-skin="arcade"]{--bg:#8FD8F5;--bg-2:#FFFFFF;--bg-3:#FFFFFF;--ink:#111111;--muted:#555555;--faint:#6B6B6B;--brass:#FFD400;--brass-ink:#1D3FBF;--coral:#FFD400;--teal:#1FA37A;--grape:#5B8CFF;--butter:#FFD400;--dim:#111111;--good:#1FA37A;--onInk:#111111;--line:#111111;--hub:#FFFFFF;--hub-ink:#111111;color-scheme:light;--display:"Poppins","Helvetica Neue",Arial,sans-serif;--body:"Poppins","Helvetica Neue",Arial,sans-serif;}
html[data-skin="blossom"]{--bg:#FBE7EC;--bg-2:#FFF6F8;--bg-3:#F5D4DD;--ink:#35141F;--muted:#7E5262;--faint:#A5798A;--brass:#B82555;--brass-ink:#B82555;--coral:#B82555;--teal:#1F6E57;--grape:#18796F;--butter:#F6A93B;--dim:#35141F;--good:#1F6E57;--onInk:#FFF6F8;--line:#35141F;--hub:#FFF6F8;--hub-ink:#35141F;color-scheme:light;--display:"Lora","Bookman Old Style","Iowan Old Style",Georgia,serif;--body:"Lora","Bookman Old Style","Iowan Old Style",Georgia,serif;}
html[data-skin="chalk"]{--bg:#2B3A36;--bg-2:#36473F;--bg-3:#36473F;--ink:#F4F1E6;--muted:#B9C2B5;--faint:#93A098;--brass:#F2C94C;--brass-ink:#F2C94C;--coral:#F2C94C;--teal:#8FD3C7;--grape:#8EC5E8;--butter:#C9553D;--dim:#F4F1E6;--good:#8FD3C7;--onInk:#2B3A36;--line:#6B7F76;--hub:#2B3A36;--hub-ink:#F4F1E6;color-scheme:dark;--display:"Lora","Bookman Old Style","Iowan Old Style",Georgia,serif;--body:"Lora","Bookman Old Style","Iowan Old Style",Georgia,serif;}
html[data-skin="chalk"] body{background-image:none;}
html[data-skin="ocean"]{--bg:#13283F;--bg-2:#1C3652;--bg-3:#1C3652;--ink:#F1E9D6;--muted:#A9B8C9;--faint:#7F92A8;--brass:#F6C65B;--brass-ink:#F6C65B;--coral:#F6C65B;--teal:#26A69A;--grape:#B39DDB;--butter:#F6C65B;--dim:#F1E9D6;--good:#26A69A;--onInk:#13283F;--line:#476384;--hub:#13283F;--hub-ink:#F1E9D6;color-scheme:dark;--display:"Inter","Helvetica Neue",Arial,sans-serif;--body:"Inter","Helvetica Neue",Arial,sans-serif;}
html[data-skin="ocean"] body{background-image:none;}
html[data-skin="news"]{--bg:#F6F4EE;--bg-2:#FFFFFF;--bg-3:#ECE9E1;--ink:#111111;--muted:#666666;--faint:#8A8A8A;--brass:#C8102E;--brass-ink:#C8102E;--coral:#C8102E;--teal:#2E7D63;--grape:#D9D6CD;--butter:#C8102E;--dim:#111111;--good:#2E7D63;--onInk:#FFFFFF;--line:#111111;--hub:#FFFFFF;--hub-ink:#111111;color-scheme:light;--display:"Bonum","Bookman Old Style","Iowan Old Style",Georgia,serif;--body:"Schola","Bookman Old Style","Iowan Old Style",Georgia,serif;}
html[data-skin="galaxy"]{--bg:#070B24;--bg-2:#121A3F;--bg-3:#121A3F;--ink:#F2F4FF;--muted:#9AA3D4;--faint:#7079B0;--brass:#3DF0E0;--brass-ink:#3DF0E0;--coral:#3DF0E0;--teal:#3DF0E0;--grape:#FFC53D;--butter:#3DF0E0;--dim:#F2F4FF;--good:#3DF0E0;--onInk:#070B24;--line:#3B4A8C;--hub:#070B24;--hub-ink:#3DF0E0;color-scheme:dark;--display:"Inter","Helvetica Neue",Arial,sans-serif;--body:"Inter","Helvetica Neue",Arial,sans-serif;}
html[data-skin="galaxy"] body{background-image:none;}
html[data-skin="sunset"]{--bg:#FBE3D1;--bg-2:#FFF3EA;--bg-3:#F5D3BE;--ink:#3B1F3A;--muted:#8A6684;--faint:#A684A0;--brass:#D9486A;--brass-ink:#D9486A;--coral:#D9486A;--teal:#2E7D63;--grape:#6E58B5;--butter:#F2A541;--dim:#3B1F3A;--good:#2E7D63;--onInk:#FFF3EA;--line:#3B1F3A;--hub:#FFF3EA;--hub-ink:#3B1F3A;color-scheme:light;--display:"Poppins","Helvetica Neue",Arial,sans-serif;--body:"Poppins","Helvetica Neue",Arial,sans-serif;}
html[data-skin="galaxy"] body{background-image:radial-gradient(2px 2px at 12% 18%,#fff 60%,transparent 61%),radial-gradient(1px 1px at 70% 9%,#fff 60%,transparent 61%),radial-gradient(2.2px 2.2px at 88% 30%,#cfd6ff 60%,transparent 61%),radial-gradient(1px 1px at 30% 55%,#fff 60%,transparent 61%),radial-gradient(2px 2px at 60% 74%,#fff 60%,transparent 61%),radial-gradient(1px 1px at 18% 86%,#cfd6ff 60%,transparent 61%),radial-gradient(2.4px 2.4px at 82% 90%,#fff 60%,transparent 61%),radial-gradient(1px 1px at 48% 40%,#fff 60%,transparent 61%),radial-gradient(1px 1px at 93% 62%,#fff 60%,transparent 61%),radial-gradient(1.1px 1.1px at 6% 50%,#fff 60%,transparent 61%),radial-gradient(ellipse 60% 40% at 50% 42%,rgba(123,92,255,.22),transparent 70%);background-attachment:fixed;}
html[data-skin="galaxy"] canvas{box-shadow:0 0 0 3px #3DF0E0,0 0 24px 6px rgba(61,240,224,.35);}
