/* PuzzleFit styling, the same palette Schakelsom uses: a black page, the grid
   on a lighter grey rounded panel, one light pill button, and that app's die
   colours — sky, amber, orange-red, purple, green.

   The roles here are Tetra's: amber `--op` for a clue, sky `--player` for a
   rectangle you drew, purple `--accent` for the one you are dragging out,
   orange-red `--bad` for a rectangle that cannot be right. Green stays off the
   board except for the transient Check answer, exactly as it does there. */
:root {
  --bg: #0a0a0a;
  --board-panel: #242424;      /* the tray the dice sit on */
  --card: #000000;             /* outlined cards */
  --outline: rgba(255, 255, 255, .92);
  --square: #2f2f2f;           /* an empty square */
  --grid: rgba(0, 0, 0, .35);  /* the hairline between two of them */
  --op: #efbc4a;
  --player: #5cc8f7;
  --tile: #4ed35e;
  --accent: #ab8dfa;
  --bad: #ff5722;
  --light: #e3e3e3;            /* the primary button */
  --primary-text: #0a0a0a;     /* ...and the text on it */
  --text: #ffffff;
  --muted: #9b9b9b;
}

/* A PGSDK host can report that it is running light; the die 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 board gets the rest.
   Tetra has no tray, so the board gets rather more of it than Schakelsom's. */
.app {
  max-width: 460px;
  height: 100vh;
  height: 100dvh;
  transition: max-width .2s ease;
  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: 12px;
}

/* The 13×13 gets more room on a desktop; phones are full width either way. */
.app.wide { max-width: 620px; }

.bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  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);
}

/* The board is laid out at a fixed square size; the viewport transform below
   is what scales it to fit, so type never has to be recomputed. */
.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;
  cursor: crosshair;
}

.viewport.panning { cursor: grabbing; }

.stage {
  position: absolute;
  top: 0;
  left: 0;
  transform-origin: 0 0;
  will-change: transform;
}

.stage.animating { transition: transform .22s ease; }

/* No gap between squares: the rectangles 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);
  display: grid;
  place-items: center;
  background: var(--square);
  box-shadow: inset 0 0 0 1px var(--grid);
  font-size: 19px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1;
  user-select: none;
}

/* A clue: the area the rectangle around it has to have. */
.cell.clue {
  background: var(--op);
  color: #10100e;
}

.cell.len2 { font-size: 16px; }
.cell.len3 { font-size: 12px; }

.cell.shake { animation: shake .3s; }
@keyframes shake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-4px); }
  75% { transform: translateX(4px); }
}

/* The rectangles, over the grid. Positioned by game.js in the same units the
   board is laid out in, so one place decides the geometry. */
.rects {
  position: absolute;
  top: var(--pad);
  left: var(--pad);
  pointer-events: none;                   /* the viewport handles every gesture */
}

.rect {
  position: absolute;
  border-radius: 8px;
  background: rgba(92, 200, 247, .17);
  box-shadow: inset 0 0 0 3px var(--player);
}

/* Wrong on the face of it: no clue inside, more than one, or an area that does
   not match the clue it holds. */
.rect.bad {
  background: rgba(255, 87, 34, .17);
  box-shadow: inset 0 0 0 3px var(--bad);
}

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

/* The rectangle under the finger, before it is let go. */
.rect.preview {
  background: rgba(171, 141, 250, .22);
  box-shadow: inset 0 0 0 3px var(--accent);
}

/* Where the keyboard is. Drawn only while the keyboard is being used. */
.rect.cursor {
  background: none;
  box-shadow: inset 0 0 0 3px var(--accent);
  border-radius: 6px;
}

.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;
}

.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; }
