/* 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; }
.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 {
  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(72px + 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;
}
/* Not decoration: the art is busy and saturated, and white type over it fails
   contrast without this. The scrim is what makes the headline readable. */
.hero-scrim {
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(10,10,20,.82) 0%, rgba(10,10,20,.55) 40%, rgba(10,10,20,.92) 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,.55);
}
.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);
}
.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-note { margin-top: 16px; font-size: 14px; color: #CFC8F0; }
.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 nav sits over the art rather than above it, so the hero really is the
   first full screen instead of a screen minus a bar. */
body.landing .nav { position: absolute; background: transparent; border-bottom: none; }
body.landing .nav a.dest { color: var(--cream); }
@media (max-width: 760px) {
  body.landing .nav a.dest { display: none; }
  body.landing .nav .cta { display: none; }
}

/* ───────────────────────── 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; }
