/* ============ DESIGN TOKENS ============ */
:root{
  --paper:#F4F5F2;
  --card:#FFFFFF;
  --ink:#182219;
  --ink-soft:#5A675D;
  --ink-faint:#8A968D;
  --pitch:#1E6B45;
  --pitch-deep:#123B27;
  --block:#1B211C;          /* blocked cells — near-black, faint green cast */
  --block-line:#1B211C;     /* same as the fill so adjacent blocks merge solid */
  --cell-line:#DFE3DD;      /* thin cell borders */
  --sel-word:#EAF3ED;
  --sel-cell:#CFE6D8;
  --wrong:#C0392B;          /* red card — a wrong letter */
  --wrong-ink:#8A2419;
  --revealed:#7A8FA6;
  --line:#D9DDD6;
  --wordbreak:#9DB3A6;      /* softened word separator */
  --cell:52px;
  --disp:"Barlow Condensed",-apple-system,"Arial Narrow",Arial,sans-serif;
  --body:"Public Sans",-apple-system,"Segoe UI",Arial,sans-serif;
  --wrong-bg:#FBE3E0;
  --gold:#F2C94C;
  --gold-ink:#3A2D00;
  --gold-ans:#F8E9B8;
  --cell-bg:#FFFFFF;
  /* Turf: a pale, desaturated field. The grid's white cells and near-black
     blocks must still dominate, so these sit only a step off --paper. */
  --turf-a:#2F7D4E;
  --turf-b:#2A7147;
  --turf-line:rgba(255,255,255,.34);
  --turf-edge:rgba(18,59,39,.45);
}
/* Theme. Follows the operating system by default — which is why the same
   build is dark on an iPad in dark mode and light on a phone that is not.
   The footer control writes data-theme to override it, so a player can
   choose rather than inherit. */
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    --paper:#12160F;
    --card:#1B2118;
  --cell-bg:#5A6356;
    --ink:#E6EAE2;
    --ink-soft:#9BA894;
    --ink-faint:#75816F;
    --pitch:#4FB07C;
    --pitch-deep:#8FD9AE;
    --block:#070907;
    --block-line:#070907;
    --cell-line:#8D9788;
    --sel-word:#47513F;
    --sel-cell:#6E8564;
    --wrong:#E3695A;
    --wrong-ink:#FFD9D3;
    --wrong-bg:#4A231D;
    --revealed:#8AA0B6;
    --line:#2A3326;
    --wordbreak:#4A5C4E;
    --gold:#C9A227;
    --gold-ink:#120E00;
    --gold-ans:#5C4E1E;
    --turf-a:#14301F;
    --turf-b:#11261B;
    --turf-line:rgba(255,255,255,.20);
    --turf-edge:rgba(0,0,0,.45);
  }
  .cell{color:var(--ink)}
  .cell.gold{color:var(--gold-ink)}
  .cell.gold-ans{color:#E9DCA8}
  .cell.wrong{color:var(--wrong-ink)}
  .dev pre{background:#141A12}
  .kick-card,.result{border-top-color:var(--pitch)}
  .grid{box-shadow:none}
}
:root[data-theme="dark"]{
  --paper:#12160F;
  --card:#1B2118;
  --cell-bg:#5A6356;
  --ink:#E6EAE2;
  --ink-soft:#9BA894;
  --ink-faint:#75816F;
  --pitch:#4FB07C;
  --pitch-deep:#8FD9AE;
  --block:#070907;
  --block-line:#070907;
  --cell-line:#8D9788;
  --sel-word:#47513F;
  --sel-cell:#6E8564;
  --wrong:#E3695A;
  --wrong-ink:#FFD9D3;
  --wrong-bg:#4A231D;
  --revealed:#8AA0B6;
  --line:#2A3326;
  --wordbreak:#4A5C4E;
  --gold:#C9A227;
  --gold-ink:#120E00;
  --gold-ans:#5C4E1E;
  --turf-a:#14301F;
  --turf-b:#11261B;
  --turf-line:rgba(255,255,255,.20);
  --turf-edge:rgba(0,0,0,.45);
}
*{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%}
body{
  background:var(--paper);color:var(--ink);font-family:var(--body);
  font-size:15px;line-height:1.5;-webkit-font-smoothing:antialiased;
}
button{font-family:inherit;cursor:pointer}
:focus-visible{outline:2px solid var(--pitch);outline-offset:2px}

/* ============ MASTHEAD ============ */
header{
  border-bottom:3px double var(--pitch-deep);
  padding:16px 20px 12px;text-align:center;
}
.masthead{
  font-family:var(--disp);font-weight:700;letter-spacing:.12em;
  font-size:clamp(24px,4vw,34px);text-transform:uppercase;
  color:var(--pitch-deep);line-height:1;
}
.masthead .ball{display:inline-block;transform:translateY(-2px);font-size:.5em;margin:0 .5em;color:var(--pitch)}
.masthead{letter-spacing:.14em}
/* The XI is the mark shared across the MatchFitness suite (Scrambled XI,
   Missing XI), so it carries the accent while the word stays ink. */
.masthead .xi{color:var(--pitch);letter-spacing:.06em}
.brandline{
  font-family:var(--disp);font-weight:500;letter-spacing:.2em;
  font-size:11.5px;text-transform:uppercase;color:var(--ink-soft);margin-top:4px;
}
.brandline .by{color:var(--ink-faint)}
.strap{
  font-family:var(--disp);font-weight:600;letter-spacing:.24em;
  font-size:10.5px;text-transform:uppercase;color:var(--pitch);margin-top:3px;
}

/* ============ TOOLBAR ============
   One bounded card, three zones: the match state (clock, position, progress),
   the point-costing help actions, and the game controls. Grouping is the point
   — a flat row of mixed-weight buttons gave no clue which ones cost you. */
.toolbar{
  display:flex;align-items:stretch;justify-content:space-between;
  gap:10px;flex-wrap:wrap;
  max-width:1180px;margin:10px auto 4px;padding:9px 11px;
  background:var(--card);border:1px solid var(--line);border-radius:12px;
  box-shadow:0 1px 2px rgba(18,59,39,.05);
}
.tb-group{display:flex;align-items:center;gap:7px;flex-wrap:wrap}
/* Help stacks into columns by kind: checking, revealing, substituting.
   Two rows, filled column-first, so Check sits above Check all and Reveal
   letter above Reveal answer without needing a wrapper per pair. */
.tb-row{
  display:grid;grid-template-rows:auto auto;grid-auto-flow:column;
  gap:6px;align-items:center;
}
#subBtn{grid-row:1 / span 2;align-self:center}
@media (max-width:560px){
  .tb-row{grid-auto-flow:row;grid-template-rows:none;grid-template-columns:1fr 1fr}
  #subBtn{grid-row:auto;grid-column:1 / span 2}
}
/* Pause is an icon: it is a single recognisable control and the word was
   taking the space of a label it did not need. */
.icon-btn{width:38px;padding:0;justify-content:center}
.icon-btn .ic{width:15px;height:15px;fill:currentColor;display:block}
.icon-btn .ic-play{display:none}
.icon-btn.playing .ic-pause{display:none}
.icon-btn.playing .ic-play{display:block}
/* Match state stacks above the controls, so the left cluster matches the
   height of the table and help group beside it and the bar reads as one
   dashboard rather than a row of loose chips. */
.tb-left{display:flex;flex-direction:column;align-items:flex-start;gap:8px}
/* The live table belongs with the clock and the solved count: they are all
   answers to "how is this going". It was in the side column, two screens away
   from the things it relates to. */
.tb-table{
  flex:0 1 auto;min-width:210px;max-width:300px;
  display:flex;flex-direction:column;gap:4px;
  padding:7px 10px 6px;border:1px solid var(--line);border-radius:9px;
  background:var(--paper);
}
.tb-table table.league{font-size:12.5px}
.tb-table table.league td{padding:2px 6px}
.tb-table table.league tr.you td{padding-top:4px;padding-bottom:4px}
.tb-table table.league tr.you td.club{font-size:13.5px}
.tb-table table.league tr.you td.pts{font-size:14px}
.tb-table .season-tag{float:none;padding:0;margin-left:4px;font-size:11px}
@media (max-width:900px){ .tb-table{min-width:0;max-width:none;flex:1 1 100%} }
/* The help group is fenced off and labelled: these are the buttons that cost
   points, and that should be legible before you press one, not after. */
.tb-help{
  position:relative;flex-direction:column;align-items:flex-start;gap:4px;
  padding:7px 10px 8px;border:1px solid var(--line);border-radius:9px;
  background:var(--paper);
}
.tb-label{
  font-family:var(--disp);font-weight:600;font-size:9.5px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--ink-faint);line-height:1;
}
/* The help label doubles as the collapse control on phones. It stays a real
   button for keyboard and screen-reader users at every width; above 640px it
   simply has nothing to collapse. */
button.tb-label{
  background:none;border:none;padding:0;cursor:default;text-align:left;
}
@media (max-width:640px){ button.tb-label{cursor:pointer} }
.toolbar .btn{padding:0 12px;height:34px;font-size:14px;white-space:nowrap;
  display:inline-flex;align-items:center;gap:4px}
.tb-sep{width:1px;height:26px;background:var(--line);margin:0 3px}
.lbl-short{display:none}
.lbl-busy{display:none}
.btn.busy .lbl-full,.btn.busy .lbl-short{display:none}
.btn.busy .lbl-busy{display:inline}
.timer{
  font-family:var(--disp);font-weight:600;font-size:19px;letter-spacing:.05em;
  min-width:66px;text-align:center;color:var(--ink-soft);
  border:1px solid var(--line);border-radius:6px;background:var(--card);
  padding:5px 10px;font-variant-numeric:tabular-nums;
}
.btn{
  font-family:var(--disp);font-weight:600;font-size:15px;letter-spacing:.06em;
  text-transform:uppercase;border-radius:6px;padding:8px 16px;
  transition:background .12s,color .12s,border-color .12s;
}
.btn.secondary{border:1px solid var(--pitch);background:var(--card);color:var(--pitch)}
.btn.secondary:hover{background:var(--sel-word)}
/* Every control carries a visible edge. The old ghost buttons had a transparent
   border and read as disabled text next to the solid primary. */
.btn.outline{border:1px solid var(--line);background:var(--card);color:var(--ink-soft)}
.btn.outline:hover{border-color:var(--ink-faint);color:var(--ink)}
.btn.ghost{border:1px solid transparent;background:none;color:var(--ink-soft)}
.btn.ghost:hover{border-color:var(--line);color:var(--ink)}
.btn.primary{border:1px solid var(--pitch);background:var(--pitch);color:#fff}
.btn.primary:hover{background:var(--pitch-deep);border-color:var(--pitch-deep)}
.btn:disabled{opacity:.5;cursor:default}
.btn .cost{
  font-size:10.5px;font-weight:600;letter-spacing:.02em;
  padding:1px 5px;border-radius:20px;background:var(--paper);
  color:var(--ink-faint);font-variant-numeric:tabular-nums;
}
.btn.secondary .cost{background:var(--sel-word);color:var(--pitch)}
.btn.primary .cost{background:rgba(255,255,255,.18);color:#fff}
.live-chip{
  font-family:var(--disp);font-weight:600;font-size:14px;letter-spacing:.04em;
  color:var(--pitch-deep);border:1px solid var(--line);border-radius:6px;
  background:var(--card);padding:5px 10px;font-variant-numeric:tabular-nums;
  white-space:nowrap;display:flex;align-items:center;gap:7px;
}
.live-chip .pos{font-size:15px;color:var(--pitch-deep)}
.live-chip .pts{color:var(--ink-soft)}
.live-chip .club{
  max-width:150px;overflow:hidden;text-overflow:ellipsis;
}
@media (max-width:1100px){ .live-chip .club{max-width:96px} }

/* ============ LAYOUT ============ */
/* One column, board first. The clue lists used to sit in a right-hand column
   beside the grid, which made the page read as a dashboard with a crossword in
   it; they now run underneath, and the board takes the full gameplay width. */
.stage{
  display:flex;flex-direction:column;align-items:center;gap:22px;
  max-width:1140px;margin:0 auto;padding:8px 16px 32px;width:100%;
}
.grid-panel{display:flex;flex-direction:column;align-items:center;gap:12px;
  min-width:0;width:100%;position:relative}
.grid-wrap > .grid{position:relative;z-index:1}

/* selected clue strip */
/* Fixed height, not auto. A one-line clue and a three-line clue used to give
   the card different heights, which moved the whole board down the page between
   answers — and moved it again when fitCells() re-measured the chrome. Sized to
   hold the longest clue in the bank (121 chars) plus its letter bank; anything
   longer scrolls rather than being clipped, because a clipped clue is unsolvable. */
.now-clue{
  width:100%;background:var(--card);border:1px solid var(--line);
  border-left:4px solid var(--pitch);border-radius:8px;
  padding:7px 9px;display:flex;align-items:center;gap:8px;
  height:96px;box-sizing:border-box;
}
.nc-main{
  flex:1;min-width:0;display:flex;flex-wrap:wrap;align-items:center;
  gap:5px 10px;                       /* row gap, column gap */
  max-height:100%;overflow-y:auto;
}
@media (max-width:900px){ .now-clue{height:118px} }
@media (max-width:560px){ .now-clue{height:132px} }
.nc-meta{
  font-family:var(--disp);font-weight:700;font-size:15px;letter-spacing:.06em;
  color:var(--pitch);white-space:nowrap;flex:none;
}
.nc-text{font-size:16px;font-weight:500;color:var(--ink);flex:1 1 auto;min-width:0}
.bank{display:flex;gap:4px;flex-wrap:wrap;align-items:center;flex:none}
.bank-cell{
  width:26px;height:30px;border:1px solid var(--line);border-radius:3px;
  display:flex;align-items:center;justify-content:center;
  font-family:var(--disp);font-weight:600;font-size:17px;color:var(--ink);
  background:var(--card);
}
.bank-cell.empty{border-style:dashed;background:transparent}
.bank-cell.wrong{background:var(--wrong-bg);color:var(--wrong-ink);border-color:var(--wrong)}
.bank-cell.gold{background:var(--gold);color:var(--gold-ink);border-color:var(--gold)}
.bank-cell.gold-ans{background:var(--gold-ans);color:#4A3A00;border-color:var(--gold-ans)}
.bank-cell.here{box-shadow:inset 0 0 0 2px var(--pitch)}
.bank-gap{width:9px}
.nc-arrow{
  background:none;border:1px solid var(--line);border-radius:6px;
  color:var(--ink-soft);font-size:17px;width:32px;height:32px;flex:none;
}
.nc-arrow:hover{background:var(--sel-word);color:var(--pitch)}

/* ============ GRID ============ */
/* ============ PITCH BACKDROP ============
   A helicopter view of the ground behind the board: mown bands and full
   markings, drawn to real 105x68 proportions. Deliberately low-contrast — §12
   keeps the grid as the main visual object, and an earlier saturated green was
   rejected for reading as a pitch where a pitch was not wanted. Here it is
   wanted, so it is a soft field the near-black grid sits on top of, not a
   colour field competing with it. Toggle in the footer; off is v05j exactly. */
/* The board: a landscape box of turf with the puzzle set inside it. Horizontal
   padding is deliberately larger than vertical, so the pitch reads as a pitch
   rather than a square, and the markings have room to show around the grid.
   Absolute positioning keeps the backdrop out of fitCells()'s measurement. */
.grid-wrap{
  /* The pitch hugs the grid rather than spanning the content width. Full width
     looked right in the abstract and wrong on a real iPad: the crossword sat
     small in the middle of an enormous pitch, which is the opposite of the
     board being the focus. The turf is a margin around the board, not a field
     the board floats on. */
  position:relative;z-index:1;align-self:center;max-width:100%;
  padding:clamp(9px,1.6vw,20px) clamp(14px,2.2vw,30px);
}
.pitch-bg{
  position:absolute;inset:0;z-index:0;border-radius:12px;
  overflow:hidden;pointer-events:none;
  background:
    repeating-linear-gradient(180deg,
      var(--turf-a) 0 34px, var(--turf-b) 34px 68px);
  box-shadow:inset 0 0 0 1px var(--turf-edge);
}
/* On phones the turf margin would come straight out of the cells, and §12.5
   protects cell size above decoration. Keep a margin, but a thin one. */
@media (max-width:700px){ .grid-wrap{padding:7px 9px} }
.pitch-bg svg{width:100%;height:100%;display:block}
.pitch-bg .pl{stroke:var(--turf-line)}
.pitch-bg .pl .spot{fill:var(--turf-line);stroke:none}
/* Pitch off restores the newspaper board: painted blocks, framed grid, no turf.
   The blocks carry the grid's structure in that mode, so they must come back. */
body.no-pitch .pitch-bg{display:none}
body.no-pitch .grid-wrap{padding:2px}
body.no-pitch .grid{
  background:var(--card);border:2px solid var(--pitch-deep);border-radius:3px;
  box-shadow:0 1px 3px rgba(18,59,39,.08);
}
body.no-pitch .cell.block{background:var(--block);border-color:var(--block-line)}
.grid{
  display:grid;gap:0;background:transparent;
  border:none;border-radius:2px;
  touch-action:manipulation;user-select:none;-webkit-user-select:none;
}
.cell{
  width:var(--cell);height:var(--cell);position:relative;background:var(--cell-bg);
  border-right:1px solid var(--cell-line);border-bottom:1px solid var(--cell-line);
  display:flex;align-items:center;justify-content:center;
  font-family:var(--disp);font-weight:600;
  font-size:calc(var(--cell) * .54);color:var(--ink);cursor:pointer;
}
/* Blocked squares are simply not painted: the pitch behind the board is the
   puzzle's background, so the turf shows through them. This reverses the
   newspaper convention in §12 deliberately — the near-black block was the
   thing making the grid read as newsprint rather than as a football game. */
.cell.block{background:transparent;border-color:transparent;cursor:default}
.cell .num{
  position:absolute;top:1px;left:3px;
  font-family:var(--body);font-weight:600;font-size:calc(var(--cell) * .22);
  color:var(--ink-faint);
}
.cell.in-word{background:var(--sel-word)}
.cell.active{background:var(--sel-cell);box-shadow:inset 0 0 0 2px var(--pitch-deep)}
.cell.wrong{color:var(--wrong-ink);background:var(--wrong-bg)}
.cell.wrong::after{
  content:"";position:absolute;inset:auto 7px 5px 7px;height:2px;border-radius:2px;
  background:var(--wrong);
}
/* Reveal Letter — locked gold cell (persists after completion) */
.cell.gold{background:var(--gold);color:var(--gold-ink)}
.cell.gold .num{color:#7A5E00}
.cell.gold::before{
  content:"";position:absolute;top:3px;right:3px;width:5px;height:5px;border-radius:50%;
  background:#8A6A00;
}
/* Reveal Answer — locked, related but lighter treatment */
.cell.gold-ans{background:var(--gold-ans);color:#4A3A00}
.cell.gold-ans .num{color:#8A7420}
.cell.gold-ans::before{
  content:"";position:absolute;top:3px;right:3px;width:5px;height:5px;border-radius:50%;
  background:#B99A2E;
}
.cell.gold.active,.cell.gold-ans.active{box-shadow:inset 0 0 0 2px var(--pitch-deep)}
/* softened multi-word separators (max 2px) */
.cell.just-solved{animation:solved .6s ease}
@keyframes solved{0%{background:var(--sel-cell)}100%{background:var(--cell-bg)}}
@media (prefers-reduced-motion:reduce){.cell.just-solved{animation:none}}
.cell.brk-r{border-right:2px solid var(--wordbreak)}
.cell.brk-b{border-bottom:2px solid var(--wordbreak)}

.stage.prestart{filter:blur(7px);pointer-events:none;user-select:none}
.kick-card{
  background:var(--card);border-radius:12px;max-width:340px;width:100%;
  padding:26px 26px 24px;text-align:center;border-top:6px solid var(--pitch);
}
.kick-card h2{
  font-family:var(--disp);font-weight:700;font-size:30px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--pitch-deep);
}
.kick-mode{
  font-family:var(--disp);font-weight:600;font-size:13px;letter-spacing:.22em;
  text-transform:uppercase;color:var(--ink-soft);margin:2px 0 16px;
}
.kick-club{display:flex;align-items:center;gap:8px;margin-bottom:18px;text-align:left}
.kick-club label{
  font-family:var(--disp);font-weight:600;font-size:12px;letter-spacing:.06em;
  text-transform:uppercase;color:var(--ink-soft);white-space:nowrap;
}
.kick-club select{
  flex:1;min-width:0;font-family:var(--body);font-size:13.5px;color:var(--ink);
  border:1px solid var(--line);border-radius:6px;background:var(--card);padding:6px 8px;
}
.kick-card .btn.primary{width:100%;font-size:18px;padding:11px}
.filters{text-align:left;margin-bottom:14px}
.filter-toggle{
  width:100%;background:none;border:1px solid var(--line);border-radius:6px;
  color:var(--ink-soft);font-family:var(--disp);font-weight:600;font-size:12px;
  letter-spacing:.1em;text-transform:uppercase;padding:7px 9px;text-align:left;
}
.filter-toggle span{float:right;color:var(--ink-faint);letter-spacing:0;text-transform:none;font-size:11.5px}
.filter-body{display:none;padding:10px 2px 0}
.filter-body.show{display:block}
.filter-group{margin-bottom:10px}
.filter-label{
  display:block;font-family:var(--disp);font-weight:600;font-size:10.5px;
  letter-spacing:.16em;text-transform:uppercase;color:var(--ink-faint);margin-bottom:5px;
}
.chips{display:flex;flex-wrap:wrap;gap:5px}
.chip{
  border:1px solid var(--line);border-radius:20px;background:var(--card);
  color:var(--ink-soft);font-family:var(--body);font-size:12px;padding:4px 10px;
}
.chip.on{background:var(--sel-word);border-color:var(--pitch);color:var(--pitch-deep);font-weight:600}
.chip .n{opacity:.55;font-size:11px;margin-left:3px}
.filter-warn{font-size:11.5px;color:#A05A00;min-height:14px;line-height:1.4}
.filter-warn.ok{color:var(--ink-faint)}
.kick-note{font-size:12px;color:var(--ink-faint);margin-top:10px}
.match-clock{
  font-family:var(--disp);font-weight:700;font-size:30px;line-height:1;letter-spacing:.02em;
  color:var(--pitch-deep);min-width:74px;text-align:center;
  border:1px solid var(--line);border-radius:8px;background:var(--card);
  padding:5px 12px 4px;font-variant-numeric:tabular-nums;
}
.match-clock small{display:block;font-size:10.5px;font-weight:600;letter-spacing:.14em;
  color:var(--ink-faint);text-transform:uppercase;margin-top:2px}
.match-clock.ht{color:#B9922E}
.season-strip{margin-top:10px}
.season-head{
  display:flex;justify-content:space-between;align-items:baseline;margin-bottom:5px;
}
.season-head .lbl{
  font-family:var(--disp);font-weight:700;font-size:11px;letter-spacing:.18em;
  color:var(--ink-faint);text-transform:uppercase;
}
.season-head .wdl{
  font-family:var(--disp);font-weight:700;font-size:12.5px;letter-spacing:.06em;
  color:var(--ink-soft);font-variant-numeric:tabular-nums;
}
.season-games{display:flex;flex-wrap:wrap;gap:2px}
.game{
  width:calc((100% - 36px) / 19);min-width:9px;height:13px;border-radius:2px;
}
.game.W{background:var(--pitch)}
.game.D{background:#B9922E}
.game.L{background:#B4483B}
.game.now{box-shadow:0 0 0 1.5px var(--ink)}
.form-strip{display:flex;align-items:center;gap:5px;margin-top:9px}
.form-strip .lbl{font-family:var(--disp);font-weight:600;font-size:11px;letter-spacing:.18em;
  color:var(--ink-faint);text-transform:uppercase;margin-right:2px}
.form-mark{
  width:21px;height:21px;border-radius:4px;display:flex;align-items:center;justify-content:center;
  font-family:var(--disp);font-weight:700;font-size:12px;color:#fff;
}
.form-mark.W{background:var(--pitch)}
.form-mark.D{background:#B9922E}
.form-mark.L{background:#B4483B}
.sheet{
  position:fixed;inset:0;background:rgba(18,34,25,.6);z-index:55;
  display:none;align-items:center;justify-content:center;padding:18px;
}
.sheet.show{display:flex}
.sheet-card{
  background:var(--card);border-radius:12px;max-width:520px;width:100%;
  max-height:92vh;overflow:auto;padding:22px 22px 20px;border-top:6px solid var(--pitch);
}
.sheet-card h2{
  font-family:var(--disp);font-weight:700;font-size:26px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--pitch-deep);margin-bottom:2px;
}
.sheet-sub{font-size:12.5px;color:var(--ink-faint);margin-bottom:16px}
.stat-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:9px;margin-bottom:18px}
.stat{border:1px solid var(--line);border-radius:8px;padding:9px 8px;text-align:center;background:var(--paper)}
.stat b{display:block;font-family:var(--disp);font-weight:700;font-size:23px;color:var(--pitch-deep);
  font-variant-numeric:tabular-nums;line-height:1.1}
.stat span{display:block;font-family:var(--disp);font-weight:600;font-size:10px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--ink-soft);margin-top:3px}
.sheet-card h3{
  font-family:var(--disp);font-weight:700;font-size:15px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--pitch-deep);
  border-bottom:2px solid var(--pitch-deep);padding-bottom:4px;margin:0 0 8px;
}
table.history{width:100%;border-collapse:collapse;font-size:13px}
table.history td{padding:6px 6px;border-bottom:1px solid var(--line);font-variant-numeric:tabular-nums}
table.history td.club{font-weight:600;color:var(--ink)}
table.history td.pos{text-align:right;font-weight:700;color:var(--pitch-deep)}
table.history td.dim{color:var(--ink-faint)}
.sheet-empty{color:var(--ink-soft);font-size:13.5px;padding:6px 0 14px}
.sheet-note{font-size:11.5px;color:var(--ink-faint);margin-top:14px;line-height:1.45}
.sheet-close{width:100%;margin-top:14px}
.toast{
  position:fixed;left:50%;transform:translateX(-50%) translateY(-8px);top:12px;z-index:60;
  background:var(--pitch-deep);color:#fff;border-radius:8px;padding:9px 16px;text-align:center;
  font-family:var(--disp);font-weight:700;letter-spacing:.1em;text-transform:uppercase;font-size:14px;
  opacity:0;pointer-events:none;transition:opacity .2s,transform .2s;box-shadow:0 4px 14px rgba(0,0,0,.22);
  max-width:90vw;
}
.toast.show{opacity:1;transform:translateX(-50%) translateY(0)}
.toast small{display:block;font-family:var(--body);font-weight:500;letter-spacing:0;
  text-transform:none;font-size:12px;opacity:.85;margin-top:2px}
.toast.loss{background:#8E3628}
.toast.draw{background:#8A6D18}
@media (prefers-reduced-motion:reduce){.sheet{
  position:fixed;inset:0;background:rgba(18,34,25,.6);z-index:55;
  display:none;align-items:center;justify-content:center;padding:18px;
}
.sheet.show{display:flex}
.sheet-card{
  background:var(--card);border-radius:12px;max-width:520px;width:100%;
  max-height:92vh;overflow:auto;padding:22px 22px 20px;border-top:6px solid var(--pitch);
}
.sheet-card h2{
  font-family:var(--disp);font-weight:700;font-size:26px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--pitch-deep);margin-bottom:2px;
}
.sheet-sub{font-size:12.5px;color:var(--ink-faint);margin-bottom:16px}
.stat-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:9px;margin-bottom:18px}
.stat{border:1px solid var(--line);border-radius:8px;padding:9px 8px;text-align:center;background:var(--paper)}
.stat b{display:block;font-family:var(--disp);font-weight:700;font-size:23px;color:var(--pitch-deep);
  font-variant-numeric:tabular-nums;line-height:1.1}
.stat span{display:block;font-family:var(--disp);font-weight:600;font-size:10px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--ink-soft);margin-top:3px}
.sheet-card h3{
  font-family:var(--disp);font-weight:700;font-size:15px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--pitch-deep);
  border-bottom:2px solid var(--pitch-deep);padding-bottom:4px;margin:0 0 8px;
}
table.history{width:100%;border-collapse:collapse;font-size:13px}
table.history td{padding:6px 6px;border-bottom:1px solid var(--line);font-variant-numeric:tabular-nums}
table.history td.club{font-weight:600;color:var(--ink)}
table.history td.pos{text-align:right;font-weight:700;color:var(--pitch-deep)}
table.history td.dim{color:var(--ink-faint)}
.sheet-empty{color:var(--ink-soft);font-size:13.5px;padding:6px 0 14px}
.sheet-note{font-size:11.5px;color:var(--ink-faint);margin-top:14px;line-height:1.45}
.sheet-close{width:100%;margin-top:14px}
.toast{transition:none}}
/* Overlaid on the foot of the pitch rather than sitting in the flow. It used
   to be a block between the board and the clue lists, so showing it — on every
   Check, every Check All, and twice per New Puzzle while "Getting the puzzle"
   came and went — moved everything below it. Taking it out of the flow means
   the page never moves when a button is pressed. */
.nudge{
  position:absolute;left:50%;bottom:10px;transform:translateX(-50%);
  z-index:3;max-width:88%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  opacity:0;visibility:hidden;transition:opacity .15s ease;
  text-align:center;font-size:13.5px;color:#7A5E00;
  background:#FBF3DA;border:1px solid #E8D9A8;border-radius:8px;padding:7px 12px;
  box-shadow:0 2px 6px rgba(18,34,25,.18);pointer-events:none;
}
.nudge.show{opacity:1;visibility:visible}
@media (prefers-reduced-motion:reduce){.nudge{transition:none}}

/* ============ CLUES ============ */
/* Two columns of the same width as the board above, with a real gutter. They
   stack below 820px rather than squeezing clue text into a narrow measure. */
.clues{
  display:grid;grid-template-columns:1fr 1fr;gap:14px 40px;
  width:100%;max-width:var(--board-w, 100%);margin:0 auto;
}
@media (max-width:820px){ .clues{grid-template-columns:1fr;gap:20px} }
.clue-col h2{
  font-family:var(--disp);font-weight:700;font-size:19px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--pitch-deep);
  border-bottom:2px solid var(--pitch-deep);padding-bottom:5px;margin-bottom:10px;
}
.clue-col ol{list-style:none}
.clue-col li{
  display:flex;gap:9px;padding:8px 9px;border-radius:6px;cursor:pointer;
  font-size:15px;line-height:1.45;border-left:3px solid transparent;
}
.clue-col li:hover{background:var(--sel-word)}
.clue-col li.active{background:var(--sel-word);border-left-color:var(--pitch)}
.clue-col li.done{opacity:.55}
.cl-num{
  font-family:var(--disp);font-weight:700;min-width:20px;text-align:right;
  color:var(--pitch);font-size:15px;padding-top:1px;
}
.cl-enum{color:var(--ink-soft);white-space:nowrap}

/* ============ CLUB + LEAGUE TABLE ============ */
/* In the header now, above the mini table: the club you pick is the table's
   identity, so the control and the table belong together. */
.club-bar{
  display:flex;align-items:center;gap:7px;margin-bottom:6px;
  font-size:13px;color:var(--ink-soft);
}
.tb-table .club-bar label{font-size:9.5px;letter-spacing:.16em;color:var(--ink-faint)}
.tb-table .club-bar select{font-size:12.5px;padding:3px 6px}
.tb-season{margin-top:5px;display:block}
.club-bar label{font-family:var(--disp);font-weight:600;letter-spacing:.06em;text-transform:uppercase;font-size:12px}
.club-bar select{
  flex:1;min-width:0;font-family:var(--body);font-size:13.5px;color:var(--ink);
  border:1px solid var(--line);border-radius:6px;background:var(--card);padding:5px 8px;
}
.table-panel{margin-top:0}
#seasonPanel{width:100%;max-width:var(--board-w, 100%);margin:0 auto}
.season-tag{
  font-family:var(--body);font-weight:600;font-size:12px;letter-spacing:0;
  text-transform:none;color:var(--ink-soft);float:right;padding-top:5px;
}
.table-panel h2{
  font-family:var(--disp);font-weight:700;font-size:19px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--pitch-deep);
  border-bottom:2px solid var(--pitch-deep);padding-bottom:5px;margin-bottom:8px;
}
table.league{width:100%;border-collapse:collapse;font-size:13.5px}
table.league td{
  padding:4px 8px;border-bottom:1px solid var(--line);font-variant-numeric:tabular-nums;
}
table.league td.pos{width:30px;color:var(--ink-soft)}
table.league td.pts{text-align:right;font-weight:600}
/* The player's row carries a much stronger identity than its neighbours */
table.league tr.you td{
  background:var(--sel-word);color:var(--pitch-deep);
  border-top:1px solid var(--pitch);border-bottom:1px solid var(--pitch);
  padding-top:7px;padding-bottom:7px;
}
table.league tr.you td.pos{box-shadow:inset 5px 0 0 var(--pitch-deep);font-weight:700;color:var(--pitch-deep)}
table.league tr.you td.club{font-weight:700;font-size:15px;letter-spacing:.01em}
table.league tr.you td.pts{font-weight:700;font-size:16px}
table.league tr.moved td{transition:background .45s ease}
table.league tr.moved.up td{background:#D8EEDF}
table.league tr.moved.down td{background:#F6E2DE}
@media (prefers-reduced-motion:reduce){table.league tr.moved td{transition:none}}
/* Game-defined zones: 1-4 Champions League, 5-6 Europe, 18-20 relegation */
table.league tr.ucl td.pos{box-shadow:inset 4px 0 0 var(--pitch)}
table.league tr.euro td.pos{box-shadow:inset 4px 0 0 #6FA8C9}
table.league tr.drop td.pos{box-shadow:inset 4px 0 0 #C25B4E}
table.league tr.zone-edge td{border-bottom:1px dashed var(--ink-faint)}
table.league tr.zone-end td{border-bottom:2px solid var(--ink-faint)}
.table-note{
  margin-top:7px;text-align:center;font-family:var(--disp);font-weight:600;
  font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-faint);
}
/* The live table is a three-row window at all widths. The full 20-team
   table belongs to Full Time, not to solving. */
/* Scoped to the row, not the container. This was `.table-panel tr.faroff`, so
   moving the live table into the toolbar silently un-hid the other 17 rows and
   the full league table appeared in the header. The rule belongs to the row:
   renderLeagueRows() marks what is outside the three-row window, and it should
   stay hidden wherever the table is rendered. */
tr.faroff{display:none}

/* ============ ON-SCREEN KEYBOARD ============ */
.osk{
  position:sticky;bottom:0;z-index:20;display:none;
  background:var(--paper);border-top:1px solid var(--line);
  padding:6px 4px calc(6px + env(safe-area-inset-bottom));
  /* Two dials, so height and width are tuned independently. Keys used to be
     capped at 44px wide, which on a tablet left the keyboard huddled in the
     middle of the screen with small letters and a lot of empty space either
     side. Width now scales with the viewport; height is scaled by viewport
     height, because that is the scarce dimension in landscape. */
  /* The widest row is 10 keys, so the floor has to fit the narrowest phone:
     10 keys + 9 gaps + padding must clear 320px. 27 + 9x3 + 8 = 305. */
  --osk-key:clamp(27px,8vw,64px);
  --osk-h:clamp(34px,5.4vh,52px);
  --osk-gap:clamp(3px,0.7vw,8px);
}
body.touch .osk{display:block}
.osk-row{display:flex;justify-content:center;gap:var(--osk-gap);margin-bottom:var(--osk-gap)}
.osk-key{
  flex:0 0 auto;width:var(--osk-key);height:var(--osk-h);
  border:1px solid var(--line);border-radius:6px;
  background:var(--card);font-family:var(--disp);font-weight:600;
  /* Clamped, not purely proportional: a plain ratio would have made the
     letters smaller on a phone than they were before, while fixing the tablet. */
  font-size:clamp(16px,calc(var(--osk-key) * .42),26px);color:var(--ink);
}
.osk-key:active{background:var(--sel-cell)}
.osk-key.wide{width:calc(var(--osk-key) * 1.5);font-size:clamp(14px,calc(var(--osk-key) * .32),20px)}

/* ============ COMPLETION ============ */
.overlay{
  position:fixed;inset:0;background:rgba(18,34,25,.6);z-index:50;
  display:none;align-items:center;justify-content:center;padding:20px;
}
.overlay.show{display:flex}
.result{
  background:var(--card);border-radius:12px;max-width:400px;width:100%;
  padding:26px 26px 24px;text-align:center;border-top:6px solid var(--pitch);
  animation:pop .35s cubic-bezier(.2,1.4,.4,1);
}
@keyframes pop{from{transform:scale(.92);opacity:0}to{transform:scale(1);opacity:1}}
@media (prefers-reduced-motion:reduce){.result{animation:none}}
.result h2{
  font-family:var(--disp);font-weight:700;font-size:26px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink-soft);
}
.res-pos{
  font-family:var(--disp);font-weight:700;font-size:64px;line-height:1;
  color:var(--pitch-deep);margin:6px 0 0;
}
.res-pos-label{
  font-family:var(--disp);font-weight:600;font-size:13px;letter-spacing:.22em;
  text-transform:uppercase;color:var(--ink-soft);margin-bottom:12px;
}
.res-score{
  font-family:var(--disp);font-weight:700;font-size:30px;color:var(--pitch);
  margin-bottom:16px;font-variant-numeric:tabular-nums;
}
.res-score small{font-size:17px;font-weight:600;color:var(--ink-soft)}
.res-club{
  font-family:var(--disp);font-weight:600;font-size:17px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--pitch);margin-top:2px;
}
.res-msg{font-size:14.5px;color:var(--ink);margin:0 0 14px;font-weight:500}
.res-final{
  display:flex;justify-content:space-between;padding:7px 6px 0;font-size:14px;
  font-family:var(--disp);font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  color:var(--pitch-deep);
}
.res-table-wrap{max-height:34vh;overflow:auto;margin-bottom:14px;border:1px solid var(--line);border-radius:8px}
.res-table-wrap table.league{font-size:12.5px}
.view-grid{
  background:none;border:0;color:var(--ink-soft);text-decoration:underline;
  font-size:12.5px;margin-top:10px;
}
.result{max-width:430px;max-height:92vh;overflow:auto}
.breakdown{
  border-top:1px solid var(--line);border-bottom:1px solid var(--line);
  padding:10px 4px;margin-bottom:14px;font-size:14px;
}
.breakdown .row{display:flex;justify-content:space-between;padding:3px 6px}
.breakdown .row span:first-child{color:var(--ink-soft);text-transform:uppercase;font-size:12px;letter-spacing:.08em;font-family:var(--disp);font-weight:600;padding-top:2px}
.breakdown .row b{font-variant-numeric:tabular-nums;font-weight:600}
.breakdown .row .pen{color:#A05A00;margin-left:10px;min-width:34px;text-align:right;display:inline-block}
.mini-table{
  width:100%;border-collapse:collapse;margin-bottom:18px;font-size:13.5px;
}
.mini-table th{
  font-family:var(--disp);font-weight:600;font-size:11px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink-faint);text-align:left;padding:2px 8px;
}
.mini-table th:last-child,.mini-table td:last-child{text-align:right}
.mini-table td{padding:5px 8px;border-top:1px solid var(--line);font-variant-numeric:tabular-nums}
.mini-table tr.you td{
  background:var(--sel-word);font-weight:700;color:var(--pitch-deep);
}

/* ============ FOOTER / DEV ============ */
footer{
  text-align:center;padding:8px 0 20px;color:var(--ink-faint);font-size:11.5px;
}
footer button{background:none;border:0;color:var(--ink-faint);text-decoration:underline;font-size:11.5px}
.dev{
  max-width:1080px;margin:0 auto 30px;padding:16px;background:var(--card);
  border:1px solid var(--line);border-radius:10px;display:none;
}
.dev.show{display:block}
.dev h3{font-family:var(--disp);letter-spacing:.1em;text-transform:uppercase;color:var(--pitch-deep);margin-bottom:8px}
.dev .dev-actions{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:10px}
.dev .btn{font-size:13px;padding:6px 12px}
.dev pre{
  background:#F7F8F5;border:1px solid var(--line);border-radius:6px;padding:10px;
  font-size:11.5px;overflow:auto;max-height:380px;white-space:pre;
}

/* ============ RESPONSIVE ============ */
@media (max-width:900px){
  /* The stage is flex now; grid-template-columns here was left over from the
     two-column layout and did nothing. The .clues override did do something,
     and it was wrong: this block sits after the 820px stacking rule, so it won
     the cascade and forced two columns from 641px to 820px — exactly the width
     where the clue text needed to stack. Removed rather than reordered. */
  .stage{gap:16px;padding-bottom:8px}
  header{padding:12px 12px 9px}
}
@media (max-width:640px){
  .clues{grid-template-columns:1fr;gap:8px}
  /* The toolbar was taking three rows before the puzzle appeared. */
  .toolbar{gap:5px;padding:8px 6px 5px}
  .toolbar .btn{font-size:12.5px;padding:6px 8px;letter-spacing:.03em}
  .lbl-full{display:none}
  .lbl-short{display:inline}
  .toolbar .cost{font-size:10px;margin-left:2px}
  .tb-sep{display:none}
  .match-clock{font-size:22px;min-width:56px;padding:3px 8px 3px}
  .match-clock small{font-size:9px;letter-spacing:.08em}
  .live-chip{font-size:12px;padding:4px 7px;gap:5px}
  .live-chip .pos{font-size:13px}
  .live-chip .club{max-width:74px}
  .nc-text{font-size:15px;flex:1 1 100%}
  .now-clue{padding:6px 7px;gap:6px}
  .nc-main{gap:4px 8px}
  .nc-arrow{width:28px;height:28px;font-size:15px}
  .bank-cell{width:22px;height:26px;font-size:15px}
  /* Club selection lives on the Kick Off card; the duplicate control
     just pushed the clue list further down the page. */
  .club-bar{display:none}
  header{padding:9px 10px 7px}
  .masthead{font-size:22px}
  .strap{font-size:9.5px;letter-spacing:.2em;margin-top:3px}
  .stage{padding:6px 8px 8px;gap:10px}

  /* The header was taking half the screen before a single square was visible:
     clock, controls, a full three-row league table and a 2x2 help grid, then
     the clue card. On a 390px phone that left about four grid rows above the
     keyboard. The table collapses to your own row here — position and points,
     which is what you glance at mid-solve — and the full table is still shown
     at Full Time. */
  #tablePanel tbody tr:not(.you){display:none}
  #tablePanel tr.you td{padding-top:4px;padding-bottom:4px}
  .tb-table{padding:5px 8px 5px;min-width:0;flex:1 1 100%}
  .tb-season{font-size:8.5px;margin-top:3px}
  .tb-help{padding:5px 7px 6px;flex:1 1 100%}
  .tb-help.collapsed .tb-row{display:none}
  .tb-help.collapsed{padding-bottom:5px}
  .help-toggle::after{content:" \25BE";font-size:8px}
  .tb-help.collapsed .help-toggle::after{content:" \25B8"}

  /* Phone header, in three lines rather than five:
       clock · solved · pause · new
       check · all · letter · answer
       (the league table has moved below the board)
     Each is one row, so the board starts far higher up the screen. */
  .tb-left{flex-direction:row;flex-wrap:nowrap;align-items:center;gap:5px}
  .tb-match,.tb-game{gap:5px;flex-wrap:nowrap}
  .tb-row{grid-template-columns:repeat(4,1fr);grid-auto-flow:row;
    grid-template-rows:none;gap:4px}
  .tb-row .btn{padding:0 5px;font-size:11px;letter-spacing:.02em;height:30px;
    justify-content:center;gap:3px}
  .tb-row .cost{font-size:9px;padding:0 4px}
  #subBtn{grid-row:auto;grid-column:1 / span 4}

  /* Moved out of the header, the table is a panel in its own right. */
  #tablePanel.below-board{
    width:100%;border:1px solid var(--line);border-radius:9px;
    background:var(--paper);padding:7px 10px;margin:0;
  }
  #tablePanel.below-board tbody tr{display:table-row}
  #tablePanel.below-board tbody tr.faroff{display:none}
  #tablePanel.below-board .club-bar{display:flex;margin-bottom:6px}
  #tablePanel.below-board .tb-season{display:block;margin-top:4px}
  .tb-label{font-size:8.5px;letter-spacing:.12em}
  .toolbar .btn{height:30px}
  .icon-btn{width:34px}
  /* 132px of clue card is a lot of a phone screen. Two lines plus the bank
     still fit; the height stays fixed so the board does not jump. */
  .now-clue{height:112px}
  .grid-wrap{padding:5px 6px}
}


/* ============ SHORT AND LANDSCAPE: GIVE THE BOARD THE HEIGHT ============
   On a landscape tablet the header, toolbar, clue card and on-screen keyboard
   together leave the grid only a few hundred pixels, so the cells come out
   small however wide the page is — height binds, not width. These rules trim
   the chrome rather than the board. Nothing here changes on a desktop monitor,
   where there is height to spare. */
@media (orientation:landscape) and (max-height:1100px){
  header{padding:8px 20px 6px}
  .masthead{font-size:clamp(20px,2.6vw,26px)}
  .brandline{display:none}          /* the masthead already says it */
  .strap{font-size:9.5px;margin-top:2px}
  .toolbar{padding:7px 9px;margin:7px auto 3px}
  .tb-table table.league td{padding:1px 6px}
  .tb-table .club-bar{margin-bottom:4px}
  .now-clue{height:64px}            /* one line plus the bank, which is inline here */
  .stage{gap:14px;padding:6px 16px 24px}
  .grid-wrap{padding:10px 16px}
  /* Keyboard height is the last thing standing between the board and the space
     it needs. Keys stay wide — width costs nothing here — but lose a little
     height, which goes straight into the cells. */
  .osk{padding:3px 4px calc(3px + env(safe-area-inset-bottom));--osk-h:clamp(30px,4vh,38px);
    --osk-gap:clamp(4px,0.6vw,7px)}
  .stage{padding-top:4px}

  .tb-help{padding:5px 9px 6px}
  .tb-label{font-size:9px}
}

/* Narrow landscape — a small tablet or a phone on its side. No room for a rail,
   so the toolbar stays on top and gives back what it can: the league table
   collapses to your own row with the club inline. The full table is still shown
   at Full Time. */
@media (orientation:landscape) and (max-height:1100px) and (max-width:859px){
  #tablePanel tbody tr:not(.you){display:none}
  #tablePanel tr.you td{padding-top:3px;padding-bottom:3px}
  .tb-table{flex-direction:row;align-items:center;gap:10px;padding:5px 10px}
  .tb-table .club-bar{margin-bottom:0;flex:0 0 auto}
  .tb-table table.league{width:auto;min-width:190px}
  .tb-season{display:none}
}

/* ============ LANDSCAPE TABLET: RAIL BESIDE THE BOARD ============
   The first version gridded the body, which put the rail beside the *stage*
   rather than beside the board — so the rail ran the height of the whole page
   while the board sat somewhere in the middle of the column, and the panels
   inside the rail spilled past the card that was supposed to hold them.

   This grids the stage instead, so the rail is a genuine column next to the
   grid: the active clue spans both, the rail stretches to the board's height,
   and the clue lists run full width underneath. The toolbar is moved into the
   stage by script, since it is a sibling of it in the markup. */
@media (orientation:landscape) and (max-height:1100px) and (min-width:860px){
  .stage{
    display:grid;align-items:start;
    /* v07g: the landscape layout has one deterministic measure. The rail width
       comes only from the viewport, never from its button/table contents, and
       --block-w is published from the puzzle dimensions. That removes the
       feedback loop where selecting a clue could re-measure the board and move
       the whole middle row by a few pixels. */
    --rail-w:clamp(230px,23.5vw,280px);
    --pair-gap:18px;
    width:min(100%,var(--block-w,1140px));max-width:1140px;margin:0 auto;
    grid-template-columns:var(--rail-w) max-content;
    justify-content:center;
    column-gap:var(--pair-gap);row-gap:10px;
  }
  /* The card ends where its content ends. Stretching it to the board's height
     left a couple of hundred pixels of empty white below the help buttons. */
  .toolbar{align-self:start}
  /* The panel's children become items of the stage grid, so the clue strip and
     the board can be placed independently without unwrapping the markup. */
  .grid-panel{display:contents}

  .now-clue{
    grid-column:1 / -1;grid-row:1;
    /* Match the exact combined width of the rail + board, rather than running
       across the whole tablet. This makes the top clue finish at the board edge. */
    width:min(100%,var(--block-w,100%));justify-self:center;
  }
  .toolbar{
    grid-column:1;grid-row:2;
    flex-direction:column;align-items:stretch;
    margin:0;max-width:none;gap:8px;
  }
  .grid-wrap{grid-column:2;grid-row:2;justify-self:center}
  .clues{
    grid-column:1 / -1;grid-row:4;
    width:min(100%,var(--block-w,100%));justify-self:center;
  }
  #seasonPanel{
    grid-column:1 / -1;grid-row:5;
    width:min(100%,var(--block-w,100%));justify-self:center;
  }

  /* The base toolbar is a row with space-between. Turned on its side that
     distributes the panels down the card, which is where the gaps between the
     controls, the table and the help block were coming from. */
  .toolbar{justify-content:flex-start}
  .tb-left{flex-direction:column;align-items:stretch;gap:8px}
  .tb-match,.tb-game{justify-content:flex-start}
  /* Inside the rail the panels are the card's contents, not free-floating
     boxes: they lose their own background so the card reads as one panel. */
  .tb-table,.tb-help{
    flex:0 0 auto;max-width:none;min-width:0;
    background:none;border:none;padding:0;
  }
  .tb-help{border-top:1px solid var(--line);padding-top:8px}
  /* minmax(0,1fr), not 1fr: a plain 1fr track will not shrink below its
     content, so "REVEAL ANSWER -9" pushed the buttons out through the side of
     the card. Short labels as well, because the rail is 280px wide. */
  .tb-row{grid-auto-flow:row;grid-template-rows:none;
    grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
  .tb-row .btn{min-width:0;padding:0 8px}
  .tb-row .lbl-full{display:none}
  .tb-row .lbl-short{display:inline}
  #subBtn{grid-row:auto;grid-column:1 / span 2}

  .grid-wrap{justify-self:start}
  /* Tighter clue rows: at this width every clue fits on one line, so the list
     can show all of them above the keyboard rather than two. */
  .clue-col li{padding:4px 8px;font-size:14px;line-height:1.35}
  .clue-col h2{font-size:16px;padding-bottom:3px;margin-bottom:5px}
  .clues{gap:10px 46px}
  /* Keep the clue lists on the same measure as the combined rail + board.
     They are still wide enough for two readable columns, but no longer create
     a full-viewport line that visually pulls the layout back toward the left. */
  .clues,#seasonPanel{max-width:var(--block-w,100%)}
  .clues{gap:14px 46px}
}

@media (orientation:landscape) and (max-height:820px){
  .masthead{font-size:20px}
  .strap{display:none}
  .now-clue{height:68px}
  .osk{--osk-h:clamp(30px,4.2vh,38px)}
}

/* ============ BUILD BADGE (temporary) ============
   Pinned top-right so the deployed build is visible in any screenshot without
   scrolling. Sits below the overlays (z-index 50+) so it never covers Kick Off
   or Full Time. Delete this block and the element in index.html when the
   layout is settled. */
.build-badge{
  position:fixed;top:0;right:0;z-index:40;
  font-family:var(--disp);font-weight:700;font-size:11px;letter-spacing:.14em;
  background:var(--gold);color:var(--gold-ink);
  padding:3px 9px;border-radius:0 0 0 7px;pointer-events:none;
  box-shadow:0 1px 3px rgba(0,0,0,.25);
}

/* ============ ACCOUNT SHEET ============
   Reuses the My Season sheet's furniture. Nothing here appears unless the
   player opens it: accounts are optional and must not intrude on a game that
   works perfectly well without one. */
.acct-why{
  font-size:14.5px;line-height:1.55;color:var(--ink-soft);margin:0 0 16px;
}
.acct-provider{display:flex;justify-content:center;min-height:44px;margin-bottom:10px}
.acct-note{font-size:13px;color:var(--ink-faint);margin:0}
.acct-field{display:block;text-align:left;margin-bottom:14px}
.acct-field span{
  display:block;font-family:var(--disp);font-weight:600;font-size:11px;
  letter-spacing:.16em;text-transform:uppercase;color:var(--ink-faint);margin-bottom:5px;
}
.acct-field input{
  width:100%;font-family:var(--body);font-size:15px;color:var(--ink);
  border:1px solid var(--line);border-radius:7px;background:var(--card);
  padding:9px 10px;
}
.acct-actions{display:flex;gap:8px;justify-content:center;margin-bottom:12px}
.acct-actions .btn{height:36px}
