/* Faceted Reflector Design Demo — graphite sketchpad theme.
   Colour roles avoid red/green contrasts (protan-safe): pass = blue ✓, fail = orange ✗, and every
   state also carries a symbol or word. */
:root {
  /* palette after the Astra build: blue-black ground, muted cyan / amber / violet */
  --bg: #0b1118; --panel: #111b25; --panel2: #182530; --line: #273541; --ink: #e5edf1; --dim: #8d9da9; --faint: #5f707c;
  --accent: #f4c17c;   /* amber: Mode A */
  --b: #88d7d4;        /* cyan: Mode B / primary actions */
  --c: #b7a6ef;        /* violet: Mode C */
  --glass: #8fb8ff;    /* lenses */
  --ok: #5aa7ff; --bad: #ff9a3d; --warn: #f2b441;
  --r: 6px;
  /* spacing scale: every padding / gap / margin goes through --density (1 = original layout).
     Set --density on ANY element (html, .side, …) to rescale that subtree — tokens are computed per element below. */
  --density: 1.3;            /* desktop (Anya's pick, 09-24) */
  font: 13px/1.35 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  color-scheme: dark;
}
* { box-sizing: border-box;
  --s-2: calc(2px * var(--density)); --s-4: calc(4px * var(--density)); --s-6: calc(6px * var(--density));
  --s-8: calc(8px * var(--density)); --s-10: calc(10px * var(--density)); --s-14: calc(14px * var(--density)); }
html, body { margin: 0; background: var(--bg); color: var(--ink); }
body { height: 100vh; height: 100dvh; display: flex; flex-direction: column; overflow: hidden; }
button, select, input { font: inherit; color: inherit; }
button, .filebtn {
  min-height: 28px; padding: calc(3px * var(--density)) var(--s-10); border-radius: var(--r); border: 1px solid var(--line);
  background: var(--panel2); cursor: pointer; display: inline-flex; align-items: center; gap: var(--s-4); touch-action: manipulation;
}
button:hover, .filebtn:hover { border-color: var(--dim); }
.filebtn { color: var(--ink); }
button.on, button[aria-selected="true"] { background: #284346; color: #b3f3ea; border-color: #3f6a6c; }
button.primary { background: var(--b); color: #092225; border-color: var(--b); font-weight: 600; }
button.primary:hover { background: #b0eeea; }
button.danger { border-color: #6b4a2a; }
button.confirming { background: var(--bad); color: #1a0d00; border-color: var(--bad); }
button:disabled { opacity: .45; cursor: default; }
select, input[type=number], input[type=text] {
  min-height: 28px; background: #0d151e; border: 1px solid var(--line); border-radius: var(--r); padding: var(--s-2) var(--s-6);
}
input[type=number] { width: 84px; }
input.w4 { width: 60px; }
input[type=checkbox] { width: 18px; height: 18px; margin: 0; accent-color: var(--b); vertical-align: middle; }   /* Astra: cyan controls */
input[type=range] { width: 100%; accent-color: var(--b); min-height: 24px; }
label { color: var(--dim); }
h2 { font-size: 13px; margin: 0; font-weight: 600; letter-spacing: .02em; }
h2 small { color: var(--faint); font-weight: 400; margin-left: var(--s-6); }

.boot-error { background: var(--bad); color: #1a0d00; padding: var(--s-10) var(--s-14); font-weight: 600; }

/* ---- top bar */
.modes { display: flex; gap: var(--s-4); }
.rays { display: flex; align-items: center; gap: var(--s-6); }

.canvas-wrap { position: relative; flex: 1; min-height: 0; }
.mf-toggle { padding: 3px 10px; font-size: 11px; }
.mf-panel { position: absolute; z-index: 3; left: 8px; bottom: 8px; width: min(280px, calc(100% - 16px)); max-height: 62%; overflow: auto; padding: 7px; background: rgba(11,17,24,0.96); border: 1px solid var(--line); border-radius: 6px; font-size: 11px; }
.mf-panel[hidden], .mf-panel [hidden], #mf-vector[hidden] { display: none; }
.mf-panel > label, #mf-vector { display: flex; align-items: center; gap: 5px; margin: 5px 0; }
.mf-panel select { min-width: 0; max-width: 195px; font-size: 11px; }
.mf-panel input[type=number] { width: 54px; min-width: 0; }
.mf-panel button { display: block; text-align: left; width: 100%; font-size: 11px; margin-top: 3px; }
.mf-panel p { margin: 6px 0; }
.mf-panel a { color: #abcffa; }
.mf-panel summary { cursor: pointer; }
.mf-ramp { height: 8px; margin: 4px 0; background: linear-gradient(to right, rgb(0,32,77), rgb(49,68,107), rgb(102,105,112), rgb(149,143,120), rgb(203,186,105), rgb(255,234,70)); }
#mf-scale { display: flex; justify-content: space-between; }
#mf-summary, #mf-worst { margin-top: 6px; }
#mf-error { color: #ffd28c; }
.canvas-wrap canvas { position: absolute; inset: 0; width: 100%; height: 100%; touch-action: none; display: block; }
.canvas-wrap.sq { aspect-ratio: 1 / 1; flex: none; width: 100%; }
.hint { position: absolute; left: 8px; bottom: 6px; color: var(--faint); font-size: 11px; pointer-events: none; }
.seg { display: inline-flex; } .seg button { border-radius: 0; } .seg button:first-child { border-radius: var(--r) 0 0 var(--r); } .seg button:last-child { border-radius: 0 var(--r) var(--r) 0; }
.tog { display: inline-flex; align-items: center; gap: var(--s-4); }

.toolrow { display: flex; flex-wrap: wrap; gap: var(--s-4) var(--s-8); align-items: center; font-size: 12px; }
.toolrow input[type=number] { width: 64px; }

/* ---- stats + feasibility */
.stats-grid { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); gap: var(--s-10); }
.stats { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: var(--s-6) calc(12px * var(--density)); align-content: start; }
.stat b { display: block; font-size: 15px; font-variant-numeric: tabular-nums; }
.stat span { display: block; color: var(--faint); font-size: 11px; }
.stat.pair { grid-column: span 2; }
.energy { grid-column: 1 / -1; display: flex; height: 12px; border-radius: 3px; overflow: hidden; border: 1px solid var(--line); }
.energy i { display: block; height: 100%; }
.legend { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: var(--s-4) calc(12px * var(--density)); color: var(--dim); font-size: 11px; }
.legend i { display: inline-block; width: 10px; height: 10px; border-radius: 2px; margin-right: var(--s-4); vertical-align: -1px; }
.feas { border-left: 1px solid var(--line); padding-left: var(--s-10); font-size: 12px; }
.feas h3 { margin: 0 0 var(--s-4); font-size: 12px; }
.feas .bind { margin-bottom: var(--s-4); }
.feas .bind.ok { color: var(--ok); }
.feas ul { margin: 0; } .feas li { margin: var(--s-2) 0; color: var(--dim); }
.notices { margin-top: var(--s-6); font-size: 12px; color: var(--warn); }
.notices div { margin: var(--s-2) 0; }

/* ---- side panel sections */
.side details { border-bottom: 1px solid var(--line); padding: var(--s-6) 0; }
.side summary { cursor: pointer; font-weight: 600; min-height: 28px; display: flex; align-items: center; gap: var(--s-6); list-style: none; }
.side summary::-webkit-details-marker { display: none; }
.side summary::before { content: '▸'; color: var(--faint); transition: transform .12s; }
.side details[open] > summary::before { transform: rotate(90deg); }
.side summary .tag { font-weight: 400; color: var(--faint); font-size: 11px; margin-left: auto; }
.side details.adv > summary { color: var(--dim); font-weight: 500; font-size: 12px; }
.row { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: var(--s-6); margin: var(--s-4) 0; }
.row > label { color: var(--dim); }
.row.help { display: block; color: var(--faint); font-size: 11px; margin-top: -2px; }
.row.full { grid-template-columns: 1fr; }
.btnrow { display: flex; flex-wrap: wrap; gap: var(--s-6); margin: var(--s-6) 0; }
.mode-A .only-B, .mode-A .only-C, .mode-B .only-A, .mode-B .only-C, .mode-C .only-A, .mode-C .only-B { display: none !important; }
/* Spec mode (D) extends Paint: Paint's sections stay, Stamp's and Profile's go, and its own appear only there */
.mode-D .only-B, .mode-D .only-C, .mode-A .only-D, .mode-B .only-D, .mode-C .only-D { display: none !important; }
.spec-table { display: grid; gap: 2px; font-size: 11px; }
.spec-table .st-row > * { min-width: 0; }
.spec-table input[type=checkbox] { margin: 0; }
.spec-table .st-row { display: grid; grid-template-columns: 15px minmax(34px, 1fr) 36px 36px 46px 46px 18px; gap: 3px; align-items: center; padding: 1px 2px; border-radius: 4px; border-left: 2px solid transparent; }
.spec-table .st-row input[type=number], .spec-table .st-row input[type=text] { width: 100%; min-width: 0; min-height: 22px; padding: 0 3px; font-size: 11px; -moz-appearance: textfield; }
.spec-table .st-row input[type=number]::-webkit-inner-spin-button, .spec-table .st-row input[type=number]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
.spec-table .st-row .icon { min-height: 20px; padding: 0 2px; font-size: 10px; justify-content: center; }
.spec-table .st-head { color: var(--faint); font-size: 11px; }
.spec-table .st-note { color: var(--faint); font-size: 11px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.spec-table .st-row.sel { background: var(--panel2); }
.st-row.v-pass { border-left-color: var(--ok); } .st-row.v-fail { border-left-color: var(--bad); } .st-row.v-unsure { border-left-color: var(--warn); }
.spec-report { margin-top: var(--s-8); }
.spec-verdict { padding: var(--s-4) var(--s-8); border-radius: var(--r); background: var(--panel2); border-left: 3px solid var(--line); }
.spec-verdict.v-pass { border-left-color: var(--ok); } .spec-verdict.v-fail { border-left-color: var(--bad); } .spec-verdict.v-unsure { border-left-color: var(--warn); }
.spec-rows, .spec-cmp { display: grid; gap: 1px; margin: var(--s-4) 0; font-size: 12px; font-variant-numeric: tabular-nums; }
.spec-rows .sr, .spec-cmp .sr { display: grid; grid-template-columns: 12px minmax(0, 1fr) auto auto; gap: var(--s-4) var(--s-6); align-items: baseline; padding: 1px 2px; cursor: pointer; border-radius: 3px; }
.sr > span { white-space: nowrap; } .sr .nm { overflow: hidden; text-overflow: ellipsis; }
.sr .off { grid-column: 2 / -1; font-size: 11px; } .sr .off:empty { display: none; }
.spec-cmp .sr { cursor: default; }
.sr.sel { background: var(--panel2); }
.sr .mk { font-weight: 700; } .sr.v-pass .mk { color: var(--ok); } .sr.v-fail .mk { color: var(--bad); } .sr.v-unsure .mk { color: var(--warn); }
.sr .need, .sr .off { color: var(--dim); } .sr.v-fail .off { color: var(--bad); }
.spec-dist button { min-height: 24px; padding: 1px var(--s-6); }
.numpair { display: inline-flex; gap: var(--s-4); } .numpair input[type=number] { width: 50px; }
.side .note { color: var(--faint); font-size: 11px; margin: var(--s-4) 0; }
.side .reason { font-size: 12px; margin: var(--s-4) 0; }
.stamp-list, .lens-list, .group-list { display: flex; flex-direction: column; gap: var(--s-4); margin: var(--s-4) 0; }
.item { display: flex; align-items: center; gap: var(--s-6); padding: calc(3px * var(--density)) var(--s-6); border: 1px solid var(--line); border-radius: var(--r); background: var(--panel2); }
.item.sel { border-color: var(--b); }
.item .grow { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.item button { min-height: 26px; padding: var(--s-2) var(--s-8); }
.checks { font-size: 12px; }
.checks .ck { border-left: 3px solid var(--line); padding: calc(3px * var(--density)) var(--s-6); margin: var(--s-4) 0; background: var(--panel2); border-radius: 0 var(--r) var(--r) 0; }
.checks .ck.pass { border-color: var(--ok); } .checks .ck.fail { border-color: var(--bad); } .checks .ck.skip { border-color: var(--faint); }
.checks .ck b.st { display: inline-block; min-width: 46px; } .checks .ck.pass b.st { color: var(--ok); } .checks .ck.fail b.st { color: var(--bad); }
.checks .ck div { color: var(--dim); margin-top: var(--s-2); word-break: break-word; }
.defs dt { color: var(--ink); font-weight: 600; margin-top: var(--s-4); } .defs dd { margin: 0 0 var(--s-2) 0; color: var(--dim); font-size: 11px; }

.tog.lens input[type=range] { width: 90px; }
.tog.lens output { min-width: 44px; font-variant-numeric: tabular-nums; }
.side-top { position: sticky; top: 0; z-index: 2; background: var(--panel); display: flex; flex-wrap: wrap; gap: var(--s-6); padding: var(--s-8) 0; border-bottom: 1px solid var(--line); }
.side-top select { flex: 1 1 100%; }
.side-top #preset-confirm { flex: 1 1 100%; }
.w6 { width: 6.5em; }

/* ---- header (after the Astra build) */
.topbar { position: sticky; top: 0; z-index: 30; display: flex; align-items: center; justify-content: space-between; gap: calc(12px * var(--density));
  height: 48px; padding: 0 var(--s-14) 0 calc(18px * var(--density)); border-bottom: 1px solid var(--line); background: var(--bg); }
.brand { display: flex; align-items: center; gap: calc(9px * var(--density)); color: var(--b); text-decoration: none; font-size: 20px; }
.brand strong { color: var(--ink); font-size: 15px; letter-spacing: 4px; font-weight: 700; }
.hdr-right { display: flex; align-items: center; gap: var(--s-6); min-width: 0; }
.status { font: 10px/1 ui-monospace, SFMono-Regular, Menlo, monospace; letter-spacing: .8px; color: var(--b); text-transform: uppercase;
  margin-right: var(--s-8); min-width: 0; max-width: 34vw; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.status::before { content: ""; display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: currentColor; margin-right: calc(7px * var(--density)); vertical-align: 1px; }
button.stop { color: var(--warn); border-color: var(--line); }
button.stop[hidden] { display: none; }
button.icon { padding: 0; width: 32px; min-height: 30px; justify-content: center; background: transparent; border-color: transparent; color: var(--dim); }
button.icon:hover:not(:disabled) { color: var(--ink); border-color: var(--line); background: var(--panel2); }
button.icon[aria-pressed="true"], button.icon[aria-expanded="true"] { color: var(--b); }
.progress-line { position: absolute; left: 0; right: 0; bottom: -1px; height: 2px; overflow: hidden; pointer-events: none; }
#progress-bar { height: 100%; width: 0; background: var(--b); transition: opacity .6s; }   /* no width transition: it updates every frame, and a restarting transition lags */
.progress-line.done #progress-bar { opacity: 0; transition-delay: .5s; }
/* solving: indeterminate shimmer — transform-only, so the compositor keeps it moving during a blocking solve */
.progress-line.solving #progress-bar { width: 35% !important; opacity: 1; animation: flux-shimmer 1.1s ease-in-out infinite; }
@keyframes flux-shimmer { from { transform: translateX(-100%); } to { transform: translateX(290%); } }
.progress-strip { position: absolute; left: 0; right: 0; top: 100%; height: 0; overflow: hidden; background: rgba(11,17,24,.92);
  border-bottom: 1px solid transparent; font: 11px/22px ui-monospace, SFMono-Regular, Menlo, monospace; color: var(--dim); padding: 0 calc(18px * var(--density));
  transition: height .18s ease, border-color .18s; pointer-events: none; }
.progress-strip.open { height: 22px; border-bottom-color: var(--line); }
@media (max-width: 560px) { .status { display: none; } .brand strong { letter-spacing: 3px; } }

#toast { position: fixed; left: 50%; bottom: 22px; z-index: 50; transform: translate(-50%, 12px); opacity: 0; pointer-events: none;
  padding: calc(7px * var(--density)) var(--s-14); border-radius: 8px; background: var(--panel2); border: 1px solid var(--line); color: var(--ink); font-size: 12px;
  box-shadow: 0 6px 20px rgba(0,0,0,.45); transition: opacity .18s, transform .18s; }
#toast.show { opacity: 1; transform: translate(-50%, 0); }

/* ---- stats footer: minimal readout + expandable details */

button.mini { min-height: 24px; padding: 1px var(--s-8); font-size: 11px; color: var(--dim); background: transparent; }
.min-limits { font-size: 12px; display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-14); }
.min-limits .bind.ok { color: var(--ok); }
.min-limits .note { color: var(--faint); }
#stats-full[hidden] { display: none; }
.notice { animation: flux-fade 1s ease forwards; animation-play-state: running; }
@keyframes flux-fade { to { opacity: 0; } }

/* ---- scene hint: shown on load / long idle / while dragging a handle */
.hint { opacity: 0; transition: opacity .4s; }
.hint.show, .hint.dragging { opacity: 1; }
/* ---- target canvases */
.reset-view { position: absolute; right: 4px; top: 4px; z-index: 2; width: 26px; min-height: 26px; font-size: 14px; opacity: .55; background: rgba(11,17,24,.6); }
.reset-view:hover { opacity: 1; }
/* In Drive the corner button is the always-visible expand / collapse (⤢ ⤡): full strength, and a touch-sized target on phones. */
.pane .reset-view[data-anim=popout], .pane:not(.active):not(:hover):not(:focus-within) .reset-view[data-anim=popout] { opacity: 1; }
.pane .reset-view[data-anim=popout]:disabled { opacity: .4; }
@media (pointer: coarse) { .reset-view[data-anim=popout] { width: 36px; min-height: 36px; font-size: 18px; } }
.colorbar { display: flex; flex-direction: column; gap: var(--s-2); font-size: 11px; color: var(--dim); }
.colorbar > i { display: block; height: 8px; border-radius: 2px; border: 1px solid var(--line); }
.colorbar .cb-labels { display: flex; justify-content: space-between; gap: 8px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.colorbar .cb-labels span { overflow: hidden; text-overflow: ellipsis; }   /* one line: a taller bar would resize (and refit) the map */
/* far-field colour bar with ticks: labels placed at their value, ends pinned */
.colorbar > i { position: relative; }
.colorbar > i > b { position: absolute; top: -2px; bottom: -2px; width: 1px; background: rgba(255,255,255,.55); }
.colorbar .cb-labels.ticks { display: block; position: relative; height: 1.25em; }
.colorbar .cb-labels.ticks span { position: absolute; top: 0; transform: translateX(-50%); }
.colorbar .cb-labels.ticks .end-l { left: 0; transform: none; }
.colorbar .cb-labels.ticks .end-r { right: 0; transform: none; }
/* far-field view toggles, floating in the canvas corner (Spec mode, Far field view only) */
.ff-tools { display: none; position: absolute; left: 4px; top: 4px; right: 4px; z-index: 2; gap: 2px; flex-wrap: wrap; pointer-events: none; }
body.mode-D .canvas-wrap.ff .ff-tools { display: flex; }
.ff-tools button { min-height: 22px; padding: 0 6px; font-size: 11px; background: rgba(11,17,24,.7); pointer-events: auto; }
/* drive-view controls (Spec mode, Drive view only) + the luminance readout under the pointer */
.drive-tools { display: none; position: absolute; left: 4px; top: 4px; right: 4px; z-index: 2; gap: 2px; flex-wrap: wrap; pointer-events: none; align-items: center; }
body.mode-D .canvas-wrap.drive .drive-tools { display: flex; }
.drive-tools button, .drive-tools select { min-height: 22px; padding: 0 6px; font-size: 11px; background: rgba(11,17,24,.7); pointer-events: auto; }
.drive-readout { position: absolute; left: 6px; bottom: 6px; z-index: 2; font-size: 11px; color: #fff; text-shadow: 0 0 3px #000, 0 0 3px #000; pointer-events: none; font-variant-numeric: tabular-nums; }
/* Animated Drive shares its controls and canvas with the full-viewport large view. */
.drive-gl { position: absolute; pointer-events: none; z-index: 1; }
.canvas-wrap:not(.drive) > .drive-gl, .canvas-wrap:not(.drive) > .drive-anim-tools { display: none; }
.drive-anim-tools { display: none; position: absolute; left: 4px; right: 4px; bottom: 4px; z-index: 2; gap: 4px; flex-wrap: wrap; pointer-events: none; align-items: center; font-size: 11px; color: #fff; }
body.mode-D .canvas-wrap.drive .drive-anim-tools:not([hidden]), .dp-stage .drive-anim-tools:not([hidden]) { display: flex; }
.drive-anim-tools button, .drive-anim-tools select { min-height: 22px; padding: 0 6px; font-size: 11px; background: rgba(11,17,24,.7); pointer-events: auto; }
.drive-anim-tools [hidden] { display: none; }
.drive-anim-tools input[type=range] { width: 110px; pointer-events: auto; }
.drive-anim-tools input.anim-seed { width: 58px; min-height: 22px; padding: 0 4px; font-size: 11px; pointer-events: auto; background: rgba(11,17,24,.7); color: #fff; border: 1px solid var(--line); border-radius: 4px; }
.drive-anim-tools .anim-speed { min-width: 54px; text-shadow: 0 0 3px #000, 0 0 3px #000; font-variant-numeric: tabular-nums; }
.drive-popout { position: fixed; inset: 0; z-index: 100; display: flex; flex-direction: column; box-sizing: border-box; padding: env(safe-area-inset-top, 0px) env(safe-area-inset-right, 0px) env(safe-area-inset-bottom, 0px) env(safe-area-inset-left, 0px); background: #05060a; overflow: hidden; }
.dp-head { display: flex; align-items: center; gap: 8px; padding: 4px 8px; font-size: 12px; border-bottom: 1px solid var(--line); }
.dp-head .dp-hint { margin-left: auto; color: var(--faint); }
.dp-stage { position: relative; flex: 1 1 0; min-height: 240px; background: #05060a; }
.dp-stage .drive-tools { display: flex; }
/* road-view toggles (Spec mode, Road view only): a wrapping row, kept off the right-hand notes */
.road-tools { display: none; position: absolute; left: 4px; top: 4px; right: 4px; z-index: 2; gap: 2px; flex-wrap: wrap; pointer-events: none; }
body.mode-D .canvas-wrap.road .road-tools { display: flex; }
.road-tools button { min-height: 22px; padding: 0 6px; font-size: 11px; background: rgba(11,17,24,.7); pointer-events: auto; }
.toolrow label.slider { display: inline-flex; align-items: center; gap: var(--s-6); }
.toolrow label.slider input[type=range] { width: 90px; }
.toolrow label.slider output { min-width: 2.5em; font-variant-numeric: tabular-nums; color: var(--dim); }

/* ---- warnings: normal-weight text with a coloured indent, not bold orange text */
.reason, .bind.bad, .notice { border-left: 2px solid var(--bad); padding-left: var(--s-8); color: var(--ink); font-weight: 400; }
.notice { border-left-color: var(--warn); color: var(--dim); }
.notices { color: var(--dim); }

/* limits list: one column of marks, every row indented the same; ✗ rows add the warning bar */
.feas ul { list-style: none; padding-left: 0; }
.feas li { position: relative; padding-left: calc(20px * var(--density)); border-left: 2px solid transparent; }
.feas li::before { position: absolute; left: 6px; top: 0; }
.feas li.ok::before { content: '✓'; color: var(--ok); }
.feas li.bad::before { content: '✗'; color: var(--bad); }
.feas li.bad { border-left-color: var(--bad); color: var(--ink); }
.feas li::marker { content: none; }
.feas > .reason { padding-left: calc(18px * var(--density)); }
/* "no limit binds": plain text, only the mark coloured */
.bind.ok { color: var(--ink) !important; } .bind.ok .mk { color: var(--ok); } .bind.bad .mk { color: var(--bad); }
.pane-head .modes button { min-height: 26px; padding: var(--s-2) var(--s-8); }
.side-top { padding-top: var(--s-6); }
#pattern-box .pat-name { flex: 1 1 90px; min-width: 70px; }

/* ---- number controls: slider + scrub field */
.numctl { display: inline-flex; align-items: center; gap: var(--s-8); min-width: 0; }
.numctl input[type=range] { width: 120px; min-height: 20px; }
input.scrub { width: 72px; text-align: right; cursor: ew-resize; touch-action: none; font-variant-numeric: tabular-nums; }
input.scrub:focus { cursor: text; }
input.scrub.scrubbing { border-color: var(--b); color: var(--b); }

.modes.seg { gap: 0; }
.pane-head .modes.seg { flex-wrap: wrap; max-width: 100%; }   /* a narrow pane: the tabs wrap rather than run past the edge (Spec was unreachable) */
/* sidebar copy of the mode tabs: always shown (the Editor's copy dims when that pane is inactive) */
.side-top .modes { display: flex; flex: 1 1 100%; }
.side-top .modes button { flex: 1; justify-content: center; }
@media (max-width: 760px) { :root { --density: 1.1; } }   /* phones: tighter */

/* ================================================================ workspace (sizes set inline by ui.layoutGrid ← layout.js) */
:root { --side-w: 300px; }
.app { flex: 1 1 0; min-height: 0; display: grid; grid-template-columns: minmax(0, 1fr) var(--side-w); }
body.side-hidden .app { grid-template-columns: minmax(0, 1fr) 0; }
body.side-hidden .side { display: none; }
.work-col { display: flex; flex-direction: column; min-width: 0; min-height: 0; padding: var(--s-8) var(--s-8) var(--s-8); gap: var(--s-8); }
.workspace { flex: 1 1 0; min-height: 0; display: grid; grid-template-columns: minmax(0, 1fr) 10px minmax(0, 1fr); }
.right { display: grid; grid-template-rows: minmax(0, 1fr) 10px minmax(0, 1fr); min-width: 0; min-height: 0; }
.pair { display: grid; min-width: 0; min-height: 0; }
.pane-tabs { display: none; }

/* sidebar: full height below the header, its own scroll; a sidebar, not a card */
.side { min-height: 0; overflow-y: auto; background: var(--panel); border-left: 1px solid var(--line);
  padding: 0 var(--s-10) calc(16px * var(--density)); }
.file-row { display: flex; flex: 1 1 100%; gap: var(--s-4); }
.file-row > * { flex: 1 1 auto; justify-content: center; font-size: 12px; padding-left: var(--s-6); padding-right: var(--s-6); }
button.text { background: transparent; border-color: transparent; color: var(--dim); padding: 0 var(--s-6); }
button.text:hover { color: var(--ink); border-color: var(--line); }

/* panes */
.pane { background: var(--panel); border: 1px solid var(--line); border-radius: 8px; min-width: 0; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }
.pane.active { border-color: #3d5a60; }
.pane-head { position: relative; display: flex; flex-wrap: wrap; align-content: flex-start; align-items: center; gap: var(--s-4) var(--s-6);
  padding: var(--s-4) 40px var(--s-4) var(--s-8); min-height: 40px; }
/* chevron + title stay top-left, ⤢ is pinned top-right; the tools follow the title and move to their own
   line (as a group) only when they don't fit, starting at the same x as the chevron and the map caption */
.pane-head > .collapse, .pane-head > h2 { height: 32px; min-height: 32px; display: inline-flex; align-items: center; }
.pane-head > h2 { padding-right: var(--s-6); }
.pane-head > .expand { position: absolute; top: var(--s-4); right: var(--s-6); height: 32px; min-height: 32px; }
.head-tools { flex: 0 1 auto; display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-4) var(--s-8); min-width: 0; min-height: 32px; }
.pane-head h2 { cursor: pointer; user-select: none; }
.pane-head .expand { font-size: 14px; width: 28px; justify-content: center; }
.pane-head .collapse { background: transparent; border-color: transparent; color: var(--faint); padding: 0; width: auto; min-width: 12px; justify-content: flex-start; }
.pane-head .collapse:hover { color: var(--ink); }
.pane .canvas-wrap { flex: 1 1 0; min-height: 0; }
figure.map { margin: 0; flex: 1 1 0; min-width: 0; min-height: 0; display: flex; flex-direction: column; gap: var(--s-4); padding: 0 var(--s-8) var(--s-8); }
figure.map > figcaption { color: var(--dim); font-size: 12px; }
figure.map .canvas-wrap.sq { aspect-ratio: auto; flex: 1 1 0; min-height: 0; }
/* caption + tools line up with the drawn square, not the letterboxed canvas box (--sq set by JS) */
figure.map > figcaption, figure.map > .toolrow, figure.map > .colorbar { width: var(--sq, 100%); min-width: min(100%, 240px); max-width: 100%; margin-left: auto; margin-right: auto; }

/* Editor | Result side by side: the two panes share their header / caption / tools rows (subgrid), so the two map squares sit at the same
   height however many lines each header wraps to (Result's view buttons wrap more than Editor's tabs) */
@media (min-width: 761px) {
  .pair:not(.stacked):not(.both-bars) { grid-template-rows: auto auto minmax(0, 1fr) auto !important; }
  .pair:not(.stacked):not(.both-bars) > .pane, .pair:not(.stacked):not(.both-bars) > .divider.pd { grid-row: 1 / span 4; }
  .pair:not(.stacked):not(.both-bars) > .pane:not(.collapsed) { display: grid; grid-template-rows: subgrid; container-type: normal; }   /* (size containment would stop it being a subgrid; no @container query reads .pane) */
  .pair:not(.stacked):not(.both-bars) > .pane:not(.collapsed) > figure.map { display: grid; grid-template-rows: subgrid; grid-row: 2 / span 3; gap: var(--s-4); }
}

/* collapsed: a BAR (header only) in a stacked split, a RAIL (vertical strip) in a side-by-side one; click restores */
.pane.collapsed { cursor: pointer; }
.pane.collapsed > :not(.pane-head) { display: none !important; }
.pane.collapsed .pane-head > :not(h2):not(.collapse) { display: none; }
.pane.collapsed .collapse { transform: rotate(-90deg); }


.pane.rail .pane-head { flex-direction: column; flex-wrap: nowrap; height: 100%; padding: var(--s-6) 0; gap: var(--s-8); align-items: center; }
.pane.rail h2 { writing-mode: vertical-rl; white-space: nowrap; }
.pane.collapsed:hover { border-color: var(--dim); }

/* dividers: the gaps between panes are the drag handles */
.divider { position: relative; touch-action: none; outline: none; }
.divider.v, .pair:not(.stacked) > .divider.pd { cursor: col-resize; }
.divider.h, .pair.stacked > .divider.pd { cursor: row-resize; }
.divider::after { content: ''; position: absolute; border-radius: 2px; background: var(--line); opacity: 0; transition: opacity .15s; }
.divider.v::after, .pair:not(.stacked) > .divider.pd::after { left: 4px; width: 2px; top: 40%; height: 20%; }
.divider.h::after, .pair.stacked > .divider.pd::after { top: 4px; height: 2px; left: 40%; width: 20%; }
.divider:hover::after, .divider:focus-visible::after, .divider.dragging::after { opacity: 1; background: var(--b); }
.divider.off { pointer-events: none; }
.pair.both-bars > .divider.pd { pointer-events: none; }

/* footer: under the panes only */
.stats-panel { flex: none; position: relative; padding: var(--s-6) var(--s-10); background: var(--panel); border: 1px solid var(--line); border-radius: 8px;
  container-type: inline-size; }
.foot { display: flex; align-items: center; gap: var(--s-6) calc(18px * var(--density)); flex-wrap: wrap; }
.heads { display: flex; align-items: center; gap: calc(16px * var(--density)); flex-wrap: wrap; }
.tile { display: flex; flex-direction: column; gap: 1px; cursor: help; }
.tile b { font-size: 15px; font-weight: 600; font-variant-numeric: tabular-nums; line-height: 1.1; }
.tile span { color: var(--faint); font-size: 10px; letter-spacing: .03em; }
.tile.capped b::after { content: '≈'; color: var(--faint); font-weight: 400; margin-left: 2px; }   /* at the noise ceiling */
.tile-sep { width: 1px; align-self: stretch; background: var(--line); }
.tile.rays b { font-size: 13px; color: var(--dim); font-weight: 500; }
.tile .ms { color: #46545f; font-size: 9px; margin-left: 3px; }   /* a teensy fun detail */
.foot-mid { flex: 1 1 120px; min-width: 0; display: flex; flex-direction: column; gap: var(--s-4); }
.foot-mid .energy { height: 7px; border: 0; border-radius: 2px; opacity: .85; }
.min-limits { font-size: 12px; line-height: 16px; display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-6); }
.min-limits .issue { color: var(--ink); }
.min-limits .issue .mk { color: var(--warn); font-weight: 700; }
/* a single-row footer: keep two lines of limits text, so the PREVIEW tile squeezing the text onto a second line doesn't make the footer (and every pane) grow mid-solve */
@container (min-width: 1100px) { .min-limits { min-height: 32px; } }
/* the energy bar only when the footer has room for it */
@container (max-width: 900px) { .foot-mid .energy { display: none; } }
/* Details: opens upward over the panes, bounded, scrolls itself */
.drawer { position: absolute; left: -1px; right: -1px; bottom: calc(100% + var(--s-6)); z-index: 20; max-height: min(62vh, 560px); overflow-y: auto;
  background: var(--panel); border: 1px solid #3a4b57; border-radius: 10px; padding: var(--s-8) var(--s-14) var(--s-14); box-shadow: 0 -10px 40px rgba(0,0,0,.5); }
.drawer[hidden] { display: none; }
.drawer-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--s-6); }
.drawer-head h3 { margin: 0; font-size: 13px; }
/* transient notices float above the footer instead of growing it */
.stats-panel > .notices { position: absolute; left: var(--s-10); bottom: calc(100% + var(--s-6)); z-index: 19; margin: 0; pointer-events: none; max-width: 70%; }
.stats-panel > .notices .notice { background: rgba(17,27,37,.94); padding: var(--s-4) var(--s-8); border-radius: 0 6px 6px 0; margin-top: var(--s-4); }

/* ---- phone: one pane at a time (tab strip), sidebar overlays */
@media (max-width: 760px) {
  body { height: auto; min-height: 100dvh; overflow: visible; }
  .app { display: block; }
  .work-col { padding: var(--s-6); }
  .pane-tabs { display: flex; gap: 2px; }
  .pane-tabs button { flex: 1; min-height: 38px; background: transparent; border-color: transparent; color: var(--dim); }
  .pane-tabs button.on { color: var(--ink); background: var(--panel2); border-color: var(--line); }
  .workspace { flex: none; }
  .workspace, .right, .pair { display: block; }
  .topbar { padding: 0 var(--s-6) 0 var(--s-10); gap: var(--s-6); }
  .hdr-right { gap: 0; }
  .hdr-right button.text { padding: 0 5px; }
  .hdr-right button.icon { width: 28px; }
  .brand strong { letter-spacing: 2px; }
  .divider { display: none; }
  .pane { height: min(78vh, calc(100vw + 120px)); }
  .pane.phone-hidden { display: none; }
  .pane-head .collapse, .pane-head .expand { display: none; }
  .stats-panel { max-height: none; }
}
.head-tools button, .head-tools label { white-space: nowrap; flex: none; }
/* narrow pane: the tools drop to their own full-width line under the title (reacts to the pane's width, not the window's) */
.pane { container-type: inline-size; }

/* inactive panes: tools dim (not hidden — no layout shift, and touch has no hover); full on hover / focus / active */
.pane .head-tools, .pane .toolrow, .pane .reset-view { transition: opacity .15s; }
.pane:not(.active):not(:hover):not(:focus-within) :is(.head-tools, .toolrow) { opacity: .45; }
.pane:not(.active):not(:hover):not(:focus-within) .reset-view { opacity: .25; }

/* ---- ≤1024px: the sidebar overlays (panes keep their split layout); a press outside closes it */
@media (max-width: 1024px) {
  .app { grid-template-columns: minmax(0, 1fr) !important; }
  .side { position: fixed; top: 48px; right: 0; bottom: 0; width: min(var(--side-w), 88vw); z-index: 25; border-left: 1px solid var(--line);
    box-shadow: -8px 0 24px rgba(0,0,0,.5); }
  body.side-hidden .side { display: block; transform: translateX(103%); visibility: hidden; }
}

/* ---- footer + Details = one shape: the drawer grows out of the footer's top edge */
.drawer { bottom: calc(100% - 1px); left: -1px; right: -1px; border-color: var(--line); border-bottom: 0; border-radius: 10px 10px 0 0;
  box-shadow: 0 -12px 32px rgba(0,0,0,.45); }
.stats-panel.open { border-top-left-radius: 0; border-top-right-radius: 0; border-top-color: transparent; }
.stats-panel.open .foot { border-top: 1px solid var(--line); margin-top: calc(-1 * var(--s-6)); padding-top: var(--s-6); }
.drawer { background: var(--panel); }

/* ---- Editor / Result: identical chrome under both maps, so the two squares come out the same size */
figure.map > figcaption { min-height: 17px; }
figure.map > .toolrow, figure.map > .colorbar { min-height: 34px; box-sizing: border-box; }
figure.map > .colorbar { justify-content: center; }
.toolrow { flex-wrap: wrap; }
.brushctl { display: inline-flex; align-items: center; gap: var(--s-4); color: var(--dim); font-size: 11px; }
.brushctl input[type=range] { width: 60px; min-height: 20px; }
.btn-pair { display: inline-flex; gap: var(--s-4); white-space: nowrap; }
.toolrow button { min-height: 24px; padding: 0 var(--s-8); font-size: 12px; }
button.toggle[aria-pressed="true"] { background: #3a2f1f; color: var(--warn); border-color: #6b5530; }

/* ---- motion (only when the user hasn't asked for less) */
@media (prefers-reduced-motion: no-preference) {
  .workspace.animating, .workspace.animating .right, .workspace.animating .pair { transition: grid-template-columns .26s cubic-bezier(.2,.7,.2,1), grid-template-rows .26s cubic-bezier(.2,.7,.2,1); }
  .drawer:not([hidden]) { animation: flux-drawer .2s cubic-bezier(.2,.7,.2,1); }
  @keyframes flux-drawer { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
  .side { transition: transform .2s ease, visibility .2s; }
  .pane.collapsed .collapse, .pane .collapse { transition: transform .2s; }
}

/* inspector selection chip (Optics, Result) */
.sel-chip { position: absolute; left: 8px; top: 8px; display: flex; align-items: center; gap: 6px; max-width: calc(100% - 56px);
  padding: 2px 4px 2px 9px; border-radius: 999px; background: rgba(12,13,16,.82); border: 1px solid rgba(242,180,65,.55);
  color: #f2d7a0; font-size: 11.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; z-index: 2; }
.sel-chip[hidden] { display: none; }
.sel-chip span { overflow: hidden; text-overflow: ellipsis; }
.sel-chip button { width: 20px; height: 20px; min-height: 0; padding: 0; font-size: 11px; border-radius: 50%; }

/* expanded Optics: the selection's numbers */
.insp-panel { position: absolute; right: 8px; top: 8px; bottom: 8px; width: min(260px, 45%); overflow: auto; z-index: 2;
  padding: 8px 10px; border-radius: 8px; background: rgba(12,13,16,.86); border: 1px solid var(--line); font-size: 12px; }
.insp-panel[hidden] { display: none; }
.insp-panel h4 { margin: 0 0 6px; font-size: 12px; color: #f2d7a0; }
.insp-panel .ir { display: flex; justify-content: space-between; gap: 10px; padding: 3px 0; border-top: 1px solid rgba(255,255,255,.05); }
.insp-panel .ir span { color: var(--dim); }
.insp-panel .ir b { font-weight: 600; font-variant-numeric: tabular-nums; text-align: right; }
.stats-sub { grid-column: 1 / -1; margin: 6px 0 0; font-size: 11px; color: var(--dim); text-transform: uppercase; letter-spacing: .06em; }
.pane.insp-open #surface-canvas { width: calc(100% - min(260px, 45%) - 16px) !important; }

#heat-display button { padding-left: 8px; padding-right: 8px; }   /* four views fit where three did */
/* Result: the view buttons keep their size and drop below the title when the header is narrow (never overflow) */
.head-tools:has(#heat-display) { flex: 0 0 auto; max-width: 100%; }   /* (the head's padding already leaves room for ⤢; -40px broke Fidelity off by 3 px at 1500) */
#heat-display { flex-wrap: wrap; }   /* a very narrow pane: the buttons wrap rather than spill past the edge */
.side details.solver-adv { border-bottom: 0; padding: var(--s-4, 6px) 0 0; }
.side details.solver-adv > summary { font-size: 12px; color: var(--dim); }
/* the design is out of date with the sidebar settings: Rebuild asks for a press (a ring + a dot, not colour alone) */
button.primary.stale { box-shadow: 0 0 0 2px var(--warn); }
button.primary.stale::after { content: ' •'; }

/* ---- a solve is running (body.solving): make it obvious, esp. on a phone where the header status is hidden.
   The Rebuild buttons carry a spinner, the strip's text and the Result map carry a slow light sweep.  Transform /
   background-position only, so the compositor keeps them moving; still indicators when motion is reduced. */
#btn-generate-top, #btn-generate { justify-content: center; }
#btn-generate-top { min-width: 7.5em; } #btn-generate { min-width: 12em; }   /* hold the width the solving spinner adds, so nothing beside the button shifts */
body.solving #btn-generate-top::before, body.solving #btn-generate::before { content: ''; width: 10px; height: 10px; margin-right: 6px; border-radius: 50%;
  border: 2px solid currentColor; border-right-color: transparent; display: inline-block; vertical-align: -1px; box-sizing: border-box; }
body.solving .canvas-wrap:has(> #heat-canvas) { position: relative; overflow: hidden; }
body.solving .canvas-wrap:has(> #heat-canvas)::after { content: 'solving…'; position: absolute; inset: 0; pointer-events: none; display: flex; align-items: flex-end; justify-content: flex-end;
  padding: 6px 8px; font: 10px/1 ui-monospace, SFMono-Regular, Menlo, monospace; letter-spacing: .8px; text-transform: uppercase; color: var(--b);
  background: linear-gradient(100deg, transparent 30%, rgba(90,167,255,.10) 50%, transparent 70%) no-repeat; background-size: 250% 100%; background-position: 100% 0; }
@media (prefers-reduced-motion: no-preference) {
  body.solving #btn-generate-top::before, body.solving #btn-generate::before { animation: flux-spin .8s linear infinite; }
  @keyframes flux-spin { to { transform: rotate(360deg); } }
  body.solving .canvas-wrap:has(> #heat-canvas)::after { animation: flux-sweep 1.6s ease-in-out infinite; }
  @keyframes flux-sweep { from { background-position: 100% 0; } to { background-position: -150% 0; } }
  /* the gradient must cover the text at every frame (a no-repeat image slid past the edge left the text blank) */
  body.solving #progress-text { background: linear-gradient(90deg, var(--dim) 0 40%, var(--ink) 50%, var(--dim) 60% 100%); background-size: 200% 100%;
    -webkit-background-clip: text; background-clip: text; color: transparent; animation: flux-textsweep 1.8s linear infinite; }
  @keyframes flux-textsweep { from { background-position: 100% 0; } to { background-position: 0% 0; } }
}

.rows-in { width: 100%; min-height: 72px; background: #0d151e; border: 1px solid var(--line); border-radius: var(--r); color: inherit; font: 12px/1.4 ui-monospace, monospace; padding: var(--s-4); }
/* watching a solve (tools.preview): the badge over each view while a preview is drawn, and the notice a solve that
   stopped without a result leaves (it stays until dismissed, unlike the fading notices) */
.watch-badge { position: absolute; left: 50%; top: 6px; transform: translateX(-50%); z-index: 3; pointer-events: auto; max-width: calc(100% - 80px); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font: 600 10.5px/1.6 system-ui; letter-spacing: .04em; color: #f3d7f6; background: rgba(60,22,70,.82); border: 1px solid rgba(226,120,236,.7); border-radius: 4px; padding: 0 8px; }
.watch-badge.failed { color: #ffd9b0; background: rgba(70,40,14,.86); border-color: rgba(255,154,61,.8); }
.watch-badge[hidden] { display: none; }
.notices .solve-fail { pointer-events: auto; display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-4) var(--s-8); background: rgba(40,26,14,.96); color: var(--ink);
  border-left: 3px solid var(--warn); padding: var(--s-4) var(--s-8); border-radius: 0 6px 6px 0; margin-top: var(--s-4); font-size: 12px; }
.notices .solve-fail button { font-size: 12px; min-height: 24px; padding: 0 var(--s-8); }
/* a solve's PREVIEW badge takes the corner: the far-field toggles step below it */
.canvas-wrap:has(> .watch-badge:not([hidden])) > .ff-tools { top: 30px; }
/* the facets tile names the solver: keep it to one short line */
.tile.facets span { max-width: 170px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* far-field hover / tap card for one spec item */
.spec-card { position: absolute; z-index: 3; max-width: 270px; padding: 6px 8px; border: 1px solid var(--line); border-radius: 6px; background: rgba(11,17,24,.95); font-size: 11px; line-height: 1.35; pointer-events: none; }
.spec-card .sc-h b { font-size: 12px; }
.spec-card .sc-h span, .spec-card .sc-l, .spec-card .sc-n { color: var(--dim); }
.spec-card .sc-n { margin-top: 3px; font-size: 10px; }
.spec-card .mk { display: inline-block; width: 1em; }
.spec-card .v-fail { color: #ff9a3d; } .spec-card .v-pass { color: #5aa7ff; } .spec-card .v-unsure { color: #f2b441; }

/* ---- overflow trims (sidebar + phones), 2026-10-05 */
/* a <select> sizes itself to its longest option (solver and preset names): let it shrink to the space it has */
.side select, .side-top select { max-width: 100%; min-width: 0; }
.row { grid-template-columns: minmax(min(40%, 7em), 1fr) minmax(0, auto); }   /* the label keeps ~7em; the control gets the rest */
.row > select { max-width: 100%; }
.side-top { flex-wrap: wrap; }
.side-top > * { min-width: 0; }
.side-top > select { flex: 1 1 100%; }
@media (max-width: 760px) {
  /* Details: one column (two squeezed into a phone wrapped the labels a word per line) */
  .stats-grid { grid-template-columns: 1fr; }
  .feas { border-left: 0; padding-left: 0; border-top: 1px solid var(--line); padding-top: var(--s-8); }
  .stats { grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); }
  /* the solving status line floats under the top bar: make room for it instead of covering the pane tabs */
  body:has(.progress-strip.open) .work-col { padding-top: calc(var(--s-6) + 22px); }
  /* constraint table: a little tighter so its delete buttons stay inside the sidebar */
  .spec-table .st-row { grid-template-columns: 14px minmax(30px, 1fr) 32px 32px 42px 42px 16px; gap: 2px; }
}
@media (max-width: 420px) {
  .brand strong { display: none; }   /* the top bar's buttons need the room more than the wordmark */
}
.spec-table .st-row .icon { width: 100%; }   /* a global .icon is 32px wide: it spilled past its 16–18px column */
.side input[type=range] { max-width: 100%; min-width: 0; }
/* footer showing a solve's traced candidate (Live numbers from previews): tagged, values dimmed */
#min-row.pv .tile:not(.pv-tag) b { opacity: .7; font-style: italic; }
#min-row .pv-tag b { color: #f3d7f6; font-size: 11px; letter-spacing: .06em; }
#min-row .pv-tag { padding: 0 6px; border-left: 2px solid rgba(226,120,236,.7); max-width: 160px; }
#min-row .pv-tag span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Spec-mode footer: verdict counts in the overlay's colours (blue / orange / amber — no red-green) */
#min-row .spec-v b span.v-pass, #min-row .spec-worst.v-pass b { color: #5aa7ff; }
#min-row .spec-v b span.v-fail, #min-row .spec-worst.v-fail b { color: #ff9a3d; }
#min-row .spec-v b span.v-unsure, #min-row .spec-worst.v-unsure b { color: #f2b441; }
#min-row .spec-worst b { max-width: 140px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Spec, Result pane NOT expanded: sized like Mode A's. The extra Spec controls (the view buttons Road / Drive / Far field and the toolbars over the map)
   show only when the pane is expanded; a faint hint says so after a moment.  Phones (tabbed panes, no ⤢) keep everything. */
@media (min-width: 761px) {
  body.mode-D .result-pane:not(.expanded) :is(.ff-tools, .road-tools, .drive-tools, .drive-anim-tools, .drive-game, .drive-gl, [data-disp=road], [data-disp=drive], [data-disp=ff]) { display: none !important; }
  body.mode-D .pair:not(.stacked) > .pane:not(.collapsed):not(.expanded) > figure.map > figcaption { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  body.mode-D .result-pane:not(.expanded):not(.collapsed) .canvas-wrap::after { content: 'Expand for more options'; position: absolute; left: 6px; bottom: 4px; z-index: 2; font-size: 11px; color: var(--faint);
    pointer-events: none; opacity: 0; animation: expand-hint .6s ease 5s forwards; }
}
@keyframes expand-hint { to { opacity: .75; } }

/* A/B comparison is opt-in; the ordinary Result canvas keeps its own layout. */
.ab-tools { display:flex; gap:6px; flex-wrap:wrap; padding:5px 10px; align-items:center; }
.ab-tools details { margin-left:auto; max-width:420px; font-size:12px; }
.ab-tools details[open] { flex-basis:100%; max-width:none; }
.ab-tools details label { display:block; margin:6px 0; }
#ab-dialog { width:min(1100px, 94vw); max-height:90vh; overflow:auto; color:var(--text, #ddd); background:var(--panel, #171d27); border:1px solid #607087; border-radius:8px; padding:16px; }
#ab-dialog::backdrop { background:#0009; }
#ab-dialog h2 { margin:0 0 10px; }
.ab-controls { display:flex; flex-wrap:wrap; gap:8px; align-items:center; }
#ab-rays { width:105px; }
#ab-maps { display:grid; grid-template-columns:1fr 1fr; gap:10px; }
#ab-maps.single { grid-template-columns:1fr; }
#ab-maps[hidden], #ab-maps figure[hidden] { display:none; }
#ab-maps figure { margin:0; min-width:0; }
#ab-maps figcaption { padding:5px 0; }
#ab-maps canvas { display:block; width:100%; height:auto; background:#00204d; }
#ab-table { width:100%; border-collapse:collapse; font-size:12px; }
#ab-table th, #ab-table td { text-align:right; padding:5px; border-bottom:1px solid #60708755; }
#ab-table th:first-child { text-align:left; }
#ab-table .ab-up td:last-child { color:#80bbff; font-weight:bold; }
#ab-table .ab-down td:last-child { color:#ffb16d; font-weight:bold; }
/* Export choices stay beside the scene download; reasons remain readable on touch devices. */
.side .file-row { position: relative; }
.side details.export-menu { position: static; padding: 0; border: 0; }
.side .export-menu summary { cursor: pointer; padding: 3px 6px; white-space: nowrap; font-weight: 400; border: 1px solid var(--line); border-radius: var(--r); background: var(--panel2); }
.export-options { position: absolute; z-index: 20; right: 0; top: 100%; width: 270px; padding: 10px; display: grid; gap: 5px; background: var(--panel); border: 1px solid var(--dim); border-radius: 6px; box-shadow: 0 5px 20px #0008; }
.export-options small { font-size: 11px; line-height: 1.4; }
.export-options small:empty { display: none; }
.export-options label { font-size: 12px; }

/* Setup and scorecards dock below the picture; the running HUD uses the same compact dock. */
.drive-game { position: static; width: 100%; box-sizing: border-box; overflow: auto; padding: 8px; background: rgba(5,10,18,.93); color: #eee; border: 1px solid #889bb5; border-radius: 6px; font-size: 12px; }
.drive-game[hidden], .drive-game [hidden] { display: none; }
.canvas-wrap:not(.drive) > .drive-game { display: none; }
.game-setup { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 6px 0; }
.drive-game input { width: 70px; }
.drive-game input, .drive-game select, .drive-game button { min-height: 32px; }
.drive-game [data-game=brake] { min-width: 96px; min-height: 44px; touch-action: none; user-select: none; background: #233f68; color: white; }
.drive-game [data-game=brake][aria-pressed=true] { outline: 2px solid #ffd580; }
.game-card { white-space: pre-line; margin: 8px 0; line-height: 1.5; }
.drive-game small { display: block; margin-top: 4px; }

.drive-game.running:not([hidden]) { display: flex; align-items: center; gap: 6px; padding: 4px 8px; }
.drive-game.running > strong, .drive-game.running > small, .drive-game.running .game-setup > label, .drive-game.running .game-setup > select { display: none; }
.drive-game.running .game-setup { margin: 0; flex-wrap: nowrap; flex: none; order: 1; }
.drive-game.running [data-game=status] { flex: 1; min-width: 0; font-size: 11px; line-height: 13px; }

/* WCAG 2.5.5 enhanced target: https://www.w3.org/WAI/WCAG22/Understanding/target-size-enhanced */

.drive-tools { z-index: 3; }
/* Drive: compact controls wrap; advanced controls share one More panel. */
.canvas-wrap > .drive-tools, .dp-stage > .drive-tools { right: 42px; }
.drive-tools, .drive-fit > .drive-tools { flex-direction: column; align-items: stretch; flex-wrap: nowrap; overflow: visible; white-space: normal; pointer-events: auto; background: rgba(5,10,18,.7); }
.drive-primary { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; min-width: 0; white-space: normal; }
.drive-fit .drive-primary { gap: 4px; }
.drive-primary > * { flex: 0 1 auto; max-width: 100%; min-width: 0; }
.drive-primary select { max-width: 160px; }
.drive-speed { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 4px; font-size: 11px; font-variant-numeric: tabular-nums; color: #fff; }
.drive-speed input[type=range] { width: 85px; pointer-events: auto; }
.drive-more { margin: 0; padding: 0; border: 0; min-width: 0; }
.drive-more > summary { cursor: pointer; padding: 3px 5px; font-size: 11px; color: #fff; }
.drive-extras { position: absolute; top: calc(100% + 4px); left: 0; right: 0; display: flex; align-items: center; flex-wrap: wrap; gap: 4px; padding: 6px; max-height: min(45vh, 280px, var(--drive-extra-height, 280px)); overflow: auto; box-sizing: border-box; background: rgba(5,10,18,.95); }
.drive-extras > * { min-width: 0; max-width: 100%; overflow-wrap: anywhere; }
.drive-extras .drive-anim-tools { position: static; flex: 1 0 100%; flex-wrap: wrap; pointer-events: auto; }
.drive-extras .drive-anim-tools > * { max-width: 100%; }
.drive-aim { flex: 1 0 100%; font-size: 11px; color: #d4deec; }
.drive-extras[hidden], .drive-below[hidden] { display: none; }
.drive-game [data-game=brake] { user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
.drive-game { touch-action: manipulation; }
.drive-game input[type=checkbox] { width: auto; }
.drive-notice { position: absolute; left: 8px; right: 8px; top: var(--drive-toolbar-bottom, 80px); z-index: 4; padding: 4px 8px; background: #17283e; color: #fff; font-size: 12px; pointer-events: none; }
.drive-notice[hidden], .canvas-wrap:not(.drive) > .drive-notice { display: none; }
.drive-notice.drive-proto { right: auto; width: max-content; max-width: 70%; transition: opacity .4s; }
.drive-notice.drive-proto.fading { opacity: 0; }
.drive-fps { position: absolute; right: 6px; top: var(--drive-toolbar-bottom, 80px); z-index: 2; padding: 2px 4px; color: #e5efff; background: #050a12b8; font: 10px/1.35 monospace; font-variant-numeric: tabular-nums; pointer-events: none; }
.drive-perf { position: absolute; left: 6px; top: calc(var(--drive-toolbar-bottom, 80px) + 24px); z-index: 2; max-width: calc(100% - 12px); max-height: min(45%, calc(100% - var(--drive-toolbar-bottom, 80px) - 30px)); overflow: auto; box-sizing: border-box; padding: 4px 6px; white-space: pre-wrap; overflow-wrap: anywhere; pointer-events: auto; touch-action: pan-y; background: rgba(5,10,18,.85); color: #e5efff; font: 10px/1.35 monospace; font-variant-numeric: tabular-nums; }
.drive-perf[hidden], .drive-fps[hidden], .canvas-wrap:not(.drive) > :is(.drive-perf, .drive-fps) { display: none; }
.drive-below:empty, .drive-below:not(:has(> :not([hidden]))), body:not(.mode-D) .drive-below, figure.map:not(:has(> .canvas-wrap.drive)) > .drive-below { display: none; }
.drive-below { flex: none; min-width: 0; width: 100%; box-sizing: border-box; }
.drive-below > .drive-game, .drive-below > .drive-game.running { position: static; width: 100%; max-height: none; margin: 4px 0 0; overflow: visible; }
figure.map:has(> .drive-below > .drive-game:not([hidden])) { display: flex !important; }
figure.map:has(> .drive-below > .drive-game:not([hidden])) > .canvas-wrap { min-height: 240px; }
figure.map > .drive-below:has(> .drive-game:not([hidden])) { flex-shrink: 1; max-height: 40%; overflow: auto; }
.drive-popout > .drive-below { flex-shrink: 1; max-height: 40%; overflow: auto; overscroll-behavior: contain; }
@media (max-width: 760px), (pointer: coarse) {
  body.mode-D:has(.canvas-wrap.drive) { height: auto; overflow: auto; }
  .result-pane:not(.phone-hidden):not(.collapsed):has(.canvas-wrap.drive) { height: auto !important; display: flex !important; }
  .result-pane:not(.phone-hidden):not(.collapsed):has(.canvas-wrap.drive) > figure.map { display: flex !important; flex: none; }
  .result-pane figure.map > .canvas-wrap.drive { flex: none; height: clamp(320px, 56.25vw, 600px); min-height: 320px; }
  .dp-stage { min-height: 320px; }
  figure.map > .drive-below:has(> .drive-game:not([hidden])) { max-height: none; overflow: visible; }
  .drive-below > :is(.drive-extras, .drive-perf) { position: static; width: 100%; max-width: 100%; max-height: none; margin: 4px 0 0; overflow: visible; }
  .drive-below .drive-anim-tools:not([hidden]) { display: flex; }
  .drive-below .drive-extras :is(button,select), .drive-tools :is(button,select), .drive-more > summary { min-height: 32px; }
  .drive-below .drive-extras select { max-width: 100%; }
}
@media (pointer: coarse) {
  figure.map > .drive-below:has(> .drive-game:not([hidden])) { padding-bottom: calc(env(safe-area-inset-bottom, 0px) + 96px); }
  .drive-popout { padding-bottom: calc(env(safe-area-inset-bottom, 0px) + 96px); }
}
/* Touch laptops/tablets keep their desktop columns, but rows must grow with More. */
@media (min-width: 761px) and (pointer: coarse) {
  body.mode-D:has(.canvas-wrap.drive) { display: block; min-height: 100dvh; }
  .app:has(.canvas-wrap.drive) { min-height: calc(100dvh - 48px); }
  .workspace:has(.canvas-wrap.drive) { flex: none; }
  .right:has(.canvas-wrap.drive) { grid-template-rows: auto 10px auto !important; align-content: start; }
  .pair:has(.canvas-wrap.drive) { grid-template-rows: auto !important; }
}

/* Recovery stays above the workspace on phones and desktop. */
.recovery-banner { padding: 8px 12px; background: #443b23; color: #fff1ca; position: relative; z-index: 60; }
.recovery-banner[hidden] { display: none; }

.first-guide { position: fixed; top: 65px; right: 12px; width: min(320px, calc(100vw - 24px)); padding: 14px; background: #172631; color: #deedf4; border: 1px solid #5c8192; border-radius: 8px; z-index: 55; box-shadow: 0 6px 24px #0008; font-size: 13px; }
.first-guide ol { padding-left: 20px; }
.first-guide li { margin: 8px 0; }
.first-guide[hidden] { display: none; }
/* GS: phones get a bottom sheet so the top bar, pane tabs and drive bar stay clickable on first visit. */
@media (max-width: 900px) { .first-guide { top: auto; bottom: 0; left: 16px; right: 16px; width: auto; max-height: 45vh; overflow-y: auto; padding-bottom: calc(14px + env(safe-area-inset-bottom, 0px)); border-radius: 8px 8px 0 0; box-shadow: 0 -6px 24px #0008; } }
