/* Table shell — the table and instant games' layout on top of shell.css (load shell.css first, then this, then the
   game's skin.css). Same tokens as the slot shell; a skin restyles by tokens and decoration, never by layout logic.
   Extra tokens: --prim-radius (the main button's corners), --strip-bg, --tact-bg / --tact-ink (the round's buttons),
   --lamp (the light pool of the lamp over the table, a colour; transparent switches it off), --room-vignette (0–1, how
   dark the room's corners fall; 0 switches it off).
   Art direction: docs/design-system/reelhaven/pages/art-direction.md §4 — one lamp over the table, a quiet room, one
   filled main button in the game's colour, quiet result marks, motion on transform / opacity only.
   Shared with the slot shell (shell.css, title.js, panels.js — not repeated here): the motion tokens (--ease-*, --t-*),
   the header (home + sound | title | info + settings, table.js builds the same groups), the title's axis, tracking and
   fit, the panels' open / close motion, the load moment (body.entering) and the quiet win meter at zero (.at-zero). */

/* ---- the room and the lamp: one static layer behind the whole table — a light pool where the lamp hangs over the
   table, darker corners (no animation, no filter). It is position:fixed on purpose: axe treats an absolutely positioned
   pseudo-element with a background behind text as an unknown background and stops checking that text's contrast. ---- */
.table-game::before{content:"";position:fixed;inset:0;z-index:-1;pointer-events:none;
  background:radial-gradient(ellipse 38% 46% at 50% 36%,var(--lamp,color-mix(in srgb,var(--primary-hi) 10%,transparent)),transparent 72%),
    radial-gradient(farthest-corner at 50% 42%,transparent 52%,rgb(0 0 0 / var(--room-vignette,.3)))}

.table-game .stage.tstage{display:flex;flex-direction:column;align-items:stretch;justify-content:flex-start;gap:8px;min-height:0}

/* ---- results strip: quiet marks, the newest first. A win is outlined in the game colour (never filled), a return is
   dashed, a loss is plain. Centred while it fits; once older marks run past the edge it starts at the newest and fades
   its far end (a centred row that overflows would cut off the newest mark). The fade never covers a figure: table.js
   marks every mark that does not fit whole .past and sets --fade-at to the left edge of the first one, so the fade runs
   over that mark's blank shape (its figure is hidden) and every figure left in view keeps its full contrast. ---- */
.tstrip{flex:none;display:flex;align-items:center;gap:6px;justify-content:safe center;margin:0;padding:0 2px;list-style:none;overflow:hidden;min-height:30px}
.tstrip.over{justify-content:flex-start}
.tstrip.cut{mask-image:linear-gradient(90deg,#000 var(--fade-at,calc(100% - 48px)),transparent calc(var(--fade-at,calc(100% - 48px)) + 48px));
  -webkit-mask-image:linear-gradient(90deg,#000 var(--fade-at,calc(100% - 48px)),transparent calc(var(--fade-at,calc(100% - 48px)) + 48px))}
.tstrip li.past>span{opacity:0}
.tstrip li{flex:none;display:grid;place-items:center;min-width:44px;height:28px;padding:0 10px;border-radius:999px;font-size:13px;font-weight:700;font-variant-numeric:tabular-nums;letter-spacing:.01em;
  border:1px solid var(--line);background:var(--strip-bg,color-mix(in srgb,var(--bg2) 85%,transparent));color:var(--muted)}
.tstrip li.won{color:var(--won-ink,var(--primary));border-color:color-mix(in srgb,var(--primary) 70%,transparent)}
.tstrip li.ret{border-style:dashed;color:var(--ink)}
.tstrip li.none{font-weight:600;padding:0 12px}
.tstrip li.fresh{animation:t-mark var(--t-slow) var(--ease-out) backwards}
@keyframes t-mark{from{opacity:0;transform:translateX(-10px) scale(.92)}}

.table-game .boardarea.tboardarea{flex:1 1 auto;min-height:0;width:100%}
.table-game .frame{width:100%;max-width:960px;min-height:0;flex:1 1 auto;justify-content:center}
.table-game .board.tboard{width:100%;min-height:0;display:flex;align-items:center;justify-content:center}
/* the result line: balanced lines; a new line rises in (table.js, Web Animations, 220 ms) */
.table-game .message{min-height:26px;text-wrap:balance}
.tcontrols{flex:none;display:flex;flex-wrap:wrap;gap:8px;justify-content:center;align-items:center;width:100%;max-width:960px;margin:0 auto}
.tcontrols:empty{display:none}

/* ---- HUD: the round's buttons on top, then balance / stake / win / the main button ---- */
.hud.thud{grid-template-columns:1fr auto 1fr auto;grid-template-areas:"acts acts acts acts" "bal bet win spin";row-gap:8px}
.thud>.tacts{grid-area:acts;display:flex;flex-wrap:wrap;gap:8px;justify-content:center}
.thud>.bal{grid-area:bal}.thud>.betctl{grid-area:bet}.thud>.win{grid-area:win}.thud>.spinbox{grid-area:spin}
/* the win meter (quiet at zero: shell.css .at-zero) — a stake that came back is not a win: it reads in the text colour */
.thud .meter.win.ret b{color:var(--ink)}
/* the stake keys step back during a round (the stake is fixed until the round settles) */
.thud .betctl .pm{transition:opacity var(--t-fast) var(--ease-std),visibility var(--t-fast),border-color var(--t-fast) var(--ease-std),transform var(--t-press) var(--ease-out)}
body.in-round .thud .betctl .pm{visibility:hidden;opacity:0}
.thud .pm:hover:not(:disabled){border-color:var(--primary)}
.thud .pm:active:not(:disabled){transform:translateY(1px)}
/* the header's icons and the stake keys are 44 px on every table game and screen (the slot shell draws 42 / 38 px and
   38 / 34 px on small phones, with a 44 px tap overlay). A floor, not a size: a skin's own smaller width / height (a
   compact landscape key) still gets 44 px, a bigger one is kept, and the shell's 44 px tap overlay stays as it was. */
body.table-shell .top .ibtn,body.table-shell .thud .pm{min-width:44px;min-height:44px}

/* the round's other moves: secondary, outlined; only the main button is filled */
.tact{min-height:44px;min-width:96px;padding:8px 16px;border-radius:var(--radius-sm);border:1.5px solid var(--line);background:var(--tact-bg,var(--ibtn-bg));color:var(--tact-ink,var(--ibtn-ink));font-weight:700;font-size:16px;line-height:1.1;
  transition:border-color var(--t-fast) var(--ease-std),transform var(--t-press) var(--ease-out),opacity var(--t-fast) var(--ease-std)}
.tact:disabled{opacity:.45}
.tact:hover:not(:disabled){border-color:var(--primary)}
.tact:active:not(:disabled){transform:translateY(1px)}
.tacts.enter .tact{animation:t-rise-s var(--t-base) var(--ease-out) backwards}
.tacts.enter .tact:nth-child(2){animation-delay:40ms}.tacts.enter .tact:nth-child(3){animation-delay:80ms}.tacts.enter .tact:nth-child(n+4){animation-delay:120ms}
@keyframes t-rise-s{from{opacity:0;transform:translateY(6px)}}

/* the main button: one object under the table's light — a lit top edge, a shaded lower lip and a contact shadow; it
   presses down 2 px (90 ms) instead of shrinking; disabled is dimmed by opacity (no filter transitions) */
.spin.tprim{width:auto;min-width:136px;height:58px;padding:0 24px;border-radius:var(--prim-radius,999px);font-family:var(--display);font-weight:800;font-size:clamp(17px,1.7vw,21px);letter-spacing:.02em;white-space:nowrap;display:grid;place-items:center;
  box-shadow:inset 0 1px 0 rgb(255 255 255 / .35),inset 0 -3px 0 rgb(0 0 0 / .16),0 2px 3px rgb(0 0 0 / .32),0 12px 22px -10px rgb(0 0 0 / .6);
  transition:transform var(--t-press) var(--ease-out),box-shadow var(--t-press) var(--ease-out),opacity var(--t-fast) var(--ease-std)}
.spin.tprim:active:not(:disabled){transform:translateY(2px);box-shadow:inset 0 2px 5px rgb(0 0 0 / .28),0 1px 2px rgb(0 0 0 / .3)}
.spin.tprim:disabled{filter:none;opacity:.55}
.spin.tprim span{display:block;max-width:15ch;overflow:hidden;text-overflow:ellipsis}
.spin.tprim.busy{cursor:progress}
/* waiting for the server longer than a blink: the label breathes (opacity only) until the answer arrives */
.spin.tprim[aria-busy="true"] #spinLbl{animation:t-wait .8s var(--ease-std) .25s infinite alternate}
@keyframes t-wait{to{opacity:.5}}
body.lefty .hud.thud{grid-template-columns:auto 1fr auto 1fr;grid-template-areas:"acts acts acts acts" "spin bal bet win"}

/* ---- the load moment (shell.css body.entering moves the board, the HUD and the title): the results strip and the
   game's own controls rise with the board, so the whole table arrives as one ---- */
body.entering .table-game .tstrip,body.entering .table-game .tcontrols{animation:shell-rise 320ms var(--ease-out) both}

/* ---- the rules panel: per-bet RTP as aligned rows (figures in tabular digits), the platform's facts below ---- */
body.table-shell .panel .trtp{list-style:none;padding:0;margin:8px 0 6px;max-width:640px}
body.table-shell .panel .trtp li{display:flex;justify-content:space-between;align-items:baseline;gap:16px;padding:7px 2px;border-bottom:1px solid var(--line)}
body.table-shell .panel .trtp li.base{color:var(--muted)}
body.table-shell .panel .trtp .v{text-align:right;white-space:nowrap}
body.table-shell .panel .trtp b{font-variant-numeric:tabular-nums;font-weight:700}
body.table-shell .panel .trtp small{color:var(--muted);font-size:13px}
body.table-shell .panel .tfacts li{margin:6px 0}
/* a notice never covers the header's buttons or the title: it drops in under the header */
body.table-shell .toast{top:calc(env(safe-area-inset-top,0px) + 62px)}

/* narrow screens: three rows — the round's buttons, balance + win, stake + the main button (thumb zone, bottom right) */
@media (max-width:860px),(max-aspect-ratio:4/5){
  .hud.thud{grid-template-columns:1fr 1fr;grid-template-areas:"acts acts" "bal win" "bet spin"}
  body.lefty .hud.thud{grid-template-columns:1fr 1fr;grid-template-areas:"acts acts" "win bal" "spin bet"}
  .tact{flex:1 1 auto;min-width:84px}
  body.table-shell .toast{top:calc(env(safe-area-inset-top,0px) + 54px)}
}
@media (max-width:400px){
  .spin.tprim{min-width:108px;height:52px;padding:0 14px;font-size:16px}
  .tstrip li{min-width:40px;padding:0 8px;font-size:12px}
  .tact{min-width:72px;padding:8px 10px;font-size:15px}
  /* 44 px icons: the groups close up to 6 px (the tap areas still do not overlap), the title keeps its room */
  .table-game .topl,.table-game .topr{gap:6px}
  /* 44 px stake keys: the stake control closes up (gaps 4 px, a 60 px floor for its value instead of 70) so that the
     stake + main button row still fits a 381–400 px phone with the autoplay key shown (narrower: the rule below) */
  .thud .betctl{gap:4px}.thud .betctl .meter{min-width:60px}
}
/* the narrowest phones (≤ 380 px): the stake keys draw 40 px (their tap area stays 44 px, shell.css ::before), so the
   row keeps the width it had; a skin's own bigger key is kept */
@media (max-width:380px){body.table-shell .thud .pm{min-width:40px;min-height:40px}}
@media (max-width:340px){
  .spin.tprim{min-width:92px;padding:0 10px;font-size:15px}
  .spin.tprim span{max-width:11ch}
  .table-game .topl,.table-game .topr{gap:4px}
}
/* ---- phones held sideways (and any short, wide window): the phone HUD's three rows (the round's buttons, balance + win,
   stake + main button) left the board 20–110 px of a 360–390 px screen. Here the HUD keeps the one-row order of wide
   screens — balance, stake, win, main button — and the round's buttons are its only second row, centred above it at
   their own width; the page's paddings and gaps tighten. A skin's own landscape layout (a grid stage, a HUD column
   beside the board, a smaller main button) still overrides these, as its skin.css comes later. ---- */
@media (orientation:landscape) and (max-height:520px){
  .table-game.game{row-gap:4px;padding-top:calc(env(safe-area-inset-top,0px) + 6px);padding-bottom:calc(env(safe-area-inset-bottom,0px) + 6px)}
  .table-game .stage.tstage{gap:4px}
  .hud.thud{grid-template-columns:1fr auto 1fr auto;grid-template-areas:"acts acts acts acts" "bal bet win spin";row-gap:6px;padding-top:6px;padding-bottom:6px}
  body.lefty .hud.thud{grid-template-columns:auto 1fr auto 1fr;grid-template-areas:"acts acts acts acts" "spin bal bet win"}
  .thud>.win,body.lefty .thud>.win{text-align:right}
  body.lefty .thud>.bal{text-align:left}
  .spin.tprim{height:48px}
  .spinbox{gap:8px}.auto{width:46px;height:46px}.auto svg{width:21px;height:21px}
  .tact{flex:0 1 auto;min-width:96px;padding:6px 14px}
}
/* reduced motion (system setting, or the shell's body.still): no arrival, no rising marks or moves, no breathing label */
body.still .tstrip li.fresh,body.still .tacts.enter .tact,body.still .spin.tprim[aria-busy="true"] #spinLbl{animation:none}
@media (prefers-reduced-motion:reduce){.tstrip li.fresh,.tacts.enter .tact,.spin.tprim[aria-busy="true"] #spinLbl{animation:none}}
