/* Puzzles — a browser front-end for Simon Tatham's Portable Puzzle Collection.
   "Newsprint" identity (warm editorial) presented as a grounded desktop app:
   flat, bordered surfaces — no gradients, no glass, no floating cards.
   Chrome is themed here; puzzle canvases are coloured by their own C code
   (Tatham) or by js/theme.js (the native Maze). */

/* ---- Self-hosted fonts (vendored WOFF2, Latin subset) ------------------- */
/* Newsreader (serif) · Inter (sans) · JetBrains Mono (cipher). All SIL OFL 1.1
   (licenses in fonts/OFL-*.txt). Vendored so the "Newsprint" identity renders
   identically on every OS instead of falling back to system-ui/serif stacks.
   The same faces are re-declared in frame/puzzle-frame.html.tmpl for the Tatham
   puzzle iframes (separate document). */
@font-face { font-family: "Newsreader"; font-style: normal; font-weight: 400; font-display: swap;
  src: url("fonts/newsreader-latin-400-normal.woff2") format("woff2"); }
@font-face { font-family: "Newsreader"; font-style: normal; font-weight: 700; font-display: swap;
  src: url("fonts/newsreader-latin-700-normal.woff2") format("woff2"); }
@font-face { font-family: "Inter"; font-style: normal; font-weight: 400; font-display: swap;
  src: url("fonts/inter-latin-400-normal.woff2") format("woff2"); }
@font-face { font-family: "Inter"; font-style: normal; font-weight: 600; font-display: swap;
  src: url("fonts/inter-latin-600-normal.woff2") format("woff2"); }
@font-face { font-family: "Inter"; font-style: normal; font-weight: 700; font-display: swap;
  src: url("fonts/inter-latin-700-normal.woff2") format("woff2"); }
@font-face { font-family: "JetBrains Mono"; font-style: normal; font-weight: 600; font-display: swap;
  src: url("fonts/jetbrains-mono-latin-600-normal.woff2") format("woff2"); }

:root {
  --paper-bg: #efeae0;
  --surface: #f7f4ec;
  --surface-2: #e9e3d6;
  --ink: #201b17;
  --ink-soft: #4a4038;
  --muted: #837a6e;
  --rule: #d8cfbf;
  --rule-strong: #c3b9a4;
  --accent: #b4552d;
  --accent-press: #97431f;
  --accent-soft: rgba(180, 85, 45, 0.13);
  --win: #4b7a3f;
  --radius: 3px;
  --radius-sm: 2px;
  --canvas-paper: #faf7f0;   /* printed-sheet paper; always light, both themes */
  --serif: "Newsreader", Georgia, "Times New Roman", serif;
  --sans: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
  --sidebar-w: 238px;
  --head-h: 56px;            /* shared height: sidebar brand + play/maker header on one row */

  --sw-grid: #b4552d;
  --sw-path: #3f6f86;
  --sw-region: #5f7a3a;
  --sw-action: #a87c2e;
  --sw-deduction: #7a5570;
  --sw-paper: #9a6a4a;
  --sw-other: #837a6e;
}

[data-theme="dark"] {
  --paper-bg: #14110d;
  --surface: #1e1a15;
  --surface-2: #29231b;
  --ink: #ece4d7;
  --ink-soft: #cfc5b5;
  --muted: #988d7c;
  --rule: #332c22;
  --rule-strong: #473c2e;
  --accent: #d9793a;
  --accent-press: #ec9052;
  --accent-soft: rgba(217, 121, 58, 0.16);
  --win: #7ba86a;

  --sw-grid: #c76a3d;
  --sw-path: #5a90a8;
  --sw-region: #7d9a54;
  --sw-action: #c39a4a;
  --sw-deduction: #a07894;
  --sw-paper: #c08a63;
  --sw-other: #988d7c;
}

* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }
body {
  font-family: var(--serif);
  color: var(--ink);
  background: var(--paper-bg);
  font-size: 14px;
  -webkit-font-smoothing: antialiased;
}
button { font-family: var(--sans); color: inherit; }
a { color: inherit; text-decoration: none; }
::selection { background: var(--accent-soft); }

/* ---- App frame ---------------------------------------------------------- */
#app { display: flex; height: 100vh; overflow: hidden; }

/* ---- Sidebar ------------------------------------------------------------ */
#sidebar {
  flex: 0 0 var(--sidebar-w);
  width: var(--sidebar-w);
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border-right: 1px solid var(--rule);
  overflow: hidden;
}
.side-brand {
  display: flex; align-items: center; gap: 9px;
  min-height: var(--head-h); box-sizing: border-box;
  padding: 0 16px;
  color: var(--ink);
  border-bottom: 1px solid var(--rule);
}
.side-brand .wordmark { font-family: var(--serif); font-size: 19px; font-weight: 700; letter-spacing: 0.01em; }
.side-search { padding: 12px 14px 8px; }
#search {
  width: 100%;
  font-family: var(--sans); font-size: 13px; color: var(--ink);
  background: var(--paper-bg);
  border: 1px solid var(--rule-strong);
  border-radius: var(--radius-sm);
  padding: 7px 9px;
}
#search:focus { outline: none; border-color: var(--accent); }

.side-nav { flex: 1 1 auto; overflow-y: auto; padding: 4px 8px 10px; }
.nav-item {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  width: 100%; text-align: left;
  font-family: var(--sans); font-size: 13px; color: var(--ink-soft);
  background: none; border: 0; border-left: 2px solid transparent;
  padding: 7px 10px; cursor: pointer;
}
.nav-item:hover { background: var(--surface-2); color: var(--ink); }
.nav-item.active { background: var(--accent-soft); color: var(--ink); font-weight: 600; border-left-color: var(--accent); }
.nav-count { font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; }
.nav-item.active .nav-count { color: var(--accent); }

.side-foot { border-top: 1px solid var(--rule); padding: 10px 12px; }
.theme-btn {
  display: flex; align-items: center; gap: 8px; width: 100%;
  font-family: var(--sans); font-size: 12.5px; color: var(--ink-soft);
  background: var(--paper-bg); border: 1px solid var(--rule-strong);
  border-radius: var(--radius-sm); padding: 7px 10px; cursor: pointer;
}
.theme-btn:hover { background: var(--surface-2); color: var(--ink); }
.theme-ico { font-size: 14px; line-height: 1; }

/* ---- Main pane ---------------------------------------------------------- */
#main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; overflow: hidden; }

/* Gallery */
.gallery { flex: 1 1 auto; overflow-y: auto; padding: 18px clamp(16px, 3vw, 30px) 40px; }
.gallery-head {
  display: flex; align-items: baseline; gap: 12px;
  padding-bottom: 10px; margin-bottom: 8px;
  border-bottom: 1px solid var(--rule);
}
.gallery-title { font-family: var(--serif); font-size: 22px; font-weight: 700; margin: 0; }
.gallery-count { font-family: var(--sans); font-size: 12px; color: var(--muted); }

.cat-label {
  font-family: var(--sans); font-size: 10.5px; font-weight: 700;
  letter-spacing: 0.13em; text-transform: uppercase; color: var(--muted);
  margin: 20px 0 8px;
}
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(232px, 1fr)); gap: 8px; }

.tile {
  display: flex; align-items: flex-start; gap: 11px;
  width: 100%; text-align: left; cursor: pointer;
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  padding: 11px 13px;
}
.tile:hover { background: var(--surface-2); border-color: var(--rule-strong); }
.tile:focus-visible { outline: 2px solid var(--accent); outline-offset: -1px; }
.tile-swatch { flex: 0 0 auto; width: 13px; height: 13px; margin-top: 3px; border-radius: 2px; background: var(--sw-other); }
.sw-grid { background: var(--sw-grid); } .sw-path { background: var(--sw-path); }
.sw-region { background: var(--sw-region); } .sw-action { background: var(--sw-action); }
.sw-deduction { background: var(--sw-deduction); } .sw-paper { background: var(--sw-paper); }
.sw-other { background: var(--sw-other); }
.tile-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.tile-name { font-family: var(--sans); font-size: 14px; font-weight: 600; color: var(--ink); }
.tile-blurb {
  font-family: var(--sans); font-size: 12px; color: var(--muted); line-height: 1.35;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.empty { font-family: var(--sans); color: var(--muted); padding: 24px 2px; }

/* ---- Play view ---------------------------------------------------------- */
.play { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.play-head {
  display: flex; align-items: center; gap: 12px;
  min-height: var(--head-h); box-sizing: border-box;
  padding: 0 clamp(14px, 2.5vw, 24px);
  border-bottom: 1px solid var(--rule); background: var(--surface);
}
.back-btn {
  font-family: var(--sans); font-size: 13px; font-weight: 600;
  padding: 6px 11px; background: var(--paper-bg);
  border: 1px solid var(--rule-strong); border-radius: var(--radius-sm); cursor: pointer;
}
.back-btn:hover { background: var(--surface-2); }
.play-titles { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.play-title { font-family: var(--serif); font-size: 18px; font-weight: 700; line-height: 1.15; }
.play-help { font-family: var(--sans); font-size: 12px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Toolbar — flat menu bar */
.toolbar {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  padding: 8px clamp(14px, 2.5vw, 24px);
  border-bottom: 1px solid var(--rule); background: var(--surface);
}
.tb-btn {
  font-family: var(--sans); font-size: 13px; font-weight: 600;
  padding: 6px 12px; background: var(--paper-bg); color: var(--ink);
  border: 1px solid var(--rule-strong); border-radius: var(--radius-sm); cursor: pointer;
}
.tb-btn:hover:not(:disabled) { background: var(--surface-2); }
.tb-btn:disabled { opacity: 0.4; cursor: default; }
.tb-btn.primary { background: var(--accent); color: #fff; border-color: var(--accent); }
.tb-btn.primary:hover { background: var(--accent-press); border-color: var(--accent-press); }
.tb-sep { width: 1px; align-self: stretch; background: var(--rule); margin: 2px 4px; }
.tb-spacer { flex: 1; }
.tb-type { display: inline-flex; align-items: center; gap: 7px; font-family: var(--sans); font-size: 12px; color: var(--muted); }
.tb-type select {
  font-family: var(--sans); font-size: 13px; color: var(--ink);
  background: var(--paper-bg); border: 1px solid var(--rule-strong);
  border-radius: var(--radius-sm); padding: 5px 7px; max-width: 220px;
}
.tb-type select:focus { outline: none; border-color: var(--accent); }

/* ---- Themed dropdown / menu (replaces native <select> + system menus) --- */
.dd { position: relative; display: inline-flex; }
.dd-btn {
  display: inline-flex; align-items: center; gap: 8px; max-width: 240px;
  font-family: var(--sans); font-size: 13px; color: var(--ink); cursor: pointer;
  background: var(--paper-bg); border: 1px solid var(--rule-strong);
  border-radius: var(--radius-sm); padding: 6px 10px;
}
.dd-btn:hover { border-color: var(--accent); }
.dd-btn:focus-visible { outline: none; border-color: var(--accent); }
.dd-menu-btn { font-weight: 600; }
.dd-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dd-caret { font-size: 10px; color: var(--muted); margin-left: auto; }
.dd-pop {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 200;
  min-width: 100%; max-height: 320px; overflow-y: auto;
  display: none; padding: 5px;
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--rule-strong); border-radius: var(--radius-sm);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.22);
}
.dd-pop.open { display: block; }
.dd-pop.dd-right { left: auto; right: 0; }
.dd-menu { min-width: 150px; }
.dd-opt {
  display: flex; align-items: center; gap: 8px; white-space: nowrap;
  font-family: var(--sans); font-size: 13px; color: var(--ink);
  padding: 7px 9px; border-radius: var(--radius-sm); cursor: pointer;
}
.dd-opt:hover, .dd-opt:focus-visible, .dd-opt.active { background: var(--surface-2); outline: none; }
.dd-opt[aria-selected="true"] { color: var(--accent); font-weight: 600; }
.dd-opt[aria-selected="true"]::after { content: "✓"; margin-left: auto; font-size: 12px; }
.dd-action.primary { color: var(--accent); font-weight: 600; }
.dd-check[aria-checked="true"] { color: var(--accent); font-weight: 600; }
.dd-check[aria-checked="true"]::after { content: "✓"; margin-left: auto; font-size: 12px; color: var(--accent); }
.dd-sep { height: 1px; background: var(--rule); margin: 5px 3px; }
.dd-note { padding: 4px 9px 2px; font-size: 12px; color: var(--muted); white-space: normal; }
/* Full-width inside the maker panel's stacked fields. */
.maker-field .dd, .maker-field .dd-btn { width: 100%; max-width: none; }

/* Stage — a bordered panel, not a floating card */
.stage {
  flex: 1 1 auto; min-height: 0; position: relative;
  display: flex; align-items: center; justify-content: center;
  padding: clamp(12px, 2.5vw, 24px); overflow: auto;
  background: var(--paper-bg);
}
.stage iframe {
  width: 100%; height: 100%; border: 1px solid var(--rule-strong);
  border-radius: var(--radius); background: var(--surface);
}
/* Natural size (square cells); the scrollable .maker-canvas-wrap pans giant mazes. */
#board { background: var(--canvas-paper); border: 1px solid var(--rule-strong); border-radius: var(--radius); outline: none; touch-action: none; }

/* Word Search — grid + word list drawn on one paper canvas (like crossword) */
.ws-grid {
  background: var(--canvas-paper); border: 1px solid var(--rule-strong);
  border-radius: var(--radius); touch-action: none; max-width: 100%;
}

/* Status bar */
.statusbar {
  flex: 0 0 auto; min-height: 34px;
  display: flex; align-items: center; gap: 10px;
  font-family: var(--sans); font-size: 13px; color: var(--ink-soft);
  padding: 7px clamp(14px, 2.5vw, 24px);
  border-top: 1px solid var(--rule); background: var(--surface);
}
.statusbar .solved { color: var(--win); font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; font-size: 12px; }
.statusbar .err { color: var(--accent); font-weight: 600; }
/* Read-only "current seed" readout (the /seed analog), pushed to the right. */
.statusbar .seed-readout { margin-left: auto; color: var(--muted); font-size: 12px; font-variant-numeric: tabular-nums; user-select: all; }

/* Maze touch D-pad */
.dpad { display: none; }
.touch .dpad {
  position: absolute; right: 16px; bottom: 16px;
  display: grid; grid-template-columns: repeat(3, 46px); grid-template-rows: repeat(3, 46px);
  gap: 6px; opacity: 0.92; z-index: 5;
}
.dpad button {
  border: 1px solid var(--rule-strong); background: var(--surface); color: var(--ink);
  border-radius: var(--radius-sm); font-size: 20px; cursor: pointer; touch-action: none; user-select: none;
}
.dpad button:active { background: var(--accent); color: #fff; }
.dpad .up { grid-area: 1 / 2; } .dpad .left { grid-area: 2 / 1; }
.dpad .right { grid-area: 2 / 3; } .dpad .down { grid-area: 3 / 2; }

/* ---- "Paper" makers (crossword / cryptogram) --------------------------- */
.maker { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.maker-body { flex: 1 1 auto; min-height: 0; }
.maker-grid { display: grid; grid-template-columns: var(--panel-w, 320px) 6px 1fr; height: 100%; }
.maker-divider {
  cursor: col-resize; background: var(--rule);
  border-left: 1px solid var(--surface); border-right: 1px solid var(--surface);
  touch-action: none;
}
.maker-divider:hover { background: var(--accent); }

.maker-panel {
  border-right: 1px solid var(--rule); background: var(--surface);
  padding: 16px clamp(12px, 2vw, 20px); overflow-y: auto;
  display: flex; flex-direction: column; gap: 14px;
}
.maker-field { display: flex; flex-direction: column; gap: 5px; font-family: var(--sans); font-size: 12px; color: var(--muted); }
.maker-field-label { font-family: var(--sans); font-size: 11px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); }
/* Read-only "current seed" readout sitting just under the Seed field. */
.maker-seed-current { margin-top: -8px; font-family: var(--sans); font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; word-break: break-all; user-select: all; }
.maker-row { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; }
.maker-check { display: flex; align-items: center; gap: 8px; font-family: var(--sans); font-size: 13px; color: var(--ink-soft); }
.maker-check input { accent-color: var(--accent); width: 15px; height: 15px; }
.maker-msg { font-family: var(--sans); font-size: 12.5px; color: var(--accent); min-height: 1em; }
.maker-help { font-family: var(--sans); font-size: 13px; color: var(--muted); line-height: 1.45; }
.maker-status {
  margin-top: auto; padding-top: 8px;
  display: flex; align-items: center; gap: 8px;
  font-family: var(--sans); font-size: 13px; color: var(--ink-soft); min-height: 1.3em;
}
.maker-status.error { color: var(--accent); font-weight: 600; }
.maker-status .solved { color: var(--win); font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; font-size: 12px; }
.maker-panel textarea, .maker-panel input[type="number"], .maker-panel input[type="text"],
.maker-panel select, .maker-panel .xw-word, .maker-panel .xw-clue {
  font-family: var(--sans); font-size: 13px; color: var(--ink);
  background: var(--paper-bg); border: 1px solid var(--rule-strong);
  border-radius: var(--radius-sm); padding: 7px 8px; width: 100%;
}
.maker-panel select:focus { outline: none; border-color: var(--accent); }
.maker-panel textarea { resize: vertical; }
.maker-panel textarea:focus, .maker-panel input:focus { outline: none; border-color: var(--accent); }

.xw-rows { display: flex; flex-direction: column; gap: 6px; }
.xw-row { display: grid; grid-template-columns: 92px 1fr auto; gap: 6px; align-items: center; }
.ws-rows .xw-row { grid-template-columns: 1fr auto; }   /* word search: word + delete only */
.xw-word { text-transform: uppercase; }
.xw-del { padding: 4px 9px; line-height: 1; }

.maker-preview { position: relative; display: flex; flex-direction: column; min-width: 0; overflow: hidden; }
.maker-actions {
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
  padding: 10px clamp(14px, 2.5vw, 24px);
  border-bottom: 1px solid var(--rule); background: var(--surface);
}
.maker-canvas-wrap {
  position: relative;
  flex: 1 1 auto; min-height: 0; overflow: auto;
  padding: clamp(14px, 3vw, 28px); background: var(--paper-bg);
  /* "safe center": center a canvas that fits, but start-align (keep the left edge
     reachable) once it overflows and the wrap scrolls. */
  display: flex; justify-content: safe center; align-items: flex-start;
}
.paper-canvas { border: 1px solid var(--rule-strong); border-radius: var(--radius); background: var(--canvas-paper); max-width: none; }

/* ---- Modal (maze custom config) ---------------------------------------- */
.modal-backdrop {
  position: fixed; inset: 0; z-index: 100;
  display: flex; align-items: center; justify-content: center;
  background: rgba(20, 17, 13, 0.42); padding: 16px;
}
.modal {
  width: 100%; max-width: 340px;
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--rule-strong); border-radius: var(--radius);
  padding: 18px 20px;
}
.modal h2 { font-family: var(--serif); font-size: 18px; font-weight: 700; margin: 0 0 14px; }
.modal-field { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 10px; font-family: var(--sans); font-size: 13px; color: var(--ink-soft); }
.modal-field input, .modal-field select {
  font-family: var(--sans); font-size: 13px; color: var(--ink);
  background: var(--paper-bg); border: 1px solid var(--rule-strong);
  border-radius: var(--radius-sm); padding: 6px 8px; width: 140px;
}
.modal-field input:focus, .modal-field select:focus { outline: none; border-color: var(--accent); }
.modal-check { display: flex; align-items: center; gap: 8px; margin: 4px 0 2px; font-family: var(--sans); font-size: 13px; color: var(--ink-soft); }
.modal-check input { accent-color: var(--accent); width: 15px; height: 15px; }
.modal-check.disabled { opacity: 0.45; }
.modal-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 18px; }
.btn-ok, .btn-cancel {
  font-family: var(--sans); font-size: 13px; font-weight: 600;
  padding: 7px 16px; border-radius: var(--radius-sm); cursor: pointer;
}
.btn-ok { background: var(--accent); color: #fff; border: 1px solid var(--accent); }
.btn-ok:hover { background: var(--accent-press); border-color: var(--accent-press); }
.btn-cancel { background: var(--paper-bg); color: var(--ink); border: 1px solid var(--rule-strong); }
.btn-cancel:hover { background: var(--surface-2); }

/* ---- Responsive: sidebar collapses to a top strip ----------------------- */
@media (max-width: 760px) {
  #app { flex-direction: column; height: 100vh; }
  #sidebar {
    flex: 0 0 auto; width: 100%;
    flex-direction: row; flex-wrap: wrap; align-items: center;
    border-right: 0; border-bottom: 1px solid var(--rule);
  }
  .side-brand { border-bottom: 0; padding: 10px 14px; min-height: 0; }
  .side-search { flex: 1 1 160px; padding: 8px 12px; }
  .side-nav {
    order: 3; flex-basis: 100%;
    display: flex; flex-direction: row; gap: 2px;
    overflow-x: auto; padding: 4px 10px 8px;
    border-top: 1px solid var(--rule);
  }
  .nav-item { border-left: 0; border-bottom: 2px solid transparent; white-space: nowrap; }
  .nav-item.active { border-left: 0; border-bottom-color: var(--accent); }
  .side-foot { border-top: 0; padding: 8px 12px; }
  .theme-btn .theme-label { display: none; }
  .theme-btn { padding: 7px 9px; }
  .play-help { display: none; }
  .maker-grid { grid-template-columns: 1fr; grid-template-rows: auto 1fr; }
  .maker-divider { display: none; }
  .maker-panel { border-right: 0; border-bottom: 1px solid var(--rule); max-height: 45vh; }
}
