:root {
  --bg: #f5f1e8;
  --surface: #fffdf8;
  --ink: #1d1b18;
  --ink-soft: #6b645a;
  --entered: #2f5d9b;
  --line: #d4ccbf;
  --line-strong: #3a352e;
  --related: #efe9dd;
  --same: #dde6f0;
  --selected: #bcd3ee;
  --locked: #f1ede4;
  --conflict-bg: #f6d3cf;
  --conflict-ink: #b3261e;
  --button: #ebe5d8;
  --button-active: #ddd4c3;
  --accent: #3a352e;
  --accent-ink: #fffdf8;
  --seal: #b3261e;
  --overlay: rgb(255 253 248 / 0.92);
  --shadow: rgb(0 0 0 / 0.18);
  --backdrop: rgb(0 0 0 / 0.35);
  --pressed: #fffdf8;
  --ok: #2e7d4f;
  /* Assist-feedback: warm, rustig oplichten (los van de spelersinvoer in blauw). */
  --assist: #f4dc9a;
  --assist-ring: #c48a1a;
  --assist-notes: #f8ebc6;
  color-scheme: light;
}

/* Donker (E16): volgt het systeem, tenzij de speler zelf licht of donker kiest (data-theme). */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #171512;
    --surface: #221f1b;
    --ink: #ece6da;
    --ink-soft: #a89f91;
    --entered: #8db8f0;
    --line: #3b362f;
    --line-strong: #cfc6b8;
    --related: #2d2924;
    --same: #26303d;
    --selected: #2f4668;
    --locked: #1c1a17;
    --conflict-bg: #4d2320;
    --conflict-ink: #ff9a8f;
    --button: #2d2924;
    --button-active: #3a352e;
    --accent: #e6dfd1;
    --accent-ink: #171512;
    --seal: #f07a6c;
    --overlay: rgb(34 31 27 / 0.92);
    --shadow: rgb(0 0 0 / 0.5);
    --backdrop: rgb(0 0 0 / 0.6);
  --pressed: #46403a;
  --ok: #7fd4a0;
    --assist: #5b4a20;
    --assist-ring: #e2b553;
    --assist-notes: #43381f;
    color-scheme: dark;
  }
}
:root[data-theme="dark"] {
  --bg: #171512;
  --surface: #221f1b;
  --ink: #ece6da;
  --ink-soft: #a89f91;
  --entered: #8db8f0;
  --line: #3b362f;
  --line-strong: #cfc6b8;
  --related: #2d2924;
  --same: #26303d;
  --selected: #2f4668;
  --locked: #1c1a17;
  --conflict-bg: #4d2320;
  --conflict-ink: #ff9a8f;
  --button: #2d2924;
  --button-active: #3a352e;
  --accent: #e6dfd1;
  --accent-ink: #171512;
  --seal: #f07a6c;
  --overlay: rgb(34 31 27 / 0.92);
  --shadow: rgb(0 0 0 / 0.5);
  --backdrop: rgb(0 0 0 / 0.6);
  --pressed: #46403a;
  --ok: #7fd4a0;
  --assist: #5b4a20;
  --assist-ring: #e2b553;
  --assist-notes: #43381f;
  color-scheme: dark;
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  padding-bottom: var(--notice-space, 0px); /* ruimte onder een blijvende melding (main.js) */
  background: var(--bg);
  color: var(--ink);
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

button {
  font: inherit;
  color: inherit;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  cursor: pointer;
}
button:disabled { cursor: default; opacity: 0.45; }
[hidden] { display: none !important; }

.visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.app {
  max-width: 1180px;
  min-height: 100dvh;
  margin: 0 auto;
  padding: max(12px, env(safe-area-inset-top)) 16px max(16px, env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* ---- kop ------------------------------------------------------------------------------- */

.top { display: flex; align-items: center; gap: 12px; }
.brand { display: flex; align-items: center; gap: 10px; min-width: 0; }
.brand img { flex: none; }
h1 { margin: 0; font-size: 1.25rem; letter-spacing: 0.02em; white-space: nowrap; }
.top-actions { display: flex; align-items: center; gap: 8px; margin-left: auto; }

.icon-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: 10px;
  background: var(--button);
}
.icon-button.small { width: 34px; height: 34px; border-radius: 8px; }

.primary {
  border: 0;
  border-radius: 10px;
  padding: 10px 16px;
  min-height: 44px;
  background: var(--accent);
  color: var(--accent-ink);
  font-weight: 600;
}
.primary.wide { width: 100%; margin-top: 8px; }

.chip {
  min-height: 38px;
  padding: 0 14px;
  border: 0;
  border-radius: 19px;
  background: var(--button);
  white-space: nowrap;
}

/* Spelvormen: op pc in de kop, op telefoon en tablet als balk onderaan (duimzone). */
.modes {
  display: flex;
  gap: 4px;
  padding: 4px;
  border-radius: 12px;
  background: var(--button);
  margin-left: auto;
}
.modes + .top-actions { margin-left: 0; }
.modes button {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 1 1 auto;
  border: 0;
  border-radius: 8px;
  min-height: 38px;
  padding: 0 12px;
  background: transparent;
  color: var(--ink-soft);
  white-space: nowrap;
}
.modes button[aria-pressed="true"] {
  background: var(--pressed);
  color: var(--ink);
  font-weight: 600;
  box-shadow: 0 1px 2px var(--shadow);
}

.segmented { display: flex; gap: 4px; padding: 4px; border-radius: 12px; background: var(--button); }
.segmented button {
  flex: 1 1 auto;
  border: 0;
  border-radius: 8px;
  min-height: 36px;
  padding: 0 10px;
  background: transparent;
  color: var(--ink-soft);
  white-space: nowrap;
}
.segmented button[aria-pressed="true"] {
  background: var(--pressed);
  color: var(--ink);
  font-weight: 600;
  box-shadow: 0 1px 2px var(--shadow);
}

.choices { display: flex; align-items: center; gap: 8px; }
.choices .segmented { flex: 1; max-width: 520px; }
.choices .segmented button { min-width: 0; }
/* Opgelost niveau: ✓ en groen. Een optioneel niveau (dag al voltooid) ziet er gewoon speelbaar uit. */
.choices .segmented button.solved:not([aria-pressed="true"]) { color: var(--ok); }

@media (max-width: 959px) {
  /* Geen spelvormbalk: onder 960 px kies je de spelvorm op Home, dus ook geen ruimte ervoor. */
  .app { padding-bottom: max(16px, env(safe-area-inset-bottom)); }
  .modes { display: none; }
  .top-actions { margin-left: auto; }
  .top .new-game { min-height: 40px; padding: 8px 14px; }
  .top .icon-button { width: 40px; height: 40px; }
}
@media (max-width: 440px) {
  h1 { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .top-actions { gap: 6px; }
  .top .icon-button { width: 38px; height: 38px; }
  .choices { gap: 6px; }
  .choices .segmented button { padding: 0 4px; font-size: 0.85rem; }
}

/* ---- speelgebied ------------------------------------------------------------------------- */

.play { display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; align-items: start; }
@media (min-width: 860px) {
  .play { grid-template-columns: minmax(0, 1fr) 300px; }
}

.stage { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.viewport-wrap { position: relative; }

.viewport {
  position: relative;
  overflow: hidden;
  width: 100%;
  touch-action: manipulation;
  user-select: none;
  -webkit-user-select: none;
}
.viewport.square {
  aspect-ratio: 1;
  max-width: min(100%, 640px, max(280px, calc(100dvh - 190px)));
  margin: 0 auto;
}
.viewport.pannable {
  height: min(75dvh, max(320px, calc(100dvh - 230px)));
  border-radius: 12px;
  background: var(--button);
  touch-action: none;
  cursor: grab;
}
.viewport.dragging { cursor: grabbing; }
.viewport.paused .field { visibility: hidden; }

.pause-cover {
  position: absolute;
  inset: 0;
  z-index: 4;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 24px;
  border-radius: 12px;
  background: var(--surface);
  border: 1px solid var(--line);
  text-align: center;
}
.pause-title { margin: 0; font-size: 1.6rem; font-weight: 700; }
.pause-text { margin: 0 0 8px; color: var(--ink-soft); }

.zoom {
  position: absolute;
  right: 8px;
  bottom: 8px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.zoom button {
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: 10px;
  background: var(--overlay);
  box-shadow: 0 1px 3px var(--shadow);
  font-size: 1.3rem;
  line-height: 1;
}
@media (hover: none) and (pointer: coarse) {
  .zoom { display: none; }
}

.parts { display: flex; flex-wrap: wrap; gap: 6px; }
.parts button {
  min-height: 40px;
  padding: 0 12px;
  border: 0;
  border-radius: 8px;
  background: var(--button);
}
@media (max-width: 719px) {
  .parts { gap: 4px; }
  .parts button { flex: 1; padding: 0 6px; font-size: 0.88rem; min-height: 38px; }
}

.toast {
  position: absolute;
  left: 50%;
  top: 10px;
  z-index: 6;
  transform: translateX(-50%);
  width: max-content;
  max-width: calc(100% - 32px);
  padding: 10px 16px;
  border-radius: 10px;
  background: var(--accent);
  color: var(--accent-ink);
  text-align: center;
  box-shadow: 0 2px 8px var(--shadow);
  animation: toast-in 0.18s ease-out;
}
@keyframes toast-in { from { opacity: 0; transform: translate(-50%, -6px); } }

/* ---- veld ------------------------------------------------------------------------------- */

.field { position: absolute; left: 0; top: 0; transform-origin: 0 0; }
.cells, .frames { position: absolute; inset: 0; }
.frames { pointer-events: none; }

.cell {
  position: absolute;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  background: var(--surface);
  font-size: 26px;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.viewport.pannable .cell { cursor: inherit; }
.cell.given { font-weight: 700; color: var(--ink); }
.cell.entered { color: var(--entered); }
.cell.locked { background: var(--locked); }
.cell.related { background: var(--related); }
.cell.same { background: var(--same); }
.cell.conflict { background: var(--conflict-bg); }
/* Middle op slot (Samusamu-finale): gedimd, gegeven cijfers licht zichtbaar, niet speelbaar. */
.cell.closed { background: var(--locked); color: var(--ink-soft); cursor: not-allowed; }
.cell.closed.given { font-weight: 400; opacity: 0.55; }
.cell.conflict.entered { color: var(--conflict-ink); }
/* Auto-Fill (Box/Row/Column): het cijfer houdt de spelerkleur; een dun goud hoekje rechtsboven laat blijvend zien dat de
   app het vak invulde. Binnen het vak, onder niets anders: geen verschuiving, geen extra achtergrond. */
.cell.autofilled::after {
  content: '';
  position: absolute;
  top: 4px;
  right: 4px;
  width: 8px;
  height: 8px;
  border-top: 2px solid var(--assist-ring);
  border-right: 2px solid var(--assist-ring);
  border-top-right-radius: 3px;
  pointer-events: none;
}
.cell.selected { background: var(--selected); }
.cell.selected.conflict.entered { color: var(--conflict-ink); }
.cell.wrong { background: var(--conflict-bg); color: var(--conflict-ink); }
.cell.wrong.selected { background: var(--selected); }
.cell.corner-open {
  background: var(--accent);
  color: var(--accent-ink);
  cursor: pointer;
  z-index: 1;
  box-shadow: 0 0 0 3px var(--selected);
}
.cell:focus { outline: none; }
.cell:focus-visible { box-shadow: inset 0 0 0 2px var(--entered); }
/* Assist-feedback: kort oplichten van wat de app deed (tap-to-fill: het ingevulde vak; Pair Notes: vakken met nieuwe
   notities). Alleen achtergrond en een rand binnen het vak, onder het cijfer: geen verschuiving, geen schaal. Zonder
   eindframe loopt de animatie terug naar de gewone celstijl. main.js haalt de klasse na ongeveer 0,65 s weg. */
.cell.assist-fill { animation: assist-fill 0.6s ease-out; }
.cell.assist-notes { animation: assist-notes 0.6s ease-out; }
@keyframes assist-fill { 0%, 25% { background-color: var(--assist); box-shadow: inset 0 0 0 2px var(--assist-ring); } }
@keyframes assist-notes { 0%, 25% { background-color: var(--assist-notes); } }

.notes {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  width: 100%;
  height: 100%;
  padding: 2px;
  font-size: 11.5px;
  font-weight: 500;
  color: var(--ink-soft);
}
.notes span { display: flex; align-items: center; justify-content: center; }

.big-digits .cell { font-size: 32px; }
.big-digits .notes { font-size: 13.5px; font-weight: 600; padding: 1px; }

.frame {
  --l: var(--line-strong);
  --bw: 2px; /* randdikte; het rasterlabel staat er net boven */
  position: absolute;
  width: 396px;
  height: 396px;
  border: var(--bw) solid var(--l);
  background-origin: border-box;
  background-image:
    linear-gradient(to right, transparent 131px, var(--l) 131px, var(--l) 133px, transparent 133px,
      transparent 263px, var(--l) 263px, var(--l) 265px, transparent 265px),
    linear-gradient(to bottom, transparent 131px, var(--l) 131px, var(--l) 133px, transparent 133px,
      transparent 263px, var(--l) 263px, var(--l) 265px, transparent 265px);
}

/* Volgnummer van een raster op het pad (A2), midden boven het raster: helemaal boven de rand, zodat het nooit een
   cijfer of notitie bedekt (stond eerst op de rand en hing 9 px over de bovenste rij). field.js houdt er ruimte voor
   vrij (LABEL_SPACE: 20 px label, 2 px tussenruimte, 2 px marge). */
.frame-label {
  position: absolute;
  bottom: calc(100% + var(--bw) + 2px);
  left: 50%;
  transform: translateX(-50%);
  min-width: 30px;
  height: 20px;
  padding: 0 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 10px;
  background: var(--line-strong);
  color: var(--accent-ink);
  font-size: 14px;
  font-weight: 700;
}

/* Gestempeld raster (A1): rood kader, en bij het stempelen een korte gloed plus een oplichtende teller.
   Geen zegel in het veld: dat lag over cellen, in Samusamu soms van een buurraster dat nog open was.
   Statussysteem (2026-10-03): kleur = status (rood = af, met een lichte rode waas, ook op de overzichtskaart),
   blauw = waar je bent (dunne blauwe rand met zachte gloed, zie .frame.focused). Samen rustig, nooit twee harde randen. */
.frame.stamped { --l: color-mix(in srgb, var(--seal) 80%, transparent); background-color: color-mix(in srgb, var(--seal) 7%, transparent); }
/* Slot en voortgang in het midden van Middle, leesbaar in elk zoomniveau (ook op de overzichtskaart). */
.frame.locked { --l: var(--line); }
.frame[data-lock]::after {
  content: attr(data-lock);
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  padding: 0.15em 0.55em;
  border-radius: 999px;
  background: var(--surface);
  box-shadow: 0 0 0 1px var(--line);
  color: var(--ink-soft);
  font-size: clamp(18px, calc(15px / var(--zoom, 1)), 84px);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.frame.celebrate { animation: grid-glow 1.1s ease-out; }
/* Expand regels 2: routes van het gekozen raster als gestippelde spookrasters (docs/15). Tekst en symbool dragen de
   betekenis (Easy/Medium/Hard, ⛓ Link); kleur ondersteunt alleen. Cellen van een spookraster zijn er nog niet. */
.cell.ghost { visibility: hidden; }
.frame-label:empty { display: none; }
.frame.route { --l: var(--line-strong); border-style: dashed; background-image: none; }
/* Het actieve raster in een veld met meerdere rasters: blauwe rand plus zachte gloed (ook ver uitgezoomd), boven de
   buurrasters. Een gestempeld actief raster houdt zijn rode rand; de gloed zegt dan alleen "hier ben je". */
.frame.focused:not(.route) { z-index: 1; box-shadow: 0 0 0 max(3px, calc(3px / var(--zoom, 1))) color-mix(in srgb, var(--entered) 38%, transparent); }
.frame.focused:not(.route):not(.stamped) { border-color: var(--entered); }
.frame.route.link { border-style: double; border-width: 6px; }
.route-pick, .route-note {
  position: absolute;
  inset: 10px;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 8px;
  border-radius: 12px;
  text-align: center;
}
.route-pick {
  border: 0;
  background: color-mix(in srgb, var(--surface) 82%, transparent);
  color: var(--ink);
  font: inherit;
  pointer-events: auto;
  cursor: pointer;
}
.route-pick::before { content: ''; width: 28px; height: 28px; border-radius: 50%; background: var(--dot); }
.route-pick[data-level="easy"] { --dot: #4caf50; }
.route-pick[data-level="medium"] { --dot: #f0a020; }
.route-pick[data-level="hard"] { --dot: #d84a3a; }
.route-pick strong { font-size: 72px; line-height: 1; letter-spacing: -0.01em; }
.route-pick .route-link { font-size: 34px; font-weight: 700; }
.route-pick small { font-size: 26px; color: var(--ink-soft); }
.route-pick:hover, .route-pick:focus-visible { background: color-mix(in srgb, var(--surface) 94%, transparent); outline: 3px solid var(--entered); }
.route-note { padding: 24px; color: var(--ink-soft); font-size: 30px; line-height: 1.25; }
/* Link gemaakt: de gedeelde hoekvakken lichten kort op. */
.cell.assist-link { animation: assist-link 0.9s ease-out; }
/* Link-melding achter het rasterlabel (in de vrije labelruimte boven het raster; geen toast over het label). */
.frame-flag { padding: 0 6px; border-radius: 8px; background: var(--seal); color: var(--accent-ink); animation: frame-flag 0.3s ease-out; }
@keyframes frame-flag { 0% { opacity: 0; } }
@keyframes assist-link { 0%, 35% { background-color: var(--assist); box-shadow: inset 0 0 0 3px var(--seal); } }
@keyframes grid-glow { 0% { box-shadow: 0 0 0 0 var(--seal); } 40% { box-shadow: 0 0 0 10px transparent; } }
.info.pulse { animation: info-pulse 1.2s ease-out; }
.field.zooming { transition: transform 0.35s ease-out; }
@keyframes info-pulse { 0%, 40% { color: var(--seal); } }
@keyframes stamp-in {
  0% { transform: rotate(-30deg) scale(2.2); opacity: 0; }
  100% { transform: rotate(-12deg) scale(1); opacity: 1; }
}

/* ---- paneel ------------------------------------------------------------------------------ */

.panel { display: flex; flex-direction: column; gap: 12px; }

.status { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.clock { display: flex; align-items: center; gap: 4px; }
.timer {
  border: 0;
  padding: 2px 6px;
  margin-left: -6px;
  border-radius: 8px;
  background: transparent;
  font-size: 1.4rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.timer.hidden-time { font-size: 1rem; font-weight: 500; color: var(--ink-soft); }
.info { color: var(--ink-soft); text-align: right; }

.controls { display: flex; flex-direction: column; gap: 10px; }

.pad { display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px; }
.pad button {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 56px;
  border: 0;
  border-radius: 10px;
  background: var(--button);
  font-size: 1.6rem;
  font-variant-numeric: tabular-nums;
}
.pad .count {
  position: absolute;
  top: 4px;
  right: 7px;
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--ink-soft);
}
.pad button.done { color: var(--ink-soft); opacity: 0.4; }
.pad button.armed { background: var(--accent); color: var(--accent-ink); }
.pad button.armed .count { color: inherit; }
.notes-mode .pad button:not(.erase) .digit { font-size: 1.15rem; color: var(--entered); }
.notes-mode .pad button.noted { box-shadow: inset 0 0 0 2px var(--entered); background: var(--same); }
.big-digits .pad button { font-size: 1.9rem; }

.tools { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
.tools button {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  min-height: 54px;
  padding: 4px 2px;
  border: 0;
  border-radius: 10px;
  background: var(--button);
  font-size: 0.8rem;
}
.tools button[aria-pressed="true"] { background: var(--accent); color: var(--accent-ink); }

.pad button:active, .tools button:active, .modes button:active, .segmented button:active,
.parts button:active, .zoom button:active, .chip:active, .icon-button:active { background: var(--button-active); }

/* Resultaatkaart na een winst. */
.result {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 16px;
  border-radius: 14px;
  background: var(--surface);
  border: 1px solid var(--line);
}
.result-head { display: flex; align-items: center; gap: 14px; }
.seal {
  flex: none;
  width: 52px;
  height: 52px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 3px solid var(--seal);
  border-radius: 50%;
  color: var(--seal);
  font-size: 28px;
  font-weight: 700;
  transform: rotate(-12deg);
}
.result.fresh .seal { animation: stamp-in 0.5s cubic-bezier(0.2, 1.4, 0.4, 1); }
.result-title { margin: 0; font-size: 1.35rem; font-weight: 700; }
.result-text { margin: 2px 0 0; color: var(--ink-soft); }
.result-rows { display: grid; grid-template-columns: max-content 1fr; gap: 8px 16px; margin: 0; }
.result-rows dt.full { grid-column: 1 / -1; color: var(--ok); font-weight: 600; }
.result-rows dt { color: var(--ink-soft); }
.result-rows dd { margin: 0; font-weight: 600; text-align: right; }
.result-rows small { display: block; margin-top: 2px; font-weight: 400; font-size: 0.82rem; color: var(--ink-soft); }
.badge {
  display: inline-block;
  padding: 1px 8px;
  border-radius: 9px;
  background: var(--seal);
  color: var(--accent-ink);
  font-size: 0.75rem;
  font-weight: 700;
  vertical-align: 1px;
}
.result-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.result-actions button { min-height: 44px; padding: 0 12px; border: 0; border-radius: 10px; background: var(--button); }
.result-actions .primary { background: var(--accent); color: var(--accent-ink); }

.help { margin: 0; font-size: 0.85rem; color: var(--ink-soft); }
/* Ook onder 860 px, met of zonder muis: de telefoonindeling hieronder rekent zonder deze regel. */
@media (hover: none), (max-width: 859px) { .help { display: none; } }

@media (max-width: 859px) {
  /* Telefoon: raster bovenaan, de bediening er direct onder (één speeloppervlak). Vrije hoogte
     blijft onder de bediening; een groot veld (Uitbreidbaar, Samusamu) vult zelf de hoogte. */
  .play { display: flex; flex-direction: column; align-items: stretch; flex: 1; }
  .panel { width: 100%; }
  /* Meer breedte voor het speelveld: 10 px zijrand (was 16) en maar 3 px rand binnen een vierkant veld
     (was 12; panzoom.js leest --fit-pad). Ingezoomd op een deel van een groot veld 6 px (was 10). */
  .app { padding-left: max(10px, env(safe-area-inset-left)); padding-right: max(10px, env(safe-area-inset-right)); }
  .viewport.square { --fit-pad: 3px; }
  .viewport.pannable { --zoom-pad: 6px; }
  /* Hoogte naast het raster: kop, paneel en onderbalk samen 345 px (gemeten), plus 16 px marge en
     de veilige onderrand. Meer reserveren liet op hoge schermen een gat van 100 px of meer.
     Ondergrens 240 px (cellen van ongeveer 26 px): op een heel kort scherm (360×560) blijft het raster
     bruikbaar en scrolt de pagina naar de bediening; de onderrand van .app (80 px) houdt die boven de
     onderbalk. */
  .viewport.square { max-width: min(100%, max(240px, calc(100dvh - 297px - env(safe-area-inset-bottom)))); }
  .play { gap: 10px; }
  .panel { gap: 8px; }
  .status .timer { font-size: 1.2rem; }
  .pad { gap: 6px; }
  .pad button { min-height: 48px; font-size: 1.45rem; }
  .big-digits .pad button { font-size: 1.7rem; }
  .tools { gap: 6px; }
  .tools button { min-height: 50px; }
}

/* ---- schermen (dialogen) ----------------------------------------------------------------- */

.sheet {
  width: min(560px, calc(100% - 32px));
  max-height: calc(100dvh - 48px);
  border: 0;
  border-radius: 14px;
  padding: 16px;
  background: var(--surface);
  color: var(--ink);
}
.sheet::backdrop { background: var(--backdrop); }
.sheet[open] { animation: sheet-in 0.18s ease-out; }
@keyframes sheet-in { from { opacity: 0; transform: translateY(8px); } }
.sheet-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 4px; }
.sheet h2 { margin: 0; font-size: 1.3rem; }
.sheet-text { margin: 4px 0 12px; color: var(--ink-soft); }

.levels { display: grid; gap: 8px; }

/* Continue (opslag v3): compacte regels, op een telefoon goed passend; per regel openen en verwijderen. Op Home één
   regel (met ›) en "View all"; de volledige lijst staat in een eigen sheet. */
.home-continue, .continue-block { display: grid; gap: 8px; margin: 0 0 16px; }
.home-continue { margin: 0; }
/* Kop altijd zo hoog als de chip: Home verspringt niet als "View all" erbij komt. */
.continue-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-width: 0; min-height: 34px; }
.home-continue h3, .continue-block h3 { margin: 0; font-size: 0.95rem; }
.continue-head .chip { flex: none; min-height: 34px; padding: 0 12px; font-size: 0.9rem; }
.continue-list { display: grid; gap: 6px; }
.continue-row { display: flex; align-items: center; gap: 6px; }
.continue-open {
  flex: 1;
  min-width: 0;
  display: grid;
  gap: 2px;
  padding: 8px 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--surface);
  color: var(--ink);
  text-align: left;
}
.continue-open strong { font-size: 0.95rem; overflow-wrap: anywhere; }
.continue-open small { color: var(--ink-soft); overflow-wrap: anywhere; }
.continue-delete { flex: none; }
/* Expand van een nieuwere versie: leesbaar, maar duidelijk niet te openen. */
.continue-open:disabled { border-style: dashed; background: transparent; cursor: default; opacity: 1; }
.continue-open:disabled .continue-go { visibility: hidden; }
.continue-open.compact { grid-template-columns: minmax(0, 1fr) auto; column-gap: 8px; }
.continue-open.compact .continue-go { grid-row: 1 / span 2; grid-column: 2; align-self: center; color: var(--ink-soft); font-size: 1.4rem; line-height: 1; }
.continue-block > .chip { justify-self: start; }
#continue-dialog .continue-list { margin-top: 4px; }
.level {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  width: 100%;
  padding: 12px 14px;
  border: 2px solid transparent;
  border-radius: 12px;
  background: var(--button);
  text-align: left;
}
.level strong { font-size: 1.05rem; }
.level small { color: var(--ink-soft); }
.level.current { border-color: var(--entered); }

.intro-art { display: flex; justify-content: center; margin: 8px 0; color: var(--seal); }
.intro-art .fill { fill: currentColor; }

#archive-body h3 { margin: 14px 0 6px; font-size: 1rem; }
/* Kolommen mogen smaller worden dan hun tekst (minmax(0, 1fr)); zo duwt "Medium ✓" in vet de rij niet
   buiten de dialoog. Is de lijst smal (in rem, dus ook bij grotere systeemletters), dan staat de datum
   boven de drie niveaus. Een label dat dan nog niet past, loopt door op een tweede regel. */
.archive-list { list-style: none; margin: 0; padding: 0; container: archive / inline-size; }
.archive-list li {
  display: grid;
  grid-template-columns: minmax(6.5rem, auto) repeat(3, minmax(0, 1fr));
  align-items: center;
  gap: 6px;
  padding: 4px 0;
  border-bottom: 1px solid var(--line);
}
.archive-list li:has(> :nth-child(2):last-child) { grid-template-columns: minmax(6.5rem, auto) minmax(0, 1fr); }
@container archive (max-width: 24rem) {
  .archive-list li:has(> :nth-child(4)) { grid-template-columns: repeat(3, minmax(0, 1fr)); row-gap: 2px; padding-top: 6px; }
  .archive-list li:has(> :nth-child(4)) .archive-date { grid-column: 1 / -1; }
}
.archive-date { color: var(--ink-soft); font-size: 0.9rem; }
.archive-rules { display: block; font-size: 0.75rem; line-height: 1.2; }
.archive-date.complete { color: var(--ok); font-weight: 600; }
.archive-pick {
  min-height: 34px;
  padding: 2px 6px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: transparent;
  font-size: 0.85rem;
  line-height: 1.2;
  overflow-wrap: anywhere;
}
.archive-pick.solved { border-color: var(--ok); color: var(--ok); font-weight: 600; }
.archive-pick.started { border-style: dashed; border-color: var(--entered); color: var(--entered); }
.archive-pick[aria-current="true"] { background: var(--selected); color: var(--ink); }

.setting {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 14px 0;
  border-bottom: 1px solid var(--line);
}
.setting.stacked { flex-direction: column; align-items: stretch; gap: 10px; border-bottom: 0; }
/* Appearance: past de keuze niet naast het label (grote letters), dan eronder; op een telefoon altijd eronder, over de
   volle breedte, zoals de niveaukeuze. */
.setting.theme { flex-wrap: wrap; row-gap: 10px; }
@media (max-width: 440px) {
  /* Geen wrap in de kolom: dan rekt alles mee met de kaart in plaats van met de breedste inhoud. */
  .setting.theme { flex-direction: column; flex-wrap: nowrap; align-items: stretch; gap: 10px; }
  .setting.theme .segmented button { min-width: 0; padding: 0 4px; }
}
.setting > span { display: flex; flex-direction: column; gap: 2px; }
.setting small { color: var(--ink-soft); font-size: 0.85rem; }
.backup { display: flex; flex-wrap: wrap; gap: 8px; }

.switch {
  appearance: none;
  flex: none;
  position: relative;
  width: 46px;
  height: 28px;
  margin: 0;
  border-radius: 14px;
  background: var(--button-active);
  cursor: pointer;
  transition: background 0.15s;
}
.switch::before {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--surface);
  box-shadow: 0 1px 2px var(--shadow);
  transition: transform 0.15s;
}
.switch:checked { background: var(--entered); }
.switch:checked::before { transform: translateX(18px); }
.switch:focus-visible { outline: 2px solid var(--entered); outline-offset: 2px; }

.stats h3 { margin: 16px 0 6px; font-size: 1.05rem; }
.stats p { margin: 0 0 6px; color: var(--ink-soft); }
.stats table { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; font-size: 0.95rem; }
.stats abbr { text-decoration: none; }
.stats small { display: block; font-weight: 400; font-size: 0.8rem; color: var(--ink-soft); }
.stats .log th[scope="row"] { font-weight: 600; }
.stats details { margin-top: 4px; }
.stats summary { cursor: pointer; color: var(--entered); }
.stats th, .stats td { padding: 6px 4px; text-align: right; border-bottom: 1px solid var(--line); }
.stats th:first-child { text-align: left; }
.stats thead th { color: var(--ink-soft); font-weight: 500; font-size: 0.9rem; }

/* Puzzel wordt gemaakt: rustig, zonder voortgangsbalk; blokkeert klikken op de app eronder. */
.loading {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: grid;
  place-items: center;
  padding: 16px;
  background: color-mix(in srgb, var(--bg) 70%, transparent);
}
.loading[hidden] { display: none; }
.loading-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  width: min(100%, 320px);
  padding: 20px;
  border-radius: 14px;
  background: var(--surface);
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.18);
  text-align: center;
}
.loading-text { margin: 0; font-size: 1.05rem; }
.loading-actions { display: flex; gap: 8px; }
.loading-actions button { min-height: 44px; padding: 0 16px; border: 0; border-radius: 10px; background: var(--button); }
.loading-actions .primary { background: var(--accent); color: var(--accent-ink); }
.loading.failed .spinner { display: none; }
.spinner {
  width: 28px;
  height: 28px;
  border: 3px solid var(--line);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.9s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
  .speed-delta.show { opacity: 1; } /* zonder animatie: even zichtbaar, main.js haalt het weg */
  /* Assist-feedback zonder animatie: even een vaste kleur (main.js haalt de klasse weg). */
  .cell.assist-fill { background-color: var(--assist); box-shadow: inset 0 0 0 2px var(--assist-ring); }
  .cell.assist-notes { background-color: var(--assist-notes); }
  .cell.assist-link { background-color: var(--assist); box-shadow: inset 0 0 0 3px var(--seal); }
}

/* Tussen 860 en 960 px: twee kolommen, maar de balk met spelvormen staat onderaan. */
@media (min-width: 860px) and (max-width: 959px) {
  .viewport.pannable { height: min(75dvh, max(320px, calc(100dvh - 236px))); }
}
@media (max-width: 859px) {
  .viewport.pannable { height: max(220px, calc(100dvh - 346px - env(safe-area-inset-bottom))); }
  /* Vandaag heeft een extra regel met keuzes. */
  .has-choices .viewport.pannable { height: max(170px, calc(100dvh - 402px - env(safe-area-inset-bottom))); }
  /* Vandaag: 54 px extra voor de rij met keuzes (gemeten 399 px naast het raster), plus ruimte voor
     een statusregel die in het Nederlands over twee regels loopt. Ondergrens 220 px (cellen van
     ongeveer 24 px): het grootste raster dat op 360×640 nog zonder scroll past. */
  .has-choices .viewport.square { max-width: min(100%, max(220px, calc(100dvh - 356px - env(safe-area-inset-bottom)))); }
}

/* ---- over, melding onderaan, privacypagina ------------------------------------------------ */

.setting.about { border-top: 1px solid var(--line); padding-top: 14px; }
.about-links { display: flex; flex-wrap: wrap; gap: 6px 16px; margin: 0; }
.about a, .doc-page a { color: var(--entered); text-underline-offset: 2px; }

.notice {
  position: fixed;
  left: 50%;
  bottom: 16px;
  z-index: 7;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 12px;
  width: min(560px, calc(100% - 24px));
  padding: 12px 12px 12px 16px;
  border-radius: 12px;
  background: var(--surface);
  color: var(--ink);
  border: 1px solid var(--line);
  box-shadow: 0 4px 16px var(--shadow);
  animation: notice-in 0.2s ease-out;
}
@keyframes notice-in { from { opacity: 0; transform: translate(-50%, 8px); } }
.notice[hidden] { display: none; }
.notice p { flex: 1; margin: 0; font-size: 0.92rem; line-height: 1.4; }
.notice-actions { display: flex; align-items: center; gap: 6px; }
.notice .primary { white-space: nowrap; }
@media (max-width: 959px) {
  .notice { bottom: calc(16px + env(safe-area-inset-bottom)); }
}
@media (max-width: 520px) {
  .notice { flex-direction: column; align-items: stretch; }
  .notice-actions { justify-content: flex-end; }
}

.doc-page { max-width: 720px; margin: 0 auto; padding: 24px 16px 64px; line-height: 1.55; }
.doc-page .brand { margin-bottom: 8px; }
.doc-page h2 { margin-top: 2em; }
.doc-page h3 { margin-top: 1.5em; font-size: 1.05rem; }
.doc-page ul { padding-left: 20px; }
.doc-page li { margin: 4px 0; }
.doc-page .meta { color: var(--ink-soft); font-size: 0.9rem; }
.doc-page nav { display: flex; flex-wrap: wrap; gap: 8px 16px; margin: 12px 0 0; }

/* Overzichtskaart van een groot veld op kleine schermen (klasse "overview" uit panzoom.js):
   dikke kaders per 9×9, gedeelde blokken getint, cijfers en notities weg (te klein om te lezen).
   De puzzel zelf verandert niet; inzoomen (tik, deelknop of knijpen) toont alles weer. */
@media (max-width: 859px) {
  .viewport.overview .cell { color: transparent; border-color: transparent; }
  .viewport.overview .cell .notes { visibility: hidden; }
  .viewport.overview .cell.shared { background: var(--line); }
  .viewport.overview .frame {
    --bw: max(2px, calc(2.5px / var(--zoom, 1)));
    background-image: none;
  }
}

/* ---- Speed Mode (E35) ----------------------------------------------------------------------- */

.speed-board {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-columns: repeat(9, 1fr);
  grid-template-rows: repeat(9, 1fr);
  border: 2px solid var(--line-strong);
  background: var(--locked);
  container-type: size;
}
.speed-cell {
  display: flex;
  align-items: center;
  justify-content: center;
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  font-size: 20px;
  font-size: 6.2cqw;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}
.speed-cell:nth-child(9n) { border-right: 0; }
.speed-cell:nth-child(n + 73) { border-bottom: 0; }
.speed-cell.br { border-right: 2px solid var(--line-strong); }
.speed-cell.bb { border-bottom: 2px solid var(--line-strong); }
.speed-cell.active { background: var(--surface); }
.speed-cell.target { background: var(--selected); box-shadow: inset 0 0 0 3px var(--entered); }
.speed-cell.target.wrong { background: var(--conflict-bg); color: var(--conflict-ink); box-shadow: inset 0 0 0 3px var(--conflict-ink); }
.speed-board.good { box-shadow: 0 0 0 3px var(--ok); }
.speed-board.bad { animation: speed-shake 0.25s ease-in-out; }
@keyframes speed-shake { 25% { transform: translateX(-6px); } 75% { transform: translateX(6px); } }

.speed-cover {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  padding: 16px;
  text-align: center;
  background: var(--overlay);
}
.speed-cover .result { width: min(100%, 340px); text-align: left; }
.speed-lead { margin: 0; max-width: 30ch; font-size: 1.05rem; }
#speed-go { min-width: 160px; min-height: 52px; font-size: 1.1rem; }

.speed-stats { display: flex; justify-content: space-between; gap: 12px; }
.speed-stat { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.speed-stat > span { color: var(--ink-soft); font-size: 0.85rem; }
.speed-stat strong { font-size: 1.5rem; font-variant-numeric: tabular-nums; }
.speed-stat:nth-child(2), .speed-stat:nth-child(3) { align-items: center; }
.speed-stat:last-child { align-items: flex-end; }
.speed-stat.quiet strong { color: var(--ink-soft); font-weight: 500; }
#speed-time.ending { color: var(--seal); }
/* Tijd erbij of eraf: klein label naast de klok, zonder de indeling te verschuiven. */
.speed-clock { position: relative; }
.speed-delta { position: absolute; left: 100%; top: 0.1em; margin-left: 4px; font-size: 0.85rem; font-weight: 600; opacity: 0; pointer-events: none; }
.speed-delta.plus { color: var(--ok); }
.speed-delta.minus { color: var(--conflict-ink); }
.speed-delta.show { animation: speed-delta 0.7s ease-out; }
@keyframes speed-delta { 0% { opacity: 1; transform: translateY(0); } 60% { opacity: 1; } 100% { opacity: 0; transform: translateY(-6px); } }
#speed-score.pop { animation: speed-pop 0.3s ease-out; color: var(--ok); }
@keyframes speed-pop { 40% { transform: scale(1.25); } }
.speed-pad button:disabled { opacity: 0.45; }

/* Speed op de telefoon (09-progressie-v2.md §3): geen gereedschapsrij, dus een eigen hoogteregel. De
   waarden en het cijferpaneel staan onderaan (duimzone); het bord staat midden in de ruimte erboven.
   Knoppen groeien mee als er hoogte over is (48–64 px); het bord wordt niet groter dan de breedte.
   316 px = kop, waarden, paneel met 48 px-knoppen, tussenruimtes en onderbalk (gemeten op 360×560). */
@media (max-width: 859px) {
  .play.speed { --speed-key: clamp(48px, calc(48px + (100dvh - 636px) / 5), 64px); }
  .play.speed .stage { flex: 1 0 auto; justify-content: center; }
  .play.speed .viewport.square {
    max-width: min(100%, max(220px, calc(100dvh - 252px - 2 * (var(--speed-key) - 48px) - env(safe-area-inset-bottom))));
  }
  .play.speed .pad button { min-height: var(--speed-key); }
}

/* Samusamu op de telefoon: overzichtsknop met voortgang vóór de deelknoppen; het actieve raster
   is in de overzichtskaart gemarkeerd. */
#grid-overview { flex: none; white-space: nowrap; }
/* Zelfde taal als ingezoomd (blauwe rand + zachte gloed), iets breder zodat hij op de kaart vindbaar blijft. */
.viewport.overview .frame.focused { box-shadow: 0 0 0 max(3px, calc(5px / var(--zoom, 1))) color-mix(in srgb, var(--entered) 45%, transparent); }

/* Home: spelvormen als grote tegels; Home-knop alleen onder 960 px in een spel. */
.home { display: flex; flex-direction: column; gap: 14px; }
.home h2 { margin: 4px 0 0; font-size: 1.3rem; }
.home-xp { margin: -8px 0 0; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
/* Rank v2: rang prominent, XP eronder, vier segmenten naar de volgende rang, poortregels. */
.stats .rank-name { margin: 0; color: var(--ink); font-size: 1.5rem; font-weight: 700; line-height: 1.2; overflow-wrap: anywhere; }
.stats .rank-name + .xp-total { margin-top: 2px; }
.stats .rank-bar { display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px; max-width: 320px; margin: 6px 0 4px; }
.stats .rank-bar span { height: 8px; border-radius: 4px; background: var(--line); }
.stats .rank-bar span.on { background: var(--seal); }
.stats .rank-next { margin: 0 0 4px; font-variant-numeric: tabular-nums; }
.stats .rank-gate { display: flex; flex-wrap: wrap; gap: 2px 16px; margin: 0 0 4px; font-variant-numeric: tabular-nums; }
.stats .xp-total { margin: 0 0 6px; font-size: 1.15rem; font-variant-numeric: tabular-nums; }
/* Assists: keuzedialoog en de slotregel in Instellingen. */
.assist-options { display: grid; gap: 8px; margin: 8px 0 12px; }
.assist-option {
  display: grid; gap: 2px; text-align: left; padding: 10px 12px; border: 1px solid var(--line); border-radius: 10px;
  background: var(--surface); color: var(--ink); font: inherit;
}
.assist-option small { color: var(--ink-soft); }
.assist-setting .assist-lock { color: var(--ink-soft); font-style: italic; }
.stats .progress-counts { display: flex; flex-wrap: wrap; gap: 4px 16px; margin: 0 0 8px; font-variant-numeric: tabular-nums; }
.stats .xp-note { margin: 6px 0 0; color: var(--ink-soft); font-size: 0.9rem; }
.home-modes { display: grid; gap: 10px; }
.home-modes button {
  display: flex;
  align-items: center;
  gap: 14px;
  min-height: 64px;
  padding: 12px 18px;
  border: 0;
  border-radius: 12px;
  background: var(--button);
  font-size: 1.15rem;
  font-weight: 600;
  text-align: left;
}
.home-modes button svg { flex: none; color: var(--seal); }
.home-modes button:focus-visible, #go-home:focus-visible { outline: 3px solid var(--entered); outline-offset: 2px; }
@media (min-width: 960px) { #go-home, .home { display: none !important; } }
