/* REKT games — shared shell.
   Built to live inside an iframe: no page header, no chrome, no scrollbars.
   Two materials: a paper bet slip and a dark arena. */

:root{
  --void:#0B0710; --arena:#140C1C;
  --paper:#F4EDE0; --paper-2:#E8DFCE;
  --ink:#140A10; --ink-2:#5A4A56;
  --pink:#FF2D8B; --drip:#D92B21;
  --win:#1E9E56; --win-bright:#3FD07A;
  --gold:#E8B54B; --violet:#8B7DD8;
  --chalk:#F3EDF7; --chalk-dim:#9E8FAE; --chalk-faint:#6B5C7A;
  color-scheme:dark;
}
*{box-sizing:border-box}
html,body{height:100%}
/* nothing in a game may widen the page (Zeppelin's players line once did,
   2026-10-06): the panels never take their content's width (below), and
   the root clips sideways as a last resort */
html{overflow-x:hidden}
body{
  margin:0;background:var(--void);color:var(--chalk);
  font-family:"Archivo",system-ui,-apple-system,"Segoe UI",sans-serif;
  font-size:15px;line-height:1.45;overflow:hidden;
  display:flex;align-items:center;justify-content:center;
  background-image:radial-gradient(rgba(255,45,139,.045) 1.4px,transparent 1.5px);
  background-size:11px 11px;
}
#app{height:100%;max-height:min(100%, 624px);display:grid;
  grid-template-columns:clamp(220px, 40%, 288px) minmax(0,1fr);
  gap:14px;padding:14px;max-width:1240px;width:100%}

/* ── bet slip ── */
  .slip{
  min-width:0;
  background:var(--paper);color:var(--ink);
  border:3px solid var(--ink);border-radius:30px 12px 34px 14px/14px 32px 12px 30px;
  box-shadow:5px 5px 0 var(--ink);
  padding:14px 14px 12px;display:flex;flex-direction:column;gap:10px;overflow:auto;
  background-image:radial-gradient(rgba(20,10,16,.055) 1px,transparent 1px);
  background-size:4px 4px;
}
.slip-head{
  font-family:"Anton",Impact,sans-serif;font-size:13px;letter-spacing:.14em;text-transform:uppercase;
  border-bottom:3px solid var(--ink);padding-bottom:7px;
  display:flex;justify-content:space-between;align-items:baseline;
}
.slip-head span{font:700 9px/1 "JetBrains Mono",ui-monospace,monospace;letter-spacing:.1em;color:var(--ink-2)}
.field{display:flex;flex-direction:column;gap:5px}
label,.lbl{font:700 9.5px/1 "JetBrains Mono",ui-monospace,monospace;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-2)}
.amount{display:flex;gap:6px}
/* two controls that share a line in a compact frame (Plinko's rows and
   risk, Lucky Wheel's segments and risk); elsewhere each has its own */
.duo{display:contents}
/* over / under — the API takes a direction, so the player gets one */
.seg{display:flex;border:2.5px solid var(--ink);border-radius:11px 5px 13px 6px/6px 13px 5px 11px;overflow:hidden}
.seg-b{flex:1;border:0;background:var(--paper-2);color:var(--ink-2);cursor:pointer;
  font:800 12px/1 "Archivo",sans-serif;letter-spacing:.06em;text-transform:uppercase;padding:9px 0}
.seg-b + .seg-b{border-left:2.5px solid var(--ink)}
.seg-b.on{background:var(--ink);color:var(--paper)}
.seg-b:not(.on):hover:not(:disabled){background:var(--paper)}
.seg-b:disabled{opacity:.55;cursor:default}
.amount input,.num,select{
  flex:1;min-width:0;background:var(--paper-2);border:2.5px solid var(--ink);color:var(--ink);
  border-radius:11px 5px 13px 6px/6px 13px 5px 11px;padding:9px 11px;
  font:700 15px/1 "JetBrains Mono",ui-monospace,monospace;font-variant-numeric:tabular-nums;
}
select{border-radius:5px 12px 6px 14px/13px 5px 15px 6px}
.amount input:focus-visible,.num:focus-visible,select:focus-visible,input[type=range]:focus-visible{outline:3px solid var(--pink);outline-offset:2px}
.chip{background:var(--ink);border:0;color:var(--paper);border-radius:8px;padding:0 11px;font:800 12px/1 "Archivo",sans-serif;cursor:pointer}
.chip:hover{background:var(--pink)}
input[type=range]{width:100%;accent-color:var(--drip);background:transparent}
.target-row{display:flex;justify-content:space-between;align-items:baseline}
.target-row b{font-family:"Anton",Impact,sans-serif;font-size:21px;color:var(--drip)}
.rows{display:flex;border-top:3px solid var(--ink);border-bottom:3px solid var(--ink);padding:5px 0}
.row{flex:1;display:flex;flex-direction:column;gap:2px;padding:0 clamp(4px,1.2vw,8px);min-width:0}
.row + .row{border-left:1.5px dashed rgba(20,10,16,.25)}
.row:first-child{padding-left:0} .row:last-child{padding-right:0}
.row b{font:700 clamp(11.5px,1.2vw,13px)/1 "JetBrains Mono",ui-monospace,monospace;font-variant-numeric:tabular-nums;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.row.good b{color:var(--win)}
  /* sits just under the stats, not pinned to the floor of a tall panel */
.act{
  margin-top:6px;font-family:"Anton",Impact,sans-serif;font-size:21px;letter-spacing:.05em;text-transform:uppercase;
  background:var(--pink);color:var(--paper);cursor:pointer;
  border:3px solid var(--ink);border-radius:26px 9px 30px 11px/11px 28px 9px 26px;
  padding:11px;box-shadow:4px 4px 0 var(--ink);
  transition:transform .1s ease,box-shadow .1s ease,background .2s ease;
}
.act:hover{transform:translate(-1px,-1px);box-shadow:5px 5px 0 var(--ink)}
.act:active{transform:translate(3px,3px);box-shadow:1px 1px 0 var(--ink)}
.act:disabled{background:var(--paper-2);color:var(--ink-2);box-shadow:2px 2px 0 var(--ink);cursor:default;transform:none}
.act.cash{background:var(--win)}
/* a second button beside the main one (Gold Field's Next step) */
.act-row{display:flex;gap:8px;align-items:stretch}
.act-row .act{flex:1 1 0;min-width:0}
.act.gf-next{flex:0 0 40%;font-size:15px;background:var(--paper);color:var(--ink)}
.act.gf-next:disabled{background:var(--paper-2);color:var(--ink-2)}
/* The slip prints a receipt. It also stops the panel from being half empty
   on a wide screen, which is where the dead space used to be. */
.log{flex:1;min-height:0;display:flex;flex-direction:column;gap:5px;
  margin-top:8px;margin-bottom:4px;border-top:3px solid var(--ink);padding-top:8px}
.log-rows{flex:1;min-height:0;overflow:hidden}
/* a row cut off by the panel edge fades rather than being sliced in half.
   Only when there is something to cut off — rekt.js sets .clipped — or a
   one-line list comes out half transparent. */
.log-rows.clipped{
  -webkit-mask-image:linear-gradient(180deg,#000 calc(100% - 20px),transparent);
          mask-image:linear-gradient(180deg,#000 calc(100% - 20px),transparent)}
.log-empty{margin:0;font:700 11px/1.4 "JetBrains Mono",ui-monospace,monospace;color:var(--ink-2);opacity:.6}
.lrow{display:flex;justify-content:space-between;align-items:baseline;gap:8px;padding:5.5px 0;
  border-bottom:1.5px dashed rgba(20,10,16,.2);
  font:700 12px/1 "JetBrains Mono",ui-monospace,monospace;font-variant-numeric:tabular-nums}
.lrow:last-child{border-bottom:0}
.lr-t{color:var(--ink-2)}
.lrow.w .lr-d{color:var(--win)} .lrow.l .lr-d{color:var(--drip)} .lrow.n .lr-d{color:var(--ink-2)}
.bal{display:flex;justify-content:space-between;align-items:baseline;position:relative;
  margin-top:auto;padding-top:11px;border-top:3px solid var(--ink)}
.bal b{font-family:"Anton",Impact,sans-serif;font-size:21px}
.bal .cur{font:800 10px/1 "Archivo",sans-serif;color:var(--pink);letter-spacing:.06em}
.pop{position:absolute;right:0;bottom:calc(100% + 3px);font-family:"Anton",Impact,sans-serif;font-size:17px;
  background:var(--paper);padding:1px 5px;border-radius:5px;opacity:0;pointer-events:none}
.pop.go{animation:pop 1.1s ease-out}
@keyframes pop{0%{opacity:0;transform:translateY(7px) rotate(-5deg)}20%{opacity:1;transform:translateY(0) rotate(-3deg)}70%{opacity:1}100%{opacity:0;transform:translateY(-12px)}}

/* ── arena ── */
.arena{
  min-width:0;
  background:var(--arena);border:3px solid var(--ink);
  border-radius:32px 13px 36px 15px/15px 34px 13px 32px;box-shadow:5px 5px 0 var(--ink);
  padding:34px 16px 14px;display:flex;flex-direction:column;gap:10px;
  position:relative;overflow:hidden;min-height:0;
  background-image:
    radial-gradient(120% 90% at 50% 0%,rgba(139,125,216,.12),transparent 62%),
    radial-gradient(rgba(255,45,139,.10) 1.7px,transparent 1.8px);
  background-size:auto,10px 10px;
}
.arena::after{
  content:attr(data-ghost);position:absolute;right:-18px;bottom:-22px;z-index:0;pointer-events:none;
  font-family:"Anton",Impact,sans-serif;font-size:clamp(132px,22vh,230px);line-height:.8;text-transform:uppercase;
  color:rgba(243,237,247,.035);transform:rotate(-7deg);white-space:nowrap;
}
.centre{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:clamp(10px,2.4vh,26px);position:relative;z-index:2;width:100%;max-width:720px;margin-inline:auto;min-height:0}
.tag{font:800 10px/1 "Archivo",sans-serif;letter-spacing:.15em;text-transform:uppercase;color:var(--chalk-faint)}
.tag.w{color:var(--win-bright)} .tag.l{color:var(--drip)}
/* waiting on the service: visibly alive, not frozen */
.tag.pending{color:var(--gold);animation:pending 1s ease-in-out infinite}
@keyframes pending{50%{opacity:.35}}

/* ── reaction ── */
.stage{display:flex;align-items:center;gap:14px;position:relative;z-index:2;width:100%;max-width:720px;margin-inline:auto}
.woj{width:clamp(64px,9vh,104px);height:clamp(64px,9vh,104px);flex:none;transition:transform .3s cubic-bezier(.2,1.5,.4,1)}
.arena.w .woj{transform:translateY(-4px) rotate(3deg)}
.arena.l .woj{transform:translateY(4px) rotate(-4deg)}
.tears{transition:opacity .25s ease}
.arena.w .tears{opacity:.12}
.say{background:var(--paper);color:var(--ink);border:2.5px solid var(--ink);
  border-radius:20px 9px 23px 10px/10px 22px 9px 20px;padding:9px 13px;box-shadow:3px 3px 0 var(--ink);
  position:relative;flex:1;min-width:0}
.say::before{content:"";position:absolute;left:-11px;top:16px;width:0;height:0;border:9px solid transparent;border-right-color:var(--ink)}
.shout{display:block;font-family:"Permanent Marker",cursive;font-size:clamp(17px,2.2vh,23px);line-height:1;color:var(--drip);margin-bottom:2px}
.say p{margin:0;font-size:clamp(12px,1.6vh,14.5px);color:var(--ink-2);line-height:1.35;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}

/* ── dice ── */
:root{--die:clamp(104px, 17vh, 176px)}
.die-stage{perspective:760px;width:var(--die);height:var(--die);flex:none}
.die{position:relative;width:var(--die);height:var(--die);transform-style:preserve-3d;transition:transform .9s cubic-bezier(.17,.82,.28,1)}
.face{position:absolute;inset:0;overflow:hidden;border:3px solid var(--ink);border-radius:20px 8px 22px 9px/9px 21px 8px 20px;
  background:var(--paper-2);display:flex;align-items:center;justify-content:center}
.f-front{transform:translateZ(calc(var(--die) / 2));background:var(--paper);transition:background .25s ease}
.f-back{transform:rotateY(180deg) translateZ(calc(var(--die) / 2))}
.f-right{transform:rotateY(90deg) translateZ(calc(var(--die) / 2))}
.f-left{transform:rotateY(-90deg) translateZ(calc(var(--die) / 2))}
.f-top{transform:rotateX(90deg) translateZ(calc(var(--die) / 2))}
.f-bottom{transform:rotateX(-90deg) translateZ(calc(var(--die) / 2))}
.pip{background-repeat:no-repeat;background-size:calc(var(--die) * .125) calc(var(--die) * .125)}
.p2{background-image:radial-gradient(circle,var(--ink) 6.5px,transparent 7.5px),radial-gradient(circle,var(--ink) 6.5px,transparent 7.5px);background-position:calc(var(--die) * .225) calc(var(--die) * .225),calc(var(--die) * .65) calc(var(--die) * .65)}
.p3{background-image:radial-gradient(circle,var(--ink) 6.5px,transparent 7.5px),radial-gradient(circle,var(--ink) 6.5px,transparent 7.5px),radial-gradient(circle,var(--ink) 6.5px,transparent 7.5px);background-position:calc(var(--die) * .19) calc(var(--die) * .19),calc(var(--die) * .435) calc(var(--die) * .435),calc(var(--die) * .675) calc(var(--die) * .675)}
.p4{background-image:radial-gradient(circle,var(--ink) 6.5px,transparent 7.5px),radial-gradient(circle,var(--ink) 6.5px,transparent 7.5px),radial-gradient(circle,var(--ink) 6.5px,transparent 7.5px),radial-gradient(circle,var(--ink) 6.5px,transparent 7.5px);background-position:calc(var(--die) * .21) calc(var(--die) * .21),calc(var(--die) * .66) calc(var(--die) * .21),calc(var(--die) * .21) calc(var(--die) * .66),calc(var(--die) * .66) calc(var(--die) * .66)}
.p5{background-image:radial-gradient(circle,var(--ink) 6.5px,transparent 7.5px),radial-gradient(circle,var(--ink) 6.5px,transparent 7.5px),radial-gradient(circle,var(--ink) 6.5px,transparent 7.5px),radial-gradient(circle,var(--ink) 6.5px,transparent 7.5px),radial-gradient(circle,var(--ink) 6.5px,transparent 7.5px);background-position:calc(var(--die) * .19) calc(var(--die) * .19),calc(var(--die) * .675) calc(var(--die) * .19),calc(var(--die) * .435) calc(var(--die) * .435),calc(var(--die) * .19) calc(var(--die) * .675),calc(var(--die) * .675) calc(var(--die) * .675)}
.p6{background-image:radial-gradient(circle,var(--ink) 5.5px,transparent 6.5px),radial-gradient(circle,var(--ink) 5.5px,transparent 6.5px),radial-gradient(circle,var(--ink) 5.5px,transparent 6.5px),radial-gradient(circle,var(--ink) 5.5px,transparent 6.5px),radial-gradient(circle,var(--ink) 5.5px,transparent 6.5px),radial-gradient(circle,var(--ink) 5.5px,transparent 6.5px);background-size:13px 13px;background-position:25px 21px,79px 21px,25px 52px,79px 52px,25px 83px,79px 83px}
.die .val{font-family:"Anton",Impact,sans-serif;font-size:calc(var(--die) * .22);color:var(--ink)}
.die.w .f-front{background:var(--win-bright)}
/* rolling, before the service has answered: a blank face tumbling (games.js
   rolling) — the real roll lands on the reply */
.die.pending{animation:dieTumble .8s linear infinite}
@keyframes dieTumble{from{transform:rotateX(0deg) rotateY(0deg)}to{transform:rotateX(360deg) rotateY(360deg)}}

.track-wrap{width:100%}
.track{position:relative;height:clamp(20px,2.6vh,30px);border:2.5px solid var(--ink);border-radius:999px;background:var(--drip);overflow:hidden;box-shadow:3px 3px 0 var(--ink)}
.track .zone{position:absolute;top:0;bottom:0;left:50%;right:0;background:var(--win-bright)}
.trail{position:absolute;left:0;top:0;bottom:0;width:0;opacity:0;background:linear-gradient(90deg,transparent,rgba(255,255,255,.7))}
.marker{position:absolute;top:-9px;width:7px;height:clamp(34px,4.4vh,50px);border-radius:3px;background:var(--paper);border:2.5px solid var(--ink);left:50%;transform:translateX(-3px)}
.marker.run{transition:left .76s cubic-bezier(.1,.7,.22,1)}
.scale{display:flex;justify-content:space-between;font:700 10px/1 "JetBrains Mono",ui-monospace,monospace;color:var(--chalk-faint);margin-top:7px}
/* Limbo's scale: ticks at their places on the log line, the ends kept inside */
.lim-scale{position:relative;display:block;height:10px}
.lim-scale span{position:absolute;top:0;transform:translateX(-50%);white-space:nowrap}
.lim-scale span:first-child{transform:none}
.lim-scale span:last-child{transform:translateX(-100%)}

/* ── limbo ── */
/* The rolled multiplier on a paper card, as the die carries its number; the
   track underneath is Dice's, with the target's zone marked. */
.lim-stage{flex:none}
.lim{position:relative;overflow:hidden;min-width:clamp(210px,36vh,340px);padding:clamp(12px,2.4vh,22px) 24px;
  border:3px solid var(--ink);border-radius:20px 8px 22px 9px/9px 21px 8px 20px;background:var(--paper);color:var(--ink);
  box-shadow:4px 4px 0 var(--ink);text-align:center;transition:background .2s ease}
.lim-num{position:relative;font-family:"Anton",Impact,sans-serif;font-size:clamp(46px,9vh,92px);line-height:1;font-variant-numeric:tabular-nums;white-space:nowrap}
.lim-target{position:relative;margin-top:7px;font:700 10px/1 "JetBrains Mono",ui-monospace,monospace;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-2)}
.lim-target b{color:var(--ink)}
/* the count has cleared the target, and a settled win keeps it */
.lim.over,.lim.w{background:var(--win-bright)}
/* rolling, before the service has answered: a blank card, pulsing */
.lim.pending .lim-num{animation:pending 1s ease-in-out infinite}
/* stretched to the card, the fracture lines keep their weight */
.lim .crack path{vector-effect:non-scaling-stroke}

/* ── plinko ── */
/* The board is drawn in the SVG's own units (100 wide); the buckets row below
   shares its width and is padded by half a peg spacing so each bucket sits
   under the gap the ball falls through. */
.pk{width:min(100%, clamp(240px, 58vh, 560px));flex:none}
.pk-board{position:relative;width:100%}
.pk-board svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible}
.pk-peg{fill:var(--chalk-dim)}
.pk-ball{fill:var(--pink);stroke:var(--ink);stroke-width:.45}
.pk-ballg{transition:transform var(--step,85ms) cubic-bezier(.4,.05,.6,1),opacity .2s ease}
/* dropped, before the service has answered: the ball waits at the top, where
   every route starts */
.pk-ballg.wait .pk-ball{animation:pending .8s ease-in-out infinite}
/* landed and settled: the ball fades out; the bucket's highlight stays */
.pk-ballg.gone{opacity:0;transition:opacity .25s ease}
.pk-buckets{display:flex;margin-top:6px}
/* the buckets: colour bars that carry the landed highlight; their numbers
   are in the strip under them (.pk-labels) */
.pk-b{flex:1;min-width:0;height:9px;margin:0 1px;border:1.5px solid var(--ink);border-radius:4px 2px 5px 2px/2px 5px 2px 4px;
  transition:transform .2s ease,box-shadow .2s ease}
.pk-b.b-lo{background:var(--ink-2);color:var(--paper)}
.pk-b.b-mid{background:var(--paper-2);color:var(--ink)}
.pk-b.b-hi{background:var(--gold);color:var(--ink)}
.pk-b.b-top{background:var(--pink);color:var(--paper)}
.pk-b.pk-on{transform:translateY(-4px)}
.pk-b.pk-won{box-shadow:0 0 0 2px var(--paper),0 0 16px var(--win-bright)}
.pk-b.pk-lost{box-shadow:0 0 0 2px var(--paper),0 0 16px var(--drip)}
.pk-b.pk-even{box-shadow:0 0 0 2px var(--paper)}
/* the numbers: horizontal, each centred under its bucket, whole; one row,
   or two staggered when one would be too small (games.js fitLabels) */
.pk-labels{position:relative;width:100%;margin-top:4px}
.pk-labels span{position:absolute;transform:translateX(-50%);white-space:nowrap;line-height:1;
  font:400 var(--lfs,11px) "Anton",Impact,sans-serif;letter-spacing:0}
.pk-labels .b-lo{color:var(--chalk-dim)} .pk-labels .b-mid{color:var(--paper)}
.pk-labels .b-hi{color:var(--gold)} .pk-labels .b-top{color:var(--pink)}
.pk-labels span.on{text-shadow:0 0 8px currentColor}
/* the landed multiplier, large */
.pk-read{text-align:center;font-family:"Anton",Impact,sans-serif;font-size:clamp(20px,3.6vh,30px);line-height:1;margin-top:-4px;color:var(--chalk-faint)}
.pk-read.w{color:var(--win-bright)} .pk-read.l{color:var(--drip)} .pk-read.n{color:var(--chalk)}

/* ── keno ── */
/* 40 numbers, 8 across by 5 down. Sized off the frame's height so the board,
   its paytable and the mascot share a landscape iframe; capped by the width
   on a phone. Numbers scale with the board (cqw), never below 11px. */
.kn{width:min(100%, clamp(260px, 74vh, 600px));flex:none;display:flex;flex-direction:column;gap:clamp(4px,.9vh,8px)}
.kn-bar{display:flex;align-items:center;gap:6px}
.kn-count{flex:1;font:700 10px/1 "JetBrains Mono",ui-monospace,monospace;letter-spacing:.1em;text-transform:uppercase;color:var(--chalk-dim)}
.kn-tool{background:transparent;color:var(--chalk);border:1.5px solid var(--chalk-faint);border-radius:999px;cursor:pointer;
  font:800 10px/1 "Archivo",sans-serif;letter-spacing:.08em;text-transform:uppercase;padding:6px 10px}
.kn-tool:hover:not(:disabled){border-color:var(--pink);color:var(--paper)}
.kn-tool:disabled{opacity:.4;cursor:default}
.kn-grid{display:grid;grid-template-columns:repeat(8,1fr);gap:clamp(3px,.8vh,7px);container-type:inline-size}
.kn-c{aspect-ratio:1;min-width:0;padding:0;border:2px solid var(--ink);background:var(--paper-2);color:var(--ink);cursor:pointer;
  border-radius:9px 4px 10px 5px/5px 10px 4px 9px;box-shadow:2px 2px 0 var(--ink);
  font:700 max(11px, 3.4cqw)/1 "JetBrains Mono",ui-monospace,monospace;font-variant-numeric:tabular-nums;
  transition:transform .12s ease,background .15s ease,color .15s ease}
.kn-c:nth-child(even){border-radius:4px 10px 5px 11px/10px 4px 12px 5px}
.kn-c:hover:not(:disabled){transform:translate(-1px,-1px);background:var(--paper)}
.kn-c:disabled{cursor:default}
.kn-c:focus-visible,.kn-tool:focus-visible{outline:3px solid var(--pink);outline-offset:2px}
.kn-c.pick{background:var(--pink);color:var(--paper)}
.kn-c.pick:hover:not(:disabled){background:#FF57A3}
/* drawn but not picked; picked and drawn */
.kn-c.miss{background:var(--violet);color:var(--paper)}
.kn-c.hit{background:var(--win-bright);color:var(--ink);animation:popfx .3s cubic-bezier(.25,1.5,.4,1)}
@keyframes knDraw{0%{transform:scale(.8)}100%{transform:scale(1)}}
.kn-c.miss{animation:knDraw .2s ease-out}
/* the paytable: hits on top, what they pay under, one row or two — a
   multiplier is never cut */
.kn-pay{display:grid;grid-template-columns:repeat(var(--np,1),minmax(0,1fr));gap:3px;min-height:30px}
.kn-pay.two{grid-template-columns:repeat(var(--np2,1),minmax(0,1fr))}
.kn-p{display:flex;flex-direction:column;align-items:center;gap:2px;min-width:0;padding:3px 1px;overflow:hidden;
  background:var(--paper-2);color:var(--ink);border:1.5px solid var(--ink);border-radius:6px 3px 7px 3px/3px 7px 3px 6px}
.kn-p i{font:700 8.5px/1 "JetBrains Mono",ui-monospace,monospace;font-style:normal;color:var(--ink-2)}
.kn-p b{font:700 clamp(9.5px,1.5vh,12px)/1 "JetBrains Mono",ui-monospace,monospace;white-space:nowrap;font-variant-numeric:tabular-nums}
.kn-p.z{opacity:.42}
.kn-p.on{opacity:1}
.kn-p.on{transform:translateY(-3px);box-shadow:0 0 0 2px var(--paper)}
.kn-p.on.w{background:var(--win-bright);box-shadow:0 0 0 2px var(--paper),0 0 14px var(--win-bright)}
.kn-p.on.l{background:var(--drip);color:var(--paper)} .kn-p.on.l i{color:var(--paper)}
.kn-hint{grid-column:1/-1;align-self:center;text-align:center;font:700 10px/1.3 "JetBrains Mono",ui-monospace,monospace;color:var(--chalk-faint)}
.kn-risk .seg-b{font-size:10.5px;letter-spacing:.02em}

/* ── lucky wheel ── */
/* The wheel takes the height the arena has left (a square inside .wl-box,
   whose size the container query reads); the readout and the key sit under
   it. The disc turns; the hub and the pointer are a still layer on top. */
.wl{flex:1 1 0;min-height:0;width:100%;display:flex;flex-direction:column;align-items:center;gap:clamp(5px,1.1vh,10px)}
.wl-box{flex:1 1 0;min-height:0;width:100%;container-type:size;display:grid;place-items:center}
.wl-wheel{position:relative;width:min(100cqw,100cqh,440px);height:min(100cqw,100cqh,440px)}
.wl-wheel svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible}
.wl-disc{transform-origin:50% 50%}
.wl-disc.go{transition:transform var(--spin,2600ms) cubic-bezier(.12,.62,.14,1)}
.wl-disc.nudge{transition:transform .25s ease-out}
.wl-rim{fill:var(--ink);stroke:var(--ink);stroke-width:3}
.wl-s{stroke:var(--ink);stroke-width:.8;stroke-linejoin:round;transition:fill-opacity .25s ease}
.wl-s.t0{fill:#33263F} .wl-s.t1{fill:var(--pink)} .wl-s.t2{fill:var(--gold)} .wl-s.t3{fill:var(--violet)}
.wl-s.t4{fill:var(--paper-2)} .wl-s.t5{fill:var(--chalk-dim)} .wl-s.t6{fill:var(--chalk-faint)}
.wl-l{font-family:"JetBrains Mono",ui-monospace,monospace;font-weight:700;dominant-baseline:central;pointer-events:none}
.wl-l.t0{fill:var(--chalk-dim)} .wl-l.t1,.wl-l.t3,.wl-l.t6{fill:var(--paper)} .wl-l.t2,.wl-l.t4,.wl-l.t5{fill:var(--ink)}
.wl.wl-compact .wl-lbls{display:none}
/* the landed slot: outlined, the rest stepped back */
.wl[data-lit] .wl-s:not(.on){fill-opacity:.42}
.wl-s.on{stroke:var(--paper);stroke-width:2.4}
.wl-s.on.w{filter:drop-shadow(0 0 3px var(--win-bright))}
.wl-s.on.l{filter:drop-shadow(0 0 3px var(--drip))}
.wl-hub{fill:var(--arena);stroke:var(--ink);stroke-width:3}
.wl-pin{fill:var(--chalk-faint)}
.wl-ptr{fill:var(--paper);stroke:var(--ink);stroke-width:2.5;stroke-linejoin:round;transition:fill .2s ease}
.wl[data-lit="w"] .wl-ptr{fill:var(--win-bright)} .wl[data-lit="l"] .wl-ptr{fill:var(--drip)}
.wl-read{flex:none;font-family:"Anton",Impact,sans-serif;font-size:clamp(28px,5.4vh,44px);line-height:1;
  color:var(--chalk-dim);font-variant-numeric:tabular-nums;white-space:nowrap}
.wl-read.w{color:var(--win-bright)} .wl-read.l{color:var(--drip)} .wl-read.n{color:var(--chalk)}
/* what each colour pays: one chip per multiplier, lowest first */
.wl-key{flex:none;display:flex;flex-wrap:wrap;justify-content:center;gap:4px;max-width:100%}
.wl-k{display:flex;flex-direction:column;align-items:center;gap:2px;min-width:52px;padding:3px 7px;
  border:1.5px solid var(--ink);border-radius:6px 3px 7px 3px/3px 7px 3px 6px;transition:transform .2s ease,box-shadow .2s ease}
.wl-k b{font:700 clamp(10px,1.6vh,12px)/1 "JetBrains Mono",ui-monospace,monospace;white-space:nowrap;font-variant-numeric:tabular-nums}
.wl-k i{font:700 8.5px/1 "JetBrains Mono",ui-monospace,monospace;font-style:normal;opacity:.75;white-space:nowrap}
.wl-k.t0{background:#33263F;color:var(--chalk)} .wl-k.t1{background:var(--pink);color:var(--paper)}
.wl-k.t2{background:var(--gold);color:var(--ink)} .wl-k.t3{background:var(--violet);color:var(--paper)}
.wl-k.t4{background:var(--paper-2);color:var(--ink)} .wl-k.t5{background:var(--chalk-dim);color:var(--ink)}
.wl-k.t6{background:var(--chalk-faint);color:var(--paper)}
.wl-k.on{transform:translateY(-3px);box-shadow:0 0 0 2px var(--paper)}
.wl-k.on.w{box-shadow:0 0 0 2px var(--paper),0 0 14px var(--win-bright)}
.wl-k.on.l{box-shadow:0 0 0 2px var(--paper),0 0 14px var(--drip)}

/* ── gold field: the rug run ── */
/* The board is a scene, lifted from the concept mockup
   (gold-field-rug-run.html, 2026-10-06): the mascot crosses a row of rugs,
   one per step of the risk's ladder, toward the vault. A rug lifts on gold
   when the service says the step passed; the arm yanks the one it says was
   the mine; after a cash out the rug it names says "rug was here". The world
   slides under the scene as the mascot walks. games.js sets --plotW (a rug's
   width) from the scene's height; everything here is sized from it. */
.centre:has(> .gr){max-width:none}
.gr{width:100%;flex:1 1 auto;min-height:0;display:flex;flex-direction:column;justify-content:center;gap:clamp(6px,1.2vh,10px);--plotW:100px}
.gr-vp{position:relative;flex:1 1 auto;min-height:150px;max-height:420px;border-radius:18px;overflow:hidden;overflow:clip;
  border:2px solid #3a1a33;--danger:0;box-shadow:inset 0 0 0 1px rgba(255,255,255,.03)}
.gr-defs{position:absolute;width:0;height:0;overflow:hidden}
.gr-sky,.gr-skyred{position:absolute;inset:0}
.gr-sky{background:linear-gradient(#150926 0%,#25102f 55%,#3a1531 100%)}
.gr-skyred{background:linear-gradient(#2a050c 0%,#6e1222 55%,#a51f2e 100%);opacity:calc(var(--danger)*var(--danger)*.85);transition:opacity .7s}
.gr-star{position:absolute;width:2px;height:2px;border-radius:50%;background:#fff;opacity:.6}
.gr-moon{position:absolute;right:7%;top:9%;width:calc(var(--plotW)*.43);height:calc(var(--plotW)*.43);border-radius:50%;
  background:radial-gradient(circle at 35% 35%,#fff8e4,#f3d89d 60%,#d7b066);box-shadow:0 0 44px 12px rgba(243,216,157,.22)}
.gr-moon::after{content:"";position:absolute;inset:0;border-radius:50%;background:#ff3b4f;mix-blend-mode:multiply;opacity:calc(var(--danger)*.9);transition:opacity .7s}
.gr-skyline{position:absolute;left:0;top:0;height:100%;transition:transform .55s cubic-bezier(.2,.8,.2,1)}
.gr-candle{position:absolute;bottom:42%;width:14px;color:#1f8f55;opacity:.55;transition:color .6s}
.gr-candle i{position:absolute;left:6px;width:2px;background:currentColor;opacity:.8}
.gr-candle b{position:absolute;left:0;width:14px;background:currentColor;border-radius:2px}
.gr-candle.red{color:#d8394c}
.gr-world{position:absolute;left:0;top:0;height:100%;transition:transform .55s cubic-bezier(.2,.8,.2,1)}
.gr-rugs{position:absolute;inset:0}
.gr-ground{position:absolute;left:0;bottom:0;height:42%;
  background:repeating-linear-gradient(90deg,rgba(255,255,255,.015) 0 3px,transparent 3px 9px),linear-gradient(#2e1724,#170b12);
  border-top:3px solid #4b2338}
.gr-start{position:absolute;bottom:13%;transform:translateX(-50%);font:700 10px/1 "JetBrains Mono",ui-monospace,monospace;
  letter-spacing:.2em;text-transform:uppercase;color:#8a5f7a}

/* a rug: the step's button, its multiplier on it and its number under it */
.gr .gf-t{position:absolute;bottom:13%;width:var(--plotW);height:calc(var(--plotW)*.46);padding:0;margin:0;border:0;
  background:none;color:inherit;font:inherit;cursor:default;-webkit-tap-highlight-color:transparent}
.gr .gf-t.next{cursor:pointer}
/* any rug ahead can be tapped: the next is a step, one further a walk there */
.gr .gf-t:not(:disabled){cursor:pointer}
.gr .gf-t:not(:disabled):not(.next):hover .gr-rug svg{filter:drop-shadow(0 0 8px rgba(242,193,78,.7))}
.gr .gf-t.dest .gr-rug svg{filter:drop-shadow(0 0 9px rgba(242,193,78,.95))}
.gr .gf-t.dest::before{content:"Walking to";position:absolute;left:50%;top:-26px;transform:translateX(-50%);white-space:nowrap;z-index:4;
  font:700 9px/1 "JetBrains Mono",ui-monospace,monospace;letter-spacing:.12em;text-transform:uppercase;color:var(--ink);background:#f2c14e;padding:3px 6px;border-radius:4px}
/* the scene can be dragged (or scrolled) to look ahead */
.gr-vp{cursor:grab;touch-action:pan-y}
.gr-vp.dragging{cursor:grabbing}
.gr .gf-t:focus-visible{outline:3px solid var(--pink);outline-offset:4px;border-radius:6px}
.gr-hole{position:absolute;left:4%;right:4%;top:20%;bottom:-14%;opacity:0;transition:opacity .2s}
.gr-hole svg{width:100%;height:100%;display:block}
.gr-hole .p{display:none}
.gr-rug{position:absolute;inset:0;transform-origin:50% 0;transition:transform .34s cubic-bezier(.3,.6,.3,1),opacity .34s}
.gr-rug svg{position:absolute;inset:0;width:100%;height:100%;display:block}
.gr .gf-t b{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);white-space:nowrap;pointer-events:none;
  font:400 16px/1 "Anton",Impact,sans-serif;letter-spacing:.02em;color:#f6e7c1;text-shadow:0 2px 0 rgba(0,0,0,.55)}
.gr .gf-t i{position:absolute;left:0;right:0;bottom:-20px;text-align:center;font:700 9px/1 "JetBrains Mono",ui-monospace,monospace;
  font-style:normal;letter-spacing:.1em;color:#7c5470}
.gr-crack{position:absolute;left:-10%;right:-10%;bottom:-36%;height:50%;opacity:.7;pointer-events:none}
/* the rug that can be taken next: lit and marked; tapped, it waits on the service */
.gr .gf-t.next b{color:#f2c14e}
.gr .gf-t.next .gr-rug svg{filter:drop-shadow(0 0 10px rgba(255,45,135,.85))}
.gr .gf-t.next::after{content:"▼";position:absolute;left:50%;top:-28px;transform:translateX(-50%);color:#ff2d87;font-size:16px;line-height:1;
  animation:gr-bob .8s ease-in-out infinite}
.gr .gf-t.pending::after{content:none}
.gr .gf-t.pending .gr-rug{animation:gr-wait .5s ease-in-out infinite}
/* the service's verdicts. Gold: the rug lifts as the mascot lands. The mine:
   the arm pulls it (games.js brings the arm in on the same beat). After a
   cash out: where the rug was. Past the end of a round, the rest fade. */
.gr .gf-t.gold .gr-hole{opacity:1;transition-delay:.3s}
.gr .gf-t.gold .gr-rug{transform:translateY(-70%) scaleY(.15) rotate(-6deg);opacity:0;transition-delay:.3s}
.gr .gf-t.mine .gr-hole,.gr .gf-t.shown .gr-hole{opacity:1}
.gr .gf-t.mine .gr-hole{transition-delay:.62s}
.gr .gf-t.mine .gr-hole .g,.gr .gf-t.shown .gr-hole .g{display:none}
.gr .gf-t.mine .gr-hole .p,.gr .gf-t.shown .gr-hole .p{display:block}
.gr .gf-t.mine .gr-rug{transition:transform .26s cubic-bezier(.7,0,.9,.4) .62s,opacity .26s .74s;transform:translateX(560px) rotate(9deg);opacity:0}
.gr .gf-t.shown .gr-rug{opacity:.18}
.gr .gf-t.shown::before{content:"Rug was here";position:absolute;left:50%;top:-26px;transform:translateX(-50%);white-space:nowrap;z-index:4;
  font:700 9px/1 "JetBrains Mono",ui-monospace,monospace;letter-spacing:.12em;text-transform:uppercase;color:#fff;background:#ff4b5c;padding:3px 6px;border-radius:4px}
.gr .gf-t.dim{opacity:.32;filter:grayscale(.7);transition:opacity .3s .9s,filter .3s .9s}

.gr-vault{position:absolute;bottom:10%;width:calc(var(--plotW)*1.7);transition:opacity .3s}
.gr-vault svg{width:100%;display:block;filter:drop-shadow(0 0 18px rgba(242,193,78,.45))}
.gr-sign{position:absolute;left:50%;top:-30px;transform:translateX(-50%);white-space:nowrap;
  font:700 10px/1 "JetBrains Mono",ui-monospace,monospace;letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink);background:#f2c14e;padding:4px 8px;border-radius:5px;border:2px solid var(--ink)}
.gr-vault.dim{opacity:.35;transition:opacity .3s .9s}
.gr-vault.burst svg{animation:gr-vaultglow 1.2s ease-out}
.gr-vault.burst .gr-sign{opacity:0;transition:opacity .2s}

.gr-mascot{position:absolute;bottom:calc(13% + var(--plotW)*.16);width:calc(var(--plotW)*.62);z-index:5;pointer-events:none;
  transition:left .38s cubic-bezier(.3,.7,.3,1)}
.gr-mascot svg{display:block;width:100%;transform-origin:50% 100%}
.gr-mascot.idle svg{animation:gr-breathe 1.8s ease-in-out infinite}
.gr-mascot.hop svg{animation:gr-hop .38s ease}
.gr-mascot.fall svg{animation:gr-fall .55s cubic-bezier(.5,0,.9,.5) forwards}
.gr-mascot.cheer svg{animation:gr-cheer .7s ease 2}
.gr-mascot .xeyes{display:none}
.gr-mascot.dead .xeyes{display:block}
.gr-mascot.dead .eyes{display:none}

.gr-arm{position:absolute;bottom:calc(13% + var(--plotW)*.08);height:calc(var(--plotW)*.3);width:520px;z-index:6;pointer-events:none;
  opacity:0;transform:translateX(520px);transition:transform .22s ease-out,opacity .1s}
.gr-arm svg{height:100%;display:block}
.gr-arm.in{opacity:1;transform:translateX(0)}
.gr-arm.out{transition:transform .26s cubic-bezier(.7,0,.9,.4);transform:translateX(620px)}

.gr-sack{position:absolute;z-index:8;width:160px;pointer-events:none;text-align:center;animation:gr-sack 2.2s ease forwards}
.gr-sack svg{width:calc(var(--plotW)*.48);display:block;margin:0 auto}
.gr-sack b{display:block;font:700 13px/1.2 "JetBrains Mono",ui-monospace,monospace;color:#f2c14e;text-shadow:0 2px 0 #000;margin-top:-2px;white-space:nowrap}
.gr-coin{position:absolute;width:18px;height:18px;margin:-9px 0 0 -9px;border-radius:50%;z-index:7;pointer-events:none;
  background:radial-gradient(circle at 35% 35%,#fff4b8,#f2c14e 45%,#c98d22);border:2px solid #7d4f0d;
  font:12px/14px "Anton",Impact,sans-serif;color:#7a4807;text-align:center;animation:gr-burst .95s cubic-bezier(.2,.7,.4,1) forwards}
.gr-coin.gr-rain{animation:gr-rain 1.5s ease-in forwards}
.gr-dust{position:absolute;width:22px;height:22px;margin:-11px 0 0 -11px;border-radius:50%;background:rgba(150,110,125,.6);z-index:6;pointer-events:none;
  animation:gr-dust .65s ease-out forwards}

.gr-stamp{position:absolute;left:50%;top:40%;z-index:10;pointer-events:none;white-space:nowrap;
  font-family:"Anton",Impact,sans-serif;font-size:calc(var(--plotW)*.76);line-height:1;letter-spacing:.02em;
  color:#ff2d87;-webkit-text-stroke:calc(var(--plotW)*.025) #fff;
  transform:translate(-50%,-50%) rotate(-9deg) scale(3);opacity:0;transition:transform .28s cubic-bezier(.2,1.6,.4,1),opacity .15s}
.gr-stamp.on{opacity:1;transform:translate(-50%,-50%) rotate(-9deg) scale(1)}
.gr-stamp.win{color:#f2c14e;-webkit-text-stroke-color:var(--ink)}
.gr-vp.shake{animation:gr-shake .42s}

/* every step at a glance: passed, the one to take, the mine, where it was */
.gr-track{flex:none;display:grid;grid-template-columns:repeat(var(--gr-n,10),minmax(0,1fr));gap:3px}
.gr-track i{height:6px;border-radius:3px;background:#2e1a2a}
.gr-track i.done{background:#f2c14e}
.gr-track i.cur{background:#ff2d87;animation:gr-pulse 1s infinite}
.gr-track i.bust{background:#ff4b5c}
.gr-track i.trap{background:transparent;box-shadow:inset 0 0 0 2px #ff4b5c}
.gr-track i.goal{background:transparent;box-shadow:inset 0 0 0 2px #f2c14e}

@keyframes gr-breathe{50%{transform:translateY(-2%) scale(1.01,.99)}}
@keyframes gr-hop{0%{transform:none}18%{transform:scale(1.1,.88)}55%{transform:translateY(-42%) scale(.94,1.07)}85%{transform:scale(1.06,.93)}100%{transform:none}}
@keyframes gr-fall{0%{transform:none}25%{transform:translateY(-8%) rotate(-10deg)}100%{transform:translateY(80%) rotate(30deg) scale(.6);opacity:0}}
@keyframes gr-cheer{30%{transform:translateY(-22%) rotate(-6deg)}60%{transform:translateY(0) rotate(6deg)}}
@keyframes gr-bob{50%{transform:translate(-50%,-5px)}}
@keyframes gr-wait{50%{transform:translateY(2px) scale(.97)}}
@keyframes gr-vaultglow{0%{filter:drop-shadow(0 0 0 rgba(242,193,78,0))}40%{filter:drop-shadow(0 0 60px rgba(255,220,120,1))}100%{filter:drop-shadow(0 0 18px rgba(242,193,78,.45))}}
@keyframes gr-sack{0%{transform:translateY(20px) scale(.3);opacity:0}15%{transform:translateY(-6px) scale(1.15);opacity:1}25%{transform:none}80%{opacity:1}100%{transform:translateY(-40px);opacity:0}}
@keyframes gr-burst{0%{transform:translate(0,0) scale(.3);opacity:1}55%{transform:translate(var(--dx),var(--dy)) scale(1)}100%{transform:translate(var(--dx),calc(var(--dy) + 70px)) scale(.8);opacity:0}}
@keyframes gr-rain{0%{transform:translateY(-30px) rotate(0);opacity:1}100%{transform:translateY(var(--fall)) rotate(560deg);opacity:.15}}
@keyframes gr-dust{to{transform:translate(var(--dx),var(--dy)) scale(2.8);opacity:0}}
@keyframes gr-shake{10%,90%{transform:translate(-2px,1px)}20%,80%{transform:translate(4px,-2px)}30%,50%,70%{transform:translate(-7px,3px)}40%,60%{transform:translate(7px,-3px)}}
@keyframes gr-pulse{50%{opacity:.4}}
.gf-risk .seg-b{font-size:10.5px;letter-spacing:.02em}

/* ── tower ── */
/* Nine levels, level 1 at the bottom, in one fixed-height grid. While a door
   can be picked, its level is the tall row (games.js sets the rows: one at
   TALL fr, the rest 1fr) and the change slides; with nothing to pick, the
   nine share the height. Beside each level, its multiplier — or its number,
   when a multiplier would not fit whole. */
.tw{width:min(100%, clamp(260px, 62vh, 440px));flex:1 1 0;min-height:0;display:flex;flex-direction:column;gap:clamp(6px,1.1vh,10px)}
.tw-box{flex:1 1 0;min-height:0;display:flex}
.tw-tower{flex:1;min-height:0;display:grid;grid-template-rows:repeat(9,1fr);gap:3px;container-type:inline-size;
  transition:grid-template-rows .3s cubic-bezier(.3,.7,.2,1)}
.tw-row{display:grid;grid-template-columns:minmax(0,24%) minmax(0,1fr);gap:6px;min-height:0}
.tw-l{display:flex;align-items:center;justify-content:flex-end;overflow:hidden;min-width:0;
  font:700 max(9px, 2.6cqw)/1 "JetBrains Mono",ui-monospace,monospace;color:var(--chalk-faint);white-space:nowrap;font-variant-numeric:tabular-nums}
.tw-l i{display:none;font-style:normal}
.tw.tw-compact .tw-l b{display:none} .tw.tw-compact .tw-l i{display:inline}
.tw-row.done .tw-l{color:var(--gold)}
.tw-row.cur .tw-l{color:var(--chalk);font-size:max(11px, 3.3cqw)}
.tw-doors{display:grid;grid-template-columns:repeat(var(--n,3),minmax(0,1fr));gap:4px;min-height:0}
.tw-d{position:relative;overflow:hidden;min-height:0;padding:0;cursor:default;
  border:1.5px solid rgba(243,237,247,.22);background:rgba(243,237,247,.04);border-radius:4px;
  transition:background .08s ease,transform .12s ease}
/* the level being climbed: real doors */
.tw-row.cur .tw-d{background:var(--paper-2);border:2px solid var(--ink);box-shadow:2px 2px 0 var(--ink);border-radius:8px 4px 9px 5px/5px 9px 4px 8px}
.tw-row.cur .tw-d:not(:disabled){cursor:pointer}
.tw-row.cur .tw-d:hover:not(:disabled){transform:translate(-1px,-1px);background:var(--paper)}
.tw-d:focus-visible{outline:3px solid var(--pink);outline-offset:2px}
.tw-d.pending{animation:pending .7s ease-in-out infinite}
/* the service's word: your doors, the wrong one, and (once over) every safe one */
.tw-d.pick{background:var(--gold);border-color:var(--ink)}
.tw-d.bust{background:var(--drip);border-color:var(--ink)}
.tw-d.safe{border-color:var(--win-bright);background:rgba(63,208,122,.16)}
.tw-read{display:flex;align-items:baseline;justify-content:center;gap:10px;flex:none}
.tw-read b{font-family:"Anton",Impact,sans-serif;font-size:clamp(26px,5vh,40px);line-height:1;color:var(--chalk);font-variant-numeric:tabular-nums}
.tw-read span{font:700 11px/1 "JetBrains Mono",ui-monospace,monospace;letter-spacing:.06em;color:var(--chalk-dim)}
/* five risks in a slip as narrow as 260px: no letter spacing */
.tw-risk .seg-b{font-size:9.5px;letter-spacing:0}
/* the tower takes the height the arena leaves: the bubble keeps room for its
   two lines whatever it says, or a one-line message would make the tower
   taller and a two-line one shorter */
#app:has(.tw) .say p{min-height:2.7em}

/* ── mines ── */
.grid{display:grid;grid-template-columns:repeat(5,1fr);gap:clamp(6px,.9vh,10px);width:min(100%, clamp(246px, 40vh, 396px))}
.cell{position:relative;overflow:hidden;aspect-ratio:1;border:2.5px solid var(--ink);background:var(--paper-2);color:var(--ink);
  border-radius:11px 5px 12px 6px/6px 12px 5px 11px;display:grid;place-items:center;cursor:pointer;
  font-size:17px;box-shadow:2px 2px 0 var(--ink);transition:transform .12s ease,background .08s ease}
.cell:nth-child(even){border-radius:5px 12px 6px 13px/12px 5px 14px 6px}
.cell:hover:not(:disabled){transform:translate(-2px,-2px);box-shadow:4px 4px 0 var(--ink);background:var(--paper)}
.cell:disabled{cursor:default}
.cell.gem{background:var(--win-bright)}
.cell.bomb{background:var(--drip);color:var(--paper)}
.cell.dim{opacity:.34}
@keyframes flip{0%{transform:rotateY(80deg) scale(.86)}100%{transform:rotateY(0) scale(1)}}
.cell.flip{animation:flip .24s ease-out}

/* ── crash ── */
.chart{position:relative;width:100%;flex:1;min-height:0;border:2.5px solid var(--ink);
  border-radius:12px 26px 14px 28px/27px 12px 30px 14px;background:var(--void);overflow:hidden;box-shadow:4px 4px 0 var(--ink)}
.chart svg{position:absolute;inset:0;width:100%;height:100%}
.curve{fill:none;stroke:var(--pink);stroke-width:5;stroke-linecap:round;stroke-linejoin:round}
.curve.busted{stroke:var(--drip)}
.fillband{fill:url(#cg)}
.mult{position:absolute;inset:0;display:grid;place-items:center;pointer-events:none;
  font-family:"Anton",Impact,sans-serif;font-size:clamp(38px,8vw,68px);line-height:1;
  color:var(--paper);text-shadow:3px 3px 0 rgba(11,7,16,.85)}
.mult.busted{color:var(--drip)} .mult.cashed{color:var(--win-bright)}
/* Zeppelin's multiplier: cream, green from 2×, gold from 10×, glowing pink from 100× */
.mult.zp-t1{color:var(--win-bright)} .mult.zp-t2{color:var(--gold)}
.mult.zp-t3{color:#ff8cc0;text-shadow:0 0 22px rgba(255,45,135,.8),3px 3px 0 rgba(11,7,16,.85)}
/* the last tick, after the feed has stopped: on screen, but not live; and
   a tick the feed delivered late (behind the service by more than BEHIND) */
.mult.stale,.mult.behind{color:var(--chalk-faint)}
/* where a cash out was asked for: a dashed level, a dot on the curve, a label */
.ask{position:absolute;inset:0;pointer-events:none}
.ask[hidden]{display:none}
.ask-line{position:absolute;left:0;right:0;top:var(--ay);border-top:2px dashed var(--gold);opacity:.55}
.ask-dot{position:absolute;left:var(--ax);top:var(--ay);width:11px;height:11px;margin:-5.5px 0 0 -5.5px;
  border-radius:50%;background:var(--gold);border:2px solid var(--ink)}
.ask-lbl{position:absolute;left:8px;top:var(--ay);transform:translateY(calc(-100% - 4px));
  font:800 10px/1 "Archivo",sans-serif;letter-spacing:.08em;text-transform:uppercase;color:var(--gold);
  text-shadow:1px 1px 0 var(--ink)}
/* the flying head (games.js flyingHead): Gold Field's mascot's head, sized
   to the chart, placed by the curve's own points — waiting at the start
   (bobbing), riding the tip, bursting (Crash) or flying off (Zeppelin).
   The glide to each new tip is here: 0.25s, never past the tip. */
.fh{position:absolute;left:0;top:0;width:var(--fd,32px);height:var(--fd,32px);margin:calc(var(--fd,32px)/-2) 0 0 calc(var(--fd,32px)/-2);
  transform:translate(var(--fx,0px),var(--fy,0px)) rotate(var(--fa,0deg));transition:transform .25s ease-out;pointer-events:none}
.fh[hidden]{display:none}
.fh-face{width:100%;height:100%} .fh-face svg{display:block;width:100%;height:100%;filter:drop-shadow(0 2px 0 rgba(11,7,16,.6))}
.fh .xeyes{display:none} .fh.dead .xeyes{display:block} .fh.dead .eyes{display:none}
.fh.wait .fh-face{animation:fh-bob 1.8s ease-in-out infinite}
@keyframes fh-bob{50%{transform:translateY(-12%) rotate(-4deg)}}
/* the burst: no glide to the crash point — it bursts where the point is */
.fh.boom{transition:none}
.fh.boom .fh-face{animation:fh-boom .4s ease-out forwards}
@keyframes fh-boom{0%{transform:scale(1)}30%{transform:scale(1.35)}100%{transform:scale(1.7);opacity:0}}
.fh-bit{position:absolute;left:50%;top:50%;width:24%;height:24%;margin:-12% 0 0 -12%;border-radius:40% 60% 50% 50%;opacity:0;
  background:var(--pink);border:1.5px solid var(--ink);animation:fh-bit .6s cubic-bezier(.2,.7,.4,1) forwards}
.fh-bit:nth-child(odd){background:var(--paper);border-radius:50% 40% 60% 50%}
@keyframes fh-bit{0%{transform:translate(0,0) scale(.6);opacity:1}100%{transform:translate(var(--dx),var(--dy)) rotate(var(--rot)) scale(.5);opacity:0}}
.chart.quake{animation:fh-quake .45s ease-out}
@keyframes fh-quake{15%{transform:translate(-4px,2px) rotate(-.6deg)}30%{transform:translate(4px,-3px) rotate(.6deg)}
  45%{transform:translate(-3px,2px)}60%{transform:translate(3px,-1px)}75%{transform:translate(-1px,1px)}}
.fh.away{transition:transform .7s cubic-bezier(.55,0,1,.45)}
/* ── zeppelin: the betting countdown in place of the multiplier; under the
   chart, the all-bets line — how many are in, and the multipliers people
   cashed out at (no amounts: the broadcasts' currency is not the player's) */
.mult.zp-count{color:var(--gold)}
.zp-all{display:flex;align-items:center;gap:10px;width:100%;min-width:0;margin-top:6px;overflow:hidden;white-space:nowrap;
  font:700 11px/1.2 "JetBrains Mono",ui-monospace,monospace;color:var(--chalk-dim)}
.zp-n{flex:none;color:var(--chalk)}
.zp-outs{flex:1 1 0;display:flex;gap:8px;min-width:0;overflow:hidden}
.zp-outs b{flex:none;color:var(--win-bright);font-weight:700}
/* ── zeppelin: sky to moon (games.js zpSky, 2026-10-12). The sky is a
   canvas under the curve; the line glows, its fill fades out near the head
   (an SVG mask); the multiplier sits a little high, so the head passes
   under it; the bar on the left shows the altitude (labels only where the
   chart is wide); a tag at each level, top left; the player's own stamp;
   confetti; the last flights strip above the chart. */
.zp-sky{position:absolute;inset:0;width:100%;height:100%;display:block}
.zp-chart{background:#1e0b30}
/* the "asked" mark is drawn above the head, which sits on the tip */
.zp-chart .ask{z-index:6}
/* boarding: the window's progress at the top, a label over the figure
   (Lift-off in, Flew away at) — just above the digits, whatever their size */
.zp-bbar{position:absolute;left:30%;right:30%;top:10px;height:4px;border-radius:2px;background:rgba(255,255,255,.14);overflow:hidden;
  opacity:0;transition:opacity .3s;pointer-events:none}
.zp-bbar.on{opacity:1}
.zp-bbar i{display:block;height:100%;background:var(--pink);transform-origin:left center}
.zp-mlab{position:absolute;left:0;right:0;bottom:calc(58% + var(--zmf,34px) * .5);text-align:center;pointer-events:none;
  font:800 11px/1 "Archivo",sans-serif;letter-spacing:.22em;text-transform:uppercase;color:rgba(243,237,247,.65)}
.zp-narrow .zp-bbar{top:7px;height:3px}
.zp-narrow .zp-mlab{font-size:9px;letter-spacing:.16em}
/* riding, the head moves with the line, tick by tick: it crosses the chart
   in the round's first seconds, and a glide trailed it onto the "asked" dot */
.zp-chart .fh.ride{transition:none}
/* the "asked" label clear of the altitude bar, on the side the head is not */
.zp-chart .ask-lbl{left:62px} .zp-chart.zp-narrow .ask-lbl{left:22px}
.zp-chart .ask.r .ask-lbl{left:auto;right:10px}
.zp-chart .mult{bottom:16%;transition:opacity .2s}
.zp-chart.zp-stamped .mult{opacity:.18}
.zp-alt{position:absolute;left:12px;top:13%;bottom:16%;width:3px;background:rgba(255,255,255,.13);border-radius:2px;pointer-events:none}
.zp-alt span{position:absolute;left:9px;transform:translateY(50%);font:700 9px/1 "JetBrains Mono",ui-monospace,monospace;color:rgba(243,237,247,.5);white-space:nowrap}
.zp-alt span::before{content:"";position:absolute;left:-12px;top:50%;width:9px;height:1px;background:rgba(255,255,255,.35)}
.zp-ptr{position:absolute;left:-5px;bottom:0;width:13px;height:13px;margin-bottom:-6.5px;border-radius:50%;background:var(--pink);border:2px solid var(--ink);box-shadow:0 0 10px var(--pink)}
.zp-narrow .zp-alt{left:8px} .zp-narrow .zp-alt span{font-size:0} .zp-narrow .zp-alt span::before{left:-3px}
.zp-lvl{position:absolute;left:62px;top:8px;font:700 10px/1 "JetBrains Mono",ui-monospace,monospace;letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink);background:var(--gold);border:2px solid var(--ink);border-radius:6px;padding:4px 8px;white-space:nowrap;pointer-events:none;
  opacity:0;transform:translateX(-16px);transition:transform .35s cubic-bezier(.2,1.5,.4,1),opacity .25s}
.zp-lvl.on{opacity:1;transform:none}
.zp-narrow .zp-lvl{left:20px;top:5px;font-size:8.5px;padding:3px 6px;letter-spacing:.1em}
.zp-stamp{position:absolute;left:50%;top:42%;z-index:9;pointer-events:none;white-space:nowrap;text-align:center;line-height:.95;
  font-family:"Anton",Impact,sans-serif;font-size:var(--zs,60px);letter-spacing:.02em;color:#ff2d87;-webkit-text-stroke:2px #fff;
  transform:translate(-50%,-50%) rotate(-9deg) scale(3);opacity:0;transition:transform .28s cubic-bezier(.2,1.6,.4,1),opacity .15s}
.zp-stamp.on{opacity:1;transform:translate(-50%,-50%) rotate(-9deg) scale(1)}
.zp-stamp.win{color:#f2c14e;-webkit-text-stroke-color:var(--ink)}
.zp-stamp small{display:block;font-size:.4em;-webkit-text-stroke:0;color:var(--paper);text-shadow:0 3px 0 #000;margin-top:4px}
.zp-cf{position:absolute;top:-12px;width:7px;height:11px;border-radius:2px;z-index:8;pointer-events:none;opacity:0;animation:zp-cf 1.4s ease-in forwards}
@keyframes zp-cf{0%{opacity:1}100%{transform:translate(var(--dx),var(--fall)) rotate(560deg);opacity:.15}}
.zp-fl{display:flex;align-items:center;gap:8px;width:100%;min-width:0;min-height:17px;white-space:nowrap}
.zp-fl-l{flex:none;font:800 9px/1 "Archivo",sans-serif;letter-spacing:.16em;text-transform:uppercase;color:var(--chalk-faint)}
.zp-chips{flex:1 1 0;display:flex;gap:5px;min-width:0;overflow:hidden;
  -webkit-mask-image:linear-gradient(90deg,#000 82%,transparent);mask-image:linear-gradient(90deg,#000 82%,transparent)}
.zp-chips b{flex:none;font:700 10px/1 "JetBrains Mono",ui-monospace,monospace;padding:3px 7px;border-radius:999px;border:1px solid}
.zp-chips .lo{color:#ff8592;border-color:#5a1f2c;background:#2a0d16}
.zp-chips .mid{color:#38d27a;border-color:#1d4a33;background:#0d2219}
.zp-chips .hi{color:var(--gold);border-color:#5a4415;background:#2a2008}
.zp-chips .new{animation:zp-chip .45s cubic-bezier(.2,1.5,.4,1)}
@keyframes zp-chip{from{transform:translateX(-16px) scale(.5);opacity:0}}
/* the head's faces: each part shows for the faces it lists (games.js GR.zhead) */
.fh .zp-p{display:none}
.fh[data-f="angry"] .zp-p[data-on~="angry"],.fh[data-f="nervous"] .zp-p[data-on~="nervous"],.fh[data-f="grin"] .zp-p[data-on~="grin"],
.fh[data-f="shades"] .zp-p[data-on~="shades"],.fh[data-f="laser"] .zp-p[data-on~="laser"],.fh[data-f="rekt"] .zp-p[data-on~="rekt"]{display:inline}
.fh[data-f="laser"] .fh-face svg{filter:drop-shadow(0 0 6px #ff2a2a) drop-shadow(0 2px 0 rgba(11,7,16,.6))}
/* the main button between rounds: bet the next one, or it is queued */
.act.zp-next{background:var(--ink);color:var(--paper);box-shadow:4px 4px 0 var(--pink)}
.act.zp-queued{background:var(--paper);color:var(--ink);box-shadow:4px 4px 0 var(--pink)}
/* auto cash out: the target and its on/off switch */
.auto-row{display:flex;gap:6px}
.tog{flex:none;min-width:76px;background:var(--win);color:var(--paper);border:2.5px solid var(--ink);cursor:pointer;
  border-radius:9px 4px 10px 5px/5px 10px 4px 9px;padding:0 10px;font:800 11px/1 "Archivo",sans-serif;letter-spacing:.06em;text-transform:uppercase}
.tog.off{background:var(--paper-2);color:var(--ink-2)}
.tog:disabled{cursor:default;opacity:.6}
.tog:focus-visible{outline:3px solid var(--pink);outline-offset:2px}
.num.off{opacity:.45}


/* ── reactions ────────────────────────────────────────────────────────────
   The arena is the only surface REKT owns, so it is where the brand has to
   act. Three things happen here that a stock casino table does not do. */

/* 2. crash tension. --heat is driven off the live multiplier, so the longer
      it stays in the air the tighter the arena closes in. */
.arena{--heat:0}
.arena::before{content:"";position:absolute;inset:0;z-index:3;pointer-events:none;
  opacity:var(--heat);transition:opacity .2s linear;
  box-shadow:inset 0 0 58px -6px rgba(255,45,139,.62), inset 0 0 20px -2px rgba(255,45,139,.5)}
/* the glow hugs the frame and rides over the chart, but the mascot and his
   paper bubble stay clean above it */
.stage{z-index:4}
.fun-badge{z-index:5}

/* 3. a losing run is remembered. The table gets bleaker as they stack, and
      the blood runs heavier — the mascot wears the streak, not the player. */
/* The table itself darkens and the play area drains. The blood does NOT get
   duller — it gets heavier — and the paper bubble stays bright, so the world
   goes grey around a mascot who is still shouting. */
.arena[data-streak]{transition:background-color .8s ease}
.arena[data-streak="3"]{background-color:#100A16}
.arena[data-streak="4"]{background-color:#0B0610}
.centre,.woj{transition:filter .8s ease}
.arena[data-streak="3"] .centre,.arena[data-streak="3"] .woj{filter:saturate(.84)}
.arena[data-streak="4"] .centre,.arena[data-streak="4"] .woj{filter:saturate(.7) brightness(.93)}
.tears{transform-box:fill-box;transform-origin:top}
.arena[data-streak="3"] .tears{transform:scaleY(1.25)}
.arena[data-streak="4"] .tears{transform:scaleY(1.5)}

/* ── idle motion: the screen should never look switched off ── */
.blink{transform-box:fill-box;transform-origin:top;animation:blink 5.6s infinite}
@keyframes blink{0%,95.5%,100%{transform:scaleY(0)}97%{transform:scaleY(1)}}
@keyframes bob{0%,100%{transform:translateY(0)}50%{transform:translateY(-7px)}}
.arena:not(.live) .die-stage:not(.hit-l):not(.hit-w),
.arena:not(.live) .lim-stage:not(.hit-l):not(.hit-w){animation:bob 3.8s ease-in-out infinite}

/* ── the hit ───────────────────────────────────────────────────────────────
   Two layers, no ornament. The object the player was watching takes the
   damage, and the mascot reacts to it. */

/* charred and split open on a loss */
.crack{position:absolute;inset:0;width:100%;height:100%;opacity:0;pointer-events:none;
  transition:opacity .3s ease .1s}
.char{background:#2A0B0C!important;color:#FF8E7A!important;
  box-shadow:0 0 26px -2px rgba(217,43,33,.75), 3px 3px 0 var(--ink)}
/* the number sits above the fractures, not under them */
.char .val{position:relative}
.char .lim-target,.char .lim-target b{color:#FFE2D6}
.char .val,.char .mult,.char .lim-num{color:#FFE2D6;z-index:2;
  text-shadow:0 2px 7px rgba(0,0,0,.85),0 0 18px rgba(217,43,33,.6)}
.char > .crack{opacity:1}
/* movement lives on its own element, never on one that already has a transform */
@keyframes shatter{0%{transform:scale(1)}18%{transform:scale(1.13) rotate(-2deg)}
  40%{transform:scale(.95) rotate(1deg)}100%{transform:scale(1)}}
@keyframes popfx{0%{transform:scale(1)}34%{transform:scale(1.09) rotate(1.2deg)}100%{transform:scale(1)}}
.hit-l{animation:shatter .5s cubic-bezier(.3,1.4,.5,1)}
.hit-w{animation:popfx .42s cubic-bezier(.25,1.5,.4,1)}

/* the mascot carries it */
@keyframes lungeL{0%{transform:scale(1)}22%{transform:scale(1.7) translate(5px,-7px) rotate(-6deg)}
  100%{transform:scale(1.16) translate(2px,-2px) rotate(-3deg)}}
@keyframes lungeW{0%{transform:scale(1)}26%{transform:scale(1.34) translate(3px,-9px) rotate(5deg)}
  100%{transform:scale(1.1) translate(1px,-3px) rotate(2deg)}}
.stage.react-l .woj{animation:lungeL .5s cubic-bezier(.2,1.5,.4,1) forwards}
.stage.react-w .woj{animation:lungeW .46s cubic-bezier(.2,1.5,.4,1) forwards}
@keyframes slam{0%{transform:translateX(-24px) scale(.92);opacity:0}
  60%{transform:translateX(5px) scale(1.03);opacity:1}100%{transform:translateX(0) scale(1);opacity:1}}
.stage.react-l .say,.stage.react-w .say{animation:slam .42s cubic-bezier(.2,1.2,.3,1)}

/* In a short frame the receipt has nowhere to go — it collapses to a bare
   label with the balance pop landing on it. Drop it and keep the controls.
   The lobby's 800×450 frame is one of these, and it is where players play:
   without the receipt the slips of Dice (by 23px), Plinko (12px) and Lucky
   Wheel (8px) were still taller than the frame, the balance cut at the
   bottom. So the labels over controls that name themselves go too
   (`.opt`: over/under, "16 rows", the risk buttons, "Auto on"), as on a
   short phone. */
@media (max-height:480px){
  /* Plinko's board takes the arena's width at its old height (games.js
     drawBoard spaces the pegs to it): every bucket wide enough for its number */
  .pk{width:100%;--pk-wide:1} .pk-board{height:50vh}
  .log{display:none}
  .bal{margin-top:auto}
  .opt{display:none}
}

/* ── states ── */
.boot{position:fixed;inset:0;display:grid;place-items:center;background:var(--void);z-index:20;text-align:center;padding:24px}
.boot[hidden]{display:none}
.fun-badge[hidden]{display:none}
.boot h2{font-family:"Anton",Impact,sans-serif;font-size:22px;margin:0 0 6px;text-transform:uppercase}
.boot p{margin:0;color:var(--chalk-dim);font-size:13.5px;max-width:42ch}
.boot-retry{margin-top:14px;font:800 12px/1 "Archivo",sans-serif;letter-spacing:.08em;
  text-transform:uppercase;background:var(--pink);color:#fff;border:0;border-radius:9px;
  padding:10px 16px;cursor:pointer}
.boot-retry[hidden]{display:none}
/* sound on or off (sound.js): top right of every arena, out of the board's way */
.snd{position:absolute;right:12px;top:9px;z-index:6;width:26px;height:26px;display:grid;place-items:center;padding:0;
  border:1.5px solid rgba(243,237,247,.22);border-radius:999px;background:rgba(20,12,28,.6);color:var(--chalk-dim);cursor:pointer}
.snd:hover{color:var(--chalk);border-color:rgba(243,237,247,.45)}
.snd:focus-visible{outline:2px solid var(--pink);outline-offset:2px}
.snd svg{width:14px;height:14px;display:block}
.snd .x{display:none}
.snd.off{color:var(--chalk-faint)}
.snd.off .x{display:block} .snd.off .w{display:none}
.fun-badge{position:absolute;left:14px;top:12px;z-index:3;
  font:800 9px/1 "JetBrains Mono",ui-monospace,monospace;letter-spacing:.12em;text-transform:uppercase;
  color:var(--gold);border:1.5px solid rgba(232,181,75,.45);border-radius:999px;padding:5px 9px}

/* ── portrait / narrow: arena first, slip under ── */
@media (max-width:560px), (max-aspect-ratio:1/1){
  body{overflow:auto}
  #app{grid-template-columns:1fr;grid-template-rows:auto auto;height:auto;min-height:100%;gap:10px;padding:10px}
  .slip{order:2;padding:11px 11px 10px;gap:8px}
  .log{flex:none;margin-top:6px;padding-top:7px}
  .log-rows{max-height:108px}
  .lrow:nth-child(n+5){display:none}
  .arena{padding-top:30px}
  .arena{order:1;min-height:270px}
  .arena::after{font-size:84px}
  .die-stage,.die{width:92px;height:92px}
  .f-front{transform:translateZ(46px)} .f-back{transform:rotateY(180deg) translateZ(46px)}
  .f-right{transform:rotateY(90deg) translateZ(46px)} .f-left{transform:rotateY(-90deg) translateZ(46px)}
  .f-top{transform:rotateX(90deg) translateZ(46px)} .f-bottom{transform:rotateX(-90deg) translateZ(46px)}
  .die .val{font-size:21px}
  .p2{background-position:21px 21px,60px 60px} .p3{background-position:18px 18px,40px 40px,62px 62px}
  .p4{background-position:19px 19px,61px 19px,19px 61px,61px 61px}
  .p5{background-position:18px 18px,62px 18px,40px 40px,18px 62px,62px 62px}
  .p6{background-position:19px 16px,61px 16px,19px 40px,61px 40px,19px 64px,61px 64px}
  .woj{width:48px;height:48px}
  .shout{font-size:15px}
  .grid{width:min(100%,220px);gap:5px}
  .lim{min-width:0;padding:10px 16px} .lim-num{font-size:44px}
  .pk{width:100%;--pk-wide:1} .pk-board{height:min(78vw,262px)}
  /* the arena's height comes from its content here, so the wheel's box gets one */
  .wl{flex:none} .wl-box{flex:none;height:min(76vw,300px)}
  .tw{flex:none} .tw-box{flex:none;height:min(96vw,420px)}
  .gr{flex:none} .gr-vp{flex:none;height:clamp(170px,31vh,250px)}
  .chart{min-height:150px}
  .act{font-size:18px;padding:10px}
}
/* A game modal on a phone: stacked AND short. Everything has to fit in one
   screen — a player must never scroll to find the button that ends the round
   they are watching. The arena takes what it needs and the slip the rest.
   The slip never scrolls inside (a tap on its button would scroll its own
   top out of sight): its receipt gives up rows, faded, before anything else
   is cut. The mascot stands down, and with it the running commentary — the
   tag says what happened. A notice is another matter (a refused stake, a
   failed call, a check under way: R.notice), since nothing else says it: it
   shows as one compact line under the board, and the receipt steps aside. */
@media (max-width:620px) and (max-height:640px){
  :root{--die:74px}
  body{overflow:hidden}
  #app{height:100%;min-height:0;gap:7px;padding:8px;grid-template-rows:auto minmax(0,1fr)}
  .slip{overflow:hidden}
  .log{flex:1 1 0;min-height:0;overflow:hidden;container-type:size}
  /* no room for even one row: the receipt goes as a whole, not as a heading over nothing */
  @container (max-height:36px){ .log > *{display:none} }
  .log-rows{max-height:none}
  .stage{display:none}
  .stage[data-notice]{display:flex}
  #app:has(.stage[data-notice]) .log{display:none}
  /* Crash's chart is the game, and it can stretch where a board can't: there
     the arena takes the spare height and the slip only what it needs */
  #app:has(.chart){grid-template-rows:minmax(0,1fr) auto}
  #app:has(.chart) .log{flex:none;container-type:normal}
  #app:has(.chart) .log-rows{max-height:50px}
  .woj{display:none}
  .say{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
    padding:4px 8px;border-width:2px;box-shadow:2px 2px 0 var(--ink);line-height:1.3}
  .say::before{display:none}
  .shout{display:inline;font-size:12.5px;margin:0 4px 0 0}
  .say p{display:inline;font-size:11px}
  .arena{min-height:0;padding:24px 10px 10px;gap:6px}
  .arena::after{font-size:62px;right:-10px;bottom:-12px}
  .fun-badge{left:9px;top:7px;padding:3px 6px;font-size:8px}
  .snd{right:8px;top:4px;width:22px;height:22px} .snd svg{width:12px;height:12px}
  .centre{gap:8px}
  .die-stage,.die{width:74px;height:74px}
  .f-front{transform:translateZ(37px)} .f-back{transform:rotateY(180deg) translateZ(37px)}
  .f-right{transform:rotateY(90deg) translateZ(37px)} .f-left{transform:rotateY(-90deg) translateZ(37px)}
  .f-top{transform:rotateX(90deg) translateZ(37px)} .f-bottom{transform:rotateX(-90deg) translateZ(37px)}
  .die .val{font-size:17px}
  .scale{display:none}
  .track{height:16px} .marker{height:26px;top:-6px}
  .grid{width:min(100%,186px);gap:4px}
  .lim{padding:7px 12px;box-shadow:3px 3px 0 var(--ink)} .lim-num{font-size:32px} .lim-target{margin-top:4px}
  .pk{width:100%} .pk-board{height:145px} .pk-buckets{margin-top:2px} .pk-b{height:7px} .pk-labels{margin-top:2px}
  .pk-read{font-size:18px;margin-top:-2px}
  .chart{min-height:96px}
  /* the wheel gives up height to the slip; the readout and the key stay whole */
  .wl{gap:3px} .wl-box{height:150px}
  /* the tower keeps all nine levels: thin rows and one tall one */
  .tw{gap:3px} .tw-box{height:222px} .tw-read b{font-size:24px} .tw-tower{gap:2px}
  .wl-read{font-size:24px}
  .wl-k{min-width:44px;padding:2px 5px;gap:1px} .wl-k b{font-size:10px} .wl-k i{font-size:7.5px}
  /* ten across, four down: the same 40 numbers, about 75px shorter */
  .kn{gap:4px} .kn-grid{grid-template-columns:repeat(10,1fr);gap:3px}
  .kn-c{border-width:1.5px;box-shadow:1.5px 1.5px 0 var(--ink)} .kn-tool{padding:4px 8px;font-size:9px}
  .kn-risk .seg-b{font-size:9.5px}
  .mult{font-size:34px}
  .slip{padding:9px 9px 8px;gap:6px;border-width:2.5px;box-shadow:3px 3px 0 var(--ink)}
  .slip-head{font-size:11px;padding-bottom:5px;border-bottom-width:2.5px}
  .amount input,.num,select{padding:6px 9px;font-size:13px}
  .target-row b{font-size:16px}
  .rows{padding:3px 0;border-width:2.5px}
  .row b{font-size:11px}
  .opt{display:none}
  .seg-b{font-size:10.5px;padding:6px 0}
  .act{font-size:16px;padding:8px;margin-top:3px;box-shadow:3px 3px 0 var(--ink)}
  .act.gf-next{font-size:13px}
  .bal{padding-top:7px;border-top-width:2.5px}
  .bal b{font-size:17px}
}

/* A phone frame shorter still: the lobby's on an iPhone gives the game about
   345×440 (Davit, 2026-10-06). Everything compacts to fit: no slip heading,
   no labels over controls that name themselves, tighter inputs, two
   controls to a line where they can share one, the boards smaller. The
   balance and the main button go to the bottom of the slip, the button
   pinned there: should the slip ever overflow, its controls scroll under
   it and the button stays in view. */
@media (max-width:620px) and (max-height:520px){
  #app{padding:6px;gap:6px}
  .arena{padding:20px 8px 6px;gap:4px;border-width:2.5px}
  .arena::after{font-size:52px}
  .fun-badge{top:4px;left:8px;padding:2px 6px;font-size:7.5px}
  .snd{top:2px;right:6px;width:19px;height:19px} .snd svg{width:11px;height:11px}
  .centre{gap:4px}
  .tag{font-size:9px}
  /* a notice floats over the arena's top line (the badge and the tag it
     explains) rather than pushing the slip down or covering the board;
     the sound button stays clear */
  .stage[data-notice]{position:absolute;left:6px;right:30px;top:3px;z-index:7;animation:notice-fade .4s ease 5s forwards}
  @keyframes notice-fade{to{opacity:0;visibility:hidden}}
  .slip{overflow-x:hidden;overflow-y:auto;padding:7px 8px;gap:5px;border-width:2px;box-shadow:2px 2px 0 var(--ink)}
  .slip-head,.field > label{display:none}
  .amount{gap:5px}
  .amount input,.num,select{padding:5px 8px;font-size:13px;border-width:2px}
  .chip{padding:0 10px;font-size:11px}
  .seg{border-width:2px} .seg-b{padding:5px 0;font-size:10px} .seg-b + .seg-b{border-left-width:2px}
  .duo{display:flex;gap:6px;align-items:stretch}
  .duo > .field{flex:1 1 0;min-width:0}
  .duo > .field:first-child{flex:0 0 40%}
  .duo select{height:100%;font-size:12px;padding-right:4px}
  /* Plinko's and Lucky Wheel's stats repeat what the board and its key
     already show: here they give their room to the board */
  .slip:has(#nb) .rows,.slip:has(#npay) .rows{display:none}
  .target-row b{font-size:15px}
  .rows{padding:2px 0;border-width:2px}
  .row{gap:1px} .row .lbl{font-size:7.5px} .row b{font-size:10.5px}
  .bal{order:8;padding-top:4px;border-top-width:2px} .bal b{font-size:15px}
  .slip > .act,.act-row{order:9;position:sticky;bottom:0;z-index:2}
  .act{font-size:15px;padding:7px;margin-top:0;box-shadow:2px 2px 0 var(--ink)}
  .act.gf-next{font-size:12px}
  /* the boards, smaller */
  /* the boards: sized for 345×440, and capped by the frame's height so they
     hold down to 300×400 (an Android lobby gives about 320×420) */
  :root{--die:60px}
  .die-stage,.die{width:60px;height:60px}
  .f-front{transform:translateZ(30px)} .f-back{transform:rotateY(180deg) translateZ(30px)}
  .f-right{transform:rotateY(90deg) translateZ(30px)} .f-left{transform:rotateY(-90deg) translateZ(30px)}
  .f-top{transform:rotateX(90deg) translateZ(30px)} .f-bottom{transform:rotateX(-90deg) translateZ(30px)}
  .die .val{font-size:15px}
  .track{height:13px} .marker{height:21px;top:-5px}
  .lim{padding:5px 12px} .lim-num{font-size:28px}
  .grid{width:min(100%,168px,36vh);gap:3px}
  .pk{width:100%} .pk-board{height:min(171px,34vh)} .pk-read{font-size:15px;margin-top:-2px}
  /* Plinko's buckets want every pixel across: the arena's sides give up 4px */
  .arena:has(.pk){padding-left:4px;padding-right:4px}
  .wl-box{height:min(146px,32vh)} .wl-read{font-size:20px}
  .tw-box{height:min(166px,35vh)} .tw-tower{gap:1px} .tw-read b{font-size:18px}
  .kn{width:min(100%,292px,62vh);gap:3px} .kn-grid{gap:2px}
  .kn-tool{padding:3px 7px;font-size:8.5px} .kn-count{font-size:9px}
  /* the paytable, two rows of small cells, so the board stays whole when
     picks fill it in (it pushed Keno's tag off a 345×440 frame) */
  .kn-pay{gap:2px;min-height:22px} .kn-p{padding:1px 0;gap:1px} .kn-p i{font-size:7px} .kn-p b{font-size:9px}
  .kn-p.on{transform:translateY(-1px)}
  /* Zeppelin's strip: the chips alone */
  .zp-fl-l{display:none} .zp-fl{min-height:15px} .zp-chips b{font-size:9px;padding:2px 5px}
  .act.zp-next,.act.zp-queued{box-shadow:2px 2px 0 var(--pink)}
  /* an arena never scrolls inside (a focus or a tap near its edge must not
     shift the board) */
  .arena{overflow:hidden;overflow:clip}
  .gr-vp{height:min(140px,32vh);min-height:0}
  .chart{min-height:80px}
}

/* shorter still (an Android lobby: about 320×420; held to 300×400): the
   slip gives up a few more pixels */
@media (max-width:620px) and (max-height:430px){
  .slip{padding:6px 7px;gap:4px}
  .amount input,.num,select{padding:4px 8px}
  .chip{padding:0 9px}
  .seg-b{padding:4px 0}
  .rows{padding:1px 0}
  .bal{padding-top:3px} .bal b{font-size:14px}
  .act{font-size:14px;padding:6px}
  .duo select{font-size:11px}
  .arena:has(.pk){padding-left:3px;padding-right:3px}
}

@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
