/* PuzzleFit styling, the same palette the other five games use: a black page,
   the board on a lighter grey rounded panel, one light pill button, and that
   app's outline.

   The block colours are this game's own, and they are the one thing kept from
   the reference: a pastel set, one per block, so a shape is recognised by its
   colour before its outline. They are roles rather than decoration — `--b0` is
   always the first block in the tray — and they stay put in both themes, the
   way the die colours do elsewhere. Nothing on the board is green-for-correct
   except the transient Check answer. */
:root {
  --bg: #0a0a0a;
  --board-panel: #242424;      /* the tray the dice sit on */
  --card: #000000;             /* outlined cards */
  --outline: rgba(255, 255, 255, .92);
  --square: #2f2f2f;           /* a square still to be covered */
  --grid: rgba(0, 0, 0, .35);  /* the hairline between two of them */
  --accent: #ab8dfa;
  --good: #4ed35e;
  --bad: #ff5722;
  --light: #e3e3e3;            /* the primary button */
  --primary-text: #0a0a0a;     /* ...and the text on it */
  --text: #ffffff;
  --muted: #9b9b9b;

  --b0: #f6c453;
  --b1: #86c7c4;
  --b2: #8aa9ee;
  --b3: #f2726f;
  --b4: #9cc55b;
  --b5: #c79ae0;
  --b6: #f0a868;
  --b7: #6fbf9c;
}

/* A PGSDK host can report that it is running light; the block colours are the
   brand and stay put, everything around them inverts. Set by applyDarkMode(). */
body.light {
  --bg: #f1f1f4;
  --board-panel: #dededf;
  --card: #ffffff;
  --outline: rgba(0, 0, 0, .88);
  --square: #c9c9cf;
  --grid: rgba(0, 0, 0, .18);
  --light: #14141a;
  --primary-text: #f4f4f6;
  --text: #101014;
  --muted: #5c5c66;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  overflow: hidden;                       /* the game owns the viewport */
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, system-ui, sans-serif;
  -webkit-tap-highlight-color: transparent;
}

/* One screenful: the header takes what it needs, the tray is capped, and the
   board gets whatever is left. Anything added here comes straight off the
   board — put it in the tray or the overlay instead. */
.app {
  max-width: 460px;
  height: 100vh;
  height: 100dvh;
  margin: 0 auto;
  padding: max(10px, env(safe-area-inset-top)) 12px calc(12px + env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.bar {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;                        /* narrow phones drop the tools to a second line */
}

.tools {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  justify-content: flex-end;
  margin-left: auto;
}

[hidden] { display: none; }

select {
  background: var(--card);
  color: var(--text);
  border: 2px solid var(--outline);
  border-radius: 999px;
  padding: 8px 14px;
  font-size: 15px;
  font-weight: 700;
}

.clock {
  font-size: 20px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}

.left {
  font-size: 14px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--muted);
}

/* There is no pan and no zoom: every level fits, so the square size picked by
   fitBoard() is the whole layout. The one gesture on the board is a block being
   dragged, which is why it never had to be shared with panning. */
.viewport {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;                          /* let it shrink inside the column */
  overflow: hidden;
  border-radius: 26px;
  background: var(--board-panel);
  touch-action: none;
  overscroll-behavior: contain;
  display: grid;
  place-items: center;
}

.stage { position: relative; }

/* The keyboard's answer to a block that will not go where it is aimed. The
   pointer needs none: a refused drop already slides the block back to the
   tray, which says the same thing. */
.stage.shake { animation: shake .3s; }
@keyframes shake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-4px); }
  75% { transform: translateX(4px); }
}

/* No gap between squares: the blocks are absolutely positioned over the grid,
   and one step of that geometry is exactly one square. The hairline is drawn
   inside the square instead, where it costs no width. */
.board {
  display: grid;
  grid-template-columns: repeat(var(--cols, 5), var(--cell));
  padding: var(--pad);
}

.cell {
  width: var(--cell);
  height: var(--cell);
  border-radius: calc(var(--cell) * .16);
}

/* A square that has to be covered. A square that does not is left empty — the
   holes in the silhouette are not board, and nothing may be put on them. */
.cell.on {
  background: var(--square);
  box-shadow: inset 0 0 0 1px var(--grid);
}

.placed {
  position: absolute;
  top: var(--pad);
  left: var(--pad);
  pointer-events: none;                   /* the viewport handles every gesture */
}

/* One square of a block that has been laid down, and one square of the outline
   showing where the block under the finger would land. Both are absolutely
   positioned in the units buildBoard laid the grid out in — game.js sets only
   `left` and `top`, so the size has to come from here, in the same variable the
   grid itself is laid out in. */
.block, .drop {
  position: absolute;
  width: var(--cell);
  height: var(--cell);
  border-radius: calc(var(--cell) * .16);
}

.block { background: var(--colour); }

/* Answers to the Check buttons. These are the one place a mark means "correct"
   rather than "still to do", and they fade out again after a moment — the board
   never carries a standing mark saying a block is right. */
.block.right { box-shadow: inset 0 0 0 3px var(--good); }
.block.wrong { box-shadow: inset 0 0 0 3px var(--bad); }

/* Where the block under the finger would land, drawn on the board under it. */
.drop { box-shadow: inset 0 0 0 3px var(--accent); }
.drop.bad { box-shadow: inset 0 0 0 3px var(--bad); }

/* The tray. Capped and scrolling: eight pentominoes must never push the board
   off the screen. */
.tray {
  flex: 0 0 auto;
  max-height: min(30vh, 190px);
  overflow-y: auto;
  overscroll-behavior: contain;
  touch-action: none;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 10px 16px;
  padding: 8px 6px;
  background: var(--card);
  border: 1px solid var(--outline);
  border-radius: 18px;
}

.tray:empty { display: none; }            /* the last block placed takes the tray with it */

.chip {
  position: relative;
  cursor: grab;
}

.chip .cell {
  position: absolute;
  width: var(--tray-cell);
  height: var(--tray-cell);
  border-radius: calc(var(--tray-cell) * .18);
  background: var(--colour);
}

.chip.taken { opacity: .25; }             /* carried by the finger right now */

/* The block under the finger: board-sized, above everything, and never in the
   way of a hit test. */
.ghost {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 20;
  pointer-events: none;
  will-change: transform;
}

.ghost.returning { transition: transform .18s ease; }
.ghost.hidden { display: none; }

.ghost .cell {
  position: absolute;
  width: var(--cell);
  height: var(--cell);
  border-radius: calc(var(--cell) * .16);
  background: var(--colour);
  box-shadow: 0 6px 14px rgba(0, 0, 0, .45);
}

.btn {
  background: var(--card);
  color: var(--text);
  border: 2px solid var(--outline);
  border-radius: 999px;
  padding: 16px 20px;
  font-size: 17px;
  font-weight: 700;
  cursor: pointer;
}

/* The header row: small enough that four of them cost the board a few pixels. */
.btn.mini {
  padding: 5px 9px;
  font-size: 12px;
  border-width: 1px;
}

.btn:active { transform: scale(.97); }
.btn.primary { background: var(--light); border-color: var(--light); color: var(--primary-text); }
.btn.hidden { display: none; }

.overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, .72);
  display: grid;
  place-items: center;
  padding: 20px;
  z-index: 30;
}

.overlay.hidden { display: none; }

.panel {
  background: var(--card);
  border-radius: 22px;
  border: 2px solid var(--outline);
  padding: 26px 22px;
  text-align: center;
  max-width: 320px;
  width: 100%;
}

.panel h2 { margin: 0 0 8px; font-size: 28px; font-weight: 800; }
.panel p { margin: 0 0 18px; color: var(--muted); font-size: 15px; line-height: 1.5; }
.panel .btn { width: 100%; }
.panel .btn + .btn { margin-top: 10px; }
