/* BLOW YOUR MINE - studio palette.
   A CLOSED square is LIT. An OPENED square is the black studio floor. The board
   is a wall of light you eat into, and the explosion is the only thing that ever
   goes brighter than the tiles. Token NAMES are load-bearing: retheme by changing
   the VALUES, never the names (the chessingo rule, learned from cropsicles). */
:root {
  --pink: #FF2D9E;
  --teal: #00E5D0;
  --gold: #FFD400;
  --red: #FF2B2B;
  --violet: #6B1FD6;
  --ink: #0A0A14;
  --panel: #14142A;
  --edge: #2A2A4D;
  --cream: #FFF8EE;
  --dim: #7E7AB8;
  --cdn: 'https://prodmedia.tyga.host/public/tyga.cloud/landing/blowyourmine.com/assets/art/v1';
}

* { box-sizing: border-box; }
body {
  margin: 0; background: var(--ink); color: var(--cream);
  font-family: Outfit, system-ui, -apple-system, sans-serif;
  min-height: 100vh;
}
.bungee { font-family: Bungee, Impact, system-ui, sans-serif; letter-spacing: 1px; }

/* ---- top bar ---- */
.top {
  display: flex; align-items: center; gap: 18px; padding: 10px 16px;
  background: var(--panel); border-bottom: 3px solid var(--pink); flex-wrap: wrap;
}
.top .brand { font-size: 18px; color: var(--gold); }
.top .meta { font-size: 11px; font-weight: 900; letter-spacing: 1.5px; color: var(--dim); }
.spacer { flex-grow: 1; }

/* ---- layout ---- */
.wrap {
  display: flex; gap: 14px; padding: 14px; align-items: flex-start;
  flex-wrap: wrap; justify-content: center;
}
.rail { width: 260px; flex: none; display: flex; flex-direction: column; gap: 10px; }
.stage { flex-grow: 1; min-width: 0; display: flex; flex-direction: column; gap: 10px; align-items: center; }

.card { background: var(--panel); border: 2px solid var(--edge); border-radius: 10px; padding: 12px; }
.label { font-size: 9px; font-weight: 900; letter-spacing: 1.2px; color: var(--dim); }

/* ---- the board ---- */
#board { display: grid; gap: 4px; touch-action: manipulation; -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
.cell {
  width: 46px; height: 46px; border: none; border-radius: 6px; padding: 0;
  font-family: Bungee, Impact, sans-serif; font-size: 18px; cursor: pointer;
  background: var(--pink); color: var(--ink);
  box-shadow: inset 0 -4px 0 rgba(0, 0, 0, .28);
  transition: transform .08s ease;
}
.cell:hover { transform: translateY(-2px); }
.cell:focus-visible { outline: 3px solid var(--cream); outline-offset: 2px; }
/* Round sets the hue, so depth is readable without a number. */
.r2 .cell { background: var(--teal); }
.r3 .cell { background: var(--gold); }
.r4 .cell { background: var(--violet); }
.r5 .cell { background: var(--red); }

.cell.open {
  background: var(--ink); box-shadow: none; cursor: default;
  /* Numbers stay FLAT and legible. Juice the events, never the readable state. */
}
.cell.open:hover { transform: none; }
.cell.flag { background: var(--ink); box-shadow: inset 0 0 0 3px var(--red); }
.cell.boom { background: var(--red); color: var(--cream); }
.n1 { color: var(--teal); } .n2 { color: #7CFF8A; } .n3 { color: var(--gold); }
.n4 { color: #FF9A3C; } .n5 { color: var(--pink); } .n6 { color: #C98BFF; }
.n7, .n8 { color: var(--cream); }

/* The cascade. The wave is in the DATA (each cell carries an order index) and
   this only plays it back, so the renderer never re-derives the shape. */
@keyframes pop { from { transform: scale(.55); opacity: 0; } to { transform: scale(1); opacity: 1; } }
.cell.open { animation: pop .18s ease both; }

@keyframes shake {
  0%, 100% { transform: translate(0, 0); }
  20% { transform: translate(-7px, 3px); }
  40% { transform: translate(6px, -4px); }
  60% { transform: translate(-5px, -2px); }
  80% { transform: translate(4px, 3px); }
}
.shake { animation: shake .4s ease; }

/* ---- hud ---- */
.cart { background: var(--gold); border-radius: 10px; padding: 12px 14px; color: var(--ink); }
.cart .big { font-family: Bungee, Impact, sans-serif; font-size: 36px; line-height: 1.1; }
.vault { display: flex; justify-content: space-between; align-items: baseline; }
.vault .big { font-family: Bungee, Impact, sans-serif; font-size: 19px; color: var(--teal); }

button.action, a.action {
  display: block; width: 100%; border: none; cursor: pointer; border-radius: 10px;
  padding: 14px; font-family: Bungee, Impact, sans-serif; font-size: 16px; letter-spacing: 1px;
  min-height: 48px;
}
button.action:disabled { opacity: .4; cursor: not-allowed; }
.bank { background: var(--teal); color: var(--ink); }
.blow { background: var(--red); color: var(--cream); border: 3px solid var(--cream); }

.host { display: flex; gap: 10px; align-items: flex-start; }
.host img { width: 64px; height: auto; flex: none; }
.say { font-size: 14px; font-weight: 600; line-height: 1.35; }

.logline { font-size: 12px; font-weight: 600; color: var(--dim); }

@media (max-width: 900px) {
  .rail { width: 100%; }
  .cell { width: 38px; height: 38px; font-size: 15px; }
}

/* A cell the RIVAL opened. The shared board is the product, so it has to be
   visible at a glance which of you found what, without a legend. */
.cell.theirs { box-shadow: inset 0 0 0 2px var(--pink); }

/* Lamp out: the numbers stop showing and you keep playing. The cells stay open,
   so the player keeps the SHAPE of what they learned and loses the detail. */
.dark .cell.open { color: transparent; }
.dark .cell.open.boom { color: var(--cream); }

/* ───────────────────────── SITE SHELL ─────────────────────────
   Six destinations, all product, no money in the bar (GDD s9). The logged-out
   bar is the SAME bar: one that changes shape on signup teaches the player the
   site is hiding things from them. */
.nav {
  position: sticky; top: 0; z-index: 40;
  display: flex; align-items: center; gap: 4px; flex-wrap: wrap;
  padding: 10px 16px; background: var(--panel);
  border-bottom: 3px solid var(--pink);
  padding-top: calc(10px + env(safe-area-inset-top, 0px));
}
.nav a.logo {
  font-family: Bungee, Impact, sans-serif; font-size: 17px; color: var(--gold);
  text-decoration: none; letter-spacing: 1px; margin-right: 10px;
}
.nav a.dest {
  color: var(--cream); text-decoration: none; font-weight: 700; font-size: 13px;
  padding: 9px 11px; border-radius: 8px; min-height: 40px; display: flex; align-items: center;
}
.nav a.dest:hover { background: var(--edge); }
.nav a.dest[aria-current="page"] { background: var(--pink); color: var(--ink); }
.nav .cta {
  background: var(--teal); color: var(--ink); font-family: Bungee, Impact, sans-serif;
  font-size: 13px; padding: 9px 14px; border-radius: 8px; text-decoration: none;
}

main { max-width: 1120px; margin: 0 auto; padding: 0 16px 56px; }
.section { padding-block: 44px; }
h1.hero {
  font-family: Bungee, Impact, sans-serif; font-size: clamp(34px, 7vw, 68px);
  line-height: 1; margin: 0 0 14px; color: var(--gold);
}
h2 { font-family: Bungee, Impact, sans-serif; font-size: clamp(22px, 3.4vw, 34px); margin: 0 0 14px; }
p.lede { font-size: clamp(16px, 2.2vw, 21px); line-height: 1.45; max-width: 60ch; margin: 0 0 18px; }
p { line-height: 1.55; }
.muted { color: var(--dim); }

.heroArt {
  width: 100%; border-radius: 14px; border: 3px solid var(--edge);
  display: block; aspect-ratio: 16 / 9; object-fit: cover; background: var(--panel);
}

.grid { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }
.tile { background: var(--panel); border: 2px solid var(--edge); border-radius: 12px; padding: 16px; }
.tile h3 { font-family: Bungee, Impact, sans-serif; font-size: 16px; margin: 0 0 8px; color: var(--teal); }
.tile img { width: 72px; height: auto; display: block; margin-bottom: 10px; }

.big-cta {
  display: inline-block; background: var(--teal); color: var(--ink);
  font-family: Bungee, Impact, sans-serif; font-size: 18px; letter-spacing: 1px;
  padding: 16px 26px; border-radius: 12px; text-decoration: none; min-height: 48px;
}
.ghost-cta {
  display: inline-block; background: transparent; color: var(--cream);
  border: 2px solid var(--edge); font-family: Bungee, Impact, sans-serif; font-size: 16px;
  padding: 14px 22px; border-radius: 12px; text-decoration: none; min-height: 48px;
}

form.signup { display: flex; gap: 8px; flex-wrap: wrap; max-width: 520px; }
form.signup input {
  flex: 1 1 240px; min-height: 48px; padding: 12px 14px; border-radius: 10px;
  border: 2px solid var(--edge); background: var(--ink); color: var(--cream); font-size: 16px;
}
form.signup input:focus-visible { outline: 3px solid var(--teal); outline-offset: 1px; }
form.signup button {
  min-height: 48px; padding: 12px 22px; border: none; border-radius: 10px; cursor: pointer;
  background: var(--gold); color: var(--ink); font-family: Bungee, Impact, sans-serif; font-size: 15px;
}
.formNote { font-size: 13px; margin-top: 10px; min-height: 20px; }

table.board { width: 100%; border-collapse: collapse; }
table.board th, table.board td { text-align: left; padding: 10px 8px; border-bottom: 1px solid var(--edge); }
table.board th { font-size: 10px; letter-spacing: 1.2px; color: var(--dim); font-weight: 900; }
table.board td.num { font-family: Bungee, Impact, sans-serif; color: var(--teal); }
.scroller { overflow-x: auto; }

footer {
  border-top: 2px solid var(--edge); margin-top: 40px; padding: 26px 16px;
  padding-bottom: calc(26px + env(safe-area-inset-bottom, 0px));
  display: flex; gap: 14px; flex-wrap: wrap; align-items: center;
}
footer a { color: var(--dim); font-size: 13px; }

.legal { max-width: 72ch; }
.legal h2 { font-size: 20px; margin-top: 30px; }
.legal li { line-height: 1.55; margin-bottom: 6px; }

/* The cast strip: our own cut sprites, not placeholders. */
.cast { display: flex; gap: 10px; flex-wrap: wrap; align-items: flex-end; }
.cast figure { margin: 0; text-align: center; width: 112px; }
.cast img { width: 100%; height: 112px; object-fit: contain; }
.cast figcaption { font-size: 11px; font-weight: 900; letter-spacing: 1px; color: var(--dim); margin-top: 4px; }

/* The ending. A roguelike lives on the moment it ends, and the payoff for the
   deduction is seeing what was under the squares you never opened. */
.endcard {
  background: var(--panel); border: 3px solid var(--red); border-radius: 14px;
  padding: 20px; max-width: 560px; margin: 0 auto;
}
.endgrid { display: grid; gap: 10px; grid-template-columns: repeat(auto-fit, minmax(96px, 1fr)); }
.endgrid > div { background: var(--ink); border-radius: 9px; padding: 10px; text-align: center; }
.endgrid span { display: block; font-size: 22px; color: var(--gold); }
.endgrid em {
  display: block; font-style: normal; font-size: 10px; font-weight: 900;
  letter-spacing: 1px; color: var(--dim); margin-top: 3px;
}
/* A bomb you never found. Dimmer than one you hit: it is information, not a wound. */
.cell.revealed {
  background: var(--ink); color: var(--pink);
  box-shadow: inset 0 0 0 2px var(--pink); opacity: .75;
}

/* ───────────────────────── THE HERO ─────────────────────────
   Full screen, one button, nothing to read. The splash art does the explaining
   and the only decision above the fold is whether to press PLAY. Everything that
   a crawler needs sits BELOW it, so the hero contract is never diluted by SEO
   copy. Same shape as chessingo's landing. */
.hero-full {
  position: relative;
  min-height: 100vh;
  min-height: 100dvh;
  display: flex; align-items: center; justify-content: center;
  text-align: center; overflow: hidden;
  padding: calc(32px + env(safe-area-inset-top, 0px)) 16px calc(32px + env(safe-area-inset-bottom, 0px));
}
.hero-bg {
  position: absolute; inset: 0;
  background-image: url('https://prodmedia.tyga.host/public/tyga.cloud/landing/blowyourmine.com/assets/art/v1/splash.jpg');
  background-size: cover; background-position: center;
}
.hero-vid {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: center;
  opacity: 0; pointer-events: none;
}
.hero-vid.on { opacity: 1; }
/* The art IS the pitch, so it stays bright (Joe, 2026-10-28: the old full-screen
   .82/.55/.92 wash buried it). Readability comes from a soft pool of shade
   behind the type only, plus a fade at the bottom into the page, and heavy
   text shadows, not from dimming the whole picture. */
.hero-scrim {
  position: absolute; inset: 0;
  background:
    radial-gradient(ellipse 60% 46% at 50% 50%, rgba(10,10,20,.55) 0%, rgba(10,10,20,.2) 60%, rgba(10,10,20,0) 100%),
    linear-gradient(180deg, rgba(10,10,20,0) 70%, rgba(10,10,20,.85) 100%);
}
.hero-inner { position: relative; max-width: 780px; }
.hero-title {
  font-family: Bungee, Impact, sans-serif;
  font-size: clamp(42px, 11vw, 104px); line-height: .95;
  margin: 0 0 18px; color: var(--gold);
  text-shadow: 0 6px 0 rgba(0,0,0,.7), 0 0 28px rgba(0,0,0,.6);
}
.hero-title .hl { display: block; color: var(--pink); }
.hero-line {
  font-size: clamp(17px, 2.6vw, 24px); font-weight: 600; line-height: 1.35;
  margin: 0 auto 30px; max-width: 30ch; color: var(--cream);
  text-shadow: 0 2px 0 rgba(0,0,0,.8), 0 0 18px rgba(0,0,0,.7);
}
.hero-play {
  display: inline-block; background: var(--teal); color: var(--ink);
  font-family: Bungee, Impact, sans-serif; font-size: clamp(20px, 3.4vw, 28px);
  letter-spacing: 2px; padding: 20px 46px; border-radius: 14px;
  text-decoration: none; min-height: 56px;
  box-shadow: 0 6px 0 #00A896;
}
.hero-play:active { transform: translateY(3px); box-shadow: 0 3px 0 #00A896; }
.hero-sub {
  margin: -14px auto 22px; font-size: clamp(15px, 2vw, 19px); font-weight: 700; color: var(--gold);
  text-shadow: 0 2px 0 rgba(0,0,0,.85), 0 0 14px rgba(0,0,0,.75);
}
.hero-proof { margin: 0 auto 22px; font-size: 15px; font-weight: 600; color: var(--cream);
  text-shadow: 0 1px 0 rgba(0,0,0,.9), 0 0 12px rgba(0,0,0,.8); }
.hero-proof b { color: var(--teal); }
.hero-cta { display: flex; gap: 14px; justify-content: center; align-items: center; flex-wrap: wrap; }
.hero-ladder {
  display: inline-block; font-family: Bungee, Impact, sans-serif; font-size: clamp(15px, 2.2vw, 19px);
  color: var(--cream); text-decoration: none; padding: 14px 22px; border-radius: 14px;
  border: 3px solid var(--pink); background: rgba(10,10,20,.55); letter-spacing: 1px;
}
.hero-ladder:hover { background: var(--pink); color: var(--ink); }
/* The landing footer rides the bottom edge of the art, so the page is ONE
   screen with nothing to scroll to (Joe: no SaaS sections). */
body.landing footer {
  position: absolute; left: 0; right: 0; bottom: 0; margin: 0; border: 0; background: transparent;
  padding: 10px 16px calc(10px + env(safe-area-inset-bottom, 0px)); justify-content: center;
}
body.landing footer a, body.landing footer .muted { color: var(--cream); opacity: .8; text-shadow: 0 1px 2px rgba(0,0,0,.9); }
body.landing footer .spacer { display: none; }
.hero-note a { color: inherit; text-decoration: underline; }
.hero-note { margin-top: 16px; font-size: 14px; color: #FFF8EE; text-shadow: 0 1px 0 rgba(0,0,0,.9), 0 0 12px rgba(0,0,0,.8); }
.hero-scroll {
  position: absolute; left: 0; right: 0; bottom: calc(14px + env(safe-area-inset-bottom, 0px));
  font-size: 11px; font-weight: 900; letter-spacing: 2px; color: var(--dim);
}
/* The landing has NO nav (Joe, 2026-10-28): one screen, one button. The
   destinations live inside the game (GDD s29), and the footer below still
   links everything a crawler or a curious reader needs. */

/* ───────────────────────── THE BOARD, WITH THE ART ON IT ─────────────────────────
   Flat CSS rectangles were a wireframe, not a game. Every closed square is a
   painted tile, every bomb that goes off is the character it actually is, and
   the studio sits behind the whole thing. All of it is already cut and on the
   CDN under assets/art/v1. */
.stage {
  position: relative;
  border-radius: 16px;
  padding: 22px 18px 16px;
  background-image:
    linear-gradient(180deg, rgba(10,10,20,.78), rgba(10,10,20,.92)),
    url('https://prodmedia.tyga.host/public/tyga.cloud/landing/blowyourmine.com/assets/art/v1/studio_backdrop.jpg');
  background-size: cover;
  background-position: center top;
  border: 3px solid var(--edge);
}

/* A closed square is a painted tile. The ROUND picks which tile, so depth still
   reads as colour the way the palette intends, and the art carries it instead
   of a flat fill. */
.cell {
  background-color: transparent;
  background-image: url('https://prodmedia.tyga.host/public/tyga.cloud/landing/blowyourmine.com/assets/art/v1/tiles/tile_01.png');
  background-size: 100% 100%;
  background-repeat: no-repeat;
  box-shadow: none;
  color: var(--ink);
  text-shadow: 0 2px 0 rgba(255,255,255,.35);
}
.r2 .cell { background-image: url('https://prodmedia.tyga.host/public/tyga.cloud/landing/blowyourmine.com/assets/art/v1/tiles/tile_02.png'); }
.r3 .cell { background-image: url('https://prodmedia.tyga.host/public/tyga.cloud/landing/blowyourmine.com/assets/art/v1/tiles/tile_04.png'); }
.r4 .cell { background-image: url('https://prodmedia.tyga.host/public/tyga.cloud/landing/blowyourmine.com/assets/art/v1/tiles/tile_03.png'); }
.r5 .cell { background-image: url('https://prodmedia.tyga.host/public/tyga.cloud/landing/blowyourmine.com/assets/art/v1/tiles/tile_08.png'); }

/* An OPENED square is the studio floor: the art comes off, the number goes on. */
.cell.open, .cell.flag, .cell.boom, .cell.revealed {
  background-image: none;
  background-color: rgba(4,4,10,.72);
  text-shadow: none;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.06);
}
.cell.theirs { box-shadow: inset 0 0 0 2px var(--pink); }
.cell.flag { background-image: none; box-shadow: inset 0 0 0 3px var(--red); }

/* A bomb that went off is the CHARACTER it is, not an exclamation mark. */
.cell img.sprite {
  width: 100%; height: 100%; object-fit: contain; display: block;
  pointer-events: none;
}
.cell.revealed img.sprite { opacity: .55; }
.cell.flag img.sprite { width: 78%; height: 78%; margin: 11%; }

/* The explosion, over the top of the cell that caused it. */
.boomfx {
  position: absolute; width: 150px; height: 150px; margin: -52px 0 0 -52px;
  pointer-events: none; z-index: 5;
  animation: boomfx .55s ease-out forwards;
}
@keyframes boomfx {
  from { transform: scale(.35); opacity: 1; }
  to   { transform: scale(1.5); opacity: 0; }
}

@media (max-width: 900px) {
  .stage { padding: 14px 10px 10px; }
}

/* ───────────── FIXES FOUND BY LOOKING AT IT (2026-10-21) ─────────────
   All three of these were invisible to 124 passing assertions and obvious in
   the first screenshot. */

/* 1. THE NUMBERS HAD VANISHED. The tile-art block above sets a dark colour so
   type reads on a bright painted tile, and it is declared AFTER .n1..n8 with
   the same specificity, so it won the cascade on OPEN cells too: dark number on
   a dark floor. Scope the dark text to squares that still have a tile on them,
   and restate the number colours at a specificity that cannot be overtaken. */
.cell.open, .cell.boom, .cell.revealed { color: var(--cream); text-shadow: none; }
.cell.open.n1 { color: #38E7FF; } .cell.open.n2 { color: #7CFF8A; }
.cell.open.n3 { color: var(--gold); } .cell.open.n4 { color: #FF9A3C; }
.cell.open.n5 { color: #FF6FA8; } .cell.open.n6 { color: #C98BFF; }
.cell.open.n7, .cell.open.n8 { color: var(--cream); }

/* 2. An opened square read as a HOLE in the board. It is a slot in the studio
   floor, so give it a floor: a recessed lip tells you it is part of the grid. */
.cell.open {
  background-color: #0C0C18;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.07), inset 0 4px 8px rgba(0,0,0,.65);
  font-size: calc(var(--cell, 46px) * 0.46);
}

/* 3. The board floated in a stage three times its size, so the backdrop was the
   subject and the game was a detail. The stage now hugs the grid. */
.stage {
  width: fit-content;
  max-width: 100%;
  margin: 0 auto;
  background-image:
    linear-gradient(180deg, rgba(10,10,20,.86), rgba(10,10,20,.95)),
    url('https://prodmedia.tyga.host/public/tyga.cloud/landing/blowyourmine.com/assets/art/v1/studio_backdrop.jpg');
}

/* 4. THE BOARD SIZES ITSELF. A fixed 46px cell overflows a phone at 10 columns
   and is hopeless at 16, which is what round 5 is. game.js measures the space
   and sets --cell, so the grid always fits whatever the board grew to. */
#board { gap: var(--gap, 4px); }
.cell {
  width: var(--cell, 46px);
  height: var(--cell, 46px);
  font-size: calc(var(--cell, 46px) * 0.46);
}

/* THE BOARD WAS TOO SMALL, and the cause was a flex rule, not a width.
   `.stage` is a flex child with flex-grow:1, which beats `width: fit-content`
   outright, so the stage stayed 864px around a 496px board and the game read as
   a detail on its own screen. Stop it growing and let the grid take the space. */
.stage { flex: 0 0 auto; align-self: center; }
.wrap { align-items: flex-start; }

/* The backdrop was scrimmed almost to black, so it was noise rather than a
   studio. Lighter, with a vignette so the grid still owns the centre. */
.stage {
  background-image:
    radial-gradient(ellipse at 50% 35%, rgba(10,10,20,.35) 0%, rgba(10,10,20,.88) 70%),
    url('https://prodmedia.tyga.host/public/tyga.cloud/landing/blowyourmine.com/assets/art/v1/studio_backdrop.jpg');
}

/* THE GRID NEEDED A FLOOR. With the backdrop showing through the gaps between
   squares, the board read as mush at full size even though every individual
   square was correct: the eye had no edge to tell where the game stopped and
   the scenery started. A dark panel under the grid makes it one object, and the
   studio stays visible around it, which is all a backdrop should be doing. */
#board {
  background: rgba(6, 6, 14, .88);
  padding: 12px;
  border-radius: 14px;
  box-shadow: 0 10px 40px rgba(0, 0, 0, .55), inset 0 0 0 1px rgba(255, 255, 255, .05);
}
.stage {
  background-image:
    radial-gradient(ellipse at 50% 40%, rgba(10,10,20,.55) 0%, rgba(10,10,20,.93) 72%),
    url('https://prodmedia.tyga.host/public/tyga.cloud/landing/blowyourmine.com/assets/art/v1/studio_backdrop.jpg');
}

/* The numbers were correct and still hard to read at a glance on a full screen:
   a thin glyph in a large square. Heavier and a touch larger, with a faint halo
   so they hold up against the lit backdrop without being "styled". */
.cell.open {
  font-size: calc(var(--cell, 46px) * 0.52);
  text-shadow: 0 0 10px rgba(0, 0, 0, .9), 0 2px 0 rgba(0, 0, 0, .6);
}

/* The rival's cursor. The single cheapest thing that makes a shared board feel
   occupied: you watch them hover over the square you were about to take. */
.cell.peeked {
  outline: 3px solid var(--pink);
  outline-offset: -3px;
  animation: peek 1s ease-in-out infinite;
}
@keyframes peek { 0%, 100% { outline-color: var(--pink); } 50% { outline-color: rgba(255,45,158,.25); } }

/* Emotes. Four fixed words, so they can be styled as buttons rather than as a
   chat box: there is no cursor to put anywhere and nothing to moderate. */
button.emote {
  flex: 1 1 auto; min-height: 40px; padding: 8px 10px; cursor: pointer;
  background: var(--ink); color: var(--cream); border: 2px solid var(--edge);
  border-radius: 8px; font-family: Bungee, Impact, sans-serif; font-size: 11px; letter-spacing: 1px;
}
button.emote:hover { border-color: var(--pink); color: var(--pink); }
.bubble {
  margin-top: 10px; background: var(--pink); color: var(--ink);
  border-radius: 9px; padding: 8px 10px; font-weight: 900; font-size: 13px;
  animation: bubble .25s ease both;
}
@keyframes bubble { from { transform: translateY(6px) scale(.9); opacity: 0; } to { transform: none; opacity: 1; } }

/* `display` BEATS THE `hidden` ATTRIBUTE, and this is the fourth time the fleet
   has paid for it: chessingo shipped a full-screen overlay this way, twice, and
   an assertion that read `el.hidden` passed for the entire life of the bug
   because the attribute really was set. Any rule with a display value defeats
   it, so say it once, globally, and stop relying on remembering. */
[hidden] { display: none !important; }

/* PHONE: the board first, not ninth.
   Stacked, the two rails put eight cards (host, match buttons, emotes, country,
   seats, log...) above the grid, so a player had to scroll past all of them to
   make a move. On a phone the rails dissolve (display: contents) and the pieces
   are reordered: score, rival, BOARD, your cart, bank. Everything else follows.
   Same "opponent, board, you" stack chessingo uses (its GDD s1.2). */
@media (max-width: 900px) {
  .wrap { flex-direction: column; flex-wrap: nowrap; align-items: stretch; }
  .wrap > .rail { display: contents; }
  .wrap > .rail > * { order: 10; }
  #clashBox { order: 1; }
  #rivalBox { order: 2; }
  .wrap > .stage { order: 3; }
  .wrap > .rail > .cart { order: 4; }
  #bankBtn { order: 5; }
  #bankHint { order: 6; }
  #blowBtn { order: 7; }
  #blowHint { order: 7; }
  .wrap > .rail > .host { order: 8; }
}

/* ───────────── FACES ON THE PODIUMS (FEAT-2026-1027-0120) ─────────────
   Every face is a TygaZen pixel config drawn by the SDK as an SVG data URI.
   Pixel art drawn soft is a blur, so it is drawn pixel-sharp at every size. */
.face {
  width: 44px; height: 44px; flex: 0 0 auto; border-radius: 8px;
  background: var(--ink); border: 2px solid var(--edge);
  image-rendering: pixelated; image-rendering: crisp-edges; object-fit: cover;
}
.face.big { width: 64px; height: 64px; }
/* vipsallowed: Avatar.placeholder renders coloured in the web v0.2.0 tag. */
.face.is-placeholder { filter: saturate(0); opacity: .7; }
#rivalBox .face { border-color: var(--pink); }
#youCard .face { border-color: var(--teal); }
.podium { display: flex; align-items: center; gap: 8px; }
.podium.theirs { flex-direction: row-reverse; }
#clashMyFace { border-color: var(--teal); }
#clashTheirFace { border-color: var(--pink); }
.tag {
  display: inline-block; padding: 1px 6px; border-radius: 6px; font-size: 10px;
  font-weight: 900; letter-spacing: 1px; background: var(--gold); color: var(--ink);
}
.facebtn { background: none; border: 0; padding: 0; cursor: pointer; border-radius: 10px; }
.facebtn:focus-visible { outline: 3px solid var(--gold); outline-offset: 2px; }
.facebtn.nudge .face { animation: facepulse 1.6s ease-in-out infinite; }
@keyframes facepulse { 50% { box-shadow: 0 0 0 4px var(--gold); } }
@media (prefers-reduced-motion: reduce) { .facebtn.nudge .face { animation: none; box-shadow: 0 0 0 3px var(--gold); } }

/* The builder dialog. The SDK ships its builder unstyled (.tz-face, .tz-tabs
   .pp-tab, .tz-strip .pp-opt, .tz-swatches), so the look is ours. */
.facebox {
  position: fixed; inset: 0; z-index: 60; display: flex; align-items: center; justify-content: center;
  background: rgba(5, 4, 12, .78); padding: 16px;
  padding-top: calc(16px + env(safe-area-inset-top, 0px));
  padding-bottom: calc(16px + env(safe-area-inset-bottom, 0px));
}
.facepanel { width: min(440px, 100%); max-height: 100%; overflow-y: auto; }
.faceinput {
  width: 100%; min-height: 44px; margin-top: 4px; border-radius: 8px; border: 2px solid var(--edge);
  background: var(--ink); color: var(--cream); font-family: Bungee, Impact, sans-serif; font-size: 16px; padding: 6px 10px;
}
:is(#faceBuilder, #suBuilder) .tz-face { display: flex; justify-content: center; }
:is(#faceBuilder, #suBuilder) .tz-face svg {
  width: 152px; height: 152px; border-radius: 12px; background: var(--ink);
  border: 3px solid var(--gold); image-rendering: pixelated;
}
:is(#faceBuilder, #suBuilder) .tz-tabs { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
:is(#faceBuilder, #suBuilder) button {
  font-family: Outfit, system-ui, sans-serif; cursor: pointer; color: var(--cream);
  background: var(--ink); border: 2px solid var(--edge); border-radius: 8px;
}
:is(#faceBuilder, #suBuilder) .pp-tab { min-height: 36px; padding: 4px 10px; font-size: 12px; font-weight: 900; letter-spacing: 1px; text-transform: uppercase; }
:is(#faceBuilder, #suBuilder) .pp-tab[aria-selected="true"], :is(#faceBuilder, #suBuilder) .pp-tab.is-on, :is(#faceBuilder, #suBuilder) .pp-tab.active,
:is(#faceBuilder, #suBuilder) .pp-opt[aria-pressed="true"], :is(#faceBuilder, #suBuilder) .pp-opt.is-on, :is(#faceBuilder, #suBuilder) .pp-opt.active { border-color: var(--gold); }
:is(#faceBuilder, #suBuilder) .tz-strip { display: flex; gap: 6px; overflow-x: auto; padding: 8px 0 4px; }
:is(#faceBuilder, #suBuilder) .pp-opt { flex: 0 0 auto; width: 52px; height: 52px; padding: 2px; }
:is(#faceBuilder, #suBuilder) .pp-opt svg { width: 100%; height: 100%; image-rendering: pixelated; }
:is(#faceBuilder, #suBuilder) .tz-swatches { display: flex; flex-wrap: wrap; gap: 6px; padding-top: 6px; }
:is(#faceBuilder, #suBuilder) .tz-swatches .pp-swatch { width: 30px; height: 30px; padding: 0; background: var(--c, var(--ink)); }
:is(#faceBuilder, #suBuilder) .pp-swatch[aria-checked="true"] { border-color: var(--gold); box-shadow: 0 0 0 2px var(--gold); }
:is(#faceBuilder, #suBuilder) .pp-opt[aria-checked="true"], :is(#faceBuilder, #suBuilder) .pp-tab[aria-checked="true"] { border-color: var(--gold); }

@media (max-width: 900px) {
  #youCard { order: 9; }
}

/* ───────────── THE BOMB WORLD: the 1v1 challenge lobby ─────────────
   Sits in the stage in place of the board while it is open. */
.stage.lobby-open > :not(.lobby) { display: none !important; }
.lobby {
  width: min(620px, calc(100vw - 32px)); display: flex; flex-direction: column;
  align-items: center; gap: 10px; text-align: center;
}
.lobby[hidden] { display: none; }
.lobby-canvas { width: 100%; max-width: 520px; aspect-ratio: 1 / 1.08; max-height: 62vh; display: block; }
.lobby-head { margin-top: -6px; }
.lobby-panel { display: flex; flex-direction: column; align-items: center; gap: 8px; width: min(340px, 100%); }
.lobby-panel .action { width: 100%; }
.lobby-card {
  width: 100%; display: flex; flex-direction: column; align-items: center; gap: 4px;
  background: var(--panel); border: 2px solid var(--edge); border-radius: 12px; padding: 12px;
}
.lobby-card .face.big { width: 88px; height: 88px; }
.lobby-badge {
  font-size: 11px; font-weight: 900; letter-spacing: 1.5px; padding: 3px 10px; border-radius: 999px;
}
.lobby-badge.is-live { background: var(--teal); color: var(--ink); }
.lobby-badge.is-machine { background: var(--gold); color: var(--ink); }
#lobbyFlat ul { list-style: none; padding: 0; margin: 6px 0 0; display: flex; flex-wrap: wrap; gap: 6px 12px; justify-content: center; }
.lobby.is-locked .lobby-canvas { max-height: 44vh; }

/* THE MOAT (GDD s27): your ladder move on the clash end card. */
.ladder-move { margin: 8px auto 0; padding: 6px 12px; border-radius: 999px; display: inline-block;
  font-size: 15px; color: var(--cream); background: rgba(255,255,255,.06); }
.ladder-move.is-up { color: var(--ink); background: var(--gold); animation: ladderPop .5s ease-out 1; }
@keyframes ladderPop { 0% { transform: scale(.7); } 70% { transform: scale(1.08); } 100% { transform: scale(1); } }
@media (prefers-reduced-motion: reduce) { .ladder-move.is-up { animation: none; } }
.board .ladder-you td { color: var(--gold); }

/* ───────────────────────── HOW TO PLAY (GDD s29) ───────────────────────── */
.howbtn {
  background: var(--gold); color: var(--ink); border: none; border-radius: 8px; cursor: pointer;
  padding: 8px 12px; min-height: 36px; font-family: Bungee, Impact, sans-serif; font-size: 12px; letter-spacing: 1px;
}
.howbox {
  position: fixed; inset: 0; z-index: 70; display: flex; align-items: center; justify-content: center;
  background: rgba(5, 4, 12, .72); padding: 16px;
  padding-top: calc(16px + env(safe-area-inset-top, 0px));
  padding-bottom: calc(16px + env(safe-area-inset-bottom, 0px));
}
.howpanel { width: min(520px, 100%); max-height: 100%; overflow-y: auto; border: 3px solid var(--pink); }
.howhead { display: flex; gap: 12px; align-items: center; }
.howhead img { width: 56px; height: auto; flex: none; }
.howhead h2 { margin: 2px 0 0; font-size: 24px; color: var(--cream); }
.howx { margin-left: auto; align-self: flex-start; background: none; border: 2px solid var(--edge); color: var(--cream);
  width: 40px; height: 40px; border-radius: 10px; font-size: 22px; cursor: pointer; }
.howsteps { list-style: none; margin: 14px 0 0; padding: 0; }
.howstep { text-align: center; min-height: 300px; animation: howIn .22s ease-out; }
.howstep h3 { margin: 14px 0 6px; font-size: 20px; color: var(--gold); }
.howstep p { margin: 0 auto; max-width: 40ch; line-height: 1.5; color: var(--cream); }
.howstep b { color: var(--teal); }
.howart { height: 150px; display: flex; align-items: center; justify-content: center; gap: 14px; }
.howart > img { max-height: 150px; width: auto; }
.howgrid { display: grid; grid-template-columns: repeat(3, 44px); gap: 4px; height: auto; margin: 0 auto; width: max-content; }
.howgrid span { width: 44px; height: 44px; border-radius: 6px; display: flex; align-items: center; justify-content: center;
  font-family: Bungee, Impact, sans-serif; font-size: 20px; }
.howgrid .c { background: var(--pink) url('https://prodmedia.tyga.host/public/tyga.cloud/landing/blowyourmine.com/assets/art/v1/tiles/tile_01.png') center/cover; }
.howgrid .o { background: #0C0C18; color: #38E7FF; box-shadow: inset 0 0 0 2px var(--edge); }
.howgrid .o.n3 { color: var(--gold); }
.howmoney { gap: 10px; }
.howcart, .howvault { border-radius: 10px; padding: 12px 16px; display: flex; flex-direction: column; gap: 2px; min-width: 120px; }
.howcart { background: var(--gold); color: var(--ink); }
.howcart .bungee { font-size: 32px; }
.howvault { background: var(--panel); border: 2px solid var(--teal); }
.howvault .bungee { font-size: 24px; color: var(--teal); }
.howarrow { font-size: 34px; color: var(--teal); }
.howvs img { max-height: 130px; width: auto; }
.howvs img.flip { transform: scaleX(-1); filter: hue-rotate(290deg) saturate(1.3); }
.howvs .bungee { font-size: 32px; color: var(--pink); }
.howfoot { display: flex; align-items: center; gap: 10px; margin-top: 16px; }
.hownav { background: none; border: 2px solid var(--edge); color: var(--cream); border-radius: 10px; cursor: pointer;
  min-height: 48px; padding: 0 16px; font-family: Bungee, Impact, sans-serif; font-size: 13px; }
.howdots { flex: 1; display: flex; justify-content: center; gap: 7px; }
.howdots i { width: 9px; height: 9px; border-radius: 50%; background: var(--edge); }
.howdots i.on { background: var(--pink); }
.howgo { width: auto !important; min-width: 140px; }
@keyframes howIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .howstep { animation: none; } }

/* ═════════════ THE PLAY SCREEN v2 (GDD s29): ONE STAGE, NOTHING ELSE ═════════════
   Scoped to body.play so no other page moves. Three things on screen while a
   board is live: the board, your money, the rival. */
body.play { min-height: 100vh; min-height: 100dvh; background:
  radial-gradient(ellipse at 50% 30%, rgba(10,10,20,.45) 0%, rgba(10,10,20,.92) 75%),
  url('https://prodmedia.tyga.host/public/tyga.cloud/landing/blowyourmine.com/assets/art/v1/studio_backdrop.jpg') center top / cover fixed,
  var(--ink); }

.gamebar {
  position: sticky; top: 0; z-index: 30; display: flex; align-items: center; gap: 14px;
  padding: calc(8px + env(safe-area-inset-top, 0px)) 16px 8px;
  background: rgba(10,10,20,.92); border-bottom: 3px solid var(--pink); backdrop-filter: blur(6px);
}
.gb-logo { color: var(--gold); text-decoration: none; font-size: 18px; }
.gb-meta { font-size: 13px; color: var(--cream); letter-spacing: 1px; }
.gb-dim { color: var(--dim); font-family: Outfit, system-ui, sans-serif; font-weight: 900; font-size: 11px; letter-spacing: 1.5px; }
.gb-short { display: none; }
.gb-menu { background: none; border: 2px solid var(--edge); color: var(--cream); border-radius: 8px;
  width: 42px; height: 38px; font-size: 20px; cursor: pointer; }

.playmain { max-width: 1180px; margin: 0 auto; padding: 12px 12px 0; }
body.play .stage {
  width: 100%; max-width: 100%; margin: 0; padding: 0; border: 0; border-radius: 0;
  background: none; flex: none; align-self: auto;
  display: flex; flex-direction: column; align-items: center; gap: 10px;
}

/* THE PODIUM STRIP */
.podiums {
  width: 100%; max-width: 1040px; display: grid; grid-template-columns: 1fr auto 1fr; gap: 12px; align-items: center;
}
.pod { display: flex; align-items: center; gap: 12px; min-width: 0; position: relative;
  background: rgba(20,20,42,.85); border: 2px solid var(--edge); border-radius: 14px; padding: 8px 12px; }
.pod-you { border-color: var(--teal); }
.pod-them { border-color: var(--pink); justify-content: flex-end; text-align: right; }
.pod .face { width: 52px; height: 52px; }
.pod-you .face { border-color: var(--teal); }
.pod-them .face { border-color: var(--pink); }
.pod-who { min-width: 0; flex: 1; }
.pod-name { font-size: 15px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pod-sub { font-size: 11px; font-weight: 700; color: var(--dim); }
.pod-money { display: flex; gap: 10px; align-items: stretch; }
.pod-cart, .pod-banked { display: flex; flex-direction: column; align-items: center; border-radius: 10px; padding: 4px 10px; min-width: 74px; }
.pod-cart { background: var(--gold); color: var(--ink); }
.pod-cart .bungee { font-size: 24px; line-height: 1.1; }
.pod-banked .bungee { font-size: 20px; line-height: 1.2; color: var(--teal); }
.pod-banked.them .bungee { color: var(--pink); }
.pod-k { font-size: 9px; font-weight: 900; letter-spacing: 1.5px; opacity: .85; }
.pod-mid { display: flex; flex-direction: column; align-items: center; gap: 4px; min-width: 84px; }
.pod-clock { font-size: 22px; color: var(--cream); }
.pod-chip { display: flex; align-items: center; gap: 6px; background: rgba(20,20,42,.85); border: 2px solid var(--edge);
  border-radius: 999px; padding: 2px 10px 2px 4px; font-family: Bungee, Impact, sans-serif; color: var(--red); }
.pod-chip img { width: 24px; height: 24px; object-fit: contain; }
.pod-lamp { font-size: 10px; font-weight: 900; letter-spacing: 1.5px; color: var(--gold); }
.clash-only { display: none; }
.podiums.is-clash .clash-only { display: block; }
.pod-share { margin-top: 4px; background: none; border: 2px solid var(--teal); color: var(--teal); border-radius: 8px;
  padding: 4px 8px; font-size: 11px; font-weight: 900; cursor: pointer; }
.pod-react { position: absolute; left: -12px; bottom: -10px; width: 32px; height: 32px; border-radius: 50%;
  border: 2px solid var(--pink); background: var(--panel); color: var(--cream); font-size: 17px; cursor: pointer; }
.reactpop { position: absolute; z-index: 20; left: 0; top: calc(100% + 8px); display: flex; gap: 6px;
  background: var(--panel); border: 2px solid var(--pink); border-radius: 12px; padding: 8px; }
.pod-them .bubble { position: absolute; right: 8px; top: calc(100% + 6px); z-index: 15; }

/* THE LAMP: a thin bar, not a card. */
.lampline { width: 100%; max-width: 1040px; height: 6px; border-radius: 999px; background: rgba(255,255,255,.08); overflow: hidden; }
.lampline #lampBar { height: 100%; width: 100%; background: var(--gold); transition: width .5s linear; }

/* THE BOARD, and the host's bubble on its edge */
.boardwrap { position: relative; max-width: 100%; }
.hostbubble { position: absolute; left: -8px; top: -14px; transform: translateX(-100%); z-index: 12;
  display: flex; align-items: flex-end; gap: 4px; max-width: 280px; pointer-events: none; }
.hostbubble img { width: 74px; height: auto; flex: none; filter: drop-shadow(0 6px 10px rgba(0,0,0,.6)); }
.hostbubble .say { background: var(--cream); color: var(--ink); border-radius: 14px 14px 14px 4px; padding: 8px 12px;
  font-size: 14px; font-weight: 700; box-shadow: 0 6px 18px rgba(0,0,0,.5); margin-bottom: 40px; }
.hostbubble.pop { animation: hostPop .32s cubic-bezier(.2,1.4,.4,1) 1; }
@keyframes hostPop { from { opacity: 0; transform: translateX(-100%) translateY(10px) scale(.9); } }
@media (max-width: 1400px) {
  .hostbubble { left: 50%; top: 8px; transform: translateX(-50%); max-width: min(92%, 380px); }
  .hostbubble img { width: 48px; }
  .hostbubble .say { margin-bottom: 18px; }
  @keyframes hostPop { from { opacity: 0; transform: translateX(-50%) translateY(-8px) scale(.94); } }
}

/* THE ACTION BAR */
.actionbar { width: 100%; max-width: 640px; display: grid; grid-template-columns: 1.6fr 1fr; gap: 10px; }
.actionbar .action { min-height: 56px; }
.playhint { text-align: center; padding-bottom: 10px; }
.end-host { width: 96px; height: auto; display: block; margin: -70px auto 4px; filter: drop-shadow(0 8px 14px rgba(0,0,0,.6)); }

/* THE MENU SHEET */
.menusheet { position: fixed; inset: 0; z-index: 65; background: rgba(5,4,12,.72); display: flex; justify-content: flex-end; }
.menupanel { width: min(340px, 100%); height: 100%; border-radius: 0; overflow-y: auto; display: flex; flex-direction: column; gap: 8px;
  padding-top: calc(14px + env(safe-area-inset-top, 0px)); padding-bottom: calc(14px + env(safe-area-inset-bottom, 0px)); }
.menuhead { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; }
.menuitem { display: block; text-align: left; width: 100%; min-height: 48px; padding: 12px 14px; border-radius: 10px;
  background: var(--ink); border: 2px solid var(--edge); color: var(--cream); text-decoration: none; cursor: pointer;
  font-family: Bungee, Impact, sans-serif; font-size: 14px; letter-spacing: 1px; }
.menuitem:hover { border-color: var(--pink); }
.menuitem.dim { color: var(--dim); }
.menurow { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 8px 2px; }
.menurow .label { width: 100%; }
.ccinput { width: 68px; min-height: 40px; text-align: center; text-transform: uppercase; border-radius: 8px; border: 2px solid var(--edge);
  background: var(--ink); color: var(--cream); font-family: Bungee, Impact, sans-serif; font-size: 16px; }
.lobby-row { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; }

/* HOW TO PLAY: the magpie PRESENTS (s29.6) */
.howpanel { width: min(760px, 100%); display: grid; grid-template-columns: minmax(180px, 36%) 1fr; gap: 0; padding: 0; overflow: hidden; }
.howhost { width: 100%; height: 100%; max-height: 560px; object-fit: cover; object-position: 50% 8%;
  align-self: end; background: radial-gradient(ellipse at 50% 70%, rgba(255,45,158,.35), transparent 70%); }
.howbody { padding: 16px 18px; min-width: 0; }
.howhead img { display: none; }

@media (max-width: 900px) {
  .gb-long { display: none; } .gb-short { display: inline; }
  .gb-dim { display: none; }
  .podiums { grid-template-columns: 1fr 1fr; gap: 8px; }
  .pod-mid { grid-column: 1 / -1; grid-row: 2; flex-direction: row; justify-content: center; gap: 12px; min-width: 0; }
  .pod { padding: 6px 8px; gap: 8px; }
  .pod .face { width: 40px; height: 40px; }
  .pod-money { flex-direction: column; gap: 4px; }
  .pod-cart, .pod-banked { min-width: 0; padding: 2px 8px; }
  .pod-cart .bungee { font-size: 18px; } .pod-banked .bungee { font-size: 16px; }
  .pod-sub { display: none; }
  .podiums.is-clash .pod-sub.clash-only { display: block; }
  .pod-name { font-size: 12px; }
  .podiums:not(:has(#rivalBox:not([hidden]))) { grid-template-columns: 1fr; }
  .actionbar { position: sticky; bottom: 0; z-index: 20; max-width: none; padding: 8px 0 calc(8px + env(safe-area-inset-bottom, 0px));
    background: linear-gradient(180deg, rgba(10,10,20,0), rgba(10,10,20,.95) 30%); }
  .playhint { display: none; }
  .howpanel { grid-template-columns: 1fr; }
  .howhost { max-height: 170px; object-position: 50% 6%; }
}
/* The names must always read: money columns never squeeze the name out. */
.pod-who { min-width: 96px; }
.pod-sub:empty { display: none !important; }
.pod-them .reactpop { left: auto; right: 0; flex-wrap: wrap; max-width: min(320px, 92vw); }
@media (max-width: 900px) {
  .pod-who { min-width: 0; }
  .pod-them .pod-who { order: 2; }
  .pod .face { width: 34px; height: 34px; }
  .pod-them .tag { font-size: 8px; }
  .pod-react { left: auto; right: -6px; bottom: -12px; width: 28px; height: 28px; font-size: 15px; }
  .pod-clock { font-size: 18px; }
}
/* Solo: no rival podium, so the strip centres on you. */
.podiums:not(:has(#rivalBox:not([hidden]))) { grid-template-columns: auto auto; justify-content: center; }
/* The lobby is not a board: the bar stops counting one. */
body:has(.stage.lobby-open) #roundLabel, body:has(.stage.lobby-open) #bombLabel { display: none; }
@media (max-width: 900px) {
  .podiums:not(:has(#rivalBox:not([hidden]))) { grid-template-columns: 1fr; }
  /* On a phone the host speaks from BELOW the board, in the space above the
     buttons: never over the squares, never over the podiums. */
  .hostbubble { top: calc(100% + 8px); bottom: auto; }
  .actionbar .action { font-size: 14px; padding: 10px; }
  /* The buttons live at the BOTTOM of a phone, where the thumb is (s29.3). */
  body.play .stage { min-height: calc(100dvh - 76px - env(safe-area-inset-top, 0px)); }
  body.play .stage.lobby-open { min-height: 0; }
  .actionbar { margin-top: auto; }
}
@media (prefers-reduced-motion: reduce) { .hostbubble.pop { animation: none; } }
@media (max-width: 900px) {
  /* Phone podiums stack: face + name on top, money underneath, and the
     MACHINE badge ALWAYS shows (honest badging, GDD s26). */
  .pod { flex-wrap: wrap; row-gap: 6px; }
  .pod-who { flex: 1 1 0; }
  .pod-money { order: 3; width: 100%; flex-direction: row; justify-content: space-between; }
  .pod-them .pod-money { order: 3; }
  .pod-sub:has(.tag:not([hidden])) { display: block; }
  .pod-name { font-size: 12px; }
}

/* ───────── THE FUSE REACHES THE BOMB (GDD s26): it blows, the world goes ───────── */
.bomb-stage { position: relative; width: 100%; display: flex; justify-content: center; }
.lobby-boom { position: absolute; inset: 0; display: none; align-items: center; justify-content: center; pointer-events: none; }
.lobby-boom::before { content: ''; position: absolute; inset: -20%; border-radius: 50%;
  background: radial-gradient(circle, rgba(255,248,238,.95) 0%, rgba(255,212,0,.6) 25%, rgba(255,45,158,.25) 50%, transparent 70%); opacity: 0; }
.lobby-boom img { width: 70%; max-width: 420px; height: auto; opacity: 0; }
.lobby.is-blowing .lobby-boom { display: flex; }
.lobby.is-blowing .lobby-boom::before { animation: boomFlash .7s ease-out forwards; }
.lobby.is-blowing .lobby-boom img { animation: boomPop .75s cubic-bezier(.2,.9,.3,1) forwards; }
.lobby.is-blowing .lobby-canvas { animation: bombShake .22s linear 1, bombGone .5s .2s ease-in forwards; }
.lobby.is-blown .bomb-stage, .lobby.is-blown .lobby-head { display: none; }
@keyframes bombShake { 25% { transform: translate(-7px, 3px) rotate(-2deg); } 50% { transform: translate(7px, -3px) rotate(2deg); } 75% { transform: translate(-4px, -2px) rotate(-1deg); } }
@keyframes bombGone { to { opacity: 0; transform: scale(1.4); filter: brightness(3) saturate(0); } }
@keyframes boomFlash { 0% { opacity: 0; transform: scale(.4); } 25% { opacity: 1; } 100% { opacity: 0; transform: scale(1.3); } }
@keyframes boomPop { 0% { opacity: 1; transform: scale(.2) rotate(-8deg); } 60% { opacity: 1; } 100% { opacity: 0; transform: scale(1.7) rotate(6deg); } }

/* What is left standing: YOU vs THEM */
.vs-row { display: flex; align-items: center; justify-content: center; gap: 14px; margin: 10px 0 8px; }
.vs-side { display: flex; flex-direction: column; align-items: center; gap: 6px; min-width: 0; width: 120px; }
.vs-side .face.big { width: 92px; height: 92px; }
.vs-side .bungee { font-size: 14px; max-width: 120px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.vs-me .face { border-color: var(--teal); } .vs-them .face { border-color: var(--pink); }
.vs-mark { font-size: 34px; color: var(--gold); text-shadow: 0 4px 0 rgba(0,0,0,.6); }
.lobby.is-blown .vs-me { animation: vsInL .45s cubic-bezier(.2,1.3,.4,1) both; }
.lobby.is-blown .vs-them { animation: vsInR .45s cubic-bezier(.2,1.3,.4,1) both; }
.lobby.is-blown .vs-mark { animation: vsPop .4s .3s cubic-bezier(.2,1.6,.4,1) both; }
@keyframes vsInL { from { opacity: 0; transform: translateX(-80px) scale(.8); } }
@keyframes vsInR { from { opacity: 0; transform: translateX(80px) scale(.8); } }
@keyframes vsPop { from { opacity: 0; transform: scale(2.4); } }
@media (prefers-reduced-motion: reduce) {
  .lobby.is-blown .vs-me, .lobby.is-blown .vs-them, .lobby.is-blown .vs-mark { animation: none; }
}
/* The reveal is the payoff: centred on the stage, big faces, a big VS. */
.lobby.is-blown { min-height: calc(100vh - 140px); justify-content: center; }
.lobby.is-blown .lobby-card { padding: 18px 22px; border-width: 3px; }
.lobby.is-blown .vs-side { width: 150px; }
.lobby.is-blown .vs-side .face.big { width: 128px; height: 128px; }
.lobby.is-blown .vs-side .bungee { font-size: 17px; max-width: 150px; }
.lobby.is-blown .vs-mark { font-size: 52px; }
.lobby-boom img { width: 115%; max-width: 640px; }
@media (max-width: 520px) {
  .lobby.is-blown .vs-side { width: 108px; }
  .lobby.is-blown .vs-side .face.big { width: 88px; height: 88px; }
  .lobby.is-blown .vs-mark { font-size: 36px; }
}
.lobby.is-blown .lobby-panel { width: min(480px, 100%); }

/* When a card ends the game, the decisions are on the card: no action bar,
   no host bubble (the card has its own magpie). */
body.play .stage:has(#clashEnd:not([hidden])) .actionbar,
body.play .stage:has(#ending:not([hidden])) .actionbar,
body.play .stage:has(#clashEnd:not([hidden])) .hostbubble,
body.play .stage:has(#ending:not([hidden])) .hostbubble { display: none !important; }
/* Never let the board push the page sideways (the 20px floor in sizeBoard
   fits 16 columns in 390px; the host bubble must not be clipped, so no
   scrolling wrapper). */
body.play { overflow-x: hidden; }
@media (max-width: 900px) {
  #clashBoards .bungee { font-size: 13px; line-height: 1.2; overflow-wrap: anywhere; }
  .end-host { width: 80px; margin-top: -46px; }
}

/* REDUCED MOTION, everywhere (GDD s28.4 drift, closed 2026-10-28). Nothing
   shakes, pulses or flies; state still changes instantly so nothing is hidden.
   The cascade keeps its ORDER (the server's flood order) with no stagger, and
   the rival's cursor becomes a steady outline instead of a pulse. */
@media (prefers-reduced-motion: reduce) {
  .cell.open { animation: none !important; animation-delay: 0s !important; }
  .shake { animation: none !important; }
  .boomfx { animation: none !important; opacity: 0 !important; }
  .cell.peeked { animation: none !important; outline: 3px solid var(--pink); outline-offset: -3px; }
  .bubble { animation: none !important; }
  .lobby.is-blowing .lobby-canvas, .lobby.is-blowing .lobby-boom img, .lobby.is-blowing .lobby-boom::before { animation: none !important; }
}

/* ---------------------------------------------------------------- 3D BOARD (GDD s31)
   board3d.js draws the board in three.js on a canvas UNDER the DOM squares.
   The squares stay as transparent hit targets with their aria-labels and focus
   rings; rows shrink to cos35 so each button sits over the square it draws. */
.boardwrap.board3d { position: relative; }
.board3d-canvas { position: absolute; z-index: 0; pointer-events: none; }
.boardwrap.board3d #board { position: relative; z-index: 1; row-gap: calc(var(--gap, 4px) * .82); background: transparent; }
.boardwrap.board3d #board .cell {
  height: calc(var(--cell, 46px) * .82);
  background: transparent !important; background-image: none !important;
  box-shadow: none !important; border-color: transparent !important;
  color: transparent !important; text-shadow: none !important;
  animation: none !important; transform: none !important; outline-offset: -2px;
}
.boardwrap.board3d #board .cell img.sprite { visibility: hidden; }
.boardwrap.board3d #board .cell.peeked { outline: none; }
.boardwrap.board3d #board .cell:focus-visible { outline: 3px solid var(--cream); }

/* s32.4: in PRACTICE on a wide screen the magpie stands in the 3D studio, so
   the bubble keeps only its words. */
.has-host3d ~ #hostBubble #hostArt, .boardwrap.has-host3d #hostArt { display: none; }

/* s30.4 / s32.7: the 3D podiums put the rival left and you right; the strip follows. */
body.studio-sides #podiums { flex-direction: row-reverse; }
body.studio-sides #podiums .pod-them { flex-direction: row-reverse; text-align: left; }
body.studio-sides #podiums .pod-you { flex-direction: row-reverse; text-align: right; }

/* s32.6: with the 3D Bomb World the planet bursts IN the canvas and the podiums
   rise there with the faces, so the stage stays and the HTML keeps the names. */
.lobby.is-3d.is-blown .bomb-stage { display: flex; }
.lobby.is-3d.is-blown .lobby-canvas { max-height: 38vh; }
.lobby.is-3d .vs-side .face.big { display: none; }
.lobby.is-3d .lobby-boom { display: none !important; }
.lobby.is-3d .vs-row { flex-direction: row-reverse; } /* rival left, you right, as the podiums stand (s32.6) */

/* s32.9: a 3D clip plays over each HOW TO PLAY picture; the picture stays as the fallback. */
.howart { position: relative; }
.howart.has-3d > :not(canvas) { visibility: hidden; }
.howart canvas.how3d { position: absolute; inset: 0; width: 100%; height: 100%; }

/* s30.7: the bar's one state button, SIGN UP or LOG IN; gone once signed in. */
.gb-auth { font: 400 13px/1 Bungee, Impact, sans-serif; letter-spacing: .02em; padding: 10px 12px; border-radius: 10px;
  border: 2px solid var(--gold); color: var(--gold); text-decoration: none; white-space: nowrap; }
.gb-auth:hover, .gb-auth:focus-visible { background: var(--gold); color: var(--ink); }
@media (max-width: 520px) { .gb-auth { padding: 8px 9px; font-size: 11px; } }
.clash-why { margin: 8px auto 0; max-width: 34ch; font-weight: 600; color: var(--cream); }
.clash-why a { color: var(--gold); }

/* /me accounts (GDD s30.7) */
.acct-card { max-width: 520px; padding: 22px; }
.acct-card h2 { margin: 4px 0 10px; }
.acct-card label { display: block; font-weight: 700; margin: 14px 0 6px; }
.acct-card input { width: 100%; box-sizing: border-box; font: 600 16px/1.2 Outfit, system-ui, sans-serif; padding: 11px 12px; border-radius: 10px; border: 2px solid rgba(255,255,255,.25); background: rgba(10,10,20,.6); color: var(--cream); }
.acct-card input:focus-visible { outline: 3px solid var(--gold); outline-offset: 1px; }
.acct-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }
.acct-actions .action { max-width: none; width: auto; flex: 1 1 180px; text-align: center; text-decoration: none; }
.action.ghost { background: transparent; color: var(--cream); border: 2px solid rgba(255,255,255,.35); }
.acct-err { color: var(--red); font-weight: 700; margin: 10px 0 0; }
.acct-note { color: var(--gold); font-weight: 700; }
.acct-builder { min-height: 200px; }
.linkish { background: none; border: 0; color: var(--gold); font: inherit; font-weight: 700; text-decoration: underline; cursor: pointer; padding: 0; }
.acct-line { font-weight: 600; }

/* The logo in every top bar: the landing's title on one line, no spaces. */
.gb-logo, .nav a.logo { color: var(--gold); text-shadow: 0 2px 0 rgba(0,0,0,.7); }
.logo-hl { color: var(--pink); }
