/* Deep Mine - the mining cabinet at /mine/.
 *
 * Self-contained: this file is the only stylesheet the game owns, and nothing in
 * this directory reaches outside it except the two lines of the cabinet contract.
 *
 * ⚠️ THE FIRST RULE IS LOAD-BEARING. `hidden` is enforced by the UA stylesheet
 *    alone, so any author rule with a `display` beats it - and this file sets
 *    `display: grid` and `display: flex` on things that ship hidden (the descend
 *    button, the records panel, three of the four views). Without this line the
 *    game would boot showing every view stacked. AGENT.md gotcha 9; it has caught
 *    this repo out three times.
 */
[hidden] {
  display: none !important;
}

/* ⚠️ `touch-action` ON `*`, NOT ON `body`. This is a game played by tapping the
 *    same area fast, which is exactly the gesture Safari reads as double-tap zoom -
 *    and a player stranded at 2x has to pinch their way back mid-run. The property
 *    DOES NOT INHERIT: Safari reads it off the element actually under the finger,
 *    so `body { touch-action }` leaves every heading, gap and panel still zooming.
 *    Deliberately not `user-scalable=no` in the viewport meta: iOS has ignored that
 *    since iOS 10, and where it is honoured it takes pinch-zoom from people who
 *    need it. Pinch and pan are untouched here. */
*,
*::before,
*::after {
  box-sizing: border-box;
  touch-action: manipulation;
}

:root {
  --basalt: #14171c;
  --basalt-2: #1b1f26;
  --panel: #21262f;
  --panel-edge: #333a46;
  --stone: #545c6a;
  --stone-lit: #6f7889;
  --ink: #e8ecf3;
  --ink-dim: #99a2b2;
  --lantern: #f0a92e;
  --lantern-dim: #8a6320;
  --coal: #24262b;
  --iron: #d8a679;
  --gold: #ffcf3f;
  --diamond: #5fd8e8;
  --lava: #ff6a2a;
  --good: #74c96b;
  --shadow: 0 0.5rem 1.4rem rgba(0, 0, 0, 0.45);
}

html {
  background: var(--basalt);
}

body {
  margin: 0;
  padding: 1rem 0.9rem 2.5rem;
  background:
    radial-gradient(120% 70% at 50% -10%, #232935 0%, transparent 60%),
    var(--basalt);
  color: var(--ink);
  font-family: "Trebuchet MS", "Gill Sans", "Segoe UI", system-ui, sans-serif;
  font-size: 16px;
  line-height: 1.5;
  min-height: 100vh;
}

.site {
  max-width: 34rem;
  margin: 0 auto;
}

/* ⚠️ THE OTHER HALF OF THE CABINET CONTRACT. Below 760px /arcade-return.css drops
 *    the chip from `fixed` to `absolute` so it scrolls away instead of riding down
 *    over the game - but it still starts in the top-left corner, and this cabinet's
 *    content starts there too. Only the cabinet knows its own layout, so the
 *    cabinet reserves the strip. Measured at 390x844 and 320x568. If the chip is
 *    ever removed from this page, remove this block in the same edit. */
@media (max-width: 760px) {
  .site {
    padding-top: 52px;
  }
}

/* ---------------------------------------------------------------- chrome --- */

.masthead {
  text-align: center;
  margin: 0 0 1.1rem;
}

.eyebrow {
  margin: 0 0 0.3rem;
  color: var(--lantern);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}

h1 {
  margin: 0 0 0.5rem;
  font-size: clamp(2rem, 11vw, 2.8rem);
  line-height: 1;
  letter-spacing: 0.02em;
  text-shadow: 0 0.18rem 0 rgba(0, 0, 0, 0.55);
}

.lede {
  margin: 0 auto;
  max-width: 30rem;
  color: var(--ink-dim);
  font-size: 0.95rem;
}

.lede strong {
  color: var(--ink);
}

.panel {
  margin: 0 0 1rem;
  padding: 1.1rem 1rem;
  border: 1px solid var(--panel-edge);
  border-radius: 0.7rem;
  background: var(--panel);
  box-shadow: var(--shadow);
}

.panel-title {
  margin: 0 0 0.7rem;
  font-size: 1.1rem;
  letter-spacing: 0.02em;
}

.panel-subtitle {
  margin: 1.2rem 0 0.6rem;
  color: var(--lantern);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.panel-line {
  margin: 0 0 0.9rem;
  color: var(--ink-dim);
  font-size: 0.92rem;
}

.fineprint {
  margin: 0.8rem 0 0;
  color: var(--stone-lit);
  font-size: 0.75rem;
}

.noscript {
  max-width: 30rem;
  margin: 2rem auto;
  padding: 1rem;
  border: 1px solid var(--panel-edge);
  border-radius: 0.6rem;
  background: var(--panel);
  color: var(--ink);
  text-align: center;
}

/* --------------------------------------------------------------- buttons --- */

.button-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
}

.primary-button {
  flex: 1 1 10rem;
  min-height: 3rem;
  padding: 0.7rem 1rem;
  border: 1px solid #b9821f;
  border-radius: 0.55rem;
  background: linear-gradient(180deg, var(--lantern) 0%, #d08c1c 100%);
  color: #201503;
  font: inherit;
  font-weight: 700;
  letter-spacing: 0.02em;
  cursor: pointer;
}

.primary-button.ghost {
  border-color: var(--panel-edge);
  background: transparent;
  color: var(--ink);
}

.primary-button:hover,
.primary-button:focus-visible {
  filter: brightness(1.08);
}

.primary-button.ghost:hover,
.primary-button.ghost:focus-visible {
  border-color: var(--lantern);
  filter: none;
}

.button-note {
  display: block;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  opacity: 0.75;
  text-transform: uppercase;
}

.text-button {
  display: block;
  width: 100%;
  margin: 0.8rem 0 0;
  padding: 0.55rem;
  border: 0;
  border-radius: 0.4rem;
  background: transparent;
  color: var(--ink-dim);
  font: inherit;
  font-size: 0.85rem;
  text-decoration: underline;
  text-underline-offset: 0.2em;
  cursor: pointer;
}

.text-button:hover,
.text-button:focus-visible {
  color: var(--lantern);
}

button:focus-visible,
.arcade-return:focus-visible {
  outline: 2px solid var(--diamond);
  outline-offset: 2px;
}

/* ⚠️ Headings take focus when a view opens so a screen reader lands in the new
 *    view rather than at the top of the document - but a mouse player must not see
 *    a ring appear on a paragraph they never touched. */
.view h2:focus,
.view h1:focus {
  outline: none;
}

/* ----------------------------------------------------------------- rules --- */

.rules {
  margin: 0;
  padding-left: 1.1rem;
  color: var(--ink-dim);
  font-size: 0.92rem;
}

.rules li {
  margin-bottom: 0.7rem;
}

.rules strong {
  color: var(--ink);
}

.glitter-word {
  color: var(--lantern);
  font-weight: 700;
}

.legend {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(8.5rem, 1fr));
  gap: 0.55rem;
  margin: 0 0 1.1rem;
  padding: 0;
  list-style: none;
}

.legend li {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.85rem;
}

/* Name over worth, rather than beside it: side by side, two columns of legend on a
   390px screen left "ore is next to it" wrapping onto three lines against a
   two-line name. */
.legend-text {
  display: flex;
  flex-direction: column;
  line-height: 1.25;
}

.legend-swatch {
  flex: 0 0 auto;
  width: 1.6rem;
  height: 1.6rem;
  border-radius: 0.2rem;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.45);
}

.legend-worth {
  color: var(--stone-lit);
  font-size: 0.78rem;
}

/* ------------------------------------------------------------------- hud --- */

.play-panel {
  padding: 0.9rem 0.8rem 1rem;
}

.hud {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.3rem;
  margin: 0 0 0.5rem;
}

.hud-cell {
  margin: 0;
  padding: 0.4rem 0.2rem;
  border-radius: 0.4rem;
  background: var(--basalt-2);
  text-align: center;
}

.hud-label {
  display: block;
  color: var(--stone-lit);
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.hud-value {
  display: block;
  font-size: 1.15rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
}

.hud-cell.is-low .hud-value {
  color: var(--lava);
}

.hud-cell.is-full .hud-value {
  color: var(--good);
}

.mode-line {
  margin: 0 0 0.7rem;
  color: var(--stone-lit);
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-align: center;
  text-transform: uppercase;
}

/* ------------------------------------------------------------------ seam ---
 *
 * Six columns, always. The seam grows DOWNWARD with depth and never sideways:
 * vertical room is free on a phone and horizontal room is the thing that runs out.
 * At 320px the marker column leaves ~41px per cell, which is still a comfortable
 * tap target; a seventh column would drop it under 36px. */

.seam {
  display: grid;
  /* Only the FIRST row is sized here; the rest are left to the square cells. The
     column torches were getting a whole cell's height of their own - 48px of grid
     to hold a one-character label, on the axis a phone has least of. */
  grid-template-columns: 1.7rem repeat(6, 1fr);
  grid-template-rows: 1.5rem;
  gap: 0.22rem;
  margin: 0 0 0.7rem;
}

.cell,
.marker {
  width: 100%;
  padding: 0;
  border: 0;
  border-radius: 0.22rem;
  font: inherit;
  cursor: pointer;
}

.cell {
  aspect-ratio: 1 / 1;
}

.marker {
  height: 100%;
}

/* Unbroken rock: a lit top edge and a dark bottom one, which is the whole of the
   blocky look and costs no images. */
.cell {
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.14) 0 18%, transparent 18%),
    linear-gradient(0deg, rgba(0, 0, 0, 0.38) 0 16%, transparent 16%),
    var(--stone);
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.35);
}

.cell:hover:not(:disabled) {
  filter: brightness(1.14);
}

.cell:disabled {
  cursor: default;
}

/* Mined out and empty. */
.cell.is-dug {
  background: #2a2f38;
  box-shadow: inset 0 0.15rem 0.5rem rgba(0, 0, 0, 0.6);
}

/* ⚠️ THE GLITTER IS THE GAME'S ONE FREE PIECE OF INFORMATION, so it has to survive
 *    a player who cannot see animation. The keyframes are the flourish; the ring
 *    and the lantern tint carry the meaning on their own. */
.is-glitter {
  background:
    radial-gradient(circle at 50% 42%, rgba(240, 169, 46, 0.55) 0 26%, transparent 27%),
    linear-gradient(180deg, rgba(255, 255, 255, 0.16) 0 18%, transparent 18%),
    var(--stone-lit);
  box-shadow: inset 0 0 0 2px var(--lantern);
  animation: glint 1.5s ease-in-out infinite;
}

@keyframes glint {
  0%, 100% { filter: brightness(1); }
  50% { filter: brightness(1.3); }
}

/* Ore textures: stone with mineral blobs in it, drawn with gradients so this
   cabinet ships no images at all. */
.cell.ore {
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.4);
}

/* ⚠️ THE ORE TEXTURES ARE NOT SCOPED TO `.cell`, AND THAT IS DELIBERATE. They were,
 *    and the how-to's legend - the one screen whose whole job is teaching what the
 *    colours mean - drew seven empty grey boxes, because a legend swatch is a
 *    <span> and not a block of rock. A texture that only exists inside the board
 *    cannot be used to explain the board. */

.ore-coal {
  background:
    radial-gradient(circle at 32% 30%, var(--coal) 0 21%, transparent 22%),
    radial-gradient(circle at 70% 58%, var(--coal) 0 17%, transparent 18%),
    radial-gradient(circle at 42% 76%, var(--coal) 0 12%, transparent 13%),
    #4a515e;
}

.ore-iron {
  background:
    radial-gradient(circle at 34% 32%, var(--iron) 0 20%, transparent 21%),
    radial-gradient(circle at 68% 62%, var(--iron) 0 16%, transparent 17%),
    radial-gradient(circle at 60% 26%, var(--iron) 0 11%, transparent 12%),
    #4a515e;
}

.ore-gold {
  background:
    radial-gradient(circle at 33% 34%, var(--gold) 0 21%, transparent 22%),
    radial-gradient(circle at 69% 60%, var(--gold) 0 17%, transparent 18%),
    radial-gradient(circle at 45% 74%, var(--gold) 0 13%, transparent 14%),
    #4a515e;
}

.ore-diamond {
  background:
    radial-gradient(circle at 36% 34%, var(--diamond) 0 23%, transparent 24%),
    radial-gradient(circle at 66% 64%, var(--diamond) 0 19%, transparent 20%),
    #454d5b;
}

.cell.ore-diamond,
.ore-gold {
  box-shadow:
    inset 0 0 0 1px rgba(0, 0, 0, 0.4),
    0 0 0.5rem rgba(255, 207, 63, 0.25);
}

.is-lava {
  background:
    radial-gradient(circle at 50% 55%, #ffd08a 0 14%, transparent 15%),
    radial-gradient(circle at 30% 34%, #ffa23c 0 22%, transparent 23%),
    var(--lava);
  box-shadow: 0 0 0.7rem rgba(255, 106, 42, 0.6);
}

.is-crate {
  background:
    linear-gradient(180deg, transparent 44%, rgba(0, 0, 0, 0.5) 44%, rgba(0, 0, 0, 0.5) 52%, transparent 52%),
    linear-gradient(90deg, transparent 46%, rgba(0, 0, 0, 0.5) 46%, rgba(0, 0, 0, 0.5) 54%, transparent 54%),
    #9a6a35;
}

/* A cell that has just been hit. Kept separate from the reveal classes so the
   flourish can be turned off without touching what the cell says. */
.cell.is-hit {
  animation: thump 0.22s ease-out;
}

@keyframes thump {
  0% { transform: scale(0.86); }
  100% { transform: scale(1); }
}

/* ---------------------------------------------------------------- markers ---
 *
 * The torch line. Unlit it is a dash; lit it is the ore still buried in that row
 * or column, counting down live as it comes out - which is what makes lighting a
 * line early worth a swing, and what tells you when a line is finished. */

/* ⚠️ AN UNLIT TORCH HAS TO LOOK LIKE A CONTROL. The first cut drew it as a dot on
 *    the same dark ground as the panel, in a strip beside a grid of tappable
 *    squares - which made the game's one deduction mechanic look like the board's
 *    empty margin. Nobody was ever going to press it. It is a lantern-coloured "?"
 *    on a dashed outline now: unmistakably a thing you buy, and unmistakably not a
 *    block of rock. */
.marker {
  background: var(--basalt-2);
  color: var(--lantern-dim);
  font-size: 0.78rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  box-shadow: inset 0 0 0 1px var(--panel-edge);
  outline: 1px dashed var(--lantern-dim);
  outline-offset: -3px;
}

.marker:hover:not(:disabled) {
  color: var(--lantern);
  background: #2c2416;
  box-shadow: inset 0 0 0 1px var(--lantern);
}

.marker.is-lit {
  background: #2c2416;
  color: var(--lantern);
  box-shadow: inset 0 0 0 1px var(--lantern-dim);
  outline: none;
  cursor: default;
}

.marker.is-lit.is-spent {
  color: var(--stone);
  box-shadow: inset 0 0 0 1px var(--panel-edge);
}

.marker:disabled {
  cursor: default;
}

/* ---------------------------------------------------------------- status --- */

.status {
  min-height: 2.6rem;
  margin: 0 0 0.6rem;
  padding: 0.45rem 0.6rem;
  border-radius: 0.4rem;
  background: var(--basalt-2);
  color: var(--ink-dim);
  font-size: 0.88rem;
}

.status.is-good {
  color: var(--good);
}

.status.is-bad {
  color: var(--lava);
}

.descend {
  width: 100%;
  animation: rise 0.3s ease-out;
}

@keyframes rise {
  0% { transform: translateY(0.4rem); opacity: 0; }
  100% { transform: translateY(0); opacity: 1; }
}

/* --------------------------------------------------------------- summary --- */

.summary-title {
  margin: 0 0 0.6rem;
  font-size: 1.5rem;
}

.score-slab {
  margin: 0 0 1rem;
  padding: 0.9rem;
  border-radius: 0.6rem;
  background: var(--basalt-2);
  text-align: center;
}

.score-value {
  margin: 0;
  color: var(--lantern);
  font-size: 3rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.score-label {
  margin: 0.2rem 0 0;
  color: var(--stone-lit);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.haul,
.record-list {
  margin: 0 0 1rem;
  padding: 0;
  list-style: none;
}

.haul li,
.record-list li {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.42rem 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  font-size: 0.9rem;
}

.haul li:last-child,
.record-list li:last-child {
  border-bottom: 0;
}

.haul-name,
.record-name {
  flex: 1 1 auto;
  color: var(--ink-dim);
}

.haul-count,
.record-value {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.records[hidden] {
  display: none !important;
}

/* ------------------------------------------------------- reduced motion --- */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

@media (min-width: 30rem) {
  body {
    padding-top: 2rem;
  }

  .seam {
    gap: 0.3rem;
  }
}
