/* Colchis frame: every selector is fenced off [data-cf] (gen-css.mjs --fence). */
/* ===========================================================================
   cross-board.css — the board itself, and nothing about where the page sits.

   WHAT CHANGED, AND WHY
   ---------------------
   The rejected build drew the four arm gates and the four corner gates as
   painted slabs occupying the whole outer ring of the 5x5 grid: 61-62% of the
   board area, eight near-empty rectangles carrying six words of text, with the
   25-cell playfield a minority of its own container.

   The gates were never a separate UI. The arms and corners ARE the outer ring
   of the same 5x5 board. So an unopened arm now renders as locked board cells
   of exactly the same size as every other cell — sealed tomb masonry inside one
   continuous gold frame — and the gate button is a transparent, cell-aligned
   hit area that carries only carved lettering (direction, price, odds) over
   that masonry. It paints no surface of its own.

   Consequences, all of them measured by tools/browser/05-composition.mjs:
     * all 25 gridcells render, covering >=95% of the board;
     * every cell is the same size (uniformity 1.00);
     * every gate's border box coincides with the cells it will open;
     * gate paint falls from 61-62% of the board to ~0%.

   Every stage/position rule that used to live here now lives in layout.css.
   This file styles the board, the gates, the roster cards and the scenery —
   never where any of them sits on the page.
   =========================================================================== */


/* ---------------------------------------------------------------------------
   1. THE BOARD — one continuous gold frame around 25 equal cells
--------------------------------------------------------------------------- */
.cross-game .machine-status:where(:not([data-cf],[data-cf] *)){display:none!important}
.cross-game .garage-sign:where(:not([data-cf],[data-cf] *)){display:none!important}
.cross-game .left-panel:where(:not([data-cf],[data-cf] *)){display:none!important}

.cross-game .frame:where(:not([data-cf],[data-cf] *)){
 position:relative!important;
 width:100%!important;height:auto!important;aspect-ratio:1!important;
 margin:0!important;padding:0!important;
 border:0!important;border-image:none!important;background:none!important;
 box-shadow:none!important;outline:0!important;overflow:visible!important;
}
.cross-game .frame>.bolt:where(:not([data-cf],[data-cf] *)),.cross-game .frame>.scanline:where(:not([data-cf],[data-cf] *)){display:none!important}
.cross-game .frame:where(:not([data-cf],[data-cf] *))::before,.cross-game .frame:where(:not([data-cf],[data-cf] *))::after,.cross-game #board:where(:not([data-cf],[data-cf] *))::before,.cross-game #board:where(:not([data-cf],[data-cf] *))::after{display:none!important}

/* The frame is a single border-image around the WHOLE grid, as in both
   reference layouts — not a frame per cell. Its width is a length derived from
   the board size: a percentage border-width is invalid CSS, and the previous
   `clamp(8px,2.2%,18px)` was silently dropped, so the gold image was being
   drawn over the outer ring of cells instead of around them. */
.cross-game .board-wrap:where(:not([data-cf],[data-cf] *)){
 --frame-w:clamp(6px,calc(var(--cross-size) * .016),13px);
 position:relative!important;box-sizing:border-box!important;
 width:100%!important;height:100%!important;aspect-ratio:1!important;
 margin:0!important;padding:2px!important;
 border:var(--frame-w) solid transparent!important;
 border-image:var(--frame-gold) 22% / var(--frame-w) / 0 stretch!important;
 background:radial-gradient(ellipse at 50% 30%,#0d2830,#061319 78%)!important;
 box-shadow:inset 0 0 40px #000a,0 10px 28px #00000073!important;
 overflow:hidden!important;
 /* The gates' wording is sized against the BOARD, not the viewport: a 36px
    cell is a 36px cell whether the window is a phone or a short laptop. */
 container-type:size;container-name:board;
}
.cross-game #board:where(:not([data-cf],[data-cf] *)){
 position:relative!important;
 display:grid!important;
 grid-template-columns:repeat(5,minmax(0,1fr))!important;
 grid-template-rows:repeat(5,minmax(0,1fr))!important;
 /* Proportional mortar: the lattice reads the same on a 568px desktop board
    and a 242px phone board, and the 25 cells keep ~96% of the area at both. */
 gap:max(1px,.42%)!important;
 width:100%!important;height:100%!important;aspect-ratio:1!important;
 background:#55462c!important;padding:0!important;border:0!important;
 overflow:visible!important;
}

/* A cell is a cell: same size, same socket, whether it is played, empty or
   still sealed. `.locked` no longer means `visibility:hidden` — that is what
   emptied 16 of the 25 gridcells and left the gates standing in their place. */
.cross-game .tile:where(:not([data-cf],[data-cf] *)){
 position:relative!important;box-sizing:border-box!important;
 width:auto!important;height:auto!important;
 min-width:0!important;min-height:0!important;aspect-ratio:auto!important;
 overflow:hidden;
 background:linear-gradient(165deg,#0c2831,#06161c)!important;
 box-shadow:inset 0 0 0 1px #d8b46a1f,inset 0 0 16px #00000059;
}
/* a11y.css (which loads last, and which this build must not reorder) carries
   `.cross-game #board .tile.locked{opacity:0}` — a workaround written when
   cross-board.css hid the 16 unopened cells outright, to keep them in the
   accessibility tree. The cells are part of the board again, so the pixels
   come back; the accessibility half of that rule still stands.

   SEALED MASONRY. An unopened cell must read as closed stone, not as missing
   content. The stone is the painted green marble already in the build (the
   face of buttons/lock.webp, cropped past its gold ring), darkened into the
   tomb palette, bevelled so each block sits proud of the mortar, and offset
   per cell so 25 blocks do not repeat one texture. */
.cross-game .tile.locked:where(:not([data-cf],[data-cf] *)){
 visibility:visible!important;opacity:1!important;pointer-events:none!important;
 background:
  linear-gradient(155deg,#ffffff24 0%,#0000 30%,#0000 68%,#0000007a 100%),
  linear-gradient(#06151a55,#06151a8c),
  url(./assets/runtime-mummies/buttons/lock.webp) var(--seam-x,50%) var(--seam-y,50%)/270% no-repeat,
  #0f2d2d!important;
 box-shadow:
  inset 0 3px 0 #ffffff26,
  inset 3px 0 0 #ffffff12,
  inset 0 -4px 0 #00000099,
  inset -3px 0 0 #0000006b,
  inset 0 0 0 7px #0000,
  inset 0 0 0 8px #00000047,
  inset 0 0 0 9px #ffffff14,
  inset 0 0 18px #0000005c;
}
.cross-game .a11y-row:nth-child(odd) .tile.locked:nth-child(even):where(:not([data-cf],[data-cf] *)),.cross-game .a11y-row:nth-child(even) .tile.locked:nth-child(odd):where(:not([data-cf],[data-cf] *)){--seam-x:38%;--seam-y:60%}
.cross-game .a11y-row .tile.locked:nth-child(3n):where(:not([data-cf],[data-cf] *)){--seam-x:62%;--seam-y:40%}
.cross-game .a11y-row:nth-child(3n) .tile.locked:nth-child(5n+1):where(:not([data-cf],[data-cf] *)){--seam-x:44%;--seam-y:34%}
.cross-game .tile.locked>*:where(:not([data-cf],[data-cf] *)){visibility:hidden!important}
.cross-game .void-cell:where(:not([data-cf],[data-cf] *)){visibility:hidden!important;pointer-events:none!important;background:none!important;border:none!important}
.cross-game .void-cell:where(:not([data-cf],[data-cf] *))::before,.cross-game .void-cell:where(:not([data-cf],[data-cf] *))::after{display:none!important}
.cross-game .tile .art:where(:not([data-cf],[data-cf] *)){inset:5%!important;width:90%!important;height:90%!important}
.cross-game .tile.rolling .art:where(:not([data-cf],[data-cf] *)){visibility:hidden;animation:none!important}
@keyframes cross-roll{from{transform:translateY(-16%);filter:blur(.5px)}to{transform:translateY(16%);filter:blur(.5px)}}
.cross-game .tile:where(:not([data-cf],[data-cf] *))::before{display:none!important}


/* ---------------------------------------------------------------------------
   2. THE GATES — cell-shaped, surface-free

   A gate occupies exactly the cells it will open (grid areas below), paints
   nothing itself, and carries carved lettering over the sealed masonry. The
   "this is for sale" signal is painted on the CELLS, not on a slab covering
   them, so the board keeps reading as a board.
--------------------------------------------------------------------------- */
.cross-game .cross-gate:where(:not([data-cf],[data-cf] *)),.cross-game .corner-gate:where(:not([data-cf],[data-cf] *)){
 position:relative;z-index:5;
 box-sizing:border-box;
 margin:0;padding:2%;
 border:0;border-image:none;border-radius:0;
 background:none;box-shadow:none;
 -webkit-appearance:none;appearance:none;
 min-width:0;min-height:0;
 display:flex;align-items:center;justify-content:center;
 gap:calc(var(--s2) * .75);
 text-align:center;cursor:pointer;
 font-family:var(--font);
 color:#cbd9cf;
 text-shadow:0 2px 4px #000,0 0 10px #000c;
 overflow:hidden;
}
.cross-gate.top:where(:not([data-cf],[data-cf] *)){grid-area:1/2/2/5}
.cross-gate.bottom:where(:not([data-cf],[data-cf] *)){grid-area:5/2/6/5}
.cross-gate.left:where(:not([data-cf],[data-cf] *)){grid-area:2/1/5/2}
.cross-gate.right:where(:not([data-cf],[data-cf] *)){grid-area:2/5/5/6}
/* A horizontal arm has one cell of height and three of width, so its wording
   sits on two centred lines instead of one crowded one:  "↑ TOP  +3"
   over  "$2.00  45%  +$4.00". Squeezing all five items onto one line is what
   clipped the price to "$2.0". */
.cross-gate.top:where(:not([data-cf],[data-cf] *)),.cross-gate.bottom:where(:not([data-cf],[data-cf] *)){
 display:grid;
 grid-template-columns:auto auto;
 grid-template-areas:"label count" "price odds";
 align-content:center;justify-content:center;
 column-gap:var(--s2);row-gap:2px;
}
.cross-gate.top .direction-label:where(:not([data-cf],[data-cf] *)),.cross-gate.bottom .direction-label:where(:not([data-cf],[data-cf] *)){grid-area:label;justify-self:end;align-self:baseline}
.cross-gate.top strong:where(:not([data-cf],[data-cf] *)),.cross-gate.bottom strong:where(:not([data-cf],[data-cf] *)){grid-area:count;justify-self:start;align-self:baseline}
.cross-gate.top small:where(:not([data-cf],[data-cf] *)),.cross-gate.bottom small:where(:not([data-cf],[data-cf] *)){grid-area:price;justify-self:end}
.cross-gate.top .gate-odds:where(:not([data-cf],[data-cf] *)),.cross-gate.bottom .gate-odds:where(:not([data-cf],[data-cf] *)){grid-area:odds;justify-self:start}
.cross-gate.left:where(:not([data-cf],[data-cf] *)),.cross-gate.right:where(:not([data-cf],[data-cf] *)){flex-direction:column}

.cross-game .corner-gate:where(:not([data-cf],[data-cf] *)){flex-direction:column;gap:1px}
.cross-gate[hidden]:where(:not([data-cf],[data-cf] *)),.cross-game .corner-gate[hidden]:where(:not([data-cf],[data-cf] *)){display:none!important}
.cross-gate:disabled:where(:not([data-cf],[data-cf] *)),.cross-game .corner-gate:disabled:where(:not([data-cf],[data-cf] *)){cursor:default}

/* Typography comes from the one scale; nothing here invents a size. */
.cross-gate .direction-label:where(:not([data-cf],[data-cf] *)){font-size:var(--t-md);font-weight:800;letter-spacing:.06em;white-space:nowrap}
.cross-gate strong:where(:not([data-cf],[data-cf] *)),.cross-game .corner-gate strong:where(:not([data-cf],[data-cf] *)){font-size:var(--t-xl);line-height:1;font-weight:800;color:var(--gold-bright)}
.cross-gate small:where(:not([data-cf],[data-cf] *)),.cross-game .corner-gate small:where(:not([data-cf],[data-cf] *)){font-size:var(--t-md);white-space:nowrap}
.cross-gate em:where(:not([data-cf],[data-cf] *)){font-style:normal;font-size:var(--t-xs);letter-spacing:.12em;color:#82beae}
.cross-gate.top em:where(:not([data-cf],[data-cf] *)),.cross-gate.bottom em:where(:not([data-cf],[data-cf] *)){display:none}
.cross-game .corner-gate>span:where(:not([data-cf],[data-cf] *)){font-size:var(--t-xs);letter-spacing:.12em}
/* A small board steps the gate wording DOWN a rung of the same scale rather
   than inventing sizes of its own, and then starts dropping facts in order of
   redundancy: the availability word (the cells already light up), then the
   prize (it stays in the accessible name and on every larger board). */
@container board (max-width:430px){
 .cross-game .cross-gate strong:where(:not([data-cf],[data-cf] *)),.cross-game .corner-gate strong:where(:not([data-cf],[data-cf] *)){font-size:var(--t-md)}
 .cross-game .cross-gate .direction-label:where(:not([data-cf],[data-cf] *)),.cross-game .cross-gate small:where(:not([data-cf],[data-cf] *)),.cross-game .corner-gate small:where(:not([data-cf],[data-cf] *)),.cross-game .gate-chance:where(:not([data-cf],[data-cf] *)){font-size:var(--t-sm)}
 .cross-game .gate-prize:where(:not([data-cf],[data-cf] *)),.cross-game .cross-gate em:where(:not([data-cf],[data-cf] *)){font-size:var(--t-xs)}
 .cross-game .cross-gate:where(:not([data-cf],[data-cf] *)),.cross-game .corner-gate:where(:not([data-cf],[data-cf] *)){line-height:1.2}
 .cross-game .cross-gate em:where(:not([data-cf],[data-cf] *)){display:none}
}
@container board (max-width:300px){
 .cross-game .cross-gate.left small:where(:not([data-cf],[data-cf] *)),.cross-game .cross-gate.right small:where(:not([data-cf],[data-cf] *)),.cross-game .cross-gate.left .direction-label:where(:not([data-cf],[data-cf] *)),.cross-game .cross-gate.right .direction-label:where(:not([data-cf],[data-cf] *)),.cross-game .corner-gate small:where(:not([data-cf],[data-cf] *)){font-size:var(--t-xs)}
 .cross-game .cross-gate.left .gate-prize:where(:not([data-cf],[data-cf] *)),.cross-game .cross-gate.right .gate-prize:where(:not([data-cf],[data-cf] *)),.cross-game .corner-gate .gate-prize:where(:not([data-cf],[data-cf] *)){display:none}
}
/* Below this the cells are ~36px: an arm keeps its direction and its "+3", and the price moves to the accessible name only. */
@container board (max-width:195px){
 .cross-game .cross-gate small:where(:not([data-cf],[data-cf] *)),.cross-game .corner-gate small:where(:not([data-cf],[data-cf] *)),.cross-game .gate-odds:where(:not([data-cf],[data-cf] *)){display:none}
}
@container board (max-width:230px){
 .cross-game .cross-gate.left small:where(:not([data-cf],[data-cf] *)),.cross-game .cross-gate.right small:where(:not([data-cf],[data-cf] *)),.cross-game .corner-gate small:where(:not([data-cf],[data-cf] *)),.cross-game .cross-gate.left .gate-chance:where(:not([data-cf],[data-cf] *)),.cross-game .cross-gate.right .gate-chance:where(:not([data-cf],[data-cf] *)){display:none}
 .cross-game .cross-gate.top small:where(:not([data-cf],[data-cf] *)),.cross-game .cross-gate.bottom small:where(:not([data-cf],[data-cf] *)){font-size:var(--t-xs)}
 .cross-game .cross-gate.top .gate-prize:where(:not([data-cf],[data-cf] *)),.cross-game .cross-gate.bottom .gate-prize:where(:not([data-cf],[data-cf] *)){display:none}
}
.cross-gate.available:where(:not([data-cf],[data-cf] *)),.cross-game .corner-gate.available:where(:not([data-cf],[data-cf] *)){color:var(--ink)}
.cross-gate.available em:where(:not([data-cf],[data-cf] *)){color:#e3f4a2}

/* The affordance lives on the cells. Each selector names the cells that gate
   opens, so "available" lights up board cells instead of a competing panel. */
.cross-game #board:has(.cross-gate.top.available) .tile[data-cell="1"]:where(:not([data-cf],[data-cf] *)),.cross-game #board:has(.cross-gate.top.available) .tile[data-cell="2"]:where(:not([data-cf],[data-cf] *)),.cross-game #board:has(.cross-gate.top.available) .tile[data-cell="3"]:where(:not([data-cf],[data-cf] *)),.cross-game #board:has(.cross-gate.bottom.available) .tile[data-cell="21"]:where(:not([data-cf],[data-cf] *)),.cross-game #board:has(.cross-gate.bottom.available) .tile[data-cell="22"]:where(:not([data-cf],[data-cf] *)),.cross-game #board:has(.cross-gate.bottom.available) .tile[data-cell="23"]:where(:not([data-cf],[data-cf] *)),.cross-game #board:has(.cross-gate.left.available) .tile[data-cell="5"]:where(:not([data-cf],[data-cf] *)),.cross-game #board:has(.cross-gate.left.available) .tile[data-cell="10"]:where(:not([data-cf],[data-cf] *)),.cross-game #board:has(.cross-gate.left.available) .tile[data-cell="15"]:where(:not([data-cf],[data-cf] *)),.cross-game #board:has(.cross-gate.right.available) .tile[data-cell="9"]:where(:not([data-cf],[data-cf] *)),.cross-game #board:has(.cross-gate.right.available) .tile[data-cell="14"]:where(:not([data-cf],[data-cf] *)),.cross-game #board:has(.cross-gate.right.available) .tile[data-cell="19"]:where(:not([data-cf],[data-cf] *)),.cross-game #board:has(.corner-gate[data-corner="0"].available) .tile[data-cell="0"]:where(:not([data-cf],[data-cf] *)),.cross-game #board:has(.corner-gate[data-corner="4"].available) .tile[data-cell="4"]:where(:not([data-cf],[data-cf] *)),.cross-game #board:has(.corner-gate[data-corner="20"].available) .tile[data-cell="20"]:where(:not([data-cf],[data-cf] *)),.cross-game #board:has(.corner-gate[data-corner="24"].available) .tile[data-cell="24"]:where(:not([data-cf],[data-cf] *)){
 background:
  linear-gradient(#0f3a3380,#0a262680),
  url(./assets/runtime-mummies/buttons/lock.webp) var(--seam-x,50%) var(--seam-y,50%)/270% no-repeat,
  #103a33!important;
 box-shadow:inset 0 0 0 2px #e8c072c4,inset 0 2px 0 #ffe9a83d,inset 0 0 26px #36c6a355;
}
.cross-gate.available:hover:enabled:where(:not([data-cf],[data-cf] *)),.cross-game .corner-gate.available:hover:enabled:where(:not([data-cf],[data-cf] *)){filter:brightness(1.18)}
.cross-gate.available:active:enabled:where(:not([data-cf],[data-cf] *)),.cross-game .corner-gate.available:active:enabled:where(:not([data-cf],[data-cf] *)){filter:brightness(.86)}

.cross-game .tile.corner-eight-win:where(:not([data-cf],[data-cf] *)){box-shadow:inset 0 0 0 3px #f7c16b,0 0 12px #e8ac51a6;z-index:3}
.cross-game .tile[data-win-label]:where(:not([data-cf],[data-cf] *))::after{
 content:attr(data-win-label);position:absolute;z-index:5;
 top:auto!important;bottom:3px!important;inset-inline:2px!important;height:auto!important;
 transform:none!important;border:0!important;
 background:#102c24ed;color:#fff4c3;text-align:center;
 font-size:var(--t-xs);line-height:1.4!important;
}


/* ---------------------------------------------------------------------------
   3. THE WIN — one framed portrait over an exact rectangle of cells

   A win group is always a rectangle of whole cells, so it is drawn as ONE
   framed portrait whose frame snaps to the group's outer cell edges. It is
   opaque, so the mortar lines inside the group disappear under it; every
   other cell keeps its mortar, which is what keeps the grid legible. The
   previous pass drew every covered cell's ring over the portrait and cut it
   into four pieces — a broken image, not a legible grid.

   The size and multiplier badges sit in the frame's bottom corners, in a band
   the portrait leaves clear, never over the art.
   05-composition.mjs asserts: the overlay coincides with its cells' union, no covered cell paints above it, and both badges lie in its corners.
--------------------------------------------------------------------------- */
.cross-game .merged-zombie:where(:not([data-cf],[data-cf] *)){z-index:6!important;pointer-events:none;overflow:hidden}
.cross-game .merged-zombie .merged-portrait:where(:not([data-cf],[data-cf] *)){
 position:absolute;inset:5% 7% 17%;width:auto;height:auto;
 background-size:contain!important;background-position:center bottom!important;background-repeat:no-repeat;
}
/* game.css hides the covered cells with visibility:hidden, which also drops
   them from the accessibility tree. They are made transparent instead, and
   come back as a visible focus target when the keyboard lands on one. */
.cross-game .tile.merged-cell:where(:not([data-cf],[data-cf] *)){visibility:visible!important;opacity:0!important}
.cross-game .tile.merged-cell:focus:where(:not([data-cf],[data-cf] *)),.cross-game .tile.merged-cell:focus-visible:where(:not([data-cf],[data-cf] *)){opacity:1!important;z-index:7!important}
.cross-game .merged-zombie .merged-size:where(:not([data-cf],[data-cf] *)),.cross-game .merged-zombie .merged-charge:where(:not([data-cf],[data-cf] *)){
 top:auto!important;bottom:3%!important;
 font:900 var(--t-sm)/1 var(--font)!important;letter-spacing:.04em;
 padding:3px 6px!important;border-width:3px!important;border-image-width:6px!important;
}
.cross-game .merged-zombie .merged-size:where(:not([data-cf],[data-cf] *)){left:3%!important;right:auto!important}
.cross-game .merged-zombie .merged-charge:where(:not([data-cf],[data-cf] *)){right:3%!important;left:auto!important}

/* ---------------------------------------------------------------------------
   4. DJINN tiles and the sealed-stone miss
--------------------------------------------------------------------------- */
.cross-game #board .tile[data-symbol="scatter"]:where(:not([data-cf],[data-cf] *)){
 box-shadow:inset 0 0 0 2px #b98ae4,0 0 12px #8a5fd066;
}
.cross-game #board .tile[data-symbol="scatter"]:not([data-win-label]):where(:not([data-cf],[data-cf] *))::after{
 content:'DJINN';position:absolute;left:2px;right:2px;bottom:2px;z-index:5;
 font:800 var(--t-xs)/1.4 var(--font);letter-spacing:.1em;text-align:center;
 color:#e2c9ff;background:#2a1145cc;pointer-events:none;
}
/* 'blank' (Sealed Stone) is the engine's inert filler for a missed arm or
   corner. It deliberately has no portrait: a face there would read as a
   consolation prize. */
.tile[data-symbol="blank"] .art:where(:not([data-cf],[data-cf] *)){
 background-image:none!important;
 background-color:#241d18;
 background-image:
  linear-gradient(135deg,#0000 0 42%,#ffffff0a 42% 46%,#0000 46%),
  linear-gradient(45deg,#0000 0 42%,#00000047 42% 46%,#0000 46%),
  radial-gradient(ellipse at 50% 38%,#4a3d30,#221b16 72%)!important;
 box-shadow:inset 0 2px 5px #00000075,inset 0 -2px 4px #ffffff0d;
 border-radius:6px;
}
.tile[data-symbol="blank"]:where(:not([data-cf],[data-cf] *)){opacity:.82}
.tile[data-symbol="blank"] .charge:where(:not([data-cf],[data-cf] *)){display:none}

.spin-strip:where(:not([data-cf],[data-cf] *)){position:absolute;inset:0;z-index:2;pointer-events:none;will-change:transform}
.spin-strip img:where(:not([data-cf],[data-cf] *)){display:block;width:100%;height:100%;object-fit:contain;padding:5%;box-sizing:border-box}


/* ---------------------------------------------------------------------------
   5. THE SYMBOL ROSTER (desktop left panel)

   The Owner asked for "a proper panel with consistent framing, not the cramped
   three-column strip it is now": one framed container, cards inside it with no
   frame of their own, so the column reads as one object.
--------------------------------------------------------------------------- */
.character-paytable:where(:not([data-cf],[data-cf] *)){display:none}
.character-paytable h2:where(:not([data-cf],[data-cf] *)){font-size:var(--t-md);line-height:1.2;margin:0 0 var(--s1);text-shadow:0 2px 4px #000}
.character-paytable>p:where(:not([data-cf],[data-cf] *)){display:none}
.payout-cast:where(:not([data-cf],[data-cf] *)){
 display:grid;grid-template-columns:repeat(6,minmax(0,1fr));
 grid-auto-rows:minmax(0,1fr);gap:var(--s1);flex:1;min-height:0;
}
.payout-character:where(:not([data-cf],[data-cf] *)){
 display:flex;flex-direction:column;align-items:center;justify-content:center;
 min-width:0;min-height:0;padding:3px;box-sizing:border-box;
 grid-column:span 2;
 background:#0b2229b3;border:0;border-image:none;border-radius:4px;
 box-shadow:inset 0 0 0 1px #d8b46a24;
}
.payout-character img:where(:not([data-cf],[data-cf] *)){display:block;width:100%;flex:1;min-height:0;object-fit:contain}
.payout-character h3:where(:not([data-cf],[data-cf] *)){display:none}
.payout-character strong:where(:not([data-cf],[data-cf] *)){font-size:var(--t-sm);line-height:1.1;color:#f2dfad;white-space:nowrap}
.payout-character[data-payout-symbol="wild"]:where(:not([data-cf],[data-cf] *)){grid-column:span 6}
.payout-character[data-payout-symbol="scatter"]:where(:not([data-cf],[data-cf] *)){grid-column:span 6}
.payout-character.payout-winning:where(:not([data-cf],[data-cf] *)){
 background:#25483c;box-shadow:inset 0 0 0 2px var(--gold),inset 0 0 18px #e8c55b35;
}
.payout-winning img:where(:not([data-cf],[data-cf] *)){animation:payout-monster-shake 2.6s ease-in-out infinite;transform-origin:50% 75%;filter:drop-shadow(0 0 5px #e4c56888)}
.payout-winning strong:where(:not([data-cf],[data-cf] *)){color:#fff4b8;text-shadow:0 0 7px #efbd59}
@keyframes payout-monster-shake{0%,36%,100%{transform:translateX(0) rotate(0)}5%,15%,25%{transform:translateX(-4px) rotate(-3deg)}10%,20%,30%{transform:translateX(4px) rotate(3deg)}}
@media(prefers-reduced-motion:reduce){.payout-winning img:where(:not([data-cf],[data-cf] *)){animation:none;transform:none}}


/* ---------------------------------------------------------------------------
   6. SCENERY — unchanged art, one mist pass then ten seconds of clear sky
--------------------------------------------------------------------------- */
.outpost-fog:where(:not([data-cf],[data-cf] *)){position:absolute;inset:0;overflow:hidden;pointer-events:none;contain:paint}
.outpost-fog .fog-wave:where(:not([data-cf],[data-cf] *)){
 position:absolute;left:0;width:110%;height:85%;bottom:-18%;opacity:0;pointer-events:none;
 background:url(./assets/runtime-mummies/fog-realistic.webp) center/100% 100% no-repeat;
 mask-image:radial-gradient(ellipse at center,#000 36%,#000c 57%,transparent 74%);
 --fog-opacity:.46;will-change:transform,opacity;
 animation:outpost-fog-with-pause 56s linear infinite;
}
.outpost-fog .fog-wave:nth-child(2):where(:not([data-cf],[data-cf] *)){width:100%;height:78%;bottom:2%;--fog-opacity:.28}
.outpost-fog .fog-wave:nth-child(3):where(:not([data-cf],[data-cf] *)){width:120%;height:70%;bottom:-24%;--fog-opacity:.5}
@keyframes outpost-fog-with-pause{0%{transform:translate3d(-110%,3%,0) scaleY(.9);opacity:0}10%{opacity:var(--fog-opacity,.46)}41%{transform:translate3d(0,-4%,0) scaleY(1.1);opacity:var(--fog-opacity,.46)}72%{opacity:var(--fog-opacity,.46)}82.142857%,100%{transform:translate3d(110%,2%,0) scaleY(.95);opacity:0}}
.effects-paused .fog-wave:where(:not([data-cf],[data-cf] *)){animation-play-state:paused!important}
@media(max-width:760px){.outpost-fog .fog-wave:where(:not([data-cf],[data-cf] *)){width:170%;height:65%;bottom:-8%}.outpost-fog .fog-wave:nth-child(2):where(:not([data-cf],[data-cf] *)){bottom:16%;height:62%}.outpost-fog .fog-wave:nth-child(3):where(:not([data-cf],[data-cf] *)){bottom:-16%;height:55%}}
@media(prefers-reduced-motion:reduce){.outpost-fog .fog-wave:where(:not([data-cf],[data-cf] *)){animation:none!important;transform:none;opacity:.16;will-change:auto}.outpost-fog .fog-wave:nth-child(n+2):where(:not([data-cf],[data-cf] *)){display:none}}
@keyframes rex-charge-flare{50%{transform:scale(1.3);filter:brightness(3)}}


/* ---------------------------------------------------------------------------
   7. DIALOGS — the buy menu, the guide, the mobile settings sheet
--------------------------------------------------------------------------- */
.cross-game .guide-cast:where(:not([data-cf],[data-cf] *)){display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px}
.cross-game .guide-character:where(:not([data-cf],[data-cf] *)){display:flex;flex-direction:column;align-items:center}
.cross-game .guide-character img:where(:not([data-cf],[data-cf] *)){width:85px;height:85px;object-fit:contain}
.cross-game .guide-character h3:where(:not([data-cf],[data-cf] *)){font-size:15px;text-align:center}
@media(max-width:760px){.cross-game .guide-cast:where(:not([data-cf],[data-cf] *)){grid-template-columns:repeat(2,minmax(0,1fr))}}

.cross-game .bonus-offers:where(:not([data-cf],[data-cf] *)){grid-template-columns:minmax(0,1fr)!important;max-width:540px;width:100%;box-sizing:border-box;margin-inline:auto}
.cross-game .bonus-offer:where(:not([data-cf],[data-cf] *)){border:0!important;border-image:none!important;background:none!important;box-shadow:none!important;outline:0!important;padding:8px 0!important;min-height:0!important;align-items:center!important;text-align:center!important;gap:18px!important}
.cross-game .bonus-offer h2:where(:not([data-cf],[data-cf] *)){display:none}
.cross-game dialog:has(.bonus-offers):where(:not([data-cf],[data-cf] *)){text-align:center!important}
.cross-game dialog:has(.bonus-offers) h1:where(:not([data-cf],[data-cf] *)){font-size:clamp(30px,4vw,40px)!important;line-height:1.2!important;text-align:center;margin:8px 35px 24px!important}
.cross-game .bonus-offer p:where(:not([data-cf],[data-cf] *)){font-size:clamp(18px,2.3vw,22px)!important;line-height:1.5!important;text-align:center!important;margin:0 0 12px!important;color:#e3eeeb!important}
.cross-game .bonus-offer>strong:where(:not([data-cf],[data-cf] *)){display:block;width:100%;font-size:30px!important;line-height:1.3!important;text-align:center!important}
.cross-game .bonus-offer .action:where(:not([data-cf],[data-cf] *)){font-size:20px!important;line-height:1.2!important;min-height:62px!important;width:100%!important}
.cross-game dialog:has(.bonus-offers) #modal-content>p:where(:not([data-cf],[data-cf] *)){font-size:clamp(16px,2vw,19px)!important;line-height:1.5!important;text-align:center!important;color:#cfdfdc!important;margin:24px auto 8px!important;max-width:600px}
@media(max-width:480px){.cross-game dialog:has(.bonus-offers):where(:not([data-cf],[data-cf] *)){padding:16px!important}.cross-game dialog:has(.bonus-offers) h1:where(:not([data-cf],[data-cf] *)){margin-inline:20px!important}.cross-game .bonus-offer>strong:where(:not([data-cf],[data-cf] *)){font-size:26px!important}.cross-game .bonus-offer .action:where(:not([data-cf],[data-cf] *)){font-size:18px!important}}

.mobile-menu-controls:where(:not([data-cf],[data-cf] *)){display:grid;grid-template-columns:repeat(2,1fr);gap:16px;margin:20px 0}
.mobile-setting:where(:not([data-cf],[data-cf] *)){display:flex;align-items:center;gap:8px}
.mobile-setting button:where(:not([data-cf],[data-cf] *)){width:44px!important;height:44px!important;flex:0 0 44px}
@media(orientation:landscape) and (max-height:600px){
 .mobile-menu-controls:where(:not([data-cf],[data-cf] *)){grid-template-columns:repeat(4,1fr);gap:12px;margin:12px 0}
 .mobile-setting:where(:not([data-cf],[data-cf] *)){flex-direction:column;gap:5px}
 .mobile-setting button:where(:not([data-cf],[data-cf] *)){width:40px!important;height:40px!important}
}


/* ---------------------------------------------------------------------------
   8. FOCUS — follows the artwork, never invisible
--------------------------------------------------------------------------- */
.cross-game :is(button,a,select,input,textarea):where(:not([data-cf],[data-cf] *)){-webkit-tap-highlight-color:transparent}
.cross-game :is(button,a,select,input,textarea):focus:where(:not([data-cf],[data-cf] *)){outline:none!important}
.cross-game :is(button,a,select,input,textarea):focus-visible:where(:not([data-cf],[data-cf] *)){
 outline:none!important;
 filter:drop-shadow(0 0 3px #b9efcf) drop-shadow(0 0 5px #53c9ba)!important;
}
.cross-game :is(.cross-gate,.corner-gate):focus-visible:where(:not([data-cf],[data-cf] *)){
 outline:2px solid #b9efcf!important;outline-offset:-3px!important;
}
