:root {
  /* default "Midnight" theme */
  --bg: #1e1e28;
  --panel: #2a2a38;
  --cell: #33333f;
  --cell-given: #2a2a38;
  --line: #11111a;
  --accent: #6c8cff;
  --text: #e8e8f0;
  --given-text: #b8b8c8;
  --error: #ff5d6c;
  --ok: #4ad991;
  --highlight: #3a3a52;
  --sel-text: #ffffff; /* text/marks on a selected cell — must contrast --accent */

  /* font scale (overridden by [data-font]) */
  --cell-font: clamp(1rem, 5vw, 1.6rem);
  --mark-font: clamp(0.42rem, 1.9vw, 0.66rem);
  --sum-font: clamp(0.55rem, 2.1vw, 0.82rem);

  /* font family (overridden by [data-fontface]) */
  --font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

/* OpenDyslexic (loaded from CDN; falls back to Comic Sans / Verdana offline). */
@font-face {
  font-family: "OpenDyslexic";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("https://cdn.jsdelivr.net/npm/@fontsource/opendyslexic@5/files/opendyslexic-latin-400-normal.woff2") format("woff2");
}

/* ---- font families ---- */
body[data-fontface="serif"]   { --font-family: Georgia, "Times New Roman", serif; }
body[data-fontface="mono"]    { --font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
body[data-fontface="rounded"] { --font-family: "Trebuchet MS", "Segoe UI", system-ui, sans-serif; }
body[data-fontface="dyslexic"]{ --font-family: "OpenDyslexic", "Comic Sans MS", Verdana, sans-serif; }

/* ---- color themes ---- */
body[data-theme="monokai"] {
  --bg: #1e1f1c;
  --panel: #2d2e2a;
  --cell: #35362f;
  --cell-given: #2d2e2a;
  --line: #131410;
  --accent: #fd971f;
  --text: #f8f8f2;
  --given-text: #a6a69c;
  --error: #f92672;
  --ok: #a6e22e;
  --highlight: #49483e;
  --sel-text: #1e1f1c;
}

body[data-theme="nord"] {
  --bg: #2e3440;
  --panel: #3b4252;
  --cell: #434c5e;
  --cell-given: #3b4252;
  --line: #21252e;
  --accent: #88c0d0;
  --text: #eceff4;
  --given-text: #aebacf;
  --error: #bf616a;
  --ok: #a3be8c;
  --highlight: #4c566a;
  --sel-text: #2e3440;
}

body[data-theme="dracula"] {
  --bg: #282a36;
  --panel: #343746;
  --cell: #3c3f52;
  --cell-given: #343746;
  --line: #1a1b23;
  --accent: #bd93f9;
  --text: #f8f8f2;
  --given-text: #b4b8d0;
  --error: #ff5555;
  --ok: #50fa7b;
  --highlight: #44475a;
  --sel-text: #282a36;
}

body[data-theme="solarized"] {
  --bg: #002b36;
  --panel: #073642;
  --cell: #0a4250;
  --cell-given: #073642;
  --line: #001b22;
  --accent: #268bd2;
  --text: #eee8d5;
  --given-text: #93a1a1;
  --error: #dc322f;
  --ok: #859900;
  --highlight: #0e4b59;
  --sel-text: #ffffff;
}

body[data-theme="light"] {
  --bg: #f4f4f8;
  --panel: #ffffff;
  --cell: #ffffff;
  --cell-given: #ececed;
  --line: #c4c4cc;
  --accent: #3b6cff;
  --text: #1e1e28;
  --given-text: #555560;
  --error: #d6293e;
  --ok: #1c9e63;
  --highlight: #d8e0ff;
  --sel-text: #ffffff;
}

/* Trans pride: dark base, blue/pink/white accents.
   Given clues in pink, your entries in blue, white text. */
body[data-theme="trans"] {
  --bg: #1a1d24;
  --panel: #242832;
  --cell: #2c313d;
  --cell-given: #242832;
  --line: #11131a;
  --accent: #5bcefa;      /* trans blue — entries + selection */
  --text: #f6f8fb;        /* white */
  --given-text: #f5a9b8;  /* trans pink — given clues */
  --error: #ff6b81;
  --ok: #7ee0b8;
  --highlight: #3c2b33;   /* subtle pink-tinted peer highlight */
  --sel-text: #10141c;    /* dark text on the light-blue selected cell */
}

/* ---- font sizes ---- */
body[data-font="small"] {
  --cell-font: clamp(0.8rem, 4vw, 1.2rem);
  --mark-font: clamp(0.35rem, 1.6vw, 0.55rem);
  --sum-font: clamp(0.5rem, 1.9vw, 0.72rem);
}
body[data-font="large"] {
  --cell-font: clamp(1.2rem, 6vw, 2rem);
  --mark-font: clamp(0.5rem, 2.2vw, 0.8rem);
  --sum-font: clamp(0.62rem, 2.4vw, 0.95rem);
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }

body {
  margin: 0;
  font-family: var(--font-family);
  background: var(--bg);
  color: var(--text);
  display: flex;
  justify-content: center;
  padding: 24px 12px;
  min-height: 100vh;
}

main {
  /* Column width. On mobile it fills the screen (board good there already).
     On desktop it is also capped by viewport height so the whole game fits on
     one screen with the board as large as possible — board and pad stay aligned
     because both are this width. */
  width: min(94vw, 480px);
  max-width: none;
}

@media (min-width: 700px) {
  main {
    /* ~400px reserved for title, controls, status and number pad so the square
       board grows to fill the remaining viewport height (capped at 760). */
    width: min(94vw, 760px, calc(100vh - 400px));
  }
}

h1 {
  margin: 0;
  text-align: center;
  font-weight: 700;
  letter-spacing: 1px;
}

.subtitle {
  margin: 4px 0 20px;
  text-align: center;
  color: var(--given-text);
  font-size: 0.85rem;
}

.controls {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  justify-content: center;
  margin-bottom: 14px;
}

.controls label { font-size: 0.85rem; color: var(--given-text); }

select, button {
  background: var(--panel);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 8px 12px;
  font-size: 0.9rem;
  cursor: pointer;
  transition: background 0.12s, transform 0.05s;
}

button:hover { background: var(--highlight); }
button:active { transform: scale(0.96); }

.status {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
  min-height: 24px;
  font-variant-numeric: tabular-nums;
}

#message { font-weight: 600; }
#message.win { color: var(--ok); }
#message.err { color: var(--error); }

.board {
  display: grid;
  grid-template-columns: repeat(9, 1fr);
  aspect-ratio: 1 / 1;
  background: var(--line);
  border: 3px solid var(--line);
  border-radius: 8px;
  overflow: hidden;
  gap: 1px;
}

.icon-btn {
  font-size: 1.1rem;
  line-height: 1;
  padding: 8px 11px;
}
.icon-btn.active { background: var(--accent); color: var(--sel-text); border-color: var(--accent); }

.settings-panel {
  display: flex;
  flex-direction: column;
  gap: 10px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 14px;
  margin-bottom: 12px;
}
.setting-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.setting-row label { font-size: 0.85rem; color: var(--given-text); }
.setting-row select { min-width: 130px; }
.setting-sep { border: none; border-top: 1px solid var(--line); margin: 4px 0; }
.share-btns { display: flex; gap: 6px; }
.share-btns button { padding: 6px 9px; font-size: 0.8rem; }
#load-str {
  flex: 1;
  min-width: 0;
  background: var(--cell);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 7px 9px;
  font-size: 0.85rem;
}
#solve-speed { flex: 1; min-width: 0; accent-color: var(--accent); }
.review-msg { font-size: 0.85rem; color: var(--given-text); }
#review-bar #review-confirm { background: var(--accent); color: var(--sel-text); border-color: var(--accent); }

/* cell the solver is currently trying / backtracking from */
.cell.trying { box-shadow: inset 0 0 0 3px var(--ok); }
.cell.backtrack { box-shadow: inset 0 0 0 3px var(--error); }

/* solver search-tree panel */
#tree-panel {
  margin-top: 12px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 10px;
}
.tree-legend {
  display: flex;
  gap: 14px;
  align-items: center;
  font-size: 0.78rem;
  color: var(--given-text);
  margin-bottom: 8px;
  flex-wrap: wrap;
}
.tree-legend i.sw {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  margin-right: 4px;
  vertical-align: -1px;
}
.tree-legend .sw.active { background: var(--accent); }
.tree-legend .sw.fail { background: var(--error); }
.tree-legend .sw.solved { background: var(--ok); }
#tree-svg {
  display: block;
  width: 100%;
  height: 260px;
  background: var(--cell);
  border-radius: 6px;
}

/* multiplayer bar */
.mp-bar input {
  background: var(--panel);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 8px 10px;
  font-size: 0.9rem;
}
.code-input { width: 80px; text-transform: uppercase; letter-spacing: 2px; }

.lobby-info {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 10px;
  font-size: 0.85rem;
}
.lobby-info strong { color: var(--accent); letter-spacing: 2px; }
.players { display: flex; gap: 6px; flex-wrap: wrap; }
.player-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 8px;
  border-radius: 999px;
  background: var(--panel);
  font-size: 0.78rem;
}
.player-chip .dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  display: inline-block;
}
.player-chip .crown { font-size: 0.8rem; }

/* remote player cursor badge (name tag in their selected cell) */
.cursor-badge {
  position: absolute;
  top: -2px;
  left: -2px;
  font-size: 0.5rem;
  font-weight: 700;
  line-height: 1;
  padding: 1px 3px;
  border-radius: 4px;
  color: #fff;
  pointer-events: none;
  white-space: nowrap;
  z-index: 2;
}

/* killer cage outline + sum label */
.cage-lines {
  position: absolute;
  inset: 3px;
  pointer-events: none;
  z-index: 1;
}
.cage-sum {
  position: absolute;
  top: 0;
  left: 0;
  font-size: var(--sum-font);
  font-weight: 700;
  line-height: 1;
  color: var(--cage-label, var(--accent));
  /* opaque chip so the dashed cage outline doesn't run through the number */
  background: var(--cell);
  padding: 1px 3px;
  border-bottom-right-radius: 5px;
  pointer-events: none;
  z-index: 3;
}
.cell.given .cage-sum { background: var(--cell-given); }
.cell.selected .cage-sum { background: var(--accent); color: var(--sel-text); }
/* on a cage's sum cell, drop the candidate grid below the sum chip */
.cell.cage-anchor .marks { padding-top: calc(var(--sum-font) + 2px); }

.cell {
  position: relative;
  background: var(--cell);
  border: none;
  color: var(--accent);
  font-size: var(--cell-font);
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  user-select: none;
  aspect-ratio: 1 / 1;
}

.cell.given {
  background: var(--cell-given);
  color: var(--given-text);
  cursor: default;
}

.cell.selected { background: var(--accent); color: var(--sel-text); }

/* pencil-mark candidate grid inside an empty cell */
.cell .marks {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
  width: 100%;
  height: 100%;
  font-size: var(--mark-font);
  font-weight: 500;
  color: var(--given-text);
  line-height: 1;
}
.cell .marks span {
  display: flex;
  align-items: center;
  justify-content: center;
}
.cell .marks span.auto { color: var(--accent); }
/* selected cell: marks must contrast the accent background */
.cell.selected .marks,
.cell.selected .marks span.auto { color: var(--sel-text); }

.toggle.active {
  background: var(--accent);
  color: var(--sel-text);
  border-color: var(--accent);
}
.cell.peer { background: var(--highlight); }
.cell.same { background: color-mix(in srgb, var(--accent) 30%, var(--cell)); }
.cell.conflict { color: var(--error); }

/* thicker borders between 3x3 boxes */
.cell:nth-child(9n+4),
.cell:nth-child(9n+7) { border-left: 2px solid var(--line); }
.cell:nth-child(n+28):nth-child(-n+36),
.cell:nth-child(n+55):nth-child(-n+63) { border-top: 2px solid var(--line); }

.pad {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 8px;
  margin-top: 16px;
}

.pad button { padding: 14px 0; font-size: 1.2rem; font-weight: 600; }
.pad .erase { color: var(--error); }

@media (max-width: 380px) {
  .pad { grid-template-columns: repeat(5, 1fr); }
}
