/* page basics */
:root{color-scheme:light;box-sizing:border-box;padding-top:env(safe-area-inset-top,0px);padding-bottom:env(safe-area-inset-bottom,0px)}
html{scroll-padding-top:env(safe-area-inset-top,0px)}
body{margin:0;padding:0;font:14px -apple-system,BlinkMacSystemFont,sans-serif;background:#faf9f5;color:#141413}
img{max-width:100%}
[hidden]:not([hidden=until-found i]){display:none!important}

/* Themes, picked in the settings popup and stored as <html data-theme>:
   light (기본) — black & white; the only colours kept are red (locks, rule violations)
     and blue (the "correct" result banner)
   dark (다크) — the same, inverted around the board
   With no data-theme at all the page follows the system light/dark preference. */
:root{
  --paper:#FFFFFF;
  --paper-raised:#F6F6F6;
  --ink:#111111;
  --line:#BDBDBD;
  --line-soft:#E2E2E2;
  --accent:#111111;
  --accent-strong:#000000;
  --accent-soft:#EBEBEB;
  --muted:#6E6E6E;
  --danger:#D32F2F;
  --danger-soft:#FDE8E8;
  --correct:#1E5BD8;
  --correct-soft:#E7EEFC;
  --fixed:#5C5C5C;
  /* the board is black-on-white here; dark mode inverts it (black grid, white doors) */
  --board-paper:#FFFFFF;
  --board-ink:#111111;
  --board-line:#BDBDBD;
  --board-hover:#E6E6E6;
  --board-mark:#C4C4C4;
  --font-display:'IBM Plex Serif', Georgia, serif;
  --font-body:'IBM Plex Sans KR','IBM Plex Sans',system-ui,sans-serif;
  --font-mono:'IBM Plex Mono',ui-monospace,monospace;
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme]){
    --paper:#0E0E0E;
    --paper-raised:#1A1A1A;
    --ink:#F2F2F2;
    --line:#474747;
    --line-soft:#2B2B2B;
    --accent:#F2F2F2;
    --accent-strong:#FFFFFF;
    --accent-soft:#2A2A2A;
    --muted:#9A9A9A;
    --danger:#FF5C5C;
    --danger-soft:#3A1A1A;
    --correct:#6EA0FF;
    --correct-soft:#15213A;
    --fixed:#7A7A7A;
    --board-paper:#111111;
    --board-ink:#D9D9D9;
    --board-line:#3C3C3C;
    --board-hover:#262626;
    --board-mark:#A6A6A6;
    --board-frame:#6A6A6A;
  }
}
:root[data-theme="dark"]{
  color-scheme:dark;
  --paper:#0E0E0E;
  --paper-raised:#1A1A1A;
  --ink:#F2F2F2;
  --line:#474747;
  --line-soft:#2B2B2B;
  --accent:#F2F2F2;
  --accent-strong:#FFFFFF;
  --accent-soft:#2A2A2A;
  --muted:#9A9A9A;
  --danger:#FF5C5C;
  --danger-soft:#3A1A1A;
  --correct:#6EA0FF;
  --correct-soft:#15213A;
  --fixed:#7A7A7A;
  --board-paper:#111111;
  --board-ink:#D9D9D9;
  --board-line:#3C3C3C;
  --board-hover:#262626;
  --board-mark:#A6A6A6;
  --board-frame:#6A6A6A;
}
/* rococo: pastel pink, ivory and gold, with a gilded double frame round the board */
:root[data-theme="rococo"]{
  --paper:#FBEAF0;
  --paper-raised:#F7DDE6;
  --ink:#5B2E3C;
  --line:#E3AF26;
  --line-soft:#F1D6DF;
  --accent:#D69C0E;
  --accent-strong:#AE7C06;
  --accent-soft:#FBEBC2;
  --muted:#9A6C7C;
  --danger:#D32F2F;
  --danger-soft:#FBDADA;
  --correct:#C98F08;
  --correct-soft:#FBEFCC;
  --fixed:#F2C12E;
  --fixed-text:#5B2E3C;
  --board-paper:#FFFBF2;
  --board-ink:#EC9DB8;
  --board-line:#F0DCA8;
  --board-hover:#FDF1F4;
  --board-mark:#F1DCC4;
  --board-frame:#D69C0E;
  --title-door:#EC9DB8;
}
:root[data-theme="rococo"] .board{ box-shadow:0 0 0 4px var(--paper), 0 0 0 5.5px #E3AF26; }
/* ivory (shown as "모던 / Modern"): a clean interior of ivory walls and soft beige */
:root[data-theme="ivory"]{
  --paper:#FBF8F1;
  --paper-raised:#F4EEE3;
  --ink:#4A4038;
  --line:#DCCFBB;
  --line-soft:#ECE4D6;
  --accent:#8C7760;
  --accent-strong:#6E5C49;
  --accent-soft:#EFE7DA;
  --muted:#9A8D7E;
  --danger:#C8553D;
  --danger-soft:#F8E4DE;
  --correct:#5B7F95;
  --correct-soft:#E6EEF2;
  --fixed:#D3C3A8;
  --fixed-text:#4A4038;
  --board-paper:#FFFDF8;
  --board-ink:#8C7760;
  --board-line:#E3D8C6;
  --board-hover:#F3ECE0;
  --board-mark:#E6DDCE;
  --board-frame:#BFAE95;
  --title-door:#8C7760;
}
/* mediterranean (Santorini): whitewashed rooms on ivory floors, vivid cobalt doors */
:root[data-theme="med"]{
  --paper:#FBFAF6;
  --paper-raised:#F1EDE4;
  --ink:#1D355A;
  --line:#C5D3E4;
  --line-soft:#E6ECF3;
  --accent:#1E5AA8;
  --accent-strong:#154684;
  --accent-soft:#E3ECF7;
  --muted:#6D7F99;
  --danger:#D23B2E;
  --danger-soft:#FBE3DF;
  --correct:#1E5AA8;
  --correct-soft:#E3ECF7;
  --fixed:#FFFFFF;
  --fixed-text:#1D355A;
  --board-paper:#FFF8DC;
  --board-ink:#0052E0;
  --board-line:#DCD4C4;
  --board-hover:#FAEDC0;
  --board-mark:#E2DBCD;
  --board-frame:#0052E0;
  --title-door:#0052E0;
}
/* cyberpunk: black base, neon light, brushed metal */
:root[data-theme="cyber"]{
  color-scheme:dark;
  --paper:#07070D;
  --paper-raised:#10111B;
  --ink:#E4F6FF;
  --line:#3A4058;
  --line-soft:#1A1D2B;
  --accent:#00E5FF;
  --accent-strong:#5CF2FF;
  --accent-soft:#0B2530;
  --muted:#8C95AD;
  --danger:#FF2E4D;
  --danger-soft:#3A0B16;
  --correct:#39FF88;
  --correct-soft:#0B2A18;
  --fixed:#262B3B;
  --fixed-text:#FF3CD8;
  --board-paper:#12141F;
  --board-ink:#00E5FF;
  --board-line:#2C3246;
  --board-hover:#1C2030;
  --board-mark:#3A4260;
  --board-frame:#FF3CD8;
  --title-door:#00E5FF;
}
:root[data-theme="cyber"] .board{ box-shadow:0 0 14px rgba(255,60,216,.55), 0 0 30px rgba(0,229,255,.18); }

/* ---- special themes: decorative page backgrounds (fixed layers behind the content) ---- */
:root[data-theme="med"] body::before,
:root[data-theme="rococo"] body::before,
:root[data-theme="cyber"] body::before{
  content:'';
  position:fixed;
  inset:0;
  z-index:-1;
  pointer-events:none;
}
/* mediterranean: morning sun and sea waves along the bottom */
:root[data-theme="med"] body::before{
  background:
    radial-gradient(circle at 88% 6%, rgba(255,205,100,.38), rgba(255,205,100,0) 26%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='80' viewBox='0 0 240 80'%3E%3Cpath d='M0 30 Q30 12 60 30 T120 30 T180 30 T240 30 V80 H0Z' fill='%231E5AA8' fill-opacity='.10'/%3E%3Cpath d='M0 48 Q30 32 60 48 T120 48 T180 48 T240 48 V80 H0Z' fill='%231E5AA8' fill-opacity='.14'/%3E%3C/svg%3E") repeat-x left bottom / 240px 80px,
    linear-gradient(#FBFAF6 0%, #F4F7FB 60%, #E4EEF9 100%);
}
/* rococo: gilded lattice ornament over soft pink glows */
:root[data-theme="rococo"] body::before{
  background:
    radial-gradient(ellipse at 15% 10%, rgba(255,255,255,.75), rgba(255,255,255,0) 40%),
    radial-gradient(ellipse at 85% 90%, rgba(236,157,184,.35), rgba(236,157,184,0) 45%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='64' height='64' viewBox='0 0 64 64'%3E%3Cg fill='none' stroke='%23D69C0E' stroke-opacity='.28' stroke-width='1.1'%3E%3Cpath d='M32 2 L62 32 L32 62 L2 32 Z'/%3E%3Cpath d='M32 22c4 4 4 6 0 10c-4-4-4-6 0-10zM32 42c4-4 4-6 0-10c-4 4-4 6 0 10zM22 32c4-4 6-4 10 0c-4 4-6 4-10 0zM42 32c-4-4-6-4-10 0c4 4 6 4 10 0z'/%3E%3C/g%3E%3Ccircle cx='32' cy='32' r='1.6' fill='%23D69C0E' fill-opacity='.35'/%3E%3Ccircle cx='0' cy='0' r='2' fill='%23EC9DB8' fill-opacity='.45'/%3E%3Ccircle cx='64' cy='0' r='2' fill='%23EC9DB8' fill-opacity='.45'/%3E%3Ccircle cx='0' cy='64' r='2' fill='%23EC9DB8' fill-opacity='.45'/%3E%3Ccircle cx='64' cy='64' r='2' fill='%23EC9DB8' fill-opacity='.45'/%3E%3C/svg%3E") repeat center / 64px 64px,
    #FBEAF0;
}
/* cyberpunk: neon horizon glow and a receding grid floor, plus faint scanlines on top */
:root[data-theme="cyber"] body::before{
  background:
    radial-gradient(ellipse at 50% 100%, rgba(255,60,216,.28), rgba(255,60,216,0) 55%),
    radial-gradient(ellipse at 50% 0%, rgba(0,229,255,.12), rgba(0,229,255,0) 45%),
    #07070D;
}
:root[data-theme="cyber"] body::after{
  content:'';
  position:fixed;
  left:-50%;
  right:-50%;
  top:55vh;
  height:60vh;
  z-index:-1;
  pointer-events:none;
  background-image:
    linear-gradient(rgba(0,229,255,.5) 1.5px, transparent 1.5px),
    linear-gradient(90deg, rgba(255,60,216,.45) 1.5px, transparent 1.5px);
  background-size:56px 56px;
  transform:perspective(260px) rotateX(60deg);
  transform-origin:50% 0;
  -webkit-mask-image:linear-gradient(transparent, #000 35%);
  mask-image:linear-gradient(transparent, #000 35%);
  animation:cyber-grid 3s linear infinite;
}
:root[data-theme="cyber"] .page::after{
  content:'';
  position:fixed;
  inset:0;
  z-index:60;
  pointer-events:none;
  background:repeating-linear-gradient(rgba(255,255,255,.025) 0 1px, transparent 1px 3px);
}
@keyframes cyber-grid{ to{ background-position:0 56px, 0 0; } }
@media (prefers-reduced-motion: reduce){
  :root[data-theme="cyber"] body::after{ animation:none; }
}

body{
  background:var(--paper);
  color:var(--ink);
  font-family:var(--font-body);
  padding:32px 16px 40px;
  display:flex;
  justify-content:center;
}

.page{
  width:100%;
  max-width:640px;
  display:flex;
  flex-direction:column;
  gap:20px;
}

header.top{
  position:relative;
  border-bottom:1px solid var(--line);
  padding:8px 44px 16px;
  text-align:center;
  display:flex;
  flex-direction:column;
}
/* settings button: top-right corner of the title section */
.settings-btn{ position:absolute; top:0; right:0; }
.icon-round-btn.settings-btn{ border:none; }
.icon-round-btn{
  width:36px;
  height:36px;
  padding:0;
  border-radius:999px;
  border:1px solid var(--line);
  background:transparent;
  color:var(--ink);
  display:inline-flex;
  align-items:center;
  justify-content:center;
  cursor:pointer;
}
.icon-round-btn svg{ width:20px; height:20px; stroke:currentColor; fill:none; stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round; }

/* ---- settings popup ---- */
.modal-backdrop{
  position:fixed;
  inset:0;
  background:rgba(0,0,0,.45);
  display:flex;
  align-items:center;
  justify-content:center;
  padding:16px;
  z-index:50;
}
.modal{
  position:relative;
  width:min(340px,100%);
  background:var(--paper);
  color:var(--ink);
  border:1px solid var(--line);
  border-radius:12px;
  padding:22px 20px 20px;
  box-shadow:0 12px 40px rgba(0,0,0,.25);
}
.modal h2{
  margin:0 0 16px;
  text-align:center;
  font-family:var(--font-display);
  font-size:24px;
  font-weight:600;
}
.modal-close{ position:absolute; top:10px; right:10px; width:32px; height:32px; border:none; }
.setting-row{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:12px;
  padding:12px 0;
  border-top:1px solid var(--line-soft);
  font-size:15px;
}
.setting-row label, .setting-row .setting-label{ font-weight:600; }
.stepper{ display:inline-flex; align-items:center; gap:10px; }
.stepper button{
  width:32px; height:32px;
  border-radius:8px;
  border:1px solid var(--line);
  background:var(--paper);
  color:var(--ink);
  font-size:18px;
  line-height:1;
  cursor:pointer;
}
.stepper button:disabled{ opacity:.35; cursor:default; }
.sound-bar{ display:inline-flex; gap:4px; }
.stepper .sound-seg{
  width:14px;
  height:22px;
  padding:0;
  border-radius:3px;
  border:1.5px solid var(--ink);
  background:transparent;
  cursor:pointer;
}
.stepper .sound-seg.on{ background:var(--ink); }
.stepper{ gap:8px; }
/* theme picker: each option is a square board cell with a right-half door in that
   theme's own colours (fixed, so they look the same whatever theme is active) */
.theme-options{ display:grid; grid-template-columns:repeat(3, 34px); gap:10px; }
.theme-swatch{
  position:relative;
  width:34px;
  height:34px;
  padding:0;
  border-radius:6px;
  border:1px solid var(--line);
  overflow:hidden;
  cursor:pointer;
}
.theme-swatch span{ position:absolute; top:0; right:0; bottom:0; width:50%; }
.theme-swatch-light{ background:#FFFFFF; }
.theme-swatch-light span{ background:#111111; }
.theme-swatch-dark{ background:#0E0E0E; border-color:#474747; }
.theme-swatch-dark span{ background:#EDEDED; }
.theme-swatch-rococo{ background:#FFFBF2; border-color:#E3AF26; border-width:2px; }
.theme-swatch-rococo span{ background:#EC9DB8; }
.theme-swatch-ivory{ background:#FFFDF8; border-color:#DCCFBB; }
.theme-swatch-ivory span{ background:#8C7760; }
.theme-swatch-med{ background:#FFF8DC; border-color:#C5D3E4; }
.theme-swatch-med span{ background:#0052E0; }
.theme-swatch-cyber{ background:#12141F; border-color:#FF3CD8; box-shadow:0 0 6px rgba(255,60,216,.6); }
.theme-swatch-cyber span{ background:#00E5FF; }
.theme-swatch[aria-checked="true"]{ outline:2.5px solid var(--ink); outline-offset:2px; }
.setting-row select{
  font:inherit;
  font-size:14px;
  padding:6px 10px;
  border-radius:8px;
  border:1px solid var(--line);
  background:var(--paper);
  color:var(--ink);
  min-width:120px;
}
.title-door{ height:.84em; width:auto; flex-shrink:0; touch-action:manipulation; } /* rapid taps knock instead of zooming */
.title-door path, .title-door rect{ fill:var(--title-door, var(--ink)); }
.title-door circle{ fill:var(--paper); }
.title-door.broken{ visibility:hidden; }
header.top h1{
  display:flex;
  align-items:center;
  justify-content:center;
  gap:.28em;
  font-family:var(--font-display);
  font-weight:600;
  font-size:clamp(40px,10vw,56px);
  letter-spacing:-.01em;
  line-height:1.05;
  margin:0;
}

/* Sections are flat and divided by a single rule, like the title header. */
.legend{
  border-bottom:1px solid var(--line);
  padding:0 0 20px;
  font-size:12.5px;
  line-height:1.6;
  color:var(--muted);
}
.legend strong{ color:var(--ink); font-weight:600; }
.info-cards{
  display:flex;
  flex-direction:column;
  gap:20px;
}
.legend ol, .legend ul{
  margin:0;
  padding-left:18px;
  display:flex;
  flex-direction:column;
  gap:6px;
}
.legend li::marker{ color:var(--ink); font-weight:600; }
.legend li.shortcut-line{ margin-top:8px; }
/* ---- start screen ---- */
.start-card{
  border-bottom:1px solid var(--line);
  padding:4px 0 20px;
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:16px;
  text-align:center;
}
.start-card h2{
  font-family:var(--font-display);
  font-size:18px;
  margin:0;
  font-weight:600;
}
.size-grid{
  display:flex;
  gap:12px;
  flex-wrap:wrap;
  justify-content:center;
}
.records-table{
  width:100%;
  max-width:360px;
  border-collapse:collapse;
  table-layout:fixed;
  font-family:var(--font-mono);
  font-size:13px;
  color:var(--ink);
}
.records-table th,
.records-table td{
  padding:8px 4px;
  border-bottom:1px solid var(--line);
  text-align:center;
  vertical-align:top;
}
.records-table th{ font-weight:600; }
.records-table tr:last-child td{ border-bottom:none; }
.records-table td + td,
.records-table th + th{ border-left:1px solid var(--line); }
.records-table .clear-count{ font-size:16px; font-weight:600; }
.records-table .best-times p{ margin:0 0 4px; font-size:12px; font-variant-numeric:tabular-nums; }
.records-table .best-times p:last-child{ margin-bottom:0; }
.size-btn{
  font-family:var(--font-mono);
  font-size:15px;
  font-weight:600;
  width:64px;
  height:64px;
  border-radius:10px;
  border:1.5px solid var(--line);
  background:var(--paper);
  color:var(--ink);
  cursor:pointer;
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  gap:2px;
  transition:border-color .15s, background .15s;
}

/* mode picker: a top-half door cell, without / with a doorknob */
.mode-swatch{
  position:relative;
  width:32px;
  height:32px;
  border:1px solid var(--line);
  border-radius:4px;
  background:var(--board-paper);
  overflow:hidden;
}
.mode-swatch .fill{ position:absolute; background:var(--board-ink); }
.mode-btn[aria-checked="true"]{
  border-color:var(--accent);
  background:var(--accent-soft);
  box-shadow:0 0 0 2px var(--accent) inset;
}

/* ---- game screen ---- */
.result-banner{
  text-align:center;
  font-family:var(--font-body);
  font-weight:600;
  font-size:20px;
  padding:12px 16px;
  border-radius:10px;
  border:1.5px solid transparent;
}
.result-banner.correct{
  color:var(--correct);
  background:var(--correct-soft);
  border-color:var(--correct);
}
.result-banner.incorrect{
  color:var(--danger);
  background:var(--danger-soft);
  border-color:var(--danger);
}

.tool-palette{
  display:flex;
  align-items:center;
  justify-content:center;
  text-align:center;
  gap:14px;
  flex-wrap:wrap;
  border-bottom:1px solid var(--line);
  padding:4px 0 16px;
}
.tool-title{
  flex-basis:100%;
  margin:0;
  font-family:var(--font-display);
  font-size:18px;
  font-weight:600;
}
/* tool rows: doors (4) / solving marks (4) / lock + eraser (2), each centered */
.tool-rows{ flex-basis:100%; display:flex; flex-direction:column; align-items:center; gap:8px; }
.tool-toggle{
  font:inherit;
  color:inherit;
  background:none;
  border:none;
  padding:2px 4px;
  cursor:pointer;
  display:inline-flex;
  align-items:center;
  gap:4px;
}
.tool-toggle svg{ width:18px; height:18px; stroke:var(--muted); fill:none; stroke-width:2; stroke-linecap:round; stroke-linejoin:round; transition:transform .15s; }
/* collapsed: only door / pencil / strip-pencil / lock / eraser, in one row */
.tool-palette.collapsed .tool-toggle svg{ transform:rotate(-90deg); }
.tool-palette.collapsed .tool-rows{ flex-direction:row; flex-wrap:wrap; justify-content:center; }
.tool-palette.collapsed .tool-buttons{ display:contents; }
.tool-palette.collapsed .tool-btn:not(.compact-keep){ display:none; }
.tool-buttons{ display:flex; gap:8px; justify-content:center; }
#submitActions{ margin-top:18px; }
#resultBanner{ margin-bottom:14px; }
#historyActions{ margin:6px 0 10px; }
.solve-timer{
  margin-top:16px;
  display:flex;
  align-items:center;
  justify-content:center;
  gap:6px;
  font-family:var(--font-mono);
  font-size:16px;
  font-weight:600;
  font-variant-numeric:tabular-nums;
  color:var(--ink);
}
.solve-timer svg{ width:17px; height:17px; stroke:currentColor; fill:none; stroke-width:2; stroke-linecap:round; stroke-linejoin:round; }
.solve-timer.stopped{ color:var(--muted); }
.btn.icon-btn{
  width:48px;
  height:44px;
  padding:0;
  display:inline-flex;
  align-items:center;
  justify-content:center;
}
.icon-btn svg{ width:22px; height:22px; stroke:currentColor; fill:none; stroke-width:2; stroke-linecap:round; stroke-linejoin:round; }
.tool-btn{
  width:44px;
  height:44px;
  padding:0;
  border-radius:8px;
  border:1.5px solid var(--line);
  background:var(--paper);
  cursor:pointer;
  display:flex;
  align-items:center;
  justify-content:center;
  transition:border-color .15s, background .15s;
}
.tool-btn.active{
  border-color:var(--accent);
  background:var(--accent-soft);
  box-shadow:0 0 0 2px var(--accent) inset;
}
.tool-swatch{
  position:relative;
  width:22px;
  height:22px;
  border:1px solid var(--line);
  border-radius:3px;
  background:var(--board-paper);
  overflow:hidden;
}
.tool-swatch .fill{ position:absolute; background:var(--board-ink); }
.tool-btn.active .tool-swatch{ border-color:var(--accent-strong); }

/* --zoom (set from the magnifier buttons) scales the board; once it outgrows the page the
   wrap scrolls. The frame centres with auto margins, which drop to 0 on overflow, so the
   left edge stays reachable. The padding keeps theme frames/glows from being clipped. */
.board-wrap{
  --zoom:1;
  display:flex;
}
.board-frame{ margin:0 auto; }
.board-wrap.zoomed{
  overflow:auto;
  padding:8px;
  margin:-8px;
  -webkit-overflow-scrolling:touch;
}
.board{
  display:grid;
  width:var(--board-w);
  aspect-ratio:1/1;
  border:2px solid var(--board-frame, var(--board-ink));
  border-radius:4px;
  overflow:hidden;
  background:var(--board-line);
  gap:1px;
}
.cell{
  position:relative;
  background:var(--board-paper);
  display:flex;
  align-items:center;
  justify-content:center;
  font-family:var(--font-mono);
  font-size:clamp(14px,4vw,20px);
  font-weight:600;
  user-select:none;
}
.cell.fixed-number{
  background:var(--fixed);
  color:var(--fixed-text, #fff);
}
/* a room the player clicked: its number fades out, like a greyed-out knob clue */
.cell.fixed-number.done{
  color:color-mix(in srgb, var(--fixed-text, #fff) 35%, var(--fixed));
}
.cell.fixed-empty{
  background:var(--fixed);
}
.cell.fixed-full{
  background:var(--board-ink);
}
.cell.player{
  background:var(--board-paper);
  cursor:pointer;
  box-shadow:inset 0 0 0 1px transparent;
}
.cell.player.interactive{
  box-shadow:inset 0 0 0 1px var(--board-hover);
}
/* locked: a red frame drawn on top of everything in the cell, doors included */
.cell.player.locked::after{
  content:'';
  position:absolute;
  inset:0;
  box-shadow:inset 0 0 0 2px var(--danger);
  pointer-events:none;
  z-index:3;
}
.cell .fill{ position:absolute; background:var(--board-ink); }
/* After an incorrect submission: cells that break a rule (not cells that merely differ from
   the generator's own answer) are marked red. */
.cell.fixed-number.violation{
  color:#fff;
  background:var(--danger);
  box-shadow:inset 0 0 0 3px var(--danger-soft);
}
.cell.player.violation{
  background:var(--danger-soft);
  box-shadow:inset 0 0 0 2px var(--danger);
}
.cell.player.violation .fill{ background:var(--danger); }
.fill-up{ top:0;left:0;right:0;height:50%; }
.fill-down{ bottom:0;left:0;right:0;height:50%; }
.fill-left{ top:0;left:0;bottom:0;width:50%; }
.fill-right{ top:0;right:0;bottom:0;width:50%; }
/* quarter-cell solving marks: light gray notes, never counted as doors */
.mark{ position:absolute; width:50%; height:50%; background:var(--board-mark); }
.mark-q-tl{ top:0; left:0; }
.mark-q-tr{ top:0; right:0; }
.mark-q-bl{ bottom:0; left:0; }
.mark-q-br{ bottom:0; right:0; }
/* strip marks: a door's black half sliced in half again, i.e. the outer quarter strip */
.mark-s-up{ top:0; left:0; width:100%; height:25%; }
.mark-s-down{ bottom:0; left:0; width:100%; height:25%; }
.mark-s-left{ top:0; left:0; width:25%; height:100%; }
.mark-s-right{ top:0; right:0; width:25%; height:100%; }

/* doorknob mode: every door carries a round knob at one end of its black half —
   up → right end, down → left end, left → top end, right → bottom end */
:root[data-knob] .fill::after,
.with-knob .fill::after{
  content:'';
  position:absolute;
  aspect-ratio:1/1;
  border-radius:50%;
  background:var(--knob, var(--fixed)); /* same colour as a room cell */
  transform:translate(-50%,-50%);
}
/* the black & white themes punch the knob out in the board's own paper colour */
:root:not([data-theme]), :root[data-theme="light"], :root[data-theme="dark"]{ --knob:var(--board-paper); }
.fill-up::after{ left:78%; top:50%; height:34%; }
.fill-down::after{ left:22%; top:50%; height:34%; }
.fill-left::after{ left:50%; top:22%; width:34%; }
.fill-right::after{ left:50%; top:78%; width:34%; }

/* doorknob clues: one number per half-row (left of the board) and per half-column
   (above it), since a knob always sits in one quarter of its cell */
.board-frame.knob{
  --clue-w:28px;
  /* room between the clues and the board, clear of any theme's frame (rococo's gilded
     double frame reaches 5.5px outside the board) */
  --clue-gap:10px;
  --kb-w:calc((min(92vw,480px) - var(--clue-w)) * var(--zoom));
  display:grid;
  grid-template-columns:var(--clue-w) var(--kb-w);
  grid-template-rows:auto var(--kb-w);
}
.board-frame.knob .board{ --board-w:var(--kb-w); width:var(--kb-w); grid-column:2; grid-row:2; }
.board-frame:not(.knob) .knob-clues{ display:none; }
.knob-clues{
  display:grid;
  font-family:var(--font-mono);
  font-size:clamp(8px, calc(var(--kb-w) / var(--n, 9) * .3), 12px);
  font-weight:600;
  font-variant-numeric:tabular-nums;
  color:var(--ink);
  line-height:1;
}
/* the 2n tracks are set from render() */
.col-clues{ grid-column:2; grid-row:1; padding:0 2px var(--clue-gap); }
.row-clues{ grid-column:1; grid-row:2; padding:2px var(--clue-gap) 2px 0; }
.knob-clue{ display:flex; align-items:center; justify-content:center; }
/* numbers sit dead centre in their slot, so the band around them is even on every side */
.col-clues .knob-clue{ padding:3px 0; }
/* every other cell's pair of numbers gets a soft band, so the two halves read as one line */
.knob-clue.band{ background:var(--line-soft); }
/* a clue the player has ticked off (click to toggle) greys out */
.knob-clue{ cursor:pointer; }
.knob-clue.done{ color:var(--board-mark); }
.knob-clue.violation{ color:var(--danger); }

.actions{
  display:flex;
  justify-content:center;
  gap:10px;
  flex-wrap:wrap;
}
.btn{
  font-family:var(--font-body);
  font-size:14px;
  font-weight:600;
  padding:11px 22px;
  border-radius:8px;
  border:1.5px solid var(--ink);
  background:var(--ink);
  color:var(--paper);
  cursor:pointer;
  transition:opacity .15s;
}
.btn.secondary{
  background:transparent;
  color:var(--ink);
  border-color:var(--line);
}
.btn.secondary.active{
  border-color:var(--accent);
  color:var(--accent-strong);
  background:var(--accent-soft);
}
.btn.danger-outline{
  background:transparent;
  color:var(--danger);
  border-color:var(--danger);
}
.btn:disabled{
  opacity:.4;
  cursor:default;
}

[hidden]{ display:none!important; }

/* ---- hover only on devices that really hover (stops "sticky" hover after a tap) ---- */
@media (hover:hover){
  .size-btn:hover{ border-color:var(--accent); background:var(--accent-soft); }
  .tool-btn:hover{ border-color:var(--accent); }
  .cell.player.interactive:hover{ background:var(--board-hover); }
  .cell.player.locked:hover{ background:var(--board-paper); }
  .btn:hover{ opacity:.85; }
  .icon-round-btn:hover{ border-color:var(--ink); }
}

/* ---- touch ---- */
button, .board{ touch-action:manipulation; }
.board.painting{ touch-action:none; }
.board{
  -webkit-user-select:none;
  user-select:none;
  -webkit-touch-callout:none;
  -webkit-tap-highlight-color:transparent;
}
.cell{ font-size:clamp(9px, calc(var(--board-w) / var(--n, 9) * .5), calc(20px * var(--zoom))); }
.board{ --board-w:calc(min(92vw,480px) * var(--zoom)); }

details.legend > summary{
  cursor:pointer;
  color:var(--ink);
  font-weight:600;
  list-style:none;
  display:flex;
  align-items:center;
  gap:6px;
}
details.legend > summary::-webkit-details-marker{ display:none; }
details.legend > summary::before{
  content:'▸';
  font-size:11px;
  color:var(--muted);
  transition:transform .15s;
}
details.legend[open] > summary::before{ transform:rotate(90deg); }
details.legend[open] > summary{ margin-bottom:10px; }

.icon-tool svg{ width:22px; height:22px; stroke:var(--ink); fill:none; stroke-width:1.8; stroke-linejoin:round; stroke-linecap:round; color:var(--ink); }
.eraser-btn svg{ width:20px; height:20px; stroke:var(--ink); fill:none; stroke-width:2; stroke-linejoin:round; stroke-linecap:round; }
.lock-btn svg{ width:20px; height:20px; stroke:var(--ink); fill:none; stroke-width:2; }
.lock-btn.active svg{ stroke:var(--danger); }
.tool-btn.lock-btn.active{
  border-color:var(--danger);
  background:var(--danger-soft);
  box-shadow:0 0 0 2px var(--danger) inset;
}

/* ---- phone layout ---- */
@media (max-width:600px){
  body{
    padding:14px 12px calc(28px + env(safe-area-inset-bottom,0px));
  }
  .page{ gap:14px; }
  header.top{ padding:8px 40px 12px; }
  .legend{ padding:0 0 14px; font-size:12px; }
  .info-cards{ gap:14px; }

  .start-card{ padding:4px 0 14px; }
  .size-btn{ width:60px; height:60px; }

  #gameScreen{ display:flex; flex-direction:column; gap:10px; }
  .tool-palette{ padding:4px 0 12px; gap:8px 10px; }
  #historyActions{ margin:0; }
  .solve-timer{ margin-top:4px; font-size:15px; }
  #historyActions .btn{ flex:none; width:52px; padding:0; }
  #submitActions{ margin-top:6px; }
  #resultBanner{ margin-bottom:0; }
  .tool-title{ font-size:16px; }
  .tool-rows{ gap:6px; }
  .tool-buttons{ gap:6px; }
  .tool-btn{ width:52px; height:48px; }

  .board{ --board-w:calc(min(100vw - 24px, 480px) * var(--zoom)); }
  .board-frame.knob{ --kb-w:calc((min(100vw - 24px, 480px) - var(--clue-w)) * var(--zoom)); }

  .actions{ gap:8px; }
  .actions .btn{ flex:1; padding:12px 10px; min-width:0; }
}
