/* Puzzle Break — daily sudoku under the Markets & Economy desk.
   Scoped variables so the board reads correctly in both paper and dark themes;
   the outer chrome reuses the shared --ink/--card/--rule tokens. */

.sudoku-desk {
  --sz-line: rgba(0, 0, 0, .55);
  --sz-cell-bg: #fffdf6;
  --sz-given: var(--ink);
  --sz-entry: #1d4f8f;
  --sz-peer: rgba(29, 78, 143, .10);
  --sz-same: rgba(138, 31, 27, .18);
  --sz-select: rgba(240, 68, 82, .22);
  --sz-cand: rgba(0, 0, 0, .42);
  margin-top: 16px;
  border-top: 3px double var(--ink);
  padding-top: 14px;
}
[data-theme="dark"] .sudoku-desk {
  --sz-line: rgba(255, 255, 255, .65);
  --sz-cell-bg: #10151c;
  --sz-entry: #7fb2ff;
  --sz-peer: rgba(127, 178, 255, .12);
  --sz-same: rgba(255, 143, 152, .20);
  --sz-select: rgba(240, 68, 82, .35);
  --sz-cand: rgba(255, 255, 255, .55);
}

.sudoku-title-link { color: inherit; text-decoration: none; border-bottom: 1px dotted var(--faded); }
.sudoku-title-link:hover { color: var(--red); border-bottom-color: currentColor; }
.sudoku-head h3 { margin: 0; font: 700 15px/1.2 "Source Serif 4", Georgia, serif; color: var(--ink); }
.sudoku-edition { font: 600 10px "IBM Plex Mono", monospace; color: var(--faded); letter-spacing: .06em; text-transform: uppercase; margin-left: 4px; }
.sudoku-nav { display: flex; flex-wrap: wrap; gap: 5px; margin: 6px 0 2px; }
.sudoku-sub { margin: 3px 0 8px; font: 400 12px/1.45 "Source Serif 4", Georgia, serif; color: var(--faded); max-width: 60ch; }
.sudoku-tabs { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.sudoku-tab {
  display: inline-flex; align-items: baseline; gap: 5px;
  padding: 5px 11px; border: 1px solid var(--rule); background: transparent;
  font: 700 10px "IBM Plex Mono", monospace; letter-spacing: .08em; text-transform: uppercase;
  color: var(--faded); cursor: pointer;
}
.sudoku-tab small { font-size: 9px; opacity: .75; }
.sudoku-tab:hover { color: var(--ink); border-color: var(--ink); }
.sudoku-tab.is-active { background: var(--red); border-color: var(--red); color: #fff; }

/* The action row now closes the controls column rather than riding in the
 * difficulty tab strip. Buttons share the width so the row stays a tidy grid
 * however many of them are showing — Check answers and Reveal only appear on
 * an archive edition. */
.sudoku-actions {
  display: flex; flex-wrap: wrap; gap: 6px;
  padding-top: 10px; border-top: 1px solid var(--rule);
}
.sudoku-actions .sudoku-btn { flex: 1 1 auto; }

/* One size for every control in the puzzle.
 *
 * Undo, Redo, Clear and Full screen were 10px type in 5px of padding — under
 * 24px tall, well below a usable tap target and visibly smaller than the mode
 * switches beside them. Both share these metrics now, so the panel reads as
 * one set of controls and every one of them can be hit with a thumb. */
.sudoku-btn, .sudoku-mode {
  min-height: 38px;
  padding: 9px 12px;
  border: 1px solid var(--rule);
  background: transparent;
  font: 600 11px "IBM Plex Mono", monospace;
  text-transform: uppercase;
  letter-spacing: .06em;
  cursor: pointer;
}
.sudoku-btn { color: var(--ink); }
.sudoku-btn:hover { border-color: var(--ink); }
.sudoku-btn-danger { color: var(--red); border-color: var(--red); }
.sudoku-btn-danger:hover { background: var(--red); color: #fff; }

.sudoku-layout { display: flex; flex-wrap: wrap; gap: 18px; margin-top: 12px; align-items: flex-start; }
.sudoku-board-col { min-width: 0; }

/* Solve timer: a small pill tucked under the board's bottom-right corner, so
   it never covers a cell. Hidden until the player's first entry starts it. */
.sudoku-board-wrap { position: relative; display: inline-block; margin-bottom: 22px; }
.sudoku-timer {
  position: absolute;
  top: calc(100% + 5px);
  right: 0;
  font-variant-numeric: tabular-nums;
  font-size: 12px;
  letter-spacing: 0.04em;
  padding: 1px 7px;
  border-radius: 999px;
  border: 1px solid var(--sz-line);
  color: var(--sz-cand);
  background: var(--sz-cell-bg);
}
.sudoku-timer.is-paused { opacity: 0.5; }
.sudoku-timer.is-done { color: #16a34a; border-color: #16a34a; }


/* Board: 9x9 grid with heavy 3x3 seams drawn via per-cell borders. */
.sudoku-board {
  display: grid;
  grid-template-columns: repeat(9, 1fr);
  /* Rows must be pinned too. Left implicit they size to content, and the top
     row — whose cells happen to be empty in some editions — collapsed to about
     two thirds the height of the rest. */
  grid-template-rows: repeat(9, 1fr);
  width: min(430px, 92vw);
  aspect-ratio: 1 / 1;
  border: 2px solid var(--sz-line);
  background: var(--sz-line);
  gap: 1px;
  user-select: none;
  touch-action: manipulation;
}
.sudoku-cell {
  position: relative;
  background: var(--sz-cell-bg);
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
}
/* 3x3 block seams. The margin eats into the cell so more of the board's
   background (the line colour) shows through: 1px of gap plus 3px of margin
   reads as a heavy seam. At 1px the seam was the same weight as an ordinary
   cell line, which left the blocks invisible — worst in dark mode, where the
   lines are lower contrast to begin with. The last column/row is skipped: the
   board's own 2px border already closes those edges. */
.sudoku-cell:nth-child(3n):not(:nth-child(9n)) { margin-right: 3px; }
.sudoku-cell:nth-child(n+19):nth-child(-n+27),
.sudoku-cell:nth-child(n+46):nth-child(-n+54) { margin-bottom: 3px; }

.sudoku-cell.is-peer { background-image: linear-gradient(var(--sz-peer), var(--sz-peer)); }
.sudoku-cell.is-same { background-image: linear-gradient(var(--sz-same), var(--sz-same)); }
.sudoku-cell.is-selected { box-shadow: inset 0 0 0 2px var(--red); background-image: linear-gradient(var(--sz-select), var(--sz-select)); }
.sudoku-cell.is-conflict::after {
  content: ""; position: absolute; inset: 0;
  outline: 2px solid #d21f28; outline-offset: -2px; pointer-events: none;
}
.sudoku-cell.is-given { cursor: default; }

.sz-value {
  font: 500 clamp(16px, 4.4vw, 26px)/1 "Source Serif 4", Georgia, serif;
  color: var(--sz-entry); position: relative; z-index: 2;
}
.sudoku-cell.is-given .sz-value { color: var(--sz-given); font-weight: 700; }

/* Candidate / pencil grid: 3x3 mini-cells inside every empty cell. */
.sz-marks {
  position: absolute; inset: 1px;
  display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(3, 1fr);
  z-index: 1;
}
.sz-mark {
  display: flex; align-items: center; justify-content: center;
  font: 600 clamp(7px, 1.7vw, 11px)/1 "IBM Plex Mono", monospace;
  color: var(--sz-cand);
}
/* Hand-entered marks must be unmistakable next to grey auto-candidates:
 * corner notes get a tinted chip, centre notes take over the mini-cell at
 * near-entry size (auto-candidates hide entirely when a cell has them). */
.sz-mark.is-corner {
  color: var(--sz-entry); font-weight: 800;
  background: rgba(29, 79, 143, .14);
  border-radius: 2px;
}
.sz-mark.is-center {
  color: var(--sz-entry); font-weight: 800;
  font-size: clamp(11px, 2.8vw, 17px);
}
[data-theme="dark"] .sz-mark.is-corner { background: rgba(127, 178, 255, .22); }
.sz-mark.c1, .sz-mark.c2, .sz-mark.c3, .sz-mark.c4,
.sz-mark.c5, .sz-mark.c6, .sz-mark.c7, .sz-mark.c8 { border-radius: 2px; }
.sudoku-cell.sz-paintable .sz-mark { cursor: pointer; }

/* Colour layers (cells) — painted via data attribute. */
.sudoku-cell[data-cell-color="1"] { background-color: #f6b3ae; }
.sudoku-cell[data-cell-color="2"] { background-color: #aed0f6; }
.sudoku-cell[data-cell-color="3"] { background-color: #b9e5b0; }
.sudoku-cell[data-cell-color="4"] { background-color: #f4e3a1; }
.sudoku-cell[data-cell-color="5"] { background-color: #dcc2ee; }
.sudoku-cell[data-cell-color="6"] { background-color: #f4c39e; }
.sudoku-cell[data-cell-color="7"] { background-color: #a8e6e0; }
.sudoku-cell[data-cell-color="8"] { background-color: #e8e8e8; }
[data-theme="dark"] .sudoku-cell[data-cell-color] { filter: saturate(.85) brightness(.8); }
.sudoku-cell[data-cell-color].is-selected { box-shadow: inset 0 0 0 2px var(--red); }

/* Review overlay ("Check answers", archives only): tints ride on
 * background-image so they stack with cell paint and selection highlights
 * instead of fighting them for background-color/box-shadow. */
.sudoku-cell.is-correct { background-image: linear-gradient(rgba(63, 153, 52, .20), rgba(63, 153, 52, .20)); }
.sudoku-cell.is-wrong { background-image: linear-gradient(rgba(210, 31, 40, .26), rgba(210, 31, 40, .26)); }
.sudoku-cell.is-missing { outline: 1px dashed var(--rule); outline-offset: -3px; }
[data-theme="dark"] .sudoku-cell.is-correct { background-image: linear-gradient(rgba(63, 153, 52, .34), rgba(63, 153, 52, .34)); }
[data-theme="dark"] .sudoku-cell.is-wrong { background-image: linear-gradient(rgba(210, 31, 40, .40), rgba(210, 31, 40, .40)); }

/* Candidate colour chips render as tinted backgrounds on the mini-cell. */
.sz-mark[data-cand-color="1"] { background: #e0493f; color: #fff !important; border-radius: 50%; }
.sz-mark[data-cand-color="2"] { background: #2f7fd4; color: #fff !important; border-radius: 50%; }
.sz-mark[data-cand-color="3"] { background: #3f9934; color: #fff !important; border-radius: 50%; }
.sz-mark[data-cand-color="4"] { background: #d9a520; color: #fff !important; border-radius: 50%; }
.sz-mark[data-cand-color="5"] { background: #8e56c9; color: #fff !important; border-radius: 50%; }
.sz-mark[data-cand-color="6"] { background: #d96f2a; color: #fff !important; border-radius: 50%; }
.sz-mark[data-cand-color="7"] { background: #2aa79d; color: #fff !important; border-radius: 50%; }
.sz-mark[data-cand-color="8"] { background: #767676; color: #fff !important; border-radius: 50%; }
.sz-mark[data-cand-color].is-corner { color: #fff !important; }

/* Side controls. */
.sudoku-controls { display: flex; flex-direction: column; gap: 10px; min-width: 200px; }

.sudoku-modes { display: flex; flex-wrap: wrap; gap: 5px; }
/* Sizing is shared with .sudoku-btn above; only the resting colour differs. */
.sudoku-mode { color: var(--faded); }
.sudoku-mode:hover { color: var(--ink); border-color: var(--ink); }
.sudoku-mode.is-active { background: var(--navy); border-color: var(--navy); color: #fff; }
html[data-theme="dark"] .sudoku-mode.is-active { background: #3d5a80; border-color: #3d5a80; }

.sudoku-swatches-row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.sudoku-swatches { display: flex; gap: 5px; }
.sudoku-active-colour {
  display: inline-flex; gap: 4px; align-items: baseline;
  font: 600 10px "IBM Plex Mono", monospace; letter-spacing: .05em;
  color: var(--faded); text-transform: uppercase;
}
.sudoku-active-colour b { font-weight: 700; color: var(--ink); }
.sudoku-swatch { width: 22px; height: 22px; border-radius: 50%; border: 2px solid transparent; cursor: pointer; padding: 0; }
.sudoku-swatch[data-sudoku-color="1"] { background: #e0493f; }
.sudoku-swatch[data-sudoku-color="2"] { background: #2f7fd4; }
.sudoku-swatch[data-sudoku-color="3"] { background: #3f9934; }
.sudoku-swatch[data-sudoku-color="4"] { background: #d9a520; }
.sudoku-swatch[data-sudoku-color="5"] { background: #8e56c9; }
.sudoku-swatch[data-sudoku-color="6"] { background: #d96f2a; }
.sudoku-swatch[data-sudoku-color="7"] { background: #2aa79d; }
.sudoku-swatch[data-sudoku-color="8"] { background: #767676; }
.sudoku-swatch.is-active { border-color: var(--ink); transform: scale(1.12); }

.sudoku-toggle { display: inline-flex; gap: 6px; align-items: center; font: 600 10px "IBM Plex Mono", monospace; color: var(--faded); text-transform: uppercase; cursor: pointer; }
.sudoku-toggle input { accent-color: var(--red); }

.sudoku-message { min-height: 18px; margin: 8px 0 0; font: 700 11px "IBM Plex Mono", monospace; color: var(--red); text-transform: uppercase; letter-spacing: .06em; }
.sudoku-message.is-win { color: #3f9934; }
.sudoku-review-stats { margin: 2px 0 0; min-height: 14px; font: 700 10.5px "IBM Plex Mono", monospace; color: var(--ink); letter-spacing: .04em; }
.sudoku-review-stats[hidden] { display: none; }
.sudoku-hint { margin: 0; font: 400 9.5px/1.6 "IBM Plex Mono", monospace; color: var(--faded); max-width: 34ch; }
.sudoku-credit { display: inline-block; margin-top: 2px; font: 600 9px "IBM Plex Mono", monospace; color: var(--faded); text-transform: uppercase; letter-spacing: .07em; text-decoration: none; }
.sudoku-credit:hover { color: var(--red); }

/* Reveal mode: solution-filled cells are italic and faded to distinguish
 * from both givens and player-entered digits. */
.sudoku-cell.is-revealed .sz-value { font-style: italic; color: var(--faded); opacity: .72; }

/* ── Fullscreen overlay ── */
.sudoku-desk.is-fullscreen {
  position: fixed; inset: 0; z-index: 9000;
  background: var(--card, #fffdf6);
  overflow-y: auto; padding: 10px env(safe-area-inset-right, 12px) env(safe-area-inset-bottom, 10px) env(safe-area-inset-left, 12px);
  display: flex; flex-direction: column; align-items: stretch;
  margin-top: 0; border-top: 0; padding-top: 10px;
}
/* Fold the header to a single row: title + date + difficulty tabs all share
 * the top line, so the tab strip no longer costs a full row of height. The
 * previous three-row head (title/date, edition nav, tabs) pushed the action
 * row — Undo/Redo/Erase/Clear — below the fold on a short window. */
.sudoku-desk.is-fullscreen .sudoku-head {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 6px 14px; margin-bottom: 4px;
}
.sudoku-desk.is-fullscreen .sudoku-head h3 { margin: 0; }
.sudoku-desk.is-fullscreen .sudoku-nav { margin: 0; }
.sudoku-desk.is-fullscreen .sudoku-nav .sudoku-btn { min-height: 30px; padding: 5px 10px; font-size: 10px; }
.sudoku-desk.is-fullscreen .sudoku-tabs { margin: 0 0 0 auto; }
.sudoku-desk.is-fullscreen .sudoku-tab { padding: 4px 10px; font-size: 9px; }
.sudoku-desk.is-fullscreen .sudoku-tab small { font-size: 8px; }
/* Landscape/desktop: board on the left sized off the viewport height, the
 * controls filling the strip beside it instead of leaving it empty. */
.sudoku-desk.is-fullscreen .sudoku-layout {
  flex: 1 1 auto; flex-direction: row; flex-wrap: nowrap;
  align-items: center; justify-content: center;
  width: 100%; max-width: none; gap: clamp(12px, 3vw, 32px); margin-top: 2px;
}
.sudoku-desk.is-fullscreen .sudoku-board-col { display: flex; flex-direction: column; align-items: center; flex: 0 0 auto; }
/* The single-line head reserves less vertical space, so the board can use
 * more of the window height instead of being shrunk to fit three header rows. */
.sudoku-desk.is-fullscreen .sudoku-board { width: min(calc(100vw - 320px), calc(100dvh - 96px)); }
.sudoku-desk.is-fullscreen .sudoku-controls {
  flex: 0 1 300px; min-width: 220px; max-width: 320px;
  align-items: stretch; justify-content: flex-start; gap: 8px;
  /* Fullscreen is a fixed box, so the controls column cannot grow the page
   * to fit: on a short window the foot of it — now the action row — was
   * simply cut off with no way to reach it. Let the column scroll instead.
   * min-height:0 is required for a flex child to be allowed to shrink below
   * its content and scroll at all. */
  min-height: 0;
  overflow-y: auto;
}
/* The static pad duplicates the keyboard (desktop) and the tap-to-open keypad
 * sheet (touch), so it and the key-hint crib sheet go; the mode switcher and
 * the palette stay — they have no keyboard-free equivalent. */
.sudoku-desk.is-fullscreen .sudoku-hint { display: none; }
.sudoku-desk.is-fullscreen .sudoku-modes { flex-direction: column; flex-wrap: nowrap; gap: 4px; }
.sudoku-desk.is-fullscreen .sudoku-mode { padding: 8px 12px; font-size: 11px; text-align: left; }
.sudoku-desk.is-fullscreen .sudoku-swatches-row { flex-wrap: wrap; gap: 8px; }
.sudoku-desk.is-fullscreen .sudoku-swatches { gap: 6px; }
.sudoku-desk.is-fullscreen .sudoku-swatch { width: 26px; height: 26px; }
.sudoku-desk.is-fullscreen .sudoku-toggle { font-size: 11px; }
/* Tighter action row: it now follows the palette directly (no hint row above
 * it), so Undo/Redo/Erase/Clear sit above the fold on a typical laptop. */
.sudoku-desk.is-fullscreen .sudoku-actions { padding-top: 6px; gap: 6px; }
.sudoku-desk.is-fullscreen .sudoku-actions .sudoku-btn { min-height: 34px; padding: 7px 10px; font-size: 10px; }

/* Portrait / narrow: stack again, board sized off the width. */
@media (max-width: 860px), (orientation: portrait) {
  .sudoku-desk.is-fullscreen .sudoku-layout { flex-direction: column; align-items: center; justify-content: flex-start; }
  .sudoku-desk.is-fullscreen .sudoku-board { width: min(96vw, calc(100dvh - 210px)); }
  .sudoku-desk.is-fullscreen .sudoku-controls { flex: 0 0 auto; width: 100%; max-width: 420px; align-items: center; }
  .sudoku-desk.is-fullscreen .sudoku-modes { flex-direction: row; flex-wrap: wrap; justify-content: center; }
  .sudoku-desk.is-fullscreen .sudoku-mode { text-align: center; }
  .sudoku-desk.is-fullscreen .sudoku-swatches-row { justify-content: center; }
}

/* ── Mobile keypad overlay (bottom sheet) ── */
.sudoku-keypad-scrim {
  display: none; position: fixed; inset: 0; z-index: 9500;
  background: rgba(0, 0, 0, .35); justify-content: center; align-items: flex-end;
}
.sudoku-keypad-scrim.is-open { display: flex; }
.sudoku-keypad-sheet {
  background: var(--card, #fffdf6); border-top: 2px solid var(--ink);
  padding: 12px env(safe-area-inset-right, 12px) env(safe-area-inset-bottom, 8px) env(safe-area-inset-left, 12px);
  width: 100%; max-width: 400px;
  border-radius: 14px 14px 0 0;
}
.sudoku-keypad-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.sudoku-keypad-grid button {
  height: 52px; border: 1px solid var(--rule); background: var(--card, #fffdf6);
  font: 700 24px/1 "Source Serif 4", Georgia, serif; color: var(--ink);
  border-radius: 8px; cursor: pointer;
}
.sudoku-keypad-grid button:active { background: var(--sz-peer); }
.sudoku-keypad-grid button.sudoku-kp-erase { font-size: 20px; }
.sudoku-keypad-grid button.sudoku-kp-cancel { font: 600 14px "IBM Plex Mono", monospace; letter-spacing: .04em; text-transform: uppercase; color: var(--faded); }

/* ── Win celebration overlay ── */
/* Fixed, not absolute: #sudoku is only a positioned container in fullscreen
   mode, and a win can happen in the normal page flow too. */
.sudoku-celebration {
  display: none; position: fixed; inset: 0; z-index: 8000;
  justify-content: center; align-items: center;
  background: rgba(0, 0, 0, .18);
}
.sudoku-celebration.is-active { display: flex; }
.sudoku-celebration-card {
  background: var(--card, #fffdf6); border: 2px solid var(--red);
  padding: 28px 36px; text-align: center; border-radius: 10px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, .22);
  animation: sz-pop .45s cubic-bezier(.2, 1.4, .4, 1) both;
  position: relative; z-index: 2;
}
.sudoku-celebration-card .sz-trophy { font-size: 56px; display: block; margin-bottom: 6px; }
.sudoku-celebration-card .sz-win-title { font: 800 28px/1.1 "Source Serif 4", Georgia, serif; color: var(--red); text-transform: uppercase; letter-spacing: .04em; }
.sudoku-celebration-card .sz-win-pts { font: 700 16px/1 "IBM Plex Mono", monospace; color: var(--ink); margin: 8px 0 4px; }
.sudoku-celebration-card .sz-win-sub { font: 500 14px/1 "IBM Plex Mono", monospace; color: var(--faded); }
@keyframes sz-pop { 0% { transform: scale(.4); opacity: 0; } 100% { transform: scale(1); opacity: 1; } }

/* Confetti pieces — pure CSS paper burst. */
.sz-confetti {
  position: absolute; width: 10px; height: 14px; border-radius: 2px;
  opacity: 0; z-index: 1;
  animation: sz-confetti-fall var(--dur, 2.4s) var(--delay, 0s) ease-out forwards;
}
@keyframes sz-confetti-fall {
  0%   { transform: translate(0, 0) rotate(0deg); opacity: 1; }
  100% { transform: translate(var(--dx, 40px), var(--dy, 280px)) rotate(var(--rot, 540deg)); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .sz-confetti { animation: none; display: none; }
  .sudoku-celebration-card { animation-duration: .01ms; }
}

@media (max-width: 700px) {
  .sudoku-layout { flex-direction: column; }
  .sudoku-actions { margin-left: 0; flex-wrap: wrap; }
  /* Legible type at phone widths — bump clamps. */
  .sz-value { font-size: clamp(20px, 6vw, 28px); }
  .sz-mark { font-size: clamp(9px, 2.5vw, 13px); }
  .sz-mark.is-center { font-size: clamp(14px, 4vw, 19px); }
}
