/* Glow Grid: minimalist, tactile. Deliberately single-dark: an LED simulator reads best on a dark ground.
   Re-theme by editing the tokens below; nothing else hard-codes a colour, radius or size. */
:root {
  color-scheme: dark;

  /* colour */
  --bg: #0b0d11;
  --panel: #13161c;
  --panel-2: #1a1e26;
  --panel-3: #222731;
  --border: #272c36;
  --border-strong: #353b48;
  --text: #eceff4;
  --text-dim: #98a1b0;
  --accent: #4fd8c4;
  --accent-edge: #2a8f80;
  --accent-ink: #07201c;
  --warn: #f2b84b;
  --shift: #c58cf2;
  --danger: #f08a8a;
  --danger-edge: #6b3434;
  --grid-off: #1b2028;
  --grid-gap-bg: #05060a;
  --ring: #7a8394;

  /* shape and space */
  --r-sm: 8px;
  --r-md: 12px;
  --r-lg: 18px;
  --s-1: 4px; --s-2: 8px; --s-3: 12px; --s-4: 16px; --s-5: 24px; --s-6: 32px;
  --tap: 44px;

  /* type */
  --font-display: system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  --font-mono: ui-monospace, 'SF Mono', Menlo, Consolas, 'Liberation Mono', monospace;
  --fs-xs: 0.72rem; --fs-sm: 0.78rem; --fs-md: 0.84rem; --fs-lg: 1.05rem;

  /* tactile surfaces: raised keys catch light on top and have a dark lip underneath; pressed ones sink */
  --raise: inset 0 1px 0 rgba(255,255,255,.07), 0 1px 0 rgba(0,0,0,.55), 0 3px 6px rgba(0,0,0,.28);
  --press: inset 0 2px 5px rgba(0,0,0,.55), inset 0 0 0 1px rgba(0,0,0,.25);
  --well: inset 0 2px 10px rgba(0,0,0,.65), inset 0 0 0 1px rgba(255,255,255,.02);
  --ease: .12s ease-out;
}
body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: var(--fs-md);
  -webkit-text-size-adjust: 100%;
  -webkit-tap-highlight-color: transparent;
  overscroll-behavior-y: none;
}
.page {
  max-width: 1120px; margin: 0 auto;
  padding-inline: max(20px, env(safe-area-inset-left), env(safe-area-inset-right));
  padding-block: max(28px, env(safe-area-inset-top)) max(48px, env(safe-area-inset-bottom));
  display: flex; flex-direction: column; gap: var(--s-5);
}
.brand { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.app-actions { margin-left: var(--s-2); padding-left: var(--s-4); border-left: 1px solid var(--border-strong); display: flex; align-items: center; gap: var(--s-2); flex-wrap: wrap; }
.app-actions .btn { text-decoration: none; color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent-edge), var(--raise); }
@media (hover: hover) { .app-actions .btn:hover { color: var(--accent); } }
.brand-mark { color: var(--accent); font-size: 0.9rem; }
h1 { font-family: var(--font-display); font-size: clamp(1.4rem, 2.4vw, 1.9rem); font-weight: 600; margin: 0; letter-spacing: -0.02em; }
.tagline { color: var(--text-dim); margin: var(--s-2) 0 0; font-size: var(--fs-md); max-width: 62ch; line-height: 1.55; }

.layout { display: flex; gap: var(--s-5); align-items: stretch; flex-wrap: wrap; }
.device-col { flex: 1 1 420px; display: flex; flex-direction: column; gap: var(--s-4); align-items: stretch; max-width: 460px; margin-inline: auto; }
.panel-col { flex: 1 1 320px; display: flex; flex-direction: column; gap: var(--s-4); min-width: 0; }

/* The grid sits in a recessed well, with a faint ambient glow around it. It never tints the pixels themselves. */
.device {
  box-sizing: border-box;
  background: var(--grid-gap-bg); border-radius: var(--r-lg); padding: 18px;
  border: 1px solid var(--border);
  box-shadow: var(--well), 0 18px 48px -20px rgba(79,216,196,.22);
  width: 100%; max-width: 100%;
}
.grid {
  display: grid;
  grid-template-columns: repeat(var(--cols), 1fr);
  grid-template-rows: repeat(var(--rows), 1fr);
  gap: 3px; aspect-ratio: var(--cols) / var(--rows);
  touch-action: none; max-width: 100%;
}
.cell { border-radius: 25%; background: var(--grid-off); position: relative; }
.grid:focus-visible { outline: 2px solid var(--accent); outline-offset: 5px; }
.grid.kb-on .cell.kb::after { content: ""; position: absolute; inset: -3px; border-radius: 35%; border: 3px solid #fff; box-shadow: 0 0 0 2px #000; pointer-events: none; z-index: 1; }
.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.flags-on .cell.flag-faint { outline: 2px dashed var(--warn); outline-offset: -2px; }
.flags-on .cell.flag-shift { outline: 2px dashed var(--shift); outline-offset: -2px; }

.playback { display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap; font-size: var(--fs-sm); color: var(--text-dim); }
.field-inline { display: flex; align-items: center; gap: 6px; }
.frame-readout { font-variant-numeric: tabular-nums; }
.strip-meta { margin: calc(-1 * var(--s-1)) 0 0; display: flex; gap: var(--s-3); flex-wrap: wrap; font-size: var(--fs-sm); color: var(--text-dim); }
.hint:empty { display: none; }

/* Cards: one quiet surface, hairline ring, no heavy borders */
.card { background: var(--panel); box-shadow: 0 0 0 1px var(--border); border-radius: var(--r-md); padding: var(--s-4) 18px; display: flex; flex-direction: column; gap: var(--s-3); }
.card h2 { font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: 0.1em; color: var(--text-dim); margin: 0; font-weight: 500; }

.diag { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-3) var(--s-4); }
.diag .full { grid-column: 1 / -1; }
.metric-label { font-size: var(--fs-xs); color: var(--text-dim); }
.metric { font-size: var(--fs-lg); font-variant-numeric: tabular-nums; font-weight: 600; }
.metric small { font-size: var(--fs-xs); font-weight: 400; color: var(--text-dim); }
.meter { height: 6px; border-radius: 3px; background: var(--grid-gap-bg); overflow: hidden; box-shadow: var(--well); }
.meter > span { display: block; height: 100%; background: var(--accent); width: 0; transition: width .15s; }
.meter.hot > span { background: var(--warn); }
.meter.over > span { background: var(--danger); }
.chip { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-sm); }
.chip i { width: 10px; height: 10px; border-radius: 3px; border: 2px dashed; display: inline-block; }
.chip.faint i { border-color: var(--warn); }
.chip.shift i { border-color: var(--shift); }
.zero { color: var(--text-dim); }

/* Keys: tool buttons are raised; the active one is pressed in and lit */
.tool-row { display: flex; gap: var(--s-2); }
.tool-btn { flex: 1; padding: 9px 0; border-radius: var(--r-sm); border: 0; background: var(--panel-3); color: var(--text); font-family: inherit; font-size: var(--fs-md); cursor: pointer; box-shadow: var(--raise); transition: transform var(--ease), box-shadow var(--ease), background var(--ease); }
.tool-btn:active { transform: translateY(1px); box-shadow: var(--press); }
.tool-btn.active { background: var(--accent); color: var(--accent-ink); font-weight: 600; box-shadow: inset 0 2px 4px rgba(0,0,0,.28), 0 0 0 1px var(--accent-edge); transform: translateY(1px); }
.picker { display: flex; gap: var(--s-3); align-items: flex-start; }
#wheel { width: 160px; height: 160px; flex: none; border-radius: 50%; cursor: crosshair; touch-action: none; box-shadow: 0 0 0 1px var(--border), 0 4px 14px rgba(0,0,0,.4); }
.picker-side { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--s-2); }
.cur-swatch { height: 36px; border-radius: var(--r-sm); box-shadow: 0 0 0 1px var(--ring); }
.hex-row { display: flex; flex-direction: column; gap: 2px; font-size: var(--fs-sm); color: var(--text-dim); }
.hex-row input { width: 100%; }
.hover-chip { display: flex; align-items: center; gap: var(--s-2); font-size: var(--fs-sm); color: var(--text-dim); }
.hover-chip i { width: 22px; height: 22px; border-radius: 5px; box-shadow: 0 0 0 1px var(--border-strong); display: inline-block; flex: none; }
.swatch-group { display: flex; flex-direction: column; gap: var(--s-1); }
.swatch-label { font-size: var(--fs-xs); color: var(--text-dim); }
.swatches { display: flex; flex-wrap: wrap; gap: 6px; }
.swatch { width: 24px; height: 24px; border-radius: 6px; border: 0; box-shadow: 0 0 0 1px var(--ring); cursor: pointer; padding: 0; transition: transform var(--ease); }
.swatch:active { transform: scale(.92); }

.btn { font-family: inherit; font-size: var(--fs-md); padding: 9px 14px; border-radius: 10px; border: 0; background: var(--accent); color: var(--accent-ink); font-weight: 600; cursor: pointer; box-shadow: inset 0 1px 0 rgba(255,255,255,.35), 0 2px 0 var(--accent-edge), 0 4px 8px rgba(0,0,0,.3); transition: transform var(--ease), box-shadow var(--ease), background var(--ease); }
.btn:active { transform: translateY(2px); box-shadow: inset 0 1px 2px rgba(0,0,0,.25), 0 0 0 var(--accent-edge); }
.btn-quiet { background: var(--panel-3); color: var(--text); font-weight: 400; box-shadow: var(--raise); }
.btn-quiet:active { transform: translateY(1px); box-shadow: var(--press); }
.btn-quiet.danger { color: var(--danger); box-shadow: inset 0 1px 0 rgba(255,255,255,.05), 0 1px 0 var(--danger-edge), 0 0 0 1px var(--danger-edge); }
select:disabled, input:disabled { opacity: .45; cursor: not-allowed; }
.check:has(input:disabled) { color: var(--text-dim); }
.check[hidden], .range-row[hidden], .hint[hidden] { display: none; }
.btn:disabled, .btn:disabled:active { opacity: .38; cursor: default; transform: none; box-shadow: none; }
.btn-row { display: flex; gap: var(--s-2); flex-wrap: wrap; }
button:focus-visible, .swatch:focus-visible, input:focus-visible, select:focus-visible, .frame-thumb:focus-visible, summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (hover: hover) {
  .btn:hover { background: #63e2cf; }
  .btn-quiet:hover { background: #2a303c; }
  .tool-btn:hover:not(.active):not(:disabled) { background: #2a303c; }
  .tool-btn.active:hover { background: var(--accent); }
  .swatch:hover { transform: scale(1.1); }
}

.frame-strip { display: grid; grid-template-columns: repeat(8, max-content); gap: var(--s-2); justify-content: start; }   /* 16 slots = two rows of 8 */
.frame-cell { position: relative; display: block; flex: none; }
.frame-n { position: absolute; left: 3px; bottom: 2px; font-size: 12px; line-height: 1; color: var(--text-dim); text-shadow: 0 0 3px #000, 0 0 3px #000; pointer-events: none; font-variant-numeric: tabular-nums; }
.frame-thumb.active + .frame-n { color: var(--accent); }
.frame-thumb { width: 40px; height: 40px; image-rendering: pixelated; border-radius: 6px; cursor: pointer; border: 0; box-shadow: 0 0 0 1px var(--ring); display: block; transition: box-shadow var(--ease), transform var(--ease); }
.frame-thumb:active { transform: scale(.94); }
.frame-slot { display: block; width: 40px; height: 40px; box-sizing: border-box; border-radius: 6px; border: 1px dashed var(--ring); opacity: .55; }
.frame-empty .frame-n { opacity: .55; }
.strip-hint, .frame-count { margin: 0; }
.strip-hint { text-wrap: balance; }
.frame-count + .strip-hint { margin-top: calc(-1 * var(--s-2)); }   /* count and hint read as one block: 4px apart instead of the card's 12px */
html:not(.phone-dock) #framesCard .frame-strip { margin-block: var(--s-2) var(--s-1); }   /* a little air between Play / FPS and the strip, and between the strip and its count */
.phone-dock .frame-empty, .phone-dock #framesCard > .strip-hint, .phone-dock #framesCard > .frame-count { display: none; }
.frame-thumb.active { box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px var(--accent); }

.form-row { display: flex; align-items: flex-end; gap: 10px; flex-wrap: wrap; font-size: var(--fs-sm); color: var(--text-dim); }
.form-row label { display: flex; flex-direction: column; gap: var(--s-1); }
input[type=number], input[type=text], input[type=password], select {
  background: var(--grid-gap-bg); border: 0; box-shadow: var(--well), 0 0 0 1px var(--border); color: var(--text);
  border-radius: var(--r-sm); padding: 7px 9px; font-family: inherit; font-size: var(--fs-md);
}
input[type=number], input[type=text] { font-variant-numeric: tabular-nums; }
input[type=number] { width: 64px; }
input[type=text], input[type=password] { width: 100%; box-sizing: border-box; }
.grow { flex: 1 1 140px; }

.file-btn { display: inline-flex; align-items: center; justify-content: center; padding: 9px 14px; border-radius: 10px; border: 1px dashed var(--border-strong); color: var(--text-dim); font-size: var(--fs-md); cursor: pointer; }
@media (hover: hover) { .file-btn:hover { border-color: var(--accent); color: var(--text); } }

.hint { font-size: var(--fs-sm); color: var(--text-dim); margin: 0; line-height: 1.55; }
.hint code, .cmd { color: var(--text); }
.hint-list { margin: 0; padding-left: 18px; font-size: var(--fs-sm); line-height: 1.55; color: var(--text-dim); display: flex; flex-direction: column; gap: var(--s-1); }
.hint-list strong, .hint-list code { color: var(--text); }
.status { font-size: var(--fs-sm); color: var(--accent); min-height: 1.2em; margin: 0; }
.cmd { display: block; background: var(--grid-gap-bg); box-shadow: var(--well); border-radius: var(--r-sm); padding: var(--s-2) 10px; font-size: var(--fs-sm); white-space: pre-wrap; word-break: break-all; user-select: all; }
.check { display: flex; align-items: center; gap: var(--s-2); font-size: var(--fs-md); color: var(--text); }
.move-row { display: flex; gap: var(--s-4); align-items: center; flex-wrap: wrap; }
.nudge { display: grid; grid-template-columns: repeat(3, 44px); grid-template-rows: repeat(3, 40px); gap: var(--s-1); }
.nudge .btn { padding: 0; font-size: 1rem; }
.nudge .n-up { grid-area: 1 / 2; } .nudge .n-left { grid-area: 2 / 1; } .nudge .n-right { grid-area: 2 / 3; } .nudge .n-down { grid-area: 3 / 2; }
.device.edit-shared { outline: 2px dashed var(--accent); outline-offset: 3px; }

.guide summary { cursor: pointer; list-style: none; display: flex; align-items: center; gap: var(--s-2); }
.guide summary::-webkit-details-marker { display: none; }
.guide summary::before { content: "▸"; color: var(--accent); transition: transform .15s; }
.guide details[open] summary::before { transform: rotate(90deg); }
.guide h3 { font-size: var(--fs-sm); margin: var(--s-3) 0 var(--s-1); color: var(--text); font-weight: 600; }
.guide ul, .guide ol { margin: 0; padding-left: 18px; font-size: var(--fs-sm); line-height: 1.6; color: var(--text-dim); display: flex; flex-direction: column; gap: var(--s-1); }
.guide strong, .guide code { color: var(--text); }
@media (prefers-reduced-motion: reduce) {
  .guide summary::before, .meter > span, .btn, .tool-btn, .swatch, .frame-thumb { transition: none; }
}

@media (max-width: 760px) {
  .layout { flex-direction: column; }
  .device-col, .panel-col { flex-basis: auto; width: 100%; max-width: 100%; }
}
/* Phones (portrait): dock + one-line frame strip; the rest of the controls scroll in below (More jumps to them). Applies only while js/phone.js has added .phone-dock;
   without it the page is the plain stacked column above. */
.history-row { display: contents; }
.move-block { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--s-2) var(--s-4); align-items: start; }
.move-block > .sub-rule, .move-block > .sub-h { grid-column: 1 / -1; }
.move-ctl { display: flex; flex-direction: column; gap: var(--s-2); min-width: 0; }
.move-ctl .tool-row { flex-direction: column; }
.tool-btn:disabled, .tool-btn:disabled:active { opacity: .38; cursor: default; transform: none; box-shadow: none; }
.tool-btn.active:disabled { background: var(--panel-3); color: var(--text); font-weight: 400; }
.frame-more-top { display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap; font-size: var(--fs-sm); color: var(--text-dim); }
.dock { position: fixed; z-index: 25; left: 0; right: 0; bottom: 0; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--s-2);
  padding: var(--s-2) max(10px, env(safe-area-inset-right)) max(var(--s-2), env(safe-area-inset-bottom)) max(10px, env(safe-area-inset-left));
  background: var(--panel); box-shadow: 0 -1px 0 var(--border), 0 -10px 24px rgba(0,0,0,.45); }
.dock[hidden] { display: none; }
.dock .tool-btn { min-height: var(--tap); }
.dock-row { display: flex; align-items: center; gap: var(--s-2); }
.dock-color { flex: none; width: var(--tap); height: var(--tap); padding: 0; border: 0; border-radius: var(--r-sm); cursor: pointer; box-shadow: 0 0 0 2px var(--panel), 0 0 0 3px var(--ring); }
.dock-palette { flex: 1; min-width: 0; overflow-x: auto; scrollbar-width: none; }
.dock-palette::-webkit-scrollbar { display: none; }
.dock-palette .swatch-label { display: none; }
.dock-palette { display: flex; align-items: center; gap: var(--s-2); }
.dock-palette .swatch-group { flex: none; }
/* the colors already used in the picture come first, set off by a hairline; hidden when the canvas is empty */
.dock-palette #imgSwatchGroup { order: -1; padding-right: var(--s-2); border-right: 1px solid var(--border-strong); }
.dock-palette #imgSwatchGroup[hidden] { display: none; }
.dock-palette .swatches { flex-wrap: nowrap; gap: 6px; padding: 4px 3px; }
.dock-palette .swatch { flex: none; width: 36px; height: 36px; }
.dock-history { display: flex; gap: 6px; flex: none; }
.dock-history:empty { display: none; }
.phone-dock #undoBtn, .phone-dock #redoBtn { font-size: 0; width: var(--tap); padding: 0; }
.phone-dock #undoBtn::before { content: "\21B6"; font-size: 1.3rem; }
.phone-dock #redoBtn::before { content: "\21B7"; font-size: 1.3rem; }
.sheet-head { position: sticky; top: 0; z-index: 1; display: flex; align-items: center; justify-content: space-between; padding: var(--s-3) 2px var(--s-2); background: var(--bg); font-family: var(--font-display); font-weight: 600; }
.phone-dock { --dock-h: 150px; --sheet-top: 440px; }
.phone-dock .page { padding-block: var(--s-2) calc(var(--dock-h) + var(--s-3)); padding-inline: max(8px, env(safe-area-inset-left), env(safe-area-inset-right)); gap: var(--s-2); }
.phone-dock .layout { gap: 0; }
.phone-dock .device-col { gap: var(--s-2); max-width: 100%; }
.phone-dock .device { width: min(100%, calc(100dvh - var(--dock-h) - 180px)); margin-inline: auto; padding: 8px; }
.phone-dock #framesCard { display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto auto auto; align-items: start; gap: var(--s-2); padding: var(--s-2) 10px; }
.phone-dock #framesCard > h2 { display: none; }
/* Row 1 reads: Play, (frames when they fit), Undo, Redo, +, More */
.phone-dock #framesCard #playBtn { order: 1; }
.phone-dock #framesCard .frame-strip { order: 2; }
.phone-dock #framesCard #undoBtn { order: 3; }
.phone-dock #framesCard #redoBtn { order: 4; }
.phone-dock #framesCard #addFrameBtn { order: 5; }
.phone-dock #framesCard #moreBtn { order: 6; }
.phone-dock #framesCard.stack #playBtn { grid-column: 1; grid-row: 1; }
.phone-dock #framesCard.stack #undoBtn { grid-column: 3; grid-row: 1; }
.phone-dock #framesCard.stack #redoBtn { grid-column: 4; grid-row: 1; }
.phone-dock #framesCard.stack #addFrameBtn { grid-column: 5; grid-row: 1; }
.phone-dock #framesCard.stack #moreBtn { grid-column: 6; grid-row: 1; }
.phone-dock #framesCard.stack .frame-strip { grid-column: 1 / -1; grid-row: 2; }
.phone-dock #framesCard .playback, .phone-dock #framesCard > .btn-row, .phone-dock #framesCard > .history-row { display: contents; }
.phone-dock #framesCard > .sub-rule, .phone-dock #framesCard > .strip-meta, .phone-dock #historyWrap { display: none; }
.phone-dock .frame-strip { display: flex; box-sizing: border-box; flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; padding: 6px 4px; }
.phone-dock #framesCard.stack .frame-strip { flex-wrap: wrap; align-content: flex-start; overflow: visible; }
.phone-dock .frame-strip::-webkit-scrollbar { display: none; }
.phone-dock .frame-thumb { flex: none; }
.phone-dock .frame-n { font-size: 12px; }
.phone-dock #addFrameBtn { font-size: 0; width: var(--tap); padding: 0; }
.phone-dock #addFrameBtn::before { content: "+"; font-size: 1.4rem; }
/* The rest of the controls sit below the strip in normal flow; the page scrolls and the dock stays fixed. */
.phone-dock .panel-col { position: static; width: 100%; max-width: 100%; box-sizing: border-box; margin-top: var(--s-2); scroll-margin-top: var(--s-2); }
.phone-dock .sheet-head { display: none; }

/* Touch magnifier (js/loupe.js) */
#loupe {
  position: fixed; z-index: 100; width: 124px; height: 124px; box-sizing: border-box; padding: 6px;
  display: grid; grid-template-columns: repeat(7, 1fr); grid-template-rows: repeat(7, 1fr); gap: 2px;
  background: var(--grid-gap-bg); border-radius: var(--r-md); pointer-events: none;
  box-shadow: 0 0 0 1px var(--border-strong), 0 12px 32px rgba(0,0,0,.6);
}
#loupe[hidden] { display: none; }
#loupe i { display: block; border-radius: 25%; background: var(--grid-off); }
#loupe i.out { background: transparent; }
#loupe i.center { outline: 2px solid var(--accent); outline-offset: 1px; position: relative; z-index: 1; }

/* Touch targets: fingers need bigger hit areas than a mouse */
.grid { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
.grid.picking .cell { cursor: crosshair; }
@media (pointer: coarse) {
  .btn, .tool-btn, .file-btn { min-height: var(--tap); }
  .nudge { grid-template-rows: repeat(3, var(--tap)); }
  .swatch { width: var(--tap); height: var(--tap); }
  .swatches { gap: var(--s-2); }
  .frame-thumb, .frame-slot { width: 48px; height: 48px; }
  input[type=number], input[type=text], input[type=password], select { font-size: 16px; min-height: 40px; box-sizing: border-box; } /* 16px stops iOS zooming on focus */
  input[type=number] { width: 76px; }
  .check input { width: 22px; height: 22px; }
}
@media (max-width: 480px) {
  .page { padding-inline: max(12px, env(safe-area-inset-left), env(safe-area-inset-right)); }
  .device { padding: 12px; }
}

/* Photo to grid dialog */
.photo-dlg { padding: 0; border: 0; box-shadow: 0 0 0 1px var(--border), 0 24px 64px rgba(0,0,0,.6); border-radius: var(--r-md); background: var(--panel); color: var(--text); width: min(760px, calc(100vw - 16px)); max-height: calc(100dvh - 16px); font-family: inherit; }
.photo-dlg::backdrop { background: rgba(0,0,0,.72); }
.photo-wrap { display: flex; flex-direction: column; max-height: calc(100dvh - 18px); }
.photo-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s-2); padding: var(--s-3) var(--s-4); border-bottom: 1px solid var(--border); }
.photo-head h2 { margin: 0; font-size: 0.9rem; font-family: var(--font-display); font-weight: 600; }
.photo-body { overflow: auto; padding: 14px var(--s-4); display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--s-4); align-items: start; }
.photo-view { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.photo-view .crop-box { flex: none; }
.photo-col { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.crop-box { background: #000; box-shadow: 0 0 0 1px var(--border); border-radius: 10px; overflow: hidden; }
#cropCanvas { display: block; width: 100%; height: auto; touch-action: none; cursor: grab; }
#cropCanvas.picking { cursor: crosshair; }
#photoPreview { display: block; width: 100%; max-width: 256px; height: auto; image-rendering: pixelated; border-radius: 10px; box-shadow: 0 0 0 1px var(--border); background: #000; align-self: center; }
.photo-foot { display: flex; gap: var(--s-2); flex-wrap: wrap; padding: var(--s-3) var(--s-4) max(var(--s-3), env(safe-area-inset-bottom)); border-top: 1px solid var(--border); }
input[type=checkbox] { accent-color: var(--accent); }
input[type=range] { width: 100%; accent-color: var(--accent); min-height: 28px; }
.range-row { display: flex; flex-direction: column; gap: 2px; font-size: var(--fs-sm); color: var(--text-dim); }
.bg-swatch { width: 26px; height: 26px; border-radius: 6px; box-shadow: 0 0 0 1px var(--border-strong); display: inline-block; vertical-align: middle; }
@media (max-width: 600px) {
  .photo-dlg { width: 100vw; max-width: 100vw; height: 100dvh; max-height: 100dvh; border-radius: 0; box-shadow: none; }
  .photo-wrap { max-height: 100dvh; height: 100dvh; }
  .photo-body { grid-template-columns: minmax(0, 1fr); gap: var(--s-3); padding-top: 0; }
  .photo-view { position: sticky; top: 0; z-index: 2; flex-direction: row; align-items: flex-start; background: var(--panel); padding-block: var(--s-3); gap: 10px; }
  .photo-view .crop-box { flex: 1 1 62%; min-width: 0; }
  #photoPreview { flex: 1 1 38%; min-width: 0; align-self: flex-start; max-width: none; width: auto; }
  .photo-foot .btn { flex: 1 1 0; }
}

/* Help dialog */
.help-dlg .help-body { overflow: auto; padding: 14px var(--s-4) 18px; display: flex; flex-direction: column; gap: var(--s-1); }
.help-dlg .help-body h3:first-of-type { margin-top: var(--s-2); }
.help-dlg .help-body { font-family: system-ui, 'Segoe UI', Roboto, sans-serif; font-size: 0.9rem; line-height: 1.65; gap: var(--s-2); }   /* sentences in a readable face; the mono font stays for code */
.help-dlg .help-body .hint, .help-dlg .help-body ul, .help-dlg .help-body ol { font-size: inherit; line-height: inherit; }
.help-dlg .help-body li { margin-bottom: 2px; }
.help-dlg .help-body .ai-prompt { margin: 0; padding: 10px 12px; max-height: 16rem; overflow: auto; white-space: pre-wrap; font-family: var(--font-mono); font-size: 0.78rem; line-height: 1.5; background: var(--panel-3); border-radius: var(--r-sm); color: var(--text); }
.help-dlg .help-body code { font-family: var(--font-mono); font-size: 0.85em; background: var(--panel-3); padding: 1px 5px; border-radius: 4px; color: var(--text); }
.help-chips { position: sticky; top: 0; z-index: 1; display: flex; flex-wrap: wrap; gap: 6px; padding: var(--s-2) 0; background: var(--panel); }
.help-chip { padding: 5px 11px; font-size: var(--fs-sm); border-radius: 999px; }
.help-sec { border-top: 1px solid var(--border); scroll-margin-top: 56px; }
.help-sec[open] { padding-bottom: var(--s-3); }
.help-sec > summary { padding: var(--s-3) 0; min-height: 24px; }
.help-sec[open] > summary { padding-bottom: var(--s-2); }
.help-dlg .help-body .help-sec > summary h3 { margin: 0; font-family: var(--font-display); font-size: 0.95rem; font-weight: 600; color: var(--text); }
.sub-h { margin: 0; font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: 0.1em; color: var(--text-dim); font-weight: 500; font-family: inherit; }
.check-details > summary { cursor: pointer; list-style: none; display: flex; align-items: center; gap: var(--s-2); min-height: 28px; }
.check-details > summary::-webkit-details-marker { display: none; }
.check-details > summary::before { content: "▸"; color: var(--accent); transition: transform .15s; }
.check-details[open] > summary::before { transform: rotate(90deg); }
.check-details[open] > summary { margin-bottom: var(--s-3); }
.check-details[open] > .diag, .check-details[open] > .hint { margin-bottom: var(--s-3); }
.diag-sum { margin-left: auto; text-transform: none; letter-spacing: 0; font-size: var(--fs-sm); font-variant-numeric: tabular-nums; }
.diag-sum.warn { color: var(--warn); }
.sub-rule { border: 0; border-top: 1px solid var(--border); margin: 6px 0 2px; width: 100%; }

/* App bar, File menu, toast, export dialog */
.appbar { position: sticky; top: 0; z-index: 20; background: var(--bg); box-sizing: border-box; padding: max(var(--s-3), env(safe-area-inset-top)) max(20px, env(safe-area-inset-right)) var(--s-2) max(20px, env(safe-area-inset-left)); }
.appbar .brand { max-width: none; flex-wrap: nowrap; }
.page { padding-block-start: var(--s-3); }
@media (max-width: 760px) { .appbar { position: static; } }
@media (max-width: 480px) { .appbar { padding-inline: max(12px, env(safe-area-inset-left), env(safe-area-inset-right)); } }
.menu { position: fixed; inset: auto; margin: 0; padding: var(--s-1); width: 240px; max-width: calc(100vw - 16px); background: var(--panel); color: var(--text); border: 0; border-radius: var(--r-md); box-shadow: 0 0 0 1px var(--border), 0 16px 40px rgba(0,0,0,.6); }
.menu:popover-open { display: flex; flex-direction: column; }
.menu-item { all: unset; box-sizing: border-box; display: flex; flex-direction: column; gap: 2px; padding: var(--s-2) var(--s-3); min-height: var(--tap); justify-content: center; border-radius: var(--r-sm); cursor: pointer; font-size: var(--fs-md); }
.menu-item small { color: var(--text-dim); font-size: var(--fs-sm); }
.menu-item:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
@media (hover: hover) { .menu-item:hover { background: var(--panel-3); } }
.toast { position: fixed; left: 50%; bottom: max(var(--s-4), env(safe-area-inset-bottom)); transform: translateX(-50%); z-index: 200; margin: 0; max-width: calc(100vw - 32px); padding: var(--s-2) var(--s-4); background: var(--panel-3); color: var(--accent); border-radius: var(--r-md); box-shadow: 0 0 0 1px var(--border), 0 10px 30px rgba(0,0,0,.6); font-size: var(--fs-sm); opacity: 0; pointer-events: none; transition: opacity .2s var(--ease); }
.toast.show { opacity: 1; }
.export-dlg { width: min(420px, calc(100vw - 16px)); }
.export-body { grid-template-columns: minmax(0, 1fr); }
.export-body label { display: flex; flex-direction: column; gap: 4px; font-size: var(--fs-sm); color: var(--text-dim); }
@media (max-width: 600px) { .photo-dlg.export-dlg { height: fit-content; width: 100vw; max-height: 100dvh; margin: auto 0 0; border-radius: var(--r-md) var(--r-md) 0 0; } .export-dlg .photo-wrap { height: auto; } }

/* blank-state hint: the line disappears when nothing in it is visible */
.strip-meta:not(:has(> :not([hidden]))) { display: none; }
/* Move and layers is its own card on desktop; on phones the block moves into the sheet and the empty card is hidden */
#moveCard .move-block > .sub-rule { display: none; }
.phone-dock #moveCard { display: none; }

/* Board card (the ESP32-C3 player over USB) */
.board-free { font-weight: 400; text-transform: none; letter-spacing: 0; margin-left: var(--s-2); }
.board-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--s-1); }
.board-row { display: grid; grid-template-columns: 1fr auto auto auto auto; gap: var(--s-2); align-items: center; padding: 4px 0; border-top: 1px solid var(--border); font-size: var(--fs-sm); }
.board-row:first-child { border-top: 0; }
.board-row.playing .board-name { color: var(--accent, #4fd1c5); font-weight: 600; }
.board-row small { color: var(--text-dim); }
.board-row .board-meta { font-weight: 400; }
.board-name-hint { margin: 0 0 4px; }
.board-sched-hint { margin: 4px 0 0; }
.board-sched-bad { color: #ff8a80; }
.board-time { width: 5.2em; text-align: center; }
.board-pager { display: flex; align-items: center; justify-content: space-between; gap: var(--s-2); font-size: var(--fs-sm); color: var(--text-dim); margin-top: var(--s-1); }
.board-pager[hidden] { display: none; }
.board-status[data-kind="err"] { color: #f08c7a; }
.board-status[data-kind="ok"] { color: var(--text); }
.net-status { position: sticky; bottom: 0; margin: 0; padding: var(--s-2) 0; background: var(--panel); border-top: 1px solid var(--border); }
.net-status:empty { display: none; }

/* Board card runs the full width under both columns. */
#boardCard { flex: 1 1 100%; box-sizing: border-box; }
.phone-dock #boardCard { margin-top: var(--s-2); }
/* The two columns keep their own heights: the Frames card ends after its buttons instead of stretching to match Panel settings. */
.device-col, .panel-col { align-self: flex-start; }
/* "Panel Check": capital P and C only, not the all-caps of the other small headings. */
.check-label { text-transform: none; letter-spacing: 0; }
.export-body h3 { margin: var(--s-1) 0 0; font-size: var(--fs-sm); font-weight: 600; color: var(--text); }

.help-badge { width: 22px; height: 22px; padding: 0; border-radius: 50%; border: 1px solid var(--border); background: var(--panel); color: var(--accent, #4fd1c5); font: inherit; font-weight: 600; cursor: pointer; vertical-align: middle; }
.help-badge:hover { border-color: var(--accent, #4fd1c5); }
.help-fig { margin: var(--s-2) 0; }
.help-fig svg { display: block; width: 100%; max-width: 440px; height: auto; }
.help-fig .b rect { fill: var(--panel-2); stroke: var(--border-strong); }
.help-fig .a { fill: none; stroke: var(--accent); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.help-fig .af { fill: var(--accent); }
.help-fig .still { fill: var(--text-dim); opacity: .55; }
.help-fig text { fill: var(--text); font: 12px system-ui, 'Segoe UI', Roboto, sans-serif; }
.help-fig text.d { fill: var(--text-dim); }
.help-fig .ink text { fill: var(--accent-ink); font-weight: 600; }
.help-fig figcaption { margin: 2px 0 0; }
.panel-top { display: flex; flex-wrap: wrap; gap: var(--s-3) var(--s-5); align-items: stretch; }
.panel-forms { display: flex; flex-direction: column; gap: var(--s-3); flex: 0 0 auto; }
.panel-amps { flex: 1 1 140px; min-width: 140px; display: flex; flex-direction: column; justify-content: space-between; gap: var(--s-2); }
.panel-amps .meter { margin-bottom: 14px; }
.metric.faint { color: var(--warn); }
.metric.shift { color: var(--shift); }
