/* Sapper's Field skin: a surveyor's field map under one lamp. Black Ops One (stencil) for the title, the map's
   coordinates and the plot numbers; IBM Plex Sans for everything read. Art bible §5: one key light from the top left
   (pads, case, objects, dial), a recessed window for the field, contact shadows, one static grain layer on the scene,
   motion on transform / opacity only. Colour tokens come from skin.js themeMap (readable on light and dark presets
   and custom colours); light and shade are colour-neutral white / black overlays, so they follow any preset. */
:root{--display:"Black Ops One",system-ui,sans-serif;--ui:"IBM Plex Sans",system-ui,sans-serif;--radius:12px;--radius-sm:8px;--prim-radius:12px;--cell:56px;--gap:5px;--co:19px;--pad:10px;
  --brass:#C9A646;--brass-hi:#F6E7B0;--brass-lo:#5E4712}
/* Black Ops One has one weight: never let the browser fake a bold */
.logo h1,.spin.tprim,.ovcard h2,.panel h2,.panel h3,.btn{font-weight:400}
/* the title: stencilled on the sheet, pressed in a little (a shadow straight down: the centring is untouched) */
.logo h1{letter-spacing:.04em;text-shadow:0 1px 0 rgb(0 0 0 / .32)}
/* the wide stencil: panel titles wrap before the close key instead of running under it */
.panel h2{padding-right:46px}
@media (max-width:400px){.panel h2{font-size:25px}}

/* the sheet behind: layer-tinted hills (each closed contour adds a breath of paper: the tops are the lightest ground),
   contour lines, a survey grid with crosses at its corners, a track and a stream ("plain": the ground only); one static
   grain layer over it (never on the plots). Kept low in contrast (a far layer): text that runs over it — the title and
   the message line — still reads at 4.5:1 where it crosses a line */
.sf-topo svg{width:100%;height:100%;display:block}
.sf-contour path{fill:var(--topo-fill);fill-opacity:.02;stroke:var(--topo);stroke-width:1.3;vector-effect:non-scaling-stroke}
.sf-contour path.idx{stroke:var(--topo-idx);stroke-width:2.2}
.sf-survey{fill:none;stroke:var(--survey);stroke-width:1;vector-effect:non-scaling-stroke}
.sf-cross{fill:none;stroke:var(--survey-cross);stroke-width:1.2;vector-effect:non-scaling-stroke}
.sf-stream{fill:none;stroke:var(--topo-idx);stroke-width:3.2;stroke-linecap:round;opacity:.5;vector-effect:non-scaling-stroke}
.sf-track{fill:none;stroke:var(--topo-idx);stroke-width:1.6;stroke-dasharray:16 10;opacity:.6;vector-effect:non-scaling-stroke}
.sf-topo::after{content:"";position:absolute;inset:0;pointer-events:none;opacity:.07;mix-blend-mode:overlay;background-size:160px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .5 0 0 0 0 .5 0 0 0 0 .5 0 0 0 .5 0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E")}
body[data-variant="plain"] .sf-topo{display:none}

/* the board fills the stage between the results strip and the mine choice (never more: main.js fits the field in it) */
.table-game #board{flex:1 1 auto;align-self:stretch;position:relative;min-height:0}
.sf{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px}
.sf-defs{position:absolute;width:0;height:0;overflow:hidden}
/* too short even for 44 px plots without the plate (320 × 480): the field scrolls inside the board */
.sf.scroll{justify-content:flex-start;overflow-y:auto;overscroll-behavior:contain;padding:3px 0}

/* the status plate: one legend strip — mines | safe plots | the next step and its chance */
.sf-plate{display:flex;flex-wrap:nowrap;justify-content:center;max-width:100%;border-radius:8px;background:var(--sheet);border:1px solid var(--sheet-line);box-shadow:0 1px 0 rgb(0 0 0 / .22)}
.sf-pv{display:flex;align-items:baseline;gap:6px;min-height:28px;padding:6px 12px;white-space:nowrap;font-variant-numeric:tabular-nums}
.sf-pv+.sf-pv{border-left:1px solid var(--sheet-line)}
.sf-pv i{font:600 12px/1 var(--ui);font-style:normal;color:var(--muted)}
.sf-pv b{font:700 16px/1 var(--ui);color:var(--ink)}
.sf-pv small{font-size:12px;font-weight:600;color:var(--muted)}
.sf-plate.struck .sf-pn i,.sf-plate.struck .sf-pn b{color:var(--alert)}

/* the map case: a canvas-bound board with four brass eyelets, lit from the top left (bevel and a soft fall-off to the
   lower right), one shadow under it; the coordinates A–E across and 1–5 down are stencilled on it */
.sf-sheet{--eye:calc(var(--pad) * .55 + 1px);--eyelet:var(--brass-hi) 0 .9px,var(--brass) 1.5px,var(--brass-lo) 2.7px,transparent 3.2px;
  position:relative;isolation:isolate;display:grid;grid-template-columns:var(--co) auto;grid-template-rows:var(--co) auto;padding:var(--pad) calc(var(--pad) + var(--co) * .5) var(--pad) var(--pad);
  border-radius:10px;background-color:var(--sheet);
  background-image:radial-gradient(circle at var(--eye) var(--eye),var(--eyelet)),radial-gradient(circle at calc(100% - var(--eye)) var(--eye),var(--eyelet)),
    radial-gradient(circle at var(--eye) calc(100% - var(--eye)),var(--eyelet)),radial-gradient(circle at calc(100% - var(--eye)) calc(100% - var(--eye)),var(--eyelet)),
    linear-gradient(135deg,rgb(255 255 255 / .1),transparent 36%,transparent 62%,rgb(0 0 0 / .18)),
    repeating-linear-gradient(90deg,rgb(0 0 0 / .05) 0 1px,transparent 1px 3px),repeating-linear-gradient(0deg,rgb(255 255 255 / .03) 0 1px,transparent 1px 3px);
  box-shadow:inset 1px 1px 0 rgb(255 255 255 / .14),inset -1px -1px 0 rgb(0 0 0 / .3),0 0 0 1px rgb(0 0 0 / .3),0 22px 44px -18px rgb(0 0 0 / .7)}
.no-coords .sf-sheet{padding-right:var(--pad)}
.sf-ch{grid-column:2;grid-row:1;display:grid;grid-template-columns:repeat(5,var(--cell));gap:var(--gap)}
.sf-rh{grid-column:1;grid-row:2;display:grid;grid-template-rows:repeat(5,var(--cell));gap:var(--gap)}
.sf-ch i,.sf-rh i{display:grid;place-items:center;font:400 13px/1 var(--display);font-style:normal;color:var(--sheet-ink);text-shadow:0 1px 0 rgb(0 0 0 / .25)}
.sf-ch i{align-items:start}
.no-coords .sf-ch,.no-coords .sf-rh{display:none}
.sf-north{display:none;position:absolute;left:calc(100% + 14px);top:2px;width:20px;height:30px;color:var(--muted)}
.sf-north svg{width:100%;height:100%}
.wide .sf-north{display:block}

/* the field in its recessed window: the light from above throws a shadow into the top of the niche, a thin lit lip
   at its foot; raised turf-canvas pads stand in it */
.sf-grid{grid-column:2;grid-row:2;position:relative;display:grid;grid-template-columns:repeat(5,var(--cell));grid-auto-rows:var(--cell);gap:var(--gap)}
.sf-grid::before{content:"";position:absolute;inset:calc(var(--gap) * -1 - 1px);z-index:-1;border-radius:7px;background:var(--niche);pointer-events:none;
  box-shadow:inset 0 12px 14px -8px rgb(0 0 0 / .55),inset 0 -1px 0 rgb(255 255 255 / .12),inset 0 0 0 1px rgb(0 0 0 / .28)}
.sf-t{--pad-face:var(--turf);position:relative;padding:0;border:0;border-radius:4px;color:var(--paper-ink);overflow:hidden;touch-action:manipulation;
  background:linear-gradient(150deg,var(--pad-lit),transparent 40%,transparent 58%,var(--pad-shade)),var(--pad-face);
  box-shadow:inset 1px 1px 0 var(--pad-lit),inset -1px -2px 0 var(--turf-edge),0 2px 0 rgb(0 0 0 / .3);
  transition:transform var(--t-press,90ms) var(--ease-out,ease-out)}
/* the canvas weave (a fine diagonal twill, static) */
.sf-t::before{content:"";position:absolute;inset:0;pointer-events:none;opacity:.5;
  background:repeating-linear-gradient(45deg,var(--weave) 0 1px,transparent 1px 5px),repeating-linear-gradient(-45deg,var(--weave) 0 1px,transparent 1px 5px)}
/* a closed plot carries a survey mark (a ring on a cross); it grows under the pointer when the plot can be opened */
.sf-t::after{content:"";position:absolute;left:50%;top:50%;width:30%;height:30%;translate:-50% -50%;scale:var(--mark,1);pointer-events:none;
  transition:scale var(--t-fast,140ms) var(--ease-out,ease-out);
  background:linear-gradient(var(--cross),var(--cross)) center/100% 1.5px no-repeat,linear-gradient(var(--cross),var(--cross)) center/1.5px 100% no-repeat,
    radial-gradient(circle closest-side,transparent 0 56%,var(--cross) 60% 74%,transparent 78%)}
.sf-t[aria-disabled="true"]{cursor:default}
.sf-t.live{cursor:pointer}
.sf-t.live:hover{--pad-face:var(--turf-hi);--mark:1.3}
.sf-t.live:active{transform:translateY(1px)}
.sf-in{position:absolute;inset:0;display:grid;place-items:center;border-radius:inherit}
.sf-in svg{width:74%;height:74%;overflow:visible}
.sf-t:not(.closed)::after{display:none}
/* safe: a map-paper inlay (warm centre, older edges, a faint survey grid), the ranging rod planted on it and the
   plot's number in the sweep */
.sf-t.safe .sf-in{background:radial-gradient(120% 120% at 32% 26%,var(--paper) 50%,var(--paper-edge));color:var(--paper-ink);
  box-shadow:inset 0 2px 3px rgb(0 0 0 / .2),inset 0 0 0 1px rgb(0 0 0 / .1)}
.sf-t.safe .sf-in::before{content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;background-size:33.34% 33.34%;
  background-image:linear-gradient(90deg,transparent calc(50% - .5px),var(--paper-rule) 0 calc(50% + .5px),transparent 0),linear-gradient(transparent calc(50% - .5px),var(--paper-rule) 0 calc(50% + .5px),transparent 0)}
.sf-t.safe .sf-in svg{width:80%;height:80%}
.sf-k{position:absolute;right:max(3px,calc(var(--cell) * .07));bottom:max(2px,calc(var(--cell) * .05));font:400 clamp(10px,calc(var(--cell) * .2),16px)/1 var(--display);color:var(--paper-ink)}
.sf-t.safe.just .sf-in{animation:sf-open .3s var(--ease-out,ease-out) both}
.sf-t.safe.just .sf-in svg{animation:sf-plant .42s .08s var(--ease-back,ease-out) both}
/* the detector scope while the server answers */
.sf-t.probe .sf-in{color:var(--probe)}
.sf-t.probe .sf-in svg{width:82%;height:82%;animation:sf-pulse .9s ease-in-out infinite}
.sf-t.probe .arm{transform-box:view-box;transform-origin:50% 50%;animation:sf-arm .8s linear infinite}
/* a mine: the struck one on signal red (lit a little at its centre, falling darker to the edge), the others shown at
   the end in a duller red */
.sf-t.hit .sf-in{background:radial-gradient(90% 90% at 46% 42%,color-mix(in srgb,var(--mine) 88%,#fff),var(--mine) 52%,color-mix(in srgb,var(--mine) 80%,#000));color:var(--mine-ink)}
.sf-t.hit.just{animation:sf-shake .42s cubic-bezier(.36,.07,.19,.97)}
.sf-t.hit.just .sf-in svg{animation:sf-pop .32s var(--ease-out,ease-out) both}
.sf-t.hit.just .sf-in::before{content:"";position:absolute;inset:18%;border-radius:50%;border:2px solid var(--mine-ink);animation:sf-ring .55s var(--ease-out,ease-out) forwards}
/* the struck plot's shock ring in the paper colour (no red flash; main.js lets it run only under the flash governor) */
.sf-t.glow{animation:sf-shake .42s cubic-bezier(.36,.07,.19,.97)}
.sf-t.glow .sf-in::after{content:"";position:absolute;inset:4%;border-radius:50%;border:2px solid var(--paper);opacity:0;pointer-events:none;animation:sf-ring .62s .06s var(--ease-out,ease-out)}
.sf-t.mine .sf-in{background:linear-gradient(150deg,rgb(255 255 255 / .1),transparent 45%,rgb(0 0 0 / .14)),var(--mine-dim);color:var(--mine-dim-ink)}
.sf-t.mine .sf-in svg{width:64%;height:64%}
.sf-t.mine.just .sf-in{animation:sf-pop .3s var(--ease-out,ease-out) both}
/* safe but never opened: the pad stays, sunk and dimmed, with a small paper ring (the opened plots and the mines stand
   out) */
.sf-t.clear{--pad-face:var(--clear);box-shadow:inset 0 1px 2px rgb(0 0 0 / .3)}
.sf-t.clear::before{opacity:.25}
.sf-t.clear .sf-in::after{content:"";width:18%;height:18%;border-radius:50%;border:2px solid var(--clear-ink)}
.sf-t.clear.just .sf-in{animation:sf-fade .3s var(--ease-out,ease-out) both}
/* the detector sweeps the field once when a sweep starts: a beam with a fading trail crosses it (transform only) */
.sf-grid.scan::after{content:"";position:absolute;top:-5px;bottom:-5px;left:0;width:56px;border-radius:2px;pointer-events:none;
  background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--probe) 24%,transparent) 72%,var(--probe) calc(100% - 3px),transparent);
  animation:sf-scan .46s var(--ease-std,ease-in-out) both}

@keyframes sf-open{from{opacity:0;transform:scale(.84)}}
@keyframes sf-plant{from{transform:translateY(-30%);opacity:0}55%{opacity:1}to{transform:none;opacity:1}}
@keyframes sf-arm{to{transform:rotate(360deg)}}
@keyframes sf-pulse{50%{transform:scale(.9)}}
@keyframes sf-shake{10%,90%{transform:translateX(-1px)}20%,80%{transform:translateX(3px)}30%,50%,70%{transform:translateX(-4px)}40%,60%{transform:translateX(4px)}}
@keyframes sf-pop{from{transform:scale(.5);opacity:0}to{transform:none;opacity:1}}
@keyframes sf-ring{from{transform:scale(.4);opacity:1}to{transform:scale(1.6);opacity:0}}
@keyframes sf-fade{from{opacity:0}to{opacity:1}}
@keyframes sf-scan{from{transform:translateX(-56px);opacity:0}15%,85%{opacity:1}to{transform:translateX(calc(5 * var(--cell) + 4 * var(--gap)));opacity:0}}

/* the cash-out ladder as the map's scale bar: one segment per step on a single strip, alternate blocks under them;
   the step in play is filled, the next one ringed in the game colour, the top step ends the bar in the game colour */
.sf-ladder{position:relative;max-width:100%;width:calc(5 * var(--cell) + 4 * var(--gap) + var(--co) + 2 * var(--pad));overflow-x:auto;scrollbar-width:none;
  mask-image:linear-gradient(90deg,transparent,#000 14px,#000 calc(100% - 14px),transparent);-webkit-mask-image:linear-gradient(90deg,transparent,#000 14px,#000 calc(100% - 14px),transparent)}
.sf-ladder::-webkit-scrollbar{display:none}
.sf-ladder:focus-visible{outline-offset:1px;-webkit-mask-image:none;mask-image:none} /* the edge fade would clip the focus ring */
.sf-ladder ol{display:flex;gap:0;width:max-content;margin:0 auto;padding:2px 12px;list-style:none}
.sf-ladder li{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;min-width:56px;height:40px;padding:0 8px 3px;
  background:var(--sheet);color:var(--ink);border:1px solid var(--sheet-line);border-right:0}
.sf-ladder li:first-child{border-radius:6px 0 0 6px}
.sf-ladder li:last-child{border-right:1px solid var(--sheet-line);border-radius:0 6px 6px 0}
.sf-ladder li::after{content:"";position:absolute;left:0;right:0;bottom:0;height:3px;background:var(--sheet-line)}
.sf-ladder li:nth-child(odd)::after{background:var(--paper-edge)}
.sf-ladder li small{font:400 11px/1 var(--display);letter-spacing:.04em;color:var(--muted)}
.sf-ladder li b{font:700 13px/1 var(--ui);font-variant-numeric:tabular-nums}
.sf-ladder li.got b{color:var(--muted)}
.sf-ladder li.cur{background:var(--ladder-on);border-color:var(--ladder-on);color:var(--ladder-on-ink)}
.sf-ladder li.cur small{color:var(--ladder-on-ink)}
.sf-ladder li.lost b{text-decoration:line-through;color:var(--muted)}
.sf-ladder li.lost::after{background:var(--mine)}
.sf-ladder li.nxt{box-shadow:inset 0 0 0 2px var(--primary)}
.sf-ladder li.top::after{background:var(--primary)}
.no-ladder .sf-ladder,.no-plate .sf-plate{display:none}

/* the mine choice (and, during a sweep, the random-plot key) under the board: quiet kit controls */
.sf-kit{display:flex;flex-wrap:wrap;gap:8px;align-items:center;justify-content:center}
.sf-mines{display:flex;align-items:center;gap:2px;padding:2px;border-radius:10px;background:var(--ibtn-bg);border:1px solid var(--line)}
.sf-stepb{position:relative;width:44px;height:44px;padding:0;border:0;border-radius:8px;background:none;color:var(--ink);font:700 22px/1 var(--ui);transition:translate var(--t-press,90ms) var(--ease-out,ease-out)}
.sf-stepb:hover:not(:disabled){box-shadow:inset 0 0 0 1px var(--line)}
.sf-stepb:active:not(:disabled){translate:0 1px}
.sf-stepb:disabled{opacity:.4}
.sf-sel{position:relative;display:flex;align-items:center;gap:8px;padding:0 2px}
.sf-sel-l{font:600 13px/1 var(--ui);color:var(--muted)}
.sf-sel select{min-height:44px;min-width:118px;padding:0 32px 0 12px;border-radius:8px;border:1px solid var(--line);background:var(--sheet);color:var(--ink);font:700 16px/1 var(--ui);appearance:none;-webkit-appearance:none;cursor:pointer}
.sf-sel select:disabled{opacity:.65;cursor:default}
.sf-sel select:focus-visible{outline:3px solid var(--focus);outline-offset:3px}
.sf-sel::after{content:"";position:absolute;right:15px;top:50%;width:7px;height:7px;border-right:2px solid var(--ink);border-bottom:2px solid var(--ink);transform:translateY(-70%) rotate(45deg);pointer-events:none}
.sf-sel option{background:var(--panel-bg);color:var(--ink)}
.sf-rand{display:flex;align-items:center;gap:8px;min-height:44px;padding:0 16px 0 10px;border-radius:10px;border:1px solid var(--line);background:var(--ibtn-bg);color:var(--ink);font:700 15px/1 var(--ui);
  transition:border-color var(--t-fast,140ms) var(--ease-std,ease),translate var(--t-press,90ms) var(--ease-out,ease-out)}
.sf-rand:hover:not(:disabled){border-color:var(--primary)}
.sf-rand:active:not(:disabled){translate:0 1px}
.sf-rand:disabled{opacity:.45}
.sf-rand-i{display:grid;color:var(--focus)}
.sf-rand-i svg{width:26px;height:26px}

/* HUD: a canvas field-kit strap with stitching, lit along its top edge */
.hud.thud{background:var(--hud-bg);border:1px solid var(--line);border-radius:12px;outline:1px dashed var(--stitch);outline-offset:-6px;
  box-shadow:inset 0 1px 0 rgb(255 255 255 / .07),0 12px 26px -16px rgb(0 0 0 / .75)}

/* the main button: an enamelled kit plate with a detector dial set in it — a brass bezel, a paper face, the needle and
   its hub in the dial colour (the dial turns while a request is in flight) */
.spin.tprim{background:var(--btn-bg);color:var(--btn-ink);grid-auto-flow:column;gap:10px;letter-spacing:.04em}
.spin.tprim::before{content:"";flex:none;width:24px;height:24px;border-radius:50%;
  background:radial-gradient(circle,var(--dial) 0 2.2px,transparent 2.7px),linear-gradient(var(--dial),var(--dial)) 50% 3px/2px 42% no-repeat,
    radial-gradient(circle at 38% 32%,#fff,color-mix(in srgb,var(--btn-bg) 86%,#000) 78%);
  box-shadow:0 0 0 2px var(--brass),0 0 0 3px var(--brass-lo),inset 0 1px 2px rgb(0 0 0 / .35)}
.spin.tprim.busy::before{animation:sf-arm .8s linear infinite}
/* during a sweep with a safe plot: two lines, "CASH OUT" small over the amount */
.spin.tprim.sf-two span{white-space:pre-line;line-height:1.08;max-width:none}
.spin.tprim.sf-two span::first-line{font-size:.68em;letter-spacing:.12em}

/* the rules: your mine count's ladder, then every mine count (they scroll sideways only if the text is enlarged; on
   phones the top step's "after k" goes under it and, with the return column, the first-plot column goes) */
.panel h3.sf-paycap{margin:18px 0 6px;font:700 15px/1.3 var(--ui);letter-spacing:0;color:var(--ink)}
.sf-paywrap{overflow-x:auto;max-height:340px;overflow-y:auto;margin:0 0 12px;border:1px solid var(--line);border-radius:8px}
.sf-pay{border-collapse:collapse;width:100%;font-size:14px;font-variant-numeric:tabular-nums;white-space:nowrap}
.sf-pay th,.sf-pay td{padding:6px 8px;text-align:center}
.sf-pay thead th{position:sticky;top:0;background:var(--panel-bg)}
.sf-pay tbody tr{border-top:1px solid var(--line)}
.sf-pay tr.on{background:color-mix(in srgb,var(--primary) 14%,transparent);font-weight:700}
.sf-pay small{font-size:12px;font-weight:600;color:var(--muted)}
.sf-paynote{font-size:13px;color:var(--muted)}
.panel .trtp{columns:3 150px;column-gap:24px}
.panel .trtp li{break-inside:avoid}

/* big wins: map pins rain onto the card and stick where they land, each on its own drawn shadow (no filter; none with
   reduced motion: skin.js) */
.sf-rain{position:absolute;top:-44px;left:var(--x);width:calc(22px * var(--z));height:calc(31px * var(--z));pointer-events:none;
  animation:sf-pin .9s var(--d) cubic-bezier(.5,0,.75,1.25) both,sf-fade .5s calc(var(--d) + 2.5s) reverse forwards}
.sf-rain svg{display:block;width:100%;height:100%}
@keyframes sf-pin{from{transform:translateY(0) rotate(var(--r))}to{transform:translateY(calc(var(--y) + 44px)) rotate(0deg)}}

/* phones: the − / + keys give way to the select (a native wheel), smaller plate and ladder */
@media (max-width:400px){
  .sf-stepb,.sf-sel-l{display:none}
  .sf-mines{padding:0;border:0;background:none}
  .sf-pv{padding:5px 8px;gap:5px}
  .sf-pv b{font-size:15px}
  .sf-ladder li{min-width:48px;padding:0 5px 3px}
}
@media (max-width:400px){.spin.tprim{gap:8px;letter-spacing:.01em}.spin.tprim::before{width:19px;height:19px}}
@media (max-width:480px){.sf-pay td small{display:block;margin-top:2px}.sf-pay.r4 .c1{display:none}}

/* phones held sideways (and other short, wide screens): the shell's phone HUD under the stage leaves no room for a
   5 × 5 field of 44 px plots in 320-500 px of height. The HUD stands as a column at the side (right; left for the
   left-handed layout), the field takes the stage's full height, and the results strip, the message line and the mine
   choice stand in a column beside it (the board's wrappers display:contents, as Brass Dial does). */
@media (max-height:500px) and (min-width:560px){
  .table-game.game{grid-template-columns:minmax(0,1fr) clamp(150px,21vw,200px);grid-template-rows:auto minmax(0,1fr);column-gap:10px}
  .table-game>.top{grid-column:1/-1}
  .table-game>.stage{grid-column:1;grid-row:2}
  .table-game>.hud.thud{grid-column:2;grid-row:2;align-self:stretch;width:100%;margin:0;display:flex;flex-direction:column;justify-content:center;align-items:stretch;gap:8px;padding:8px 10px;text-align:center;outline-offset:-5px}
  .thud>.bal,.thud>.win,body.lefty .thud>.bal,body.lefty .thud>.win{text-align:center}
  /* the stake over its − / + keys (side by side, the column is too narrow for − stake +) */
  .thud .betctl{display:grid;grid-template-columns:1fr 1fr;grid-template-areas:"m m" "dn up";gap:4px 8px}
  .thud .betctl .meter{grid-area:m;min-width:0}
  .thud .betctl .pm{width:100%;height:36px}.thud .pm[data-bet="-1"]{grid-area:dn}.thud .pm[data-bet="1"]{grid-area:up}
  .thud .meter b{font-size:18px}
  .thud>.spinbox,body.lefty .thud>.spinbox{order:0;justify-content:center;flex-direction:row}
  .table-game .spin.tprim{width:100%;min-width:0;height:50px;padding:0 10px;gap:8px;font-size:16px;letter-spacing:.02em}
  .table-game .spin.tprim::before{width:18px;height:18px}
  body.lefty .table-game.game{grid-template-columns:clamp(150px,21vw,200px) minmax(0,1fr)}
  body.lefty .table-game>.stage{grid-column:2}
  body.lefty .table-game>.hud.thud{grid-column:1}
  .table-game .stage.tstage{display:grid;grid-template-columns:minmax(0,1fr) clamp(128px,22vw,220px);grid-template-rows:auto minmax(0,1fr) auto;
    grid-template-areas:"board strip" "board msg" "board ctl";justify-items:stretch;gap:8px 10px}
  body.lefty .table-game .stage.tstage{grid-template-columns:clamp(128px,22vw,220px) minmax(0,1fr);grid-template-areas:"strip board" "msg board" "ctl board"}
  .table-game .boardarea.tboardarea,.table-game .frame{display:contents}
  .tstrip{grid-area:strip;min-width:0;justify-content:flex-start}
  .table-game .board.tboard{grid-area:board;height:100%}
  .table-game .message{grid-area:msg;align-self:center;font-size:14px;line-height:1.35;text-align:center}
  .tcontrols{grid-area:ctl;margin:0;width:auto}
  .sf-kit{flex:1 1 auto;flex-direction:column;align-items:stretch;gap:8px}
  .sf-pv{padding:5px 8px;gap:4px}.sf-pv b{font-size:15px}
  .sf-stepb,.sf-sel-l{display:none}
  .sf-mines{padding:0;border:0;background:none}
  .sf-sel{padding:0;flex:1}.sf-sel select{width:100%;min-width:0}
  .sf-rand{justify-content:center;padding:0 10px}
}
/* most sideways phones (568-880 px): no dial on the main button, so "Start sweep" fits the column */
@media (max-height:500px) and (min-width:560px) and (max-width:880px){.table-game .spin.tprim::before{display:none}}
/* the shortest (≈ 320 px): the results strip goes, the message line takes its place */
@media (max-height:340px) and (min-width:560px){
  .tstrip{display:none}
  .table-game .stage.tstage{grid-template-areas:"board msg" "board msg" "board ctl"}
  body.lefty .table-game .stage.tstage{grid-template-areas:"msg board" "msg board" "ctl board"}
  .thud #mBetSub{display:none}
  .table-game>.hud.thud{gap:6px}
  .table-game .spin.tprim{height:46px}
}
@media (max-width:340px){.sf-pv small{display:none}.spin.tprim::before{display:none}}
@media (prefers-reduced-motion:reduce){
  .sf-t,.sf-t::after,.sf-t .sf-in,.sf-t .sf-in::before,.sf-t .sf-in::after,.sf-t .sf-in svg,.sf-t .arm,.spin.tprim.busy::before,.sf-grid.scan::after,.sf-stepb,.sf-rand{animation:none!important;transition:none!important}
}
