/* Isopix. The canvas fills the screen; controls float over it.
   Phone first: tools along the bottom, the grid-level slider on the right
   edge. From 768 px wide (and tall enough), the slider is a bar along the top. */

:root {
  --bg: #f7f5f0;
  --panel: rgba(255, 255, 255, 0.92);
  --ink: #1d1e22;
  --muted: #5d606b;
  --line: #2b2d3a;
  --accent: #d9480f;
  --accent-ink: #ffffff;
  --border: rgba(0, 0, 0, 0.14);
  --pressed: #ffe3d3;
  --shadow: 0 2px 10px rgba(0, 0, 0, 0.14);
  --btn: 48px;
  color-scheme: light dark;
}
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #1b1d22;
    --panel: rgba(38, 41, 48, 0.94);
    --ink: #eceef2;
    --muted: #a9adb8;
    --line: #dfe3ee;
    --accent: #ff8a4c;
    --accent-ink: #1b1d22;
    --border: rgba(255, 255, 255, 0.16);
    --pressed: #5a3423;
    --shadow: 0 2px 10px rgba(0, 0, 0, 0.5);
  }
}

* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; overflow: hidden; background: var(--bg); color: var(--ink);
  font: 16px/1.35 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; }
body { overscroll-behavior: none; -webkit-user-select: none; user-select: none; }

#stage { position: fixed; inset: 0; width: 100%; height: 100%; touch-action: none; display: block; outline: none; }
#stage:focus-visible { outline: 3px solid var(--accent); outline-offset: -3px; }
body.gray #stage { filter: grayscale(1); }

[hidden] { display: none !important; }

.btn {
  min-width: var(--btn); min-height: var(--btn);
  display: inline-flex; align-items: center; justify-content: center; gap: 2px;
  border: 1px solid var(--border); border-radius: 12px;
  background: var(--panel); color: var(--ink); padding: 0 6px;
  font: inherit; font-weight: 600; cursor: pointer; touch-action: manipulation;
}
.btn.wide { padding: 0 14px; }
.btn svg { width: 26px; height: 26px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.btn[aria-pressed="true"], .btn[aria-checked="true"] { background: var(--pressed); border-color: var(--accent); }
.btn:disabled { opacity: 0.4; cursor: default; }
.btn:focus-visible, .swatch:focus-visible, .notch:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
.btn.danger { color: #c92a2a; }
@media (prefers-color-scheme: dark) { .btn.danger { color: #ff8787; } }

.cluster { position: fixed; display: flex; gap: 6px; z-index: 3; }
.topleft { top: calc(8px + env(safe-area-inset-top)); left: calc(8px + env(safe-area-inset-left)); }
.topright { top: calc(8px + env(safe-area-inset-top)); right: calc(8px + env(safe-area-inset-right)); }
.cluster .btn { box-shadow: var(--shadow); }

/* ---- Grid-level slider: vertical on the right edge (phone) ---- */
.levels {
  position: fixed; z-index: 3; right: calc(6px + env(safe-area-inset-right)); top: 50%; transform: translateY(-55%);
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  background: var(--panel); border: 1px solid var(--border); border-radius: 16px; padding: 4px; box-shadow: var(--shadow);
}
.notches { display: flex; flex-direction: column; gap: 2px; }
.notch {
  width: 44px; height: 44px; border: 0; border-radius: 10px; background: transparent; color: var(--ink);
  display: flex; align-items: center; justify-content: center; cursor: pointer; position: relative; padding: 0;
  touch-action: none;
}
.notch svg { overflow: visible; }
.notch svg path { fill: currentColor; opacity: 0.55; }
.notch svg path.cells { fill: none; stroke: var(--bg); stroke-width: 1.2; opacity: 0.8; }
.notch[aria-checked="true"] { background: var(--accent); color: var(--accent-ink); }
.notch[aria-checked="true"] svg path { opacity: 1; }
.notch[aria-checked="true"] svg path.cells { stroke: var(--accent); opacity: 1; }
.lock { width: 44px; min-width: 44px; }
.lock .shackle { transition: transform 0.15s; }
.lock[aria-pressed="true"] .shackle { transform: none; }
.lock[aria-pressed="false"] .shackle { transform: translate(5px, -1px) rotate(18deg); transform-origin: 16px 11px; }
.readout {
  position: fixed; z-index: 3; right: calc(60px + env(safe-area-inset-right)); top: 50%; transform: translateY(-55%);
  background: var(--panel); border: 1px solid var(--border); border-radius: 8px; padding: 2px 8px; font-size: 13px; color: var(--muted);
  pointer-events: none; opacity: 0; transition: opacity 0.3s;
}
.readout.show { opacity: 1; }

/* ---- Bottom: palette and tools ---- */
.bottom {
  position: fixed; z-index: 3; left: 0; right: 0; bottom: 0;
  padding: 6px calc(6px + env(safe-area-inset-right)) calc(6px + env(safe-area-inset-bottom)) calc(6px + env(safe-area-inset-left));
  display: flex; flex-direction: column; gap: 6px; pointer-events: none;
}
.bottom > * { pointer-events: auto; }
.palette {
  display: flex; gap: 6px; overflow-x: auto; scrollbar-width: none; padding: 4px; margin: 0 auto; max-width: 100%;
  background: var(--panel); border: 1px solid var(--border); border-radius: 16px; box-shadow: var(--shadow);
}
.palette::-webkit-scrollbar { display: none; }
.swatch {
  flex: 0 0 44px; width: 44px; height: 44px; border-radius: 50%; border: 2px solid var(--border); padding: 0; cursor: pointer;
  position: relative; overflow: hidden; background: var(--c);
}
.swatch .tones { position: absolute; inset: 0; display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr; }
.swatch .tones i:first-child { grid-column: 1 / 3; }
.swatch[aria-checked="true"] { border: 3px solid var(--ink); box-shadow: 0 0 0 2px var(--bg) inset; }
.swatch.tool { background: var(--panel); color: var(--ink); display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 20px; }
.swatch.tool svg { width: 24px; height: 24px; fill: none; stroke: currentColor; stroke-width: 2; }
.swatch.tool[aria-pressed="true"] { background: var(--pressed); border-color: var(--accent); }
/* Add-color and auto-shade, pinned at the palette's end; inks scroll under them. */
.pal-pinned { position: sticky; right: -4px; display: flex; gap: 6px; margin: -4px -4px -4px auto; padding: 4px 4px 4px 6px;
  background: var(--panel); border-radius: 0 16px 16px 0; box-shadow: -6px 0 8px -6px rgba(0, 0, 0, 0.35); }
.swatch input[type="color"] { position: absolute; inset: 0; opacity: 0; width: 100%; height: 100%; cursor: pointer; }

.tools {
  display: flex; gap: 4px; justify-content: space-between; margin: 0 auto; width: 100%; max-width: 440px;
  background: var(--panel); border: 1px solid var(--border); border-radius: 16px; padding: 4px; box-shadow: var(--shadow);
}
.tools .btn { flex: 1 1 0; min-width: 44px; border-color: transparent; background: transparent; }
.tools .btn[aria-pressed="true"] { background: var(--pressed); border-color: var(--accent); }
.tools .opts { border-color: var(--border); }

/* ---- Selection bar and handle ---- */
.selbar {
  /* Centered with auto margins, not translate: a translated fixed box shrinks to half the screen and wraps. */
  position: fixed; z-index: 4; left: 0; right: 0; margin: 0 auto; width: max-content; bottom: calc(132px + env(safe-area-inset-bottom));
  display: flex; flex-wrap: wrap; justify-content: center; gap: 4px; max-width: calc(100vw - 16px);
  background: var(--panel); border: 1px solid var(--border); border-radius: 16px; padding: 4px; box-shadow: var(--shadow);
}
.selbar .btn span { font-size: 20px; font-weight: 700; }
/* One row: the less-used actions sit behind ⋯ on phones (shown inline from 768 px). */
.selbar { flex-wrap: nowrap; }
.selbar .mode { font-size: 14px; padding: 0 6px; min-width: 52px; }
.sel-extra { display: none; gap: 4px; }
.selbar.more { flex-wrap: wrap; }
.selbar.more .sel-extra { display: flex; flex-basis: 100%; justify-content: center; }
.chip { min-width: 44px; min-height: 44px; display: inline-flex; align-items: center; justify-content: center; font-weight: 700; color: var(--muted); }
.handle {
  position: fixed; z-index: 4; width: 44px; height: 44px; margin: -22px 0 0 -22px; border-radius: 50%;
  background: var(--accent); border: 3px solid var(--bg); box-shadow: var(--shadow); touch-action: none; cursor: ns-resize;
}
.handle::after { content: "⇕"; color: var(--accent-ink); font-weight: 800; position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; }
.handle-track {
  position: absolute; left: 52px; top: 50%; display: none; flex-direction: column; gap: 3px;
  background: var(--panel); border: 1px solid var(--border); border-radius: 10px; padding: 6px 8px; transform: translateY(-50%);
  font-size: 12px; color: var(--ink); white-space: nowrap;
}
.handle.dragging .handle-track { display: flex; }
.handle-track .tick { display: flex; align-items: center; gap: 6px; opacity: 0.5; }
.handle-track .tick.on { opacity: 1; font-weight: 800; color: var(--accent); }
.handle-track .tick.off { text-decoration: line-through; opacity: 0.25; }
.handle-track .tick.now::after { content: "◀"; font-size: 9px; }

/* ---- Popover (brush shapes, line styles, marquee shapes) ---- */
.popover {
  position: fixed; z-index: 5; left: 0; right: 0; margin: 0 auto; width: max-content; bottom: calc(132px + env(safe-area-inset-bottom));
  background: var(--panel); border: 1px solid var(--border); border-radius: 16px; padding: 8px; box-shadow: var(--shadow);
  display: grid; grid-template-columns: repeat(4, minmax(64px, 1fr)); gap: 6px; max-width: calc(100vw - 16px);
}
.popover .btn { flex-direction: column; min-height: 64px; font-size: 12px; font-weight: 600; padding: 4px; }
.popover .btn svg { width: 28px; height: 28px; }
.popover h4 { grid-column: 1 / -1; margin: 2px 4px; font-size: 14px; color: var(--muted); }

/* The update notice floats over the bottom, just above whatever bars are
   there (app.js sets its bottom), so it covers no control. It does not fade:
   it is an action. */
.update-bar {
  position: fixed; z-index: 6; left: 0; right: 0; margin: 0 auto; bottom: calc(132px + env(safe-area-inset-bottom));
  width: min(34rem, calc(100vw - 16px)); display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  padding: 6px 6px 6px 14px; border-radius: 14px; background: var(--ink); color: var(--bg); font-weight: 700; box-shadow: var(--shadow);
}
.update-text { flex: 1 1 12em; min-width: 0; }
.update-buttons { display: flex; gap: 6px; margin-left: auto; }
.update-reload { background: var(--accent); color: var(--accent-ink); border: 0; padding: 0 18px; }
.update-close { background: transparent; color: var(--bg); border: 2px solid currentColor; }

/* The Keep / Behind / Replace chip: an icon over a short word, 48 px square. */
.mode-chip { flex-direction: column; gap: 0; padding: 2px 4px; line-height: 1; }
.mode-chip svg { width: 22px; height: 22px; }
.mode-chip span { font-size: 10px; font-weight: 700; }
.mode-chip[data-mode="replace"] { border-color: var(--accent); }

.toast {
  position: fixed; z-index: 6; left: 50%; top: calc(64px + env(safe-area-inset-top)); transform: translateX(-50%);
  background: var(--ink); color: var(--bg); padding: 8px 14px; border-radius: 10px; max-width: calc(100vw - 32px);
  font-size: 15px; opacity: 0; pointer-events: none; transition: opacity 0.25s;
}
.toast.show { opacity: 1; }
.replay-bar { position: fixed; z-index: 6; left: 50%; top: calc(64px + env(safe-area-inset-top)); transform: translateX(-50%);
  display: flex; gap: 10px; align-items: center; background: var(--panel); border: 1px solid var(--border); border-radius: 14px; padding: 6px 6px 6px 14px; box-shadow: var(--shadow); }

/* ---- Menu ---- */
dialog#settings, dialog#help, dialog#drawing {
  border: 1px solid var(--border); border-radius: 18px; padding: 0; background: var(--bg); color: var(--ink);
  width: min(560px, calc(100vw - 16px)); max-height: calc(100dvh - 24px); box-shadow: var(--shadow);
}
dialog#help::backdrop, dialog#settings::backdrop, dialog#drawing::backdrop { background: rgba(0, 0, 0, 0.35); }
.menu { padding: 12px 16px 20px; user-select: text; -webkit-user-select: text; }
.menu header { display: flex; justify-content: space-between; align-items: center; position: sticky; top: 0; background: var(--bg); }
.menu h2 { margin: 0; font-size: 22px; }
.menu h3 { margin: 18px 0 6px; font-size: 17px; }
.menu fieldset { border: 1px solid var(--border); border-radius: 12px; margin: 8px 0; padding: 6px 10px 10px; }
.menu legend { font-weight: 600; padding: 0 4px; }
.menu label { display: flex; align-items: center; gap: 10px; min-height: 44px; }
.menu input[type="radio"], .menu input[type="checkbox"] { width: 22px; height: 22px; accent-color: var(--accent); flex: none; }
.menu select { min-height: 44px; font: inherit; border-radius: 8px; padding: 0 8px; }
.menu input[type="range"] { flex: 1; min-height: 44px; accent-color: var(--accent); }
.menu .row { display: flex; gap: 8px; align-items: center; }
.menu .wrap { flex-wrap: wrap; }
.menu .note { color: var(--muted); font-size: 14px; margin: 6px 0; }
.menu fieldset .btn { margin-top: 6px; }

/* ---- Top bar: labeled buttons (Drawing; New, Open, Save from 700 px) ---- */
.btn.labeled { gap: 6px; padding: 0 12px 0 8px; }
.btn-words { display: flex; flex-direction: column; align-items: flex-start; line-height: 1.05; }
.btn-word { font-size: 15px; }
.btn-sub { font-size: 11px; font-weight: 500; color: var(--muted); max-width: 9em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.btn-sub:empty { display: none; }
.wide-only { display: none; }
@media (min-width: 700px) { .wide-only { display: inline-flex; } }
/* The narrowest phones: Drawing shows its folder only (its label stays for screen readers). */
@media (max-width: 359px) { #drawing-open .btn-words { display: none; } #drawing-open { padding: 0 6px; } }

/* ---- Settings: folding sections, as in Noodle Pads ---- */
.set-fold { border-top: 1px solid var(--border); }
.set-fold h3 { margin: 0; }
.set-head {
  width: 100%; min-height: 48px; display: flex; align-items: center; gap: 10px; padding: 6px 4px;
  border: 0; background: transparent; color: var(--ink); font: inherit; font-size: 17px; font-weight: 700; text-align: left; cursor: pointer;
}
.set-head:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
.set-head-caret { flex: none; width: 1em; }
.set-head-chip { flex: 0 1 auto; margin-left: auto; padding: 2px 10px; border-radius: 999px; background: var(--panel); border: 1px solid var(--border); font-size: 13px; font-weight: 600; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 55%; }
.set-body { padding: 0 2px 12px; }
.set-about { border-top: 1px solid var(--border); padding-top: 4px; }
.set-about h3 { margin: 12px 0 8px; }
/* The build stamp: release and commit, tiny, in the strip under the tool bar. Never takes a tap. */
.build-stamp {
  position: fixed; z-index: 4; right: calc(8px + env(safe-area-inset-right)); bottom: env(safe-area-inset-bottom);
  font: 8px/1 ui-monospace, SFMono-Regular, Menlo, monospace; color: var(--muted); opacity: 0.7;
  pointer-events: none; user-select: none; -webkit-user-select: none;
}
.version { text-align: center; color: var(--muted); font-size: 14px; margin: 14px 0 4px; }

/* ---- Drawing sheet: the name, big file buttons ---- */
.menu .name-field { display: flex; flex-direction: column; align-items: stretch; gap: 4px; font-weight: 600; margin: 8px 0 12px; }
.name-field input { min-height: 48px; font: inherit; font-size: 18px; padding: 0 12px; border-radius: 10px; border: 1px solid var(--border); background: var(--panel); color: var(--ink); }
.big-buttons { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 8px; }
.btn.big { flex-direction: column; min-height: 84px; gap: 6px; font-size: 16px; }
.btn.big svg { width: 32px; height: 32px; }
.confirm { border: 2px solid var(--accent); border-radius: 12px; padding: 8px 12px; margin: 10px 0; }
.confirm p { margin: 4px 0 8px; }

/* ---- Help sheet: icon, then name and what it does ---- */
.help-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.help-list li { display: grid; grid-template-columns: 44px 1fr; gap: 10px; align-items: start; }
.help-icon { width: 44px; min-height: 36px; display: flex; align-items: center; justify-content: center; border: 1px solid var(--border); border-radius: 10px; background: var(--panel); }
.help-icon svg { width: 26px; height: 26px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.help-icon svg path[fill="currentColor"] { fill: currentColor; }
.help-icon.help-key { font: 700 13px ui-monospace, monospace; }
.help-text-icon { font-weight: 800; font-size: 15px; }
.help b { margin-right: 4px; }

/* ---- Zoom slider: a rail on the left edge, + at the top, − at the bottom ---- */
.zoom {
  position: fixed; z-index: 3; left: calc(6px + env(safe-area-inset-left)); top: 50%; transform: translateY(-50%);
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  background: var(--panel); border: 1px solid var(--border); border-radius: 14px; padding: 3px; box-shadow: var(--shadow);
}
.zoom .btn { min-width: 44px; min-height: 44px; width: 44px; height: 44px; padding: 0; border: 0; border-radius: 10px; background: transparent; }
/* The track shrinks on short screens so the rail never reaches the bars. */
.zoom-track { position: relative; width: 44px; height: clamp(72px, calc(100dvh - 420px), 220px); touch-action: none; cursor: ns-resize; border-radius: 10px; outline: none; }
.zoom-track:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
.zoom-track::before { content: ""; position: absolute; left: 20px; width: 4px; top: 14px; bottom: 14px; border-radius: 2px; background: var(--border); }
.zoom-thumb { position: absolute; left: 8px; width: 28px; height: 28px; border-radius: 50%; top: calc((1 - var(--t, 0.5)) * (100% - 28px));
  background: var(--accent); border: 3px solid var(--panel); box-shadow: var(--shadow); pointer-events: none; }

/* Phones: the level slider is a slim rail (the current size and the lock),
   hanging under the top buttons like the zoom rail opposite. Touching it opens
   all eight notches around the finger, with the chosen one staying put unless
   that would run off the screen or into the bottom bars (--nudge, set by
   app.js); it folds again after the finger lifts (.open, set by app.js). */
@media (max-width: 767px), (max-height: 559px) {
  .levels { top: calc(64px + env(safe-area-inset-top)); bottom: auto; transform: none; flex-direction: column; padding: 3px; gap: 4px; border-radius: 14px; }
  .notch-window { position: relative; width: 44px; height: 44px; }
  .notches { position: absolute; left: 0; top: calc(var(--k, 0) * -46px); border-radius: 12px; z-index: 1; }
  .levels.open .notches { top: calc(var(--k, 0) * -46px + var(--nudge, 0px)); }
  .levels:not(.open) .notch-window { overflow: hidden; border-radius: 10px; }
  .levels.open .notches { background: var(--panel); outline: 1px solid var(--border); box-shadow: var(--shadow); }
  /* The open notches pass over the lock's place, so the lock steps aside, still in reach. */
  .levels.open .lock { transform: translateX(-56px); box-shadow: var(--shadow); }
  .levels.open + .readout { right: calc(122px + env(safe-area-inset-right)); }
  .readout { right: calc(64px + env(safe-area-inset-right)); top: calc(80px + env(safe-area-inset-top)); bottom: auto; transform: none; }
  .popover { width: calc(100vw - 16px); grid-template-columns: repeat(auto-fill, minmax(64px, 1fr)); }
}

/* ---- Tablet and up: the slider becomes a bar along the top ---- */
@media (min-width: 768px) and (min-height: 560px) {
  /* A second row under the top bar, so the Drawing, New, Open and Save buttons have the first. */
  .levels { top: calc(64px + env(safe-area-inset-top)); right: auto; left: 50%; transform: translateX(-50%); flex-direction: row; }
  .notches { flex-direction: row; }
  .notch { width: 52px; }
  .readout { top: calc(128px + env(safe-area-inset-top)); right: auto; left: 50%; transform: translateX(-50%); }
  .bottom { flex-direction: row; align-items: flex-end; justify-content: center; gap: 10px; }
  .palette { margin: 0; flex: 0 1 auto; }
  .tools { margin: 0; width: auto; flex: 0 0 auto; }
  .tools .btn { flex: 0 0 52px; }
  .selbar, .popover { bottom: calc(80px + env(safe-area-inset-bottom)); margin: 0 auto; max-width: calc(100vw - 16px); }
  #sel-more { display: none; }
  .sel-extra, .selbar.more .sel-extra { display: flex; flex-basis: auto; }
  .selbar.more { flex-wrap: nowrap; }
  .popover { width: max-content; grid-template-columns: repeat(4, minmax(64px, 1fr)); }
}
/* Short landscape phones: the open rail runs leftward along the screen instead,
   and the palette and tools share one row (the palette scrolls under its pinned
   buttons) so the side rails fit between the top buttons and the bottom. The
   brush picker and selection bar sit between the two side rails. */
@media (max-height: 559px) and (min-width: 540px) {
  .bottom { flex-direction: row; align-items: flex-end; justify-content: center; gap: 6px; }
  .palette { margin: 0; flex: 0 1 auto; min-width: 0; }
  .tools { margin: 0; width: auto; flex: 0 0 auto; }
  .tools .btn { flex: 0 0 48px; }
  .selbar, .popover { bottom: calc(76px + env(safe-area-inset-bottom)); max-width: calc(100vw - 132px); }
  .popover { width: max-content; grid-template-columns: repeat(auto-fill, minmax(64px, 1fr)); }
}
@media (max-height: 559px) {
  .notches { flex-direction: row-reverse; left: auto; top: 0; right: calc(var(--k, 0) * -46px); }
  .levels.open .notches { right: 0; top: 0; } /* the open row sits level with the rail, never shifted up */
  /* Just above the bottom row, clear of the top buttons and the open rail. */
  .readout { top: auto; bottom: calc(80px + env(safe-area-inset-bottom)); left: 0; right: 0; margin: 0 auto; width: max-content; transform: none; }
}

/* Phones: the zoom rail hangs under the top buttons, and its track stays above
   where the brush picker and the selection bar open. Under 620 px tall there
   is no room for a track worth aiming, so only the buttons remain. */
@media (max-width: 767px), (max-height: 559px) {
  .zoom { top: calc(64px + env(safe-area-inset-top)); transform: none; }
  .zoom-track { height: clamp(72px, calc(100dvh - 540px), 220px); }
}
@media (max-width: 767px) and (max-height: 619px), (max-height: 559px) {
  .zoom-track { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
}
