:root {
  --n: 9; /* board size; kept in sync with sim.js ROWS/COLS */
  --gap: 4px;
  --pad: 16px; /* horizontal padding of .app */
  /* tile size derives from viewport so the board + padding + gaps always fit,
     capped at 52px on wide screens */
  --cell: min(52px, calc((100vw - 2 * var(--pad) - (var(--n) - 1) * var(--gap)) / var(--n)));
  --radius: 10px;
  --bg: #16161d;
  --panel: #1f1f2b;
  --ink: #e8e8f0;
  --muted: #9a9ab0;
  --anim: 150ms;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  background: radial-gradient(circle at 50% 0%, #23233150, transparent 60%), var(--bg);
  color: var(--ink);
  font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

.app {
  max-width: max-content;
  margin: 0 auto;
  padding: 18px var(--pad) 28px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.hud { display: flex; align-items: center; justify-content: space-between; gap: 20px; }
.hud h1 { font-size: 20px; margin: 0; font-weight: 700; letter-spacing: 0.2px; }
.hud .sub { color: var(--muted); font-weight: 500; }

.scores { display: flex; gap: 10px; }
.score {
  background: var(--panel);
  border-radius: var(--radius);
  padding: 6px 14px;
  min-width: 74px;
  text-align: right;
  display: flex;
  flex-direction: column;
}
.score .label { font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: 1px; }
.score span:last-child { font-size: 20px; font-weight: 700; font-variant-numeric: tabular-nums; }

.board-wrap { position: relative; width: max-content; margin: 0 auto; }

/* The horizontal shading fakes the curve of a cylinder: bright centre, edges
   falling away — and hints that the two edges meet. */
.board {
  position: relative;
  width: calc(var(--cell) * var(--n) + var(--gap) * (var(--n) - 1));
  height: calc(var(--cell) * var(--n) + var(--gap) * (var(--n) - 1));
  border-radius: 16px;
  outline: none;
  padding: 0;
  background:
    linear-gradient(90deg, #0c0c12 0%, #2a2a3a 22%, #33334a 50%, #2a2a3a 78%, #0c0c12 100%);
  box-shadow: inset 0 0 0 1px #ffffff10, 0 20px 40px -20px #000;
  overflow: hidden;
  touch-action: none;
}

.board:focus-visible { box-shadow: inset 0 0 0 2px #ffffff40, 0 20px 40px -20px #000, 0 0 0 3px #ffffff30; }

/* used briefly to teleport a wrapping tile off-board before it slides in */
.tile.noanim { transition: none; }

.tile {
  position: absolute;
  width: var(--cell);
  height: var(--cell);
  border-radius: var(--radius);
  display: grid;
  place-items: center;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  color: #141418; /* fallback; per-tile contrast colour is set in game.js */
  transform: translate(
    calc(var(--c) * (var(--cell) + var(--gap))),
    calc(var(--r) * (var(--cell) + var(--gap)))
  );
  transition: transform var(--anim) ease, opacity var(--anim) ease;
  will-change: transform, opacity;
  box-shadow: inset 0 -3px 0 #00000025, inset 0 2px 0 #ffffff30;
}

/* font scales with the cell, and shrinks as the number grows so big values fit */
.tile { font-size: calc(var(--cell) * 0.42); }
.tile.d3 { font-size: calc(var(--cell) * 0.34); }
.tile.d4 { font-size: calc(var(--cell) * 0.28); }
.tile.d5 { font-size: calc(var(--cell) * 0.24); }

.tile.enter { opacity: 0; transform: translate(
    calc(var(--c) * (var(--cell) + var(--gap))),
    calc(var(--r) * (var(--cell) + var(--gap)))
  ) scale(0.5); }

.tile.selected { box-shadow: 0 0 0 3px #fff, inset 0 -3px 0 #00000025; z-index: 5; }

/* keyboard cursor: an outline that slides between cells (torus navigation) */
.cursor {
  position: absolute;
  width: var(--cell);
  height: var(--cell);
  border-radius: var(--radius);
  box-shadow: 0 0 0 3px #ffffffcc, 0 0 12px 2px #ffffff55;
  pointer-events: none;
  z-index: 6;
  transform: translate(
    calc(var(--c) * (var(--cell) + var(--gap))),
    calc(var(--r) * (var(--cell) + var(--gap)))
  );
  transition: transform 90ms ease, box-shadow 120ms ease;
}
/* armed: a tile is picked up and a direction key will swap it */
.cursor.armed { box-shadow: 0 0 0 3px #ffd166, 0 0 16px 4px #ffd16688; }
.cursor.hidden { opacity: 0; }

/* pulse via glow/brightness so it never fights the translate transform */
@keyframes pulse {
  0% { filter: brightness(1); box-shadow: inset 0 -3px 0 #00000025, inset 0 2px 0 #ffffff30; }
  40% { filter: brightness(1.55); box-shadow: 0 0 14px 3px #ffffffaa, inset 0 2px 0 #ffffff30; }
  100% { filter: brightness(1); box-shadow: inset 0 -3px 0 #00000025, inset 0 2px 0 #ffffff30; }
}
.tile.pulse { animation: pulse 280ms ease; }

/* floating "+N" score popup on a merge (outer positions at the cell, inner
   floats up so the animation never fights the cell transform) */
.popup {
  position: absolute;
  width: var(--cell);
  height: var(--cell);
  pointer-events: none;
  z-index: 7;
  transform: translate(
    calc(var(--c) * (var(--cell) + var(--gap))),
    calc(var(--r) * (var(--cell) + var(--gap)))
  );
}
.popup span {
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  font-weight: 800;
  font-size: calc(var(--cell) * 0.34);
  text-shadow: 0 1px 2px #ffffffcc, 0 0 3px #ffffffcc;
  animation: floatUp 780ms ease-out forwards;
}
@keyframes floatUp {
  0% { opacity: 0; transform: translateY(0.2em) scale(0.9); }
  20% { opacity: 1; transform: translateY(0) scale(1); }
  100% { opacity: 0; transform: translateY(-1.1em) scale(1); }
}

button {
  font: inherit;
  font-weight: 700;
  color: #101013;
  background: #e9d8a6;
  border: 0;
  border-radius: 10px;
  padding: 10px 18px;
  cursor: pointer;
}
button:active { transform: translateY(1px); }
button.ghost { background: transparent; color: var(--muted); box-shadow: inset 0 0 0 1px #ffffff20; }

.foot { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.foot p { color: var(--muted); font-size: 13px; line-height: 1.5; margin: 0; max-width: 48ch; }
.foot b { color: var(--ink); font-weight: 600; }

@media (max-width: 520px) {
  :root { --gap: 3px; --pad: 10px; } /* cell recomputes from these automatically */
  .hud { flex-wrap: wrap; gap: 10px; }
  .foot { flex-direction: column; align-items: flex-start; }
}
