/* ============================================================================
   Pixl — shared design system with the sibling puzzle games.
   Tokens live on :root; the dark set is applied under prefers-color-scheme
   and again under [data-theme="dark"] so the manual toggle wins either way.
   ========================================================================= */

:root {
  /* Light theme (default) */
  --bg: #F7F8FB;
  --surface: #FFFFFF;
  --surface-2: #F0F2F7;
  --line: #E2E6EF;
  --text: #10131A;
  --text-dim: #666E82;

  --accent: #7C5CFF;
  --accent-ink: #0E0F13;
  --accent-soft: rgba(124, 92, 255, 0.12);
  --accent-press: #6B46F2;

  /* Filled cells: a slightly deeper violet so the finished picture reads
     clearly against white without going flat black. */
  --fill: #6B46F2;
  --fill-edge: #5A36E0;
  --grid-weak: #E6E9F1;
  --grid-strong: #C9CFDE;
  --mark: #99A1B4;

  --good: #1F9254;
  --warn: #C2561F;

  /* Radii + spacing scale (4/8/12/16/24/32) */
  --r-card: 16px;
  --r-btn: 10px;
  --r-cell: 4px;
  --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px; --s6: 24px; --s8: 32px;

  /* Motion */
  --t-in: 140ms;
  --t-ui: 180ms;
  --t-reveal: 520ms;
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);

  --shadow-1: 0 1px 2px rgba(14, 15, 19, 0.04), 0 2px 8px rgba(14, 15, 19, 0.05);
  --shadow-2: 0 8px 32px rgba(14, 15, 19, 0.14);

  /* Set from JS once the board is measured; these are only fallbacks. */
  --cell: 24px;
  --clue-slot: 16px;
  --clue-font: 12px;
  --block5: 120px;

  color-scheme: light;
}

/* OS preference — guarded so a manual "light" choice still wins. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #0E0F13;
    --surface: #171922;
    --surface-2: #1F2230;
    --line: #2A2E3F;
    --text: #F2F4F8;
    --text-dim: #8A90A2;

    --accent: #7C5CFF;
    --accent-soft: rgba(124, 92, 255, 0.18);
    --accent-press: #8F74FF;

    --fill: #8B6CFF;
    --fill-edge: #A58CFF;
    --grid-weak: #232736;
    --grid-strong: #363B50;
    --mark: #6E7589;

    --good: #4BD28A;
    --warn: #FF9B5C;

    --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.3), 0 2px 10px rgba(0, 0, 0, 0.3);
    --shadow-2: 0 10px 40px rgba(0, 0, 0, 0.55);

    color-scheme: dark;
  }
}

/* Manual dark — repeated so the toggle beats a light OS preference too. */
:root[data-theme="dark"] {
  --bg: #0E0F13;
  --surface: #171922;
  --surface-2: #1F2230;
  --line: #2A2E3F;
  --text: #F2F4F8;
  --text-dim: #8A90A2;

  --accent: #7C5CFF;
  --accent-soft: rgba(124, 92, 255, 0.18);
  --accent-press: #8F74FF;

  --fill: #8B6CFF;
  --fill-edge: #A58CFF;
  --grid-weak: #232736;
  --grid-strong: #363B50;
  --mark: #6E7589;

  --good: #4BD28A;
  --warn: #FF9B5C;

  --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.3), 0 2px 10px rgba(0, 0, 0, 0.3);
  --shadow-2: 0 10px 40px rgba(0, 0, 0, 0.55);

  color-scheme: dark;
}

@media (prefers-reduced-motion: reduce) {
  :root { --t-in: 0ms; --t-ui: 0ms; --t-reveal: 0ms; }
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  color: var(--text);
  font-family: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  /* Kill double-tap zoom while leaving pinch zoom alone. */
  touch-action: manipulation;
  overflow-x: hidden;
}

button { font: inherit; color: inherit; }

/* ---------- Header ---------- */

.site-header {
  display: flex;
  align-items: center;
  gap: var(--s3);
  padding: var(--s3) var(--s4);
  padding-top: max(var(--s3), env(safe-area-inset-top));
  background: var(--surface);
  border-bottom: 1px solid var(--line);
}

.brand { display: flex; align-items: center; gap: var(--s2); min-width: 0; }

.brand-mark {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  grid-template-rows: repeat(2, 1fr);
  gap: 2px;
  width: 22px;
  height: 22px;
  flex: none;
}
.brand-mark span { border-radius: 2px; background: var(--accent); }
.brand-mark span:nth-child(3) { background: var(--line); }

.brand-name {
  font-size: 19px;
  font-weight: 700;
  letter-spacing: -0.02em;
}

.header-right { margin-left: auto; display: flex; align-items: center; gap: var(--s2); }

.timer {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  font-size: 15px;
  min-width: 56px;
  padding: 6px var(--s2);
  border: 1px solid var(--line);
  border-radius: var(--r-btn);
  background: var(--surface-2);
  cursor: pointer;
  transition: color var(--t-ui) var(--ease), border-color var(--t-ui) var(--ease);
}
.timer.paused { color: var(--text-dim); border-style: dashed; }

.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--r-btn);
  background: var(--surface-2);
  color: var(--text-dim);
  cursor: pointer;
  transition: color var(--t-ui) var(--ease), background var(--t-ui) var(--ease);
}
.icon-btn:hover { color: var(--text); }

/* ---------- Segmented switchers ---------- */

.switchers {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
  justify-content: center;
  padding: var(--s3) var(--s4) 0;
}

.seg {
  display: inline-flex;
  padding: 3px;
  gap: 2px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-btn);
}

.seg-btn {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--text-dim);
  font-size: 13px;
  font-weight: 600;
  padding: 7px 14px;
  border-radius: 7px;
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--t-in) var(--ease), color var(--t-in) var(--ease);
}
.seg-btn:hover { color: var(--text); }
.seg-btn.active {
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-1);
}
.seg-tool .seg-btn.active { color: var(--accent); }
.seg-tool .seg-btn { display: inline-flex; align-items: center; gap: 6px; }

.tool-swatch {
  width: 12px; height: 12px;
  border-radius: 3px;
  background: var(--fill);
}
.tool-x {
  position: relative;
  width: 12px; height: 12px;
}
.tool-x::before, .tool-x::after {
  content: '';
  position: absolute;
  inset: 50% 0 auto 0;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
  transform-origin: center;
}
.tool-x::before { transform: translateY(-50%) rotate(45deg); }
.tool-x::after { transform: translateY(-50%) rotate(-45deg); }

/* ---------- Game ---------- */

.game {
  width: 100%;
  max-width: 560px;
  margin: 0 auto;
  padding: var(--s3) var(--s4) var(--s6);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s3);
}

.meta-row {
  width: 100%;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s2);
  font-size: 12px;
  color: var(--text-dim);
}
.puzzle-label { font-weight: 600; letter-spacing: 0.01em; }
.countdown-wrap { display: inline-flex; align-items: baseline; gap: 5px; }
.countdown-label { text-transform: uppercase; font-size: 10px; letter-spacing: 0.08em; }
.countdown { font-variant-numeric: tabular-nums; font-weight: 600; }

.status {
  margin: 0;
  width: 100%;
  min-height: 20px;
  font-size: 13px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  text-align: center;
  transition: color var(--t-ui) var(--ease);
}
.status.idle { color: var(--text-dim); }
.status.good { color: var(--good); }
.status.warn { color: var(--warn); }

/* ---------- Board ---------- */

/* The board is sized to fit in JS, so this rarely engages — but at absurdly
   narrow widths (below any real phone) the board scrolls inside its own
   wrapper rather than being clipped or widening the page. Centring is done
   with auto margins, not flexbox, because a centred flex item overflowing its
   container has its leading edge cut off and becomes unreachable. */
.board-wrap {
  width: 100%;
  overflow-x: auto;
  overscroll-behavior-x: contain;
}

.board {
  width: max-content;
  margin-inline: auto;
  display: grid;
  grid-template-columns: auto minmax(0, max-content);
  grid-template-rows: auto minmax(0, max-content);
  gap: 6px;
  padding: var(--s2);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-1);
}

.board-corner { grid-area: 1 / 1; }

.col-clues {
  grid-area: 1 / 2;
  display: grid;
  /* repeat(N, minmax(0, Xpx)) is written from JS — minmax(0, ...) rather than
     a bare track so dense grids are allowed to shrink instead of overflowing. */
  align-items: end;
}
.row-clues {
  grid-area: 2 / 1;
  display: grid;
  justify-items: end;
}

.clue-strip {
  display: flex;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  font-size: var(--clue-font);
  line-height: 1;
  color: var(--text);
}
.clue-row {
  flex-direction: row;
  align-items: center;
  justify-content: flex-end;
  gap: 1px;
  height: 100%;
  padding-right: 3px;
}
.clue-col {
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: 1px;
  width: 100%;
  padding-bottom: 3px;
}

.clue {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: var(--clue-slot);
  height: var(--clue-slot);
  border-radius: 3px;
  transition: color var(--t-ui) var(--ease), opacity var(--t-ui) var(--ease);
}
/* Satisfied runs dim — the quality-of-life feature Picross players expect. */
.clue.done { color: var(--text-dim); opacity: 0.4; }
.clue-strip.line-done .clue { color: var(--text-dim); opacity: 0.3; }
.clue-zero { color: var(--text-dim); opacity: 0.35; }

.cells {
  grid-area: 2 / 2;
  display: grid;
  position: relative;
  border: 2px solid var(--grid-strong);
  border-radius: var(--r-cell);
  background-color: var(--surface);
  /* Grid rules drawn as background layers: no per-cell borders to knock the
     pixel geometry out, and a heavier line every 5 cells for counting. */
  background-image:
    repeating-linear-gradient(to right, var(--grid-strong) 0 1px, transparent 1px var(--block5)),
    repeating-linear-gradient(to bottom, var(--grid-strong) 0 1px, transparent 1px var(--block5)),
    repeating-linear-gradient(to right, var(--grid-weak) 0 1px, transparent 1px var(--cell)),
    repeating-linear-gradient(to bottom, var(--grid-weak) 0 1px, transparent 1px var(--cell));
  /* Pointer Events drive everything; the browser must not steal the gesture. */
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  cursor: crosshair;
}
.cells.tool-mark { cursor: cell; }

.cell {
  position: relative;
  transition: background-color var(--t-in) var(--ease);
}

.cell.filled {
  background-color: var(--fill);
  border-radius: 2px;
  box-shadow: inset 0 0 0 1px var(--fill-edge);
}

.cell.marked::before,
.cell.marked::after {
  content: '';
  position: absolute;
  left: 26%;
  right: 26%;
  top: 50%;
  height: 2px;
  border-radius: 2px;
  background: var(--mark);
}
.cell.marked::before { transform: translateY(-50%) rotate(45deg); }
.cell.marked::after { transform: translateY(-50%) rotate(-45deg); }

/* Won: strip the chrome away before the picture is lifted into the overlay. */
.board.won .col-clues,
.board.won .row-clues {
  opacity: 0;
  transition: opacity var(--t-ui) var(--ease);
}
.board.won .cells {
  background-image: none;
  border-color: transparent;
  transition: border-color var(--t-ui) var(--ease);
}
.board.won .cell.filled { border-radius: 0; box-shadow: none; }
.board.won .cell.marked::before,
.board.won .cell.marked::after { opacity: 0; }
.board.won .cells { cursor: zoom-in; }

/* ---------- Toolbar ---------- */

.toolbar {
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--s2);
}
.toolbar-actions { display: flex; gap: var(--s2); }

.btn {
  appearance: none;
  padding: 9px 16px;
  border: 1px solid var(--line);
  border-radius: var(--r-btn);
  background: var(--surface);
  color: var(--text);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: background var(--t-in) var(--ease), border-color var(--t-in) var(--ease),
              transform var(--t-in) var(--ease);
}
.btn:hover { background: var(--surface-2); }
.btn:active { transform: translateY(1px); }

.btn-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #FFFFFF;
}
.btn-primary:hover { background: var(--accent-press); border-color: var(--accent-press); }

:is(.btn, .seg-btn, .icon-btn, .timer, .rules-toggle):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.tip {
  margin: 0;
  max-width: 44ch;
  text-align: center;
  font-size: 12px;
  line-height: 1.55;
  color: var(--text-dim);
}

/* ---------- Rules ---------- */

.rules {
  width: 100%;
  max-width: 560px;
  margin: 0 auto;
  padding: 0 var(--s4) var(--s4);
}
.rules-toggle {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s2);
  padding: var(--s3) var(--s4);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  font-size: 14px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}
.rules-arrow { color: var(--text-dim); transition: transform var(--t-ui) var(--ease); }
.rules-toggle[aria-expanded="true"] .rules-arrow { transform: rotate(90deg); }

.rules-body {
  margin-top: var(--s2);
  padding: var(--s4);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  font-size: 13.5px;
  color: var(--text-dim);
}
.rules-body ul { margin: 0 0 var(--s3); padding-left: 1.2em; }
.rules-body li { margin-bottom: var(--s2); }
.rules-body strong { color: var(--text); }
.rules-body p { margin: 0; }
.rules-body code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.92em;
  padding: 1px 5px;
  border-radius: 4px;
  background: var(--surface-2);
  color: var(--text);
}

/* ---------- Footer ---------- */

.site-footer {
  margin-top: auto;
  padding: var(--s4);
  padding-bottom: max(var(--s4), env(safe-area-inset-bottom));
  text-align: center;
  font-size: 12px;
  color: var(--text-dim);
  border-top: 1px solid var(--line);
}

/* ---------- Win reveal ---------- */

.win-overlay {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--s4);
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  opacity: 0;
  transition: opacity var(--t-ui) var(--ease);
}
@supports not (background: color-mix(in srgb, red 50%, transparent)) {
  .win-overlay { background: var(--bg); }
}
.win-overlay.show { opacity: 1; }

.win-card {
  position: relative;
  width: 100%;
  max-width: 420px;
  padding: var(--s6) var(--s4) var(--s4);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s3);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-2);
  transform: translateY(10px) scale(0.98);
  transition: transform var(--t-ui) var(--ease);
}
.win-overlay.show .win-card { transform: none; }

.reveal-grid {
  display: grid;
  width: min(74vw, 320px);
  aspect-ratio: 1;
  gap: 0;
}
.rcell { border-radius: 0; }
.rcell.on {
  background: var(--fill);
  animation: popIn var(--t-reveal) var(--ease) both;
}
@keyframes popIn {
  from { opacity: 0; transform: scale(0.1); }
  60%  { opacity: 1; transform: scale(1.06); }
  to   { opacity: 1; transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .rcell.on { animation: none; }
}

.win-name {
  margin: 0;
  font-size: 26px;
  font-weight: 700;
  letter-spacing: -0.02em;
  text-align: center;
}
.win-meta {
  margin: 0;
  font-size: 13px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--text-dim);
}
.win-actions { display: flex; gap: var(--s2); margin-top: var(--s1); }

.win-close {
  position: absolute;
  top: var(--s2);
  right: var(--s2);
  width: 32px; height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: var(--r-btn);
  background: transparent;
  color: var(--text-dim);
  cursor: pointer;
}
.win-close:hover { background: var(--surface-2); color: var(--text); }

/* ---------- Narrow phones ---------- */

@media (max-width: 400px) {
  .game { padding-left: var(--s3); padding-right: var(--s3); }
  .switchers { padding-left: var(--s3); padding-right: var(--s3); gap: 6px; }
  .rules { padding-left: var(--s3); padding-right: var(--s3); }
  .site-header { padding-left: var(--s3); padding-right: var(--s3); }
  .seg-btn { padding: 7px 11px; font-size: 12.5px; }
  .board { padding: 6px; }
}

@media (min-width: 720px) {
  .tip { font-size: 13px; }
}
