/* Chase Down: game window, maze and readouts. The page around the game follows the site theme
   (/assets/site.css); the hack window itself is always dark, like the FiveM hack it imitates. */

:root {
  --hk-win: #121316;
  --hk-edge: #2a2c33;
  --hk-board: #0d0d0e;
  --hk-ink: #f2f3f5;
  --hk-muted: #8b8f99;
  --hk-track: rgba(255, 255, 255, 0.12);
  --hk-red: #e3202e;
  --hk-red-hot: #ff3845;
  --hk-green: #34d27a;
  --hk-amber: #f0b04d;
  --hk-scrim: rgba(5, 5, 7, 0.62);
  --hk-card: #17181c;
  --hk-focus: #ffffff;

  /* Maze pieces (match the canvas palette in game.js) */
  --cd-pac: #ffd700;
  --cd-pip: #2b2a2a;
  --cd-pip-on: #d6d6d6;
  --cd-ghost: #a3a3a3;
}

.desk {
  box-sizing: border-box;
  flex: none;
  min-height: calc(100vh - var(--hdr));
  padding-inline: 16px;
  padding-block: 16px;
  display: grid;
  place-items: center;
  background-image: radial-gradient(circle, var(--desk-dot) 1px, transparent 1.5px);
  background-size: 20px 20px;
}
@supports (height: 100dvh) {
  .desk { min-height: calc(100dvh - var(--hdr)); }
}

/* ---------- The hack window ---------- */
/* Width follows the viewport height so the whole window fits: the maze is 23:19 and the
   rest of the window (title, pips, timer, footer, gutters) is about 270px tall, under the site header. */
.window {
  box-sizing: border-box;
  width: min(100%, 900px, max(300px, calc((100vh - 270px - var(--hdr)) * 23 / 19 + 76px)));
  display: flex;
  flex-direction: column;
  background: var(--hk-win);
  color: var(--hk-ink);
  color-scheme: dark;
  line-height: 1.45;   /* the prototype's text rhythm (the site's body uses 1.5) */
  border: 1px solid var(--hk-edge);
  border-radius: 12px;
  box-shadow: 0 34px 80px -30px rgba(0, 0, 0, 0.75), 0 0 0 1px rgba(0, 0, 0, 0.35);
  overflow: hidden;
}
@supports (height: 100dvh) {
  .window { width: min(100%, 900px, max(300px, calc((100dvh - 270px - var(--hdr)) * 23 / 19 + 76px))); }
}
.window.is-opening { animation: win-in 0.22s ease-out; }
.window.is-closing { animation: win-out 0.16s ease-in forwards; pointer-events: none; }

.titlebar {
  position: relative;
  display: grid;
  place-items: center;
  padding: 12px 48px 10px;
}
.title {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  font: 400 17px/1 "Michroma", "Arial Black", Impact, sans-serif;
  -webkit-text-stroke: 0.5px currentColor;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  white-space: nowrap;
}
.title svg { flex: none; color: var(--cd-ghost); }
.icon-btn {
  position: absolute;
  right: 8px;
  top: 50%;
  translate: 0 -50%;
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--hk-muted);
  cursor: pointer;
  transition: background-color 0.12s, color 0.12s;
}
.icon-btn:hover { background: var(--hk-red); color: #fff; }

/* ---------- The board ---------- */
.board-wrap { flex: none; padding: 0 14px; }
.board {
  position: relative;
  display: grid;
  padding: 22px 24px 12px;
  border-radius: 8px;
  background: var(--hk-board);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.04);
  outline: none;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
}
.maze {
  position: relative;
  width: 100%;
  max-width: 100%;
  aspect-ratio: 23 / 19;
  --tile: 34px;
}
.maze canvas {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
}

/* READY / CAUGHT / TIME UP / CLEARED over the middle of the maze */
.hud {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: grid;
  place-items: center;
  pointer-events: none;
}
.hud-box {
  display: grid;
  justify-items: center;
  gap: calc(var(--tile) * 0.22);
  padding: calc(var(--tile) * 0.42) calc(var(--tile) * 0.8);
  border: 1px solid var(--hk-edge);
  border-radius: 8px;
  background: rgba(10, 10, 12, 0.86);
  box-shadow: 0 12px 30px -12px rgba(0, 0, 0, 0.8);
  text-align: center;
}
.hud-box.is-bare { border-color: transparent; background: none; box-shadow: none; }
.hud-big {
  font: 400 clamp(15px, calc(var(--tile) * 0.78), 30px)/1 "Michroma", "Arial Black", Impact, sans-serif;
  -webkit-text-stroke: 0.04em currentColor;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  white-space: nowrap;
  text-shadow: 0 0 6px #000, 0 0 14px #000;
}
.hud-big.is-ready { color: var(--cd-pac); }
.hud-big.is-bad { color: var(--hk-red-hot); }
.hud-big.is-ok { color: var(--hk-green); }
.hud-small {
  font: 700 clamp(10px, calc(var(--tile) * 0.34), 13px)/1.2 "Figtree", system-ui, sans-serif;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--hk-muted);
  font-variant-numeric: tabular-nums;
}

/* Pips under the maze, one per dot */
.progress {
  display: grid;
  justify-items: center;
  gap: 8px;
  padding-top: 14px;
}
.pips { display: flex; gap: 11px; }
.pips i {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--cd-pip);
  transition: background-color 0.15s;
}
.pips i.is-on { background: var(--cd-pip-on); animation: pip-pop 0.28s ease-out; }
.collected {
  font: 400 10px/1 "Michroma", "Arial Black", Impact, sans-serif;
  -webkit-text-stroke: 0.3px currentColor;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--hk-muted);
  font-variant-numeric: tabular-nums;
}
.collected.is-done { color: var(--hk-green); }

/* ---------- Start card ---------- */
.intro {
  position: absolute;
  inset: 0;
  z-index: 6;
  display: grid;
  place-items: center;
  padding: 16px;
  border-radius: 8px;
  background: var(--hk-scrim);
}
.card {
  box-sizing: border-box;
  width: min(100%, 360px);
  max-height: 100%;
  overflow: auto;
  padding: 20px 22px 22px;
  border: 1px solid var(--hk-edge);
  border-radius: 10px;
  background: var(--hk-card);
  color: var(--hk-ink);
  box-shadow: 0 20px 50px -20px rgba(0, 0, 0, 0.8);
}
.card h2 {
  margin: 0 0 12px;
  font: 400 16px/1.2 "Michroma", "Arial Black", Impact, sans-serif;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  text-wrap: balance;
}
.card ol {
  display: grid;
  gap: 6px;
  margin: 0 0 18px;
  padding-left: 1.25em;
  color: var(--hk-muted);
}
.card li::marker { color: var(--hk-red-hot); font-weight: 700; }
.card kbd {
  font: 700 0.86em/1 "Figtree", system-ui, sans-serif;
  padding: 2px 5px;
  border: 1px solid var(--hk-edge);
  border-bottom-width: 2px;
  border-radius: 4px;
  color: var(--hk-ink);
  background: rgba(255, 255, 255, 0.04);
}

/* ---------- Time remaining ---------- */
.time {
  display: grid;
  gap: 7px;
  padding: 12px 14px 0;
}
.time-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}
.time-label {
  font: 700 11px/1 "Figtree", system-ui, sans-serif;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--hk-muted);
}
.time-left {
  font: 400 13px/1 "Michroma", "Arial Black", Impact, sans-serif;
  color: var(--hk-ink);
  font-variant-numeric: tabular-nums;
  transition: color 0.2s;
}
.time-left.is-urgent { color: var(--hk-red-hot); }
.time-bar {
  height: 4px;
  border-radius: 2px;
  background: var(--hk-track);
  overflow: hidden;
}
.time-fill {
  height: 100%;
  background: var(--hk-red);
  transform-origin: left center;
  will-change: transform;
}
.time-fill.is-urgent { animation: urgent 0.8s ease-in-out infinite; }

/* ---------- Footer: message, best, leaderboard status, end-of-round actions ---------- */
.footer {
  box-sizing: border-box;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px 16px;
  min-height: 64px;
  padding: 12px 14px 14px;
}
.readout { display: grid; gap: 3px; flex: 1 1 220px; min-width: 0; }
.message { margin: 0; font-weight: 600; color: var(--hk-ink); }
.best {
  font: 600 11px/1.3 "Figtree", system-ui, sans-serif;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--hk-muted);
}
/* "· won 12 of 30 · 40%": this device's rounds that cleared, kept on one line */
.best-win { white-space: nowrap; }
.actions { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 8px; }
/* Leaderboard status after a round: saving, saved and rank, held for review, not saved, or log in */
.lb-note {
  flex: 0 1 auto;
  max-width: 42ch;
  margin: 0 6px 0 0;
  font: 600 12px/1.35 "Figtree", system-ui, sans-serif;
  letter-spacing: 0.02em;
  color: var(--hk-muted);
  text-wrap: pretty;
}
.lb-note.is-saved { color: var(--hk-green); }
.lb-note.is-held { color: var(--hk-amber); }
.lb-note.is-failed { color: var(--hk-red-hot); }
.lb-note a { color: inherit; font-weight: 700; text-underline-offset: 3px; }
.lb-note.is-guest a { color: var(--hk-amber); }
.btn {
  font: 700 13px/1 "Figtree", system-ui, sans-serif;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 12px 18px;
  border: 1px solid var(--hk-red);
  border-radius: 8px;
  background: var(--hk-red);
  color: #fff;
  cursor: pointer;
  transition: background-color 0.12s ease, border-color 0.12s ease, transform 0.1s ease;
}
.btn:hover { background: var(--hk-red-hot); border-color: var(--hk-red-hot); }
.btn:active { transform: translateY(1px); }
.btn-quiet { background: transparent; color: var(--hk-ink); border-color: var(--hk-edge); }
.btn-quiet:hover { background: rgba(255, 255, 255, 0.06); border-color: var(--hk-muted); }
.btn:focus-visible,
.icon-btn:focus-visible,
.lb-note a:focus-visible { outline: 2px solid var(--hk-focus); outline-offset: 2px; }

@keyframes pip-pop { 0% { transform: scale(1.8); } 100% { transform: none; } }
@keyframes urgent { 50% { opacity: 0.45; } }
@keyframes win-in { from { opacity: 0; transform: translateY(8px) scale(0.98); } to { opacity: 1; transform: none; } }
@keyframes win-out { to { opacity: 0; transform: translateY(6px) scale(0.97); } }

/* Short screens: the footer can wrap to two rows once the leaderboard status shows, so budget for it */
@media (max-height: 612px) {
  .window { width: min(100%, 900px, max(300px, calc((100vh - 297px - var(--hdr)) * 23 / 19 + 76px))); }
}
@supports (height: 100dvh) {
  @media (max-height: 612px) {
    .window { width: min(100%, 900px, max(300px, calc((100dvh - 297px - var(--hdr)) * 23 / 19 + 76px))); }
  }
}

@media (max-width: 480px) {
  .title { font-size: 14px; letter-spacing: 0.16em; }
  .window { width: min(100%, max(300px, calc((100vh - 236px - var(--hdr)) * 23 / 19 + 36px))); }
  .board-wrap { padding: 0 8px; }
  .board { padding: 10px 10px 8px; }
  .progress { gap: 6px; padding-top: 10px; }
  .pips { gap: 6px; }
  .pips i { width: 6px; height: 6px; }
  .time { padding-inline: 10px; }
  .footer { padding-inline: 10px; }
  .card { padding: 16px; }
  .card h2 { font-size: 14px; }
  .card ol { gap: 4px; margin-bottom: 14px; font-size: 14px; }
  .actions { width: 100%; }
  .actions .btn { flex: 1; }
  .lb-note { flex-basis: 100%; max-width: none; margin: 0 0 2px; }
}
@supports (height: 100dvh) {
  @media (max-width: 480px) {
    .window { width: min(100%, max(300px, calc((100dvh - 236px - var(--hdr)) * 23 / 19 + 36px))); }
  }
}
/* The smallest phones: keep the title clear of the close button */
@media (max-width: 360px) {
  .title { gap: 8px; font-size: 12px; letter-spacing: 0.12em; }
}

/* Small boards: keep the whole start card, Start included, inside the board */
@media (max-width: 720px), (max-height: 640px) {
  .intro { padding: 10px; }
  .card { padding: 14px 14px 16px; }
  .card h2 { margin-bottom: 8px; font-size: 13px; }
  .card ol { gap: 2px; margin-bottom: 12px; font-size: 13px; line-height: 1.35; }
  .card .btn { padding: 10px 16px; }
}
/* The narrowest phones (320px): tighter still, so Start is never scrolled out of the card */
@media (max-width: 350px) {
  .intro { padding: 6px; }
  .card { padding: 10px 12px 12px; }
  .card h2 { margin-bottom: 6px; font-size: 12px; }
  .card ol { gap: 2px; margin-bottom: 10px; padding-left: 1.1em; font-size: 12px; line-height: 1.3; }
  .card kbd { padding: 1px 4px; }
  .card .btn { padding: 9px 14px; }
}

/* Very short screens (small phones held sideways, under the site header): just the title and Start,
   as on Drift Recall. The full rules are in "How to play" below the game. */
@media (max-height: 350px) {
  .card ol { display: none; }
  .card h2 { margin-bottom: 10px; }
}

/* Landscape phones: the timer and footer move beside the board */
@media (orientation: landscape) and (max-height: 540px) and (min-width: 560px) {
  .desk { padding-block: 8px; }
  .window {
    width: auto;
    max-width: 100%;
    display: grid;
    grid-template-columns: auto minmax(180px, 240px);
    grid-template-rows: auto auto 1fr;
  }
  .titlebar { grid-column: 1 / -1; box-sizing: border-box; height: 36px; padding-block: 0; }
  .board-wrap { grid-column: 1; grid-row: 2 / span 2; padding-bottom: 10px; }
  .board { padding: 10px 12px 8px; }
  /* The board is too short for the start card here, so the card covers the whole window
     under the title bar (the board and the side column) instead of only the board. */
  .window { position: relative; }
  .board-wrap, .board { position: static; }
  .intro { top: 36px; border-radius: 0 0 11px 11px; }
  .maze { width: min(calc((100vh - 142px - var(--hdr)) * 23 / 19), calc(100vw - 330px)); }
  .progress { gap: 6px; padding-top: 8px; }
  .pips { gap: 7px; }
  .pips i { width: 6px; height: 6px; }
  .time { grid-column: 2; grid-row: 2; padding-top: 0; }
  .footer { grid-column: 2; grid-row: 3; align-content: end; }
  .lb-note { flex-basis: 100%; max-width: none; margin: 0 0 2px; }
}
@supports (height: 100dvh) {
  @media (orientation: landscape) and (max-height: 540px) and (min-width: 560px) {
    .maze { width: min(calc((100dvh - 142px - var(--hdr)) * 23 / 19), calc(100vw - 330px)); }
  }
}

/* Windows High Contrast: colours get replaced, so keep the bars visible */
@media (forced-colors: active) {
  .time-fill { background: Highlight; }
  .pips i { border: 1px solid ButtonText; }
  .pips i.is-on { background: Highlight; }
}

/* Reduced motion: only decoration stops. Pac-Man and the ghosts are the game and move at full speed. */
@media (prefers-reduced-motion: reduce) {
  .window.is-opening,
  .window.is-closing,
  .pips i.is-on,
  .time-fill.is-urgent { animation: none; }
  .btn, .icon-btn, .time-left, .pips i { transition: none; }
}
