/* AstraLayer — engineering dashboard, Apple‑style visual language */
:root {
  color-scheme: light;
  --bg: #f5f5f7;
  --card: #ffffff;
  --card-border: rgba(0, 0, 0, 0.06);
  --card-shadow: 0 1px 2px rgba(0, 0, 0, 0.04), 0 8px 24px rgba(0, 0, 0, 0.05);
  --ink: #1d1d1f;
  --ink-2: #515154;
  --ink-3: #86868b;
  --line: rgba(0, 0, 0, 0.08);
  --grid: rgba(0, 0, 0, 0.07);
  --accent: #0071e3;
  --accent-ink: #ffffff;
  --control: rgba(120, 120, 128, 0.12);
  --control-active: #ffffff;
  --input: #ffffff;
  --input-border: rgba(0, 0, 0, 0.12);
  --focus: rgba(0, 113, 227, 0.35);
  --series-current: #2a78d6;
  --series-current-fill: rgba(42, 120, 214, 0.10);
  --series-target: #1d1d1f;
  --series-gdd: #c47a12;
  --pol-s: #0a9bb5;
  --pol-p: #c2479c;
  --mat-h: #6250d6;
  --mat-h-fill: rgba(98, 80, 214, 0.78);
  --mat-l: #1baf7a;
  --mat-l-fill: rgba(27, 175, 122, 0.70);
  /* the additional materials of a task of several materials (2.18): M₁ … M₄ */
  --mat-m1: #1b8fc2;
  --mat-m1-fill: rgba(27, 143, 194, 0.74);
  --mat-m2: #c53f8e;
  --mat-m2-fill: rgba(197, 63, 142, 0.72);
  --mat-m3: #b8860b;
  --mat-m3-fill: rgba(184, 134, 11, 0.74);
  --mat-m4: #6f7f98;
  --mat-m4-fill: rgba(111, 127, 152, 0.76);
  --needle: #eb6834;
  --needle-fill: rgba(235, 104, 52, 0.18);
  --source: #c99700;              /* light source × detector profile on the spectrum (2.12.2) */
  --source-fill: rgba(217, 164, 0, 0.13);
  --substrate: #c7c7cc;
  --field: #c81e4a;               /* the electric field |E|² on the structure chart (2.15) */
  --field-fill: rgba(200, 30, 74, 0.10);
  --good: #1a8f3f;
  --bad: #d13b2f;
  --font: -apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Pro Display", "Helvetica Neue", Inter, Segoe UI, Roboto, sans-serif;
  --mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  --radius: 18px;
  --chart-fs: 11px;   /* tick labels and axis titles on the canvases (12 px in the wide three‑column layout) */
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --bg: #000000;
    --card: #1c1c1e;
    --card-border: rgba(255, 255, 255, 0.08);
    --card-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
    --ink: #f5f5f7;
    --ink-2: #c7c7cc;
    --ink-3: #8e8e93;
    --line: rgba(255, 255, 255, 0.10);
    --grid: rgba(255, 255, 255, 0.09);
    --accent: #0a84ff;
    --control: rgba(120, 120, 128, 0.24);
    --control-active: #636366;
    --input: #2c2c2e;
    --input-border: rgba(255, 255, 255, 0.14);
    --series-current: #3987e5;
    --series-current-fill: rgba(57, 135, 229, 0.16);
    --series-target: #f5f5f7;
    --series-gdd: #e8a04a;
    --pol-s: #2fb8d1;
    --pol-p: #e05fb6;
    --mat-h: #9085e9;
    --mat-h-fill: rgba(144, 133, 233, 0.80);
    --mat-l: #199e70;
    --mat-l-fill: rgba(25, 158, 112, 0.75);
    --mat-m1: #45b0e0;
    --mat-m1-fill: rgba(69, 176, 224, 0.78);
    --mat-m2: #e068b5;
    --mat-m2-fill: rgba(224, 104, 181, 0.76);
    --mat-m3: #d9a640;
    --mat-m3-fill: rgba(217, 166, 64, 0.78);
    --mat-m4: #9aabc4;
    --mat-m4-fill: rgba(154, 171, 196, 0.78);
    --needle: #d95926;
    --source: #e0b23a;
    --source-fill: rgba(224, 178, 58, 0.16);
    --needle-fill: rgba(217, 89, 38, 0.22);
    --substrate: #3a3a3c;
    --field: #ff5c8a;
    --field-fill: rgba(255, 92, 138, 0.14);
    --good: #30d158;
    --bad: #ff453a;
  }
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }
html, body { height: 100%; }
body {
  margin: 0; background: var(--bg); color: var(--ink); font-family: var(--font);
  font-size: 14px; line-height: 1.35; -webkit-font-smoothing: antialiased;
  display: flex; flex-direction: column; height: 100vh;
}
/* iPad Safari: 100vh is the height with the browser's toolbar collapsed, so the bottom of a page that fills 100vh stays
   under the toolbar (the x‑axis labels of the lowest charts) until the page is scrolled; 100dvh is what is visible now */
@supports (height: 1dvh) { body { height: 100dvh; } }
h1, h2, h3, p { margin: 0; }
button, input, select { font: inherit; color: inherit; }
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
.muted { color: var(--ink-3); font-weight: 400; font-size: 12px; }

/* ---------- top bar ---------- */
.topbar {
  display: flex; align-items: center; flex-wrap: wrap; gap: 6px 20px; padding: 7px 20px 8px;   /* 2.17.2: the controls go to a row of their own when the bar is too narrow for them beside the brand — never over it */
  background: color-mix(in srgb, var(--card) 72%, transparent);
  backdrop-filter: saturate(180%) blur(20px); -webkit-backdrop-filter: saturate(180%) blur(20px);
  border-bottom: 1px solid var(--line); position: sticky; top: 0; z-index: 10;
  /* installed as a web app the page runs under the status bar: the bar keeps that strip for itself (viewport-fit=cover) */
  border-top: env(safe-area-inset-top, 0px) solid transparent;
}
.brand { display: flex; align-items: flex-start; gap: 12px; flex: none; min-width: 0; }   /* never squeezed: the name and the version badge keep their line */
.brand h1 { font-size: 17px; font-weight: 600; letter-spacing: -0.01em; line-height: 30px; display: flex; align-items: center; white-space: nowrap; }   /* 2.17.1: the title line is the icon's height — the name and the version badge sit on the icon's centre line */
.brand .logo { flex: none; display: flex; }
.brand .logo svg { display: block; }
.brand p { font-size: 12px; color: var(--ink-3); white-space: nowrap; }
.brand .version { font-size: 11px; font-weight: 600; line-height: 1.3; color: var(--ink-2); background: var(--control); border-radius: 999px; padding: 2px 8px; margin-left: 8px; font-variant-numeric: tabular-nums; }
.stage-indicator { flex: 1 1 0; display: flex; align-items: center; gap: 10px; font-size: 13px; color: var(--ink-2); min-width: 0; }
.stage-indicator .dot { width: 9px; height: 9px; border-radius: 50%; background: var(--ink-3); flex: none; transition: background .3s; }
.stage-indicator.running .dot { background: var(--accent); box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 25%, transparent); animation: pulse 1.4s ease-in-out infinite; }
.stage-indicator.done .dot { background: var(--good); }
.stage-indicator.paused .dot { background: #f0a020; }
@keyframes pulse { 0%, 100% { box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 25%, transparent); } 50% { box-shadow: 0 0 0 7px color-mix(in srgb, var(--accent) 8%, transparent); } }
#stage-text { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.topbar-controls { display: flex; align-items: center; gap: 10px; flex: none; margin-left: auto; --top-h: 36px; }   /* the status line yields, never the controls; on a row of their own they keep to the right */
/* 2.17.1: one height for every control of the top bar — the buttons of the Project group, the pace switch, Start / Reset, Robustness, Export, Help */
.topbar-controls .btn, .topbar-controls .segmented { height: var(--top-h); box-sizing: border-box; }
.topbar-controls .btn { display: inline-flex; align-items: center; justify-content: center; padding-top: 0; padding-bottom: 0; }
.topbar-controls .segmented button { padding-top: 0; padding-bottom: 0; }
.project-group .btn { padding-left: 13px; padding-right: 13px; font-size: 13px; }
/* the synthesis controls as one group: a tinted pill with a small label; the group wraps inside on narrow screens */
.topgroup { position: relative; display: flex; align-items: center; gap: 8px; flex-wrap: nowrap; margin-top: 4px; padding: 7px 6px 3px; border-radius: 999px; background: color-mix(in srgb, var(--accent) 6%, transparent); border: 1px solid color-mix(in srgb, var(--accent) 28%, transparent); }
/* the group's name as a small caption sitting on the border, like a legend of an instrument panel: it costs no width */
.topgroup-label { position: absolute; top: -8px; left: 16px; padding: 0 6px; line-height: 12px; font-size: 9px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--accent); background: var(--card); border-radius: 4px; }
/* the project group (2.17): the caption is the project's name (a button: click to rename), a star marks unsaved changes */
.project-group { background: color-mix(in srgb, var(--ink-3) 7%, transparent); border-color: color-mix(in srgb, var(--ink-3) 35%, transparent); }
.project-group .topgroup-label.project-name { border: 0; cursor: text; color: var(--ink-2); text-transform: none; letter-spacing: .02em; font-size: 10px; max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: inherit; }
.project-group .topgroup-label.project-name:hover { color: var(--accent); }
.project-group .project-dirty { color: var(--accent); margin-left: 1px; }
.project-group input.project-rename { font: inherit; font-size: 10px; border: 1px solid var(--accent); border-radius: 4px; padding: 0 4px; background: var(--card); color: var(--ink); width: 160px; }

.btn {
  border: 0; border-radius: 999px; padding: 8px 16px; background: var(--control); color: var(--ink);
  font-weight: 500; cursor: pointer; transition: transform .08s ease, background .2s, opacity .2s; white-space: nowrap;
}
.btn:hover { background: color-mix(in srgb, var(--control) 100%, var(--ink) 6%); }
.btn:active { transform: scale(0.97); }
.btn:disabled { opacity: 0.45; cursor: default; transform: none; }
.btn.primary { background: var(--accent); color: var(--accent-ink); }
.btn.primary:hover { background: color-mix(in srgb, var(--accent) 88%, black); }
.btn.link { background: none; color: var(--accent); padding: 4px 8px; font-size: 12px; }
.btn.small { padding: 4px 11px; font-size: 12px; }
.segmented { display: inline-flex; background: var(--control); border-radius: 999px; padding: 2px; }
.segmented button {
  border: 0; background: transparent; border-radius: 999px; padding: 6px 12px; cursor: pointer; color: var(--ink-2);
  font-weight: 500; font-size: 13px; transition: background .2s, color .2s, box-shadow .2s;
}
.segmented button.active { background: var(--control-active); color: var(--ink); box-shadow: 0 1px 3px rgba(0,0,0,.12); }
.segmented.small button { padding: 4px 10px; font-size: 12px; }
.segmented button { white-space: nowrap; }   /* «0–100 %» never breaks into lines, however narrow the row */
.segmented button.off { opacity: .45; }   /* a choice not available yet (the Saved design before the project has one): the click explains */

/* ---------- layout: inputs · charts · status ----------
   Three columns. The sidebar holds everything the user enters; the centre
   column stacks the three charts of the synthesis (spectrum, coating
   structure, needle derivative) so that all of them stay in view while a run
   is animated; the right rail holds the state of the run (verdict, tiles),
   the merit history and the event log. The centre column and the rail share
   one row template, so their cards line up row by row. The sidebar folds into
   a narrow strip (Hide / Show inputs) to give the charts the full width; on
   screens narrower than 1280 px it folds by itself when a run starts and
   unfolds on Reset. Below 1024 px the page stacks. */
.layout { flex: 1; display: grid; grid-template-columns: 316px minmax(0, 1fr) 340px; gap: 16px; padding: 16px; min-height: 0; }
.sidebar { overflow: auto; padding-right: 2px; display: flex; flex-direction: column; gap: 12px; }
.sidebar-bar { display: flex; align-items: center; gap: 8px; padding: 10px 2px 0 6px; flex: none; }   /* the top padding puts the bar on the line of the card headers of the other columns */
.sidebar-bar #btn-inputs { margin-left: auto; }   /* the title left, the fold button and the text-size control at the right edge of the column */
.sidebar-bar .sidebar-title { font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--ink-3); }
.layout.inputs-hidden { grid-template-columns: 36px minmax(0, 1fr) 340px; }
.layout.inputs-hidden .sidebar { overflow: visible; padding: 0; }
.layout.inputs-hidden .sidebar > :not(.sidebar-bar) { display: none; }
.layout.inputs-hidden .sidebar-bar { padding: 0; justify-content: flex-start; }
.layout.inputs-hidden .sidebar-bar .zoom-slot { display: none; }   /* the strip of 36 px holds the Show button alone — the text-size pill would push it under the charts */
.layout.inputs-hidden .sidebar-bar #btn-inputs { margin-left: 0; }
.layout.inputs-hidden .sidebar-title { display: none; }
.layout.inputs-hidden #btn-inputs { writing-mode: vertical-rl; transform: rotate(180deg); padding: 14px 8px; border-radius: 12px; width: 36px; }
.dashboard, .rail {
  display: grid; min-height: 0; gap: 14px;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: minmax(0, 1.26fr) minmax(0, 0.96fr) minmax(0, 0.93fr);   /* 2.11: the needle derivative a little taller than before (its minima must be readable) */
}
.dashboard { grid-template-areas: "spectrum" "structure" "needle"; }   /* three columns: structure under the spectrum, the needle derivative at the bottom (2.5.1) */
.rail { grid-template-rows: minmax(0, 1.65fr) minmax(0, 0.85fr) minmax(0, 0.85fr); }   /* 2.13: the Color block under the tiles — the Synthesis card shows the tiles and the colors of the design together */
/* «R & GDD»: the spectrum card carries two panels (R and GDD) and the Synthesis card six tiles — the first row grows; both columns keep one template */
.dashboard.gdd, .rail.gdd { grid-template-rows: minmax(0, 1.6fr) minmax(0, 0.9fr) minmax(0, 1fr); }   /* the needle derivative keeps a readable height */
.rail.gdd { grid-template-rows: minmax(0, 1.9fr) minmax(0, 0.8fr) minmax(0, 0.9fr); }   /* 2.13: three rows of tiles and the Color block */
/* the electric field (2.15): with the E‑field or the Both view the Coating structure card carries the tools, a wrapping legend and
   the field curve — it takes the height from the needle derivative, which keeps the minimum its minima need */
.dashboard.field-on { grid-template-rows: minmax(0, 1.12fr) minmax(0, 1.42fr) minmax(160px, 0.61fr); }
.dashboard.gdd.field-on { grid-template-rows: minmax(0, 1.45fr) minmax(0, 1.3fr) minmax(160px, 0.65fr); }
/* a color target (2.13) adds a tile — three rows of tiles — and the Color block under them: the Synthesis card takes the height to show both */
.rail.colortile { grid-template-rows: minmax(0, 2fr) minmax(0, 0.8fr) minmax(0, 0.9fr); }
.rail.gdd.colortile { grid-template-rows: minmax(0, 2.4fr) minmax(0, 0.7fr) minmax(0, 0.8fr); }
/* Materials (2.12): while a material card is open the spectrum card takes most of the column, so that the card's data, chart
   and choice are seen together; the structure and needle charts shrink for the moment */
.dashboard.material { grid-template-rows: minmax(0, 2.6fr) minmax(0, 0.7fr) minmax(0, 0.7fr); }
.rail { grid-template-areas: "stats" "merit" "log"; }
/* multi-start: a fourth card (the starts and their status) under Synthesis */
.rail.multi { grid-template-rows: minmax(258px, 1fr) minmax(150px, 0.95fr) minmax(150px, 1fr) minmax(90px, 0.6fr); grid-template-areas: "stats" "multistart" "merit" "log"; overflow-y: auto; overflow-x: hidden; }   /* 258 px: header, label, 2 × 2 tiles and the progress bar whole */
.rail.multi.gdd, .rail.multi.colortile { grid-template-rows: minmax(330px, 1.1fr) minmax(150px, 0.95fr) minmax(150px, 1fr) minmax(90px, 0.6fr); }   /* «R & GDD»: three rows of tiles */
/* Robustness (2.11): a card under Synthesis (and under Multi‑start) — the rail scrolls when the cards need more than the window */
.rail.robust { grid-template-rows: minmax(258px, 1fr) max-content minmax(150px, 0.9fr) minmax(90px, 0.6fr); grid-template-areas: "stats" "robust" "merit" "log"; overflow-y: auto; overflow-x: hidden; }   /* the card takes the height of its content; the rail scrolls */
.rail.robust.gdd, .rail.robust.colortile { grid-template-rows: minmax(330px, 1.1fr) max-content minmax(150px, 0.9fr) minmax(90px, 0.6fr); }
.rail.multi.robust { grid-template-rows: minmax(258px, 1fr) minmax(150px, 0.95fr) max-content minmax(150px, 0.9fr) minmax(90px, 0.6fr); grid-template-areas: "stats" "multistart" "robust" "merit" "log"; }
.rail.multi.robust.gdd, .rail.multi.robust.colortile { grid-template-rows: minmax(330px, 1.1fr) minmax(150px, 0.95fr) max-content minmax(150px, 0.9fr) minmax(90px, 0.6fr); }
#card-robust { grid-area: robust; overflow: visible; }
#card-robust > * { flex: none; }
#card-robust > header { flex-wrap: nowrap; }
#robust-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#btn-robust-report { margin-left: auto; }
.verdict { margin: 0 16px 6px; font-size: 12px; color: var(--ink-2); line-height: 1.4; display: flex; flex-direction: column; gap: 3px; }
.verdict:empty { display: none; }
.verdict .light { display: inline-block; vertical-align: 1px; margin-right: 6px; font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; border-radius: 6px; padding: 1px 7px; background: var(--control); color: var(--ink-2); white-space: nowrap; }
.verdict .light.robust { background: color-mix(in srgb, var(--good) 18%, transparent); color: var(--good); }
.verdict .light.sensitive { background: color-mix(in srgb, #f0a020 24%, transparent); color: #b26a00; }
.verdict .light.fragile { background: color-mix(in srgb, var(--bad) 16%, transparent); color: var(--bad); }
.verdict .light.testing { background: color-mix(in srgb, var(--accent) 16%, transparent); color: var(--accent); }
.verdict .light.outside { background: color-mix(in srgb, var(--ink-3) 18%, transparent); color: var(--ink-2); }
.verdict .note { color: var(--ink-3); font-size: 11px; }
.verdict b { color: var(--ink); }
.progress.robust { height: 8px; position: relative; }
.progress.robust canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
#card-robust .plot.hist { flex: none; height: 64px; margin: 2px 12px 0; }
.robust-actions { display: flex; align-items: center; gap: 8px; margin: 6px 16px 4px; }
#robust-status { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* the error model inside the card: the sidebar's rows, without the card chrome */
.group.inner { background: none; border: 0; box-shadow: none; border-radius: 0; padding: 4px 16px 10px; }
.group.inner summary { margin-bottom: 4px; }
.group.inner .row input { width: 84px; }
.group.inner .row input.switch { width: 40px; }
.group.inner .hint.inner { margin: 2px 0 6px; font-size: 11px; line-height: 1.35; color: var(--ink-3); }
.group.inner .pair { display: inline-flex; gap: 6px; }
.group.inner .pair input { width: 58px; }
.group.inner .segmented.small button { padding: 3px 8px; font-size: 11px; }
#card-robust .tile strong.robust { color: var(--good); }
#card-robust .tile strong.sensitive { color: #b26a00; }
#card-robust .tile strong.fragile { color: var(--bad); }
#card-robust .tile strong.outside { color: var(--ink-3); }
/* the note under the acceptance ΔR: widened to fit the design, or the user's own value with the way back */
.group.inner .row.note-row { min-height: 0; margin-top: -2px; align-items: baseline; gap: 8px; }
.group.inner .row.note-row .value { font-size: 11px; color: var(--ink-3); text-align: right; flex: 1; min-width: 0; }
button.mini { border: 1px solid var(--line); background: var(--control); color: var(--ink); border-radius: 999px; padding: 2px 9px; font-size: 11px; cursor: pointer; white-space: nowrap; }
button.mini:hover { border-color: var(--accent); color: var(--accent); }
#r-critical { cursor: pointer; }
#r-critical.many { font-size: 15px; letter-spacing: -0.2px; }
#r-critical span { text-decoration: underline dotted; text-underline-offset: 2px; }
#r-critical span.on { color: var(--accent); }
/* a stack (2.16): the critical layers are listed per coating — the coating's name before its layer numbers */
#r-critical em.grp { font-style: normal; font-weight: 600; font-size: 11px; color: var(--ink-3); margin: 0 2px 0 6px; vertical-align: 1px; }
#r-critical em.grp:first-child { margin-left: 0; }
/* the legend toggles of the robustness overlay (the spectrum card): buttons that look like legend items, dimmed when off */
.legend-item.toggle { border: 0; background: none; padding: 0; cursor: pointer; color: var(--ink-2); font: inherit; font-size: 12px; opacity: 0.45; }
.legend-item.toggle.on { opacity: 1; }
.swatch.corridor { width: 16px; height: 9px; border-radius: 2px; background: color-mix(in srgb, var(--series-current) 24%, transparent); border: 1px solid color-mix(in srgb, var(--series-current) 60%, transparent); }
.swatch.tests { width: 16px; height: 0; border-top: 1px solid var(--ink-3); background: none; }
.swatch.envelope { width: 16px; height: 0; border-top: 1px dashed var(--series-current); background: none; }
.swatch.accent { background: var(--accent); height: 10px; border-radius: 3px; }
.swatch.outline { width: 12px; height: 10px; border-radius: 3px; background: none; border: 2px solid var(--accent); }
/* the needle card header carries the tabs: as compact as the plain header of 2.10, so the plot keeps its height; where the
   legend has to wrap under the tabs (a 1024 px screen with the inputs open) the second row sits close, not a row‑gap away */
#card-needle > header { gap: 10px; row-gap: 3px; padding-top: 8px; padding-bottom: 4px; }
#needle-tabs { margin-left: 2px; }
#needle-tabs button { padding: 3px 9px; font-size: 11.5px; }
.robust-summary { font-size: 12px; color: var(--ink-2); line-height: 1.5; margin-bottom: 10px; }
.robust-summary b { color: var(--ink); }
#robust-table { width: 100%; border-collapse: collapse; font-size: 13px; font-variant-numeric: tabular-nums; }
#robust-table th, #robust-table td { padding: 6px 8px; text-align: right; border-bottom: 1px solid var(--line); }
#robust-table th:first-child, #robust-table td:first-child, #robust-table th:nth-child(2), #robust-table td:nth-child(2) { text-align: left; }
#robust-table th { color: var(--ink-3); font-weight: 600; font-size: 11px; text-transform: uppercase; letter-spacing: .04em; position: sticky; top: 0; background: var(--card); }
#robust-table tr.critical td { color: var(--needle); font-weight: 600; }
#robust-table th .sym { text-transform: none; }
.robust-summary h4 { margin: 10px 0 2px; font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3); }
.robust-summary h4:first-child { margin-top: 0; }
.robust-summary p { margin: 4px 0; }
#robust-table caption { caption-side: top; text-align: left; font-size: 12px; color: var(--ink-3); padding: 0 0 8px; }
.log li.robust .tag { background: color-mix(in srgb, var(--needle) 16%, transparent); color: var(--needle); }
#card-merit > header { row-gap: 2px; }
#card-spectrum { grid-area: spectrum; }
#card-stats { grid-area: stats; }
#card-multistart { grid-area: multistart; }
#card-needle { grid-area: needle; }
#card-merit { grid-area: merit; }
#card-structure { grid-area: structure; }
#card-log { grid-area: log; }

/* ---------- cards ---------- */
.card {
  background: var(--card); border: 1px solid var(--card-border); border-radius: var(--radius); box-shadow: var(--card-shadow);
  display: flex; flex-direction: column; min-height: 0; overflow: hidden;
}
.card > header { display: flex; align-items: center; gap: 14px; padding: 12px 16px 6px; flex-wrap: wrap; }
.card > header h3 { font-size: 14px; font-weight: 600; letter-spacing: -0.01em; }
.card > header h3 .muted { margin-left: 6px; }
/* the sensitivity plot: a one‑line note above the bars with the selected layer's figures (shortened to the room) */
#sensitivity-note { margin: 0 16px -4px; font-size: 11px; color: var(--ink-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#sensitivity-note b { color: var(--accent); font-weight: 600; }
/* the spectrum header holds two rows (title + tabs, legend + tools): tight row gap, so the plot keeps the height */
#card-spectrum > header { row-gap: 2px; padding-top: 6px; padding-bottom: 0; }   /* 2.17.1: the plot gets the room */
#card-spectrum > header > #spectrum-tools { order: 1; }
#card-spectrum > header > #yscale { order: 2; }   /* the y‑scale switch ends the tools row (it is a child of the header since 2.17.1) */
#card-spectrum > header .tabs { margin-left: 2px; }
#card-spectrum > header .legend { line-height: 1.2; }
.card-tools { margin-left: auto; display: flex; align-items: center; gap: 10px; }
.tool { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; color: var(--ink-2); }
.tool input, .tool select {
  border: 1px solid var(--input-border); border-radius: 8px; padding: 3px 6px; background: var(--input); font-size: 12px;
  font-variant-numeric: tabular-nums; outline: none; transition: box-shadow .15s, border-color .15s; color: var(--ink);
}
.tool input { width: 58px; text-align: right; }
/* a range of angles: the second angle is an optional field («to»); a filled one marks the range */
.tool input.angle-to { width: 48px; }
.tool input.angle-to::placeholder { color: var(--ink-3); font-style: italic; }
.tool .range-sep { color: var(--ink-3); margin: 0 -2px; }
.tool .short { display: none; }
.tool input:focus, .tool select:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--focus); }
.sidebar.locked ~ .dashboard .tool, .card-tools.locked .tool { opacity: 0.6; pointer-events: none; }
/* the stack editor is not for a running synthesis: its button and the editor dim with the inputs */
.sidebar.locked ~ .dashboard #btn-stack, .sidebar.locked ~ .dashboard .stack-editor { opacity: 0.6; pointer-events: none; }
.swatch.pol-s { height: 0; border-top: 2px solid var(--pol-s); background: none; }
.swatch.pol-p { height: 0; border-top: 2px dashed var(--pol-p); background: none; }
.header-break { flex-basis: 100%; height: 0; }
.tabs { margin-left: 4px; }
.panel { flex: 1; min-height: 0; overflow: auto; display: grid; grid-template-columns: 1fr 1fr; gap: 18px; padding: 6px 18px 14px; }
.panel h4 { font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--ink-3); margin: 6px 0 6px; }
.panel .row input { width: 120px; }
.panel .chips { margin-top: 4px; }
.panel .chip { padding: 4px 10px; font-size: 12px; line-height: 1.25; }   /* the preset chips match the Chart / Presets / Target tabs in size */
.panel .bands { max-width: 420px; }
.settings-panel.locked { opacity: 0.6; pointer-events: none; }
.preset-table { width: 100%; border-collapse: collapse; font-size: 12px; margin-top: 8px; font-variant-numeric: tabular-nums; }
.preset-table td { padding: 5px 6px 5px 0; border-bottom: 1px solid var(--line); color: var(--ink-2); vertical-align: top; }
.preset-table td:first-child { color: var(--ink-3); white-space: nowrap; width: 38%; }
#card-stats > header { flex-wrap: nowrap; }
#card-structure > header { gap: 4px 10px; padding-top: 8px; padding-bottom: 4px; }   /* 2.17.1: the two rows closer, the plot gets the room */
#card-structure > header .btn { margin-left: auto; }
#cycle-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.timer { flex: none; font-variant-numeric: tabular-nums; font-size: 12px; color: var(--ink-2); background: var(--control); border-radius: 999px; padding: 3px 9px; }
.swatch.ghost { width: 14px; height: 0; border-top: 2px solid var(--ink-3); background: none; opacity: 0.7; }
.plot { flex: 1; position: relative; min-height: 0; }
.plot canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; touch-action: none; }
.legend { display: flex; gap: 12px; align-items: center; font-size: 12px; color: var(--ink-2); }
.legend-item { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }   /* an item never breaks inside; the legend wraps between items */
.swatch { display: inline-block; width: 14px; height: 3px; border-radius: 2px; background: var(--ink-3); }
/* target swatches mirror the chart: a translucent band with a faint edge; in the «Rs & Rp» mode tinted by polarization, the Rp band with a dashed edge */
.swatch.target { width: 16px; height: 8px; border-radius: 2px; background: color-mix(in srgb, var(--series-target) 24%, transparent); border: 1px solid color-mix(in srgb, var(--series-target) 55%, transparent); }
.swatch.target.tint-s { background: color-mix(in srgb, var(--pol-s) 28%, transparent); border-color: color-mix(in srgb, var(--pol-s) 70%, transparent); }
.swatch.target.target2 { background: color-mix(in srgb, var(--pol-p) 28%, transparent); border: 1px dashed color-mix(in srgb, var(--pol-p) 85%, transparent); }
/* «R & GDD»: the GDD corridor is an amber translucent band on the lower panel, the computed GDD an amber line */
.swatch.target.gdd { background: color-mix(in srgb, var(--series-gdd) 22%, transparent); border-color: color-mix(in srgb, var(--series-gdd) 60%, transparent); }
.swatch.gdd { background: var(--series-gdd); }
.swatch.pol-p.thick { border-top-width: 2.5px; }
.swatch.current { background: var(--series-current); }
.swatch.current.tint-s { background: var(--pol-s); }
/* a range of angles: the family of curves over the band between the lowest and the highest of them */
.swatch.angles { width: 16px; height: 9px; border-radius: 2px; background: linear-gradient(to bottom, color-mix(in srgb, var(--series-current) 45%, transparent) 0 2px, color-mix(in srgb, var(--series-current) 14%, transparent) 2px 7px, var(--series-current) 7px 9px); }
.swatch.grid { width: 6px; height: 6px; border-radius: 50%; background: var(--ink-3); }
.swatch.mat-h { background: var(--mat-h); height: 10px; border-radius: 3px; }
.swatch.mat-l { background: var(--mat-l); height: 10px; border-radius: 3px; }
.swatch.mat-m1 { background: var(--mat-m1); height: 10px; border-radius: 3px; }
.swatch.mat-m2 { background: var(--mat-m2); height: 10px; border-radius: 3px; }
.swatch.mat-m3 { background: var(--mat-m3); height: 10px; border-radius: 3px; }
.swatch.mat-m4 { background: var(--mat-m4); height: 10px; border-radius: 3px; }
.swatch.needle { background: var(--needle); height: 10px; border-radius: 3px; }
.swatch.field { height: 0; border-top: 2.5px solid var(--field); background: none; width: 16px; }
.swatch.field-start { height: 0; border-top: 2px dashed var(--ink-3); background: none; width: 16px; }
/* the electric field (2.15): the view switch beside the title, the tools under the header, the caption with the peak */
#card-structure > header #structure-view { flex: none; }
#legend-field-comp .segmented.small button { padding: 2px 7px; font-size: 11px; }
.field-tools { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; padding: 0 16px 6px; font-size: 12px; color: var(--ink-2); }
.field-tools .tool { display: inline-flex; align-items: center; gap: 5px; color: var(--ink-3); white-space: nowrap; }
.field-tools input[type=number] { width: 60px; border: 1px solid var(--input-border); border-radius: 8px; padding: 3px 6px; background: var(--input); color: var(--ink); text-align: right; font-variant-numeric: tabular-nums; font-size: 12px; }
.field-tools input[type=range] { width: clamp(90px, 14vw, 180px); accent-color: var(--field); }
.field-tools select { border: 1px solid var(--input-border); border-radius: 8px; padding: 3px 6px; background: var(--input); color: var(--ink); font-size: 12px; }
.field-tools .caption { display: none; }   /* 2.17.1: the peak is written in the chart's strip above the bars (the row went to the plot); the element keeps the full text for the tests */
.field-tools { padding-bottom: 4px; }
.field-tools .caption.ok { color: var(--good); }
.field-tools .caption.bad { color: var(--bad); }
.field-tools .caption b { font-weight: 600; color: inherit; }
.swatch.heat { background: linear-gradient(90deg, color-mix(in srgb, var(--ink-3) 28%, var(--card)) 0%, #f7c948 35%, #f0750a 70%, #d0202a 100%); height: 10px; width: 36px; border-radius: 3px; }
.tooltip {
  position: absolute; pointer-events: none; background: color-mix(in srgb, var(--card) 92%, transparent); backdrop-filter: blur(10px);
  border: 1px solid var(--line); border-radius: 10px; padding: 6px 10px; font-size: 12px; color: var(--ink); box-shadow: var(--card-shadow);
  white-space: nowrap; z-index: 3; font-variant-numeric: tabular-nums;
}
.tooltip b { font-weight: 600; }
/* the per‑angle lists of a range of angles wrap inside the tooltip instead of running off the chart */
.tooltip .wrap { white-space: normal; display: inline-block; max-width: 360px; vertical-align: top; }

/* ---------- stats ---------- */
.tiles { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; padding: 4px 16px; }
.tile { background: color-mix(in srgb, var(--control) 55%, transparent); border-radius: 14px; padding: 10px 12px; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.rail .tile { padding-left: 10px; padding-right: 10px; }   /* «OPTICAL THICKNESS» on one line of a tile of the 340 px rail, whatever the system font */
.tile .k { font-size: 11px; color: var(--ink-3); text-transform: uppercase; letter-spacing: 0.04em; font-weight: 600; }
.tile .k .short { display: none; }
.tile strong { font-size: clamp(15px, 1.35vw, 22px); font-weight: 600; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* «R & GDD»: three rows of tiles in the rail — tighter, so that the rows and the progress bar fit the Synthesis card without scrolling */
.rail .tiles.gdd { gap: 8px; }
.rail .tiles.gdd .tile { padding: 7px 10px; gap: 0; }
.tile .sub { font-size: 11px; color: var(--ink-3); font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }   /* one line: the tile height never depends on the text */
.progress { margin: 10px 16px 6px; height: 6px; border-radius: 3px; background: var(--control); overflow: hidden; }
.progress .bar { height: 100%; width: 0; background: var(--accent); border-radius: 3px; transition: width .4s ease; }
.result { margin: 2px 16px 10px; padding: 10px 12px; font-size: 12px; color: var(--ink-2); display: flex; flex-direction: column; gap: 6px; flex: none; background: color-mix(in srgb, var(--control) 55%, transparent); border-radius: 14px; line-height: 1.45; }   /* under the tiles and the progress bar (2.7.0) */
.result:empty { display: none; }
.result .line b { color: var(--ink); }
.result.good .line:first-child b { color: var(--good); }
.result .tag { display: inline-block; vertical-align: 1px; margin-right: 6px; font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; border-radius: 6px; padding: 1px 6px; background: var(--control); color: var(--ink-2); white-space: nowrap; }
.result .tag.stop { background: color-mix(in srgb, var(--good) 16%, transparent); color: var(--good); }
.result .tag.multi { background: color-mix(in srgb, var(--accent) 16%, transparent); color: var(--accent); }
.result .tag.best { background: color-mix(in srgb, var(--good) 16%, transparent); color: var(--good); }
.result ul.facts { list-style: none; margin: 0; padding: 4px 0 4px 2px; display: flex; flex-direction: column; gap: 1px; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.result ul.facts li { padding-left: 16px; text-indent: -16px; color: var(--ink-3); cursor: default; }
.result ul.facts li i { display: inline-block; width: 16px; text-indent: 0; font-style: normal; font-size: 9px; color: var(--ink-3); }
.result ul.facts li .k { color: var(--ink-2); }
.result ul.facts li.hit { color: var(--ink-2); }
.result ul.facts li.hit i { color: var(--accent); }
.result ul.facts li.hit .k { color: var(--ink); font-weight: 600; }
.result ul.facts li.decisive i { color: var(--good); }
.result ul.facts li.decisive .k::after { content: " · decisive"; font-weight: 500; color: var(--good); }

/* ---------- sidebar forms ---------- */
.group { background: var(--card); border: 1px solid var(--card-border); border-radius: 16px; box-shadow: var(--card-shadow); padding: 12px 14px; }
.group h2, .group summary { font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--ink-3); margin-bottom: 8px; cursor: default; }
.group summary { cursor: pointer; list-style: none; display: flex; align-items: center; }
.group summary::after { content: "›"; margin-left: auto; font-size: 16px; transition: transform .2s; }
details[open] summary::after { transform: rotate(90deg); }
.rows { display: flex; flex-direction: column; }
.rows.sep { border-top: 1px solid var(--line); margin-top: 8px; }   /* a group of rows after a hint: a separator line above it (Advanced → Substrate back side) */
.row { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 7px 0; border-bottom: 1px solid var(--line); font-size: 13px; }
.row:last-child { border-bottom: 0; }
.row > span { color: var(--ink); }
.row em { font-style: normal; color: var(--ink-3); margin-left: 4px; font-size: 12px; }
.row em.value { color: var(--ink-2); text-align: right; max-width: 60%; }   /* a read‑only value in place of an input (the tolerance stop of the R & GDD mode) */
.row input, .row select {
  width: 112px; border: 1px solid var(--input-border); border-radius: 9px; padding: 6px 8px; background: var(--input); text-align: right;
  font-variant-numeric: tabular-nums; outline: none; transition: box-shadow .15s, border-color .15s;
}
.row select { text-align: left; width: 140px; }
.row input:focus, .row select:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--focus); }
.hint { font-size: 12px; color: var(--ink-3); margin-top: 6px; }
.hint:empty { display: none; }
input.switch { appearance: none; -webkit-appearance: none; width: 40px; height: 24px; border-radius: 12px; background: var(--control); position: relative; cursor: pointer; transition: background .2s; border: 0; margin: 0; }
input.switch::after { content: ""; position: absolute; top: 2px; left: 2px; width: 20px; height: 20px; border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,.25); transition: transform .2s; }
input.switch:checked { background: #34c759; }
input.switch:checked::after { transform: translateX(16px); }
.row input.switch { width: 40px; }
#start-type button { padding: 4px 7px; }
/* the Type row (Single · QW stack · Chirped · Saved): the switch stays beside the label when it fits, else wraps under it,
   right‑aligned, instead of running out of the card (2.17.1: every width, not only the compact three columns) */
.sidebar .row:has(> .segmented) { flex-wrap: wrap; row-gap: 4px; }
.sidebar .row:has(> .segmented) > span:first-child { flex: 1 1 min-content; }
.sidebar .row > .segmented { margin-left: auto; max-width: 100%; }
.row > span .placeholder { color: var(--ink-3); }
.row.dim > span { color: var(--ink-3); }   /* a row whose input is disabled (the number of angles without a range) */
.row.dim input:disabled { opacity: 0.55; }
.starts-list { list-style: none; margin: 0 16px 10px; padding: 0; font-size: 12px; flex: 1; min-height: 0; overflow: auto; }
.starts-list li { display: grid; grid-template-columns: 1fr auto auto; gap: 10px; padding: 4px 0; border-bottom: 1px solid var(--line); color: var(--ink-2); font-variant-numeric: tabular-nums; }
.starts-list li.best { color: var(--good); font-weight: 600; }
.starts-list li.running { color: var(--accent); }
.starts-list li.pending { color: var(--ink-3); }
#multi-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }   /* the status gives way (ellipsis) so that the Ranking button never leaves the card */
#btn-starts { margin-left: auto; }   /* stays at the right edge when it wraps */
#card-multistart > header { flex-wrap: nowrap; }
.swatch.line-accent { height: 0; border-top: 2px solid var(--accent); background: none; }
.swatch.line-good { height: 0; border-top: 2px solid var(--good); background: none; }
#merit-legend { margin-left: auto; }
.starts-list li .n { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.starts-list li { cursor: default; }
.starts-list li:hover, .starts-list li.highlighted { color: var(--needle); }
@media (hover: none) { .starts-list li:hover:not(.highlighted) { color: var(--ink-2); } }   /* a tap's sticky :hover means nothing on a touch screen; the tapped start carries .highlighted */
/* after the exploration every finished start can be clicked: its explored result is shown on the dashboard
   as the current design (the row gets the current‑design colour and a ▸ marker) */
.starts-list.selectable li { cursor: pointer; border-radius: 6px; padding-left: 4px; padding-right: 4px; margin: 0 -4px; }
.starts-list.selectable li:hover { background: color-mix(in srgb, var(--needle) 10%, transparent); }
.starts-list li.shown { color: var(--series-current); font-weight: 600; background: color-mix(in srgb, var(--series-current) 12%, transparent); }
.starts-list li.shown .n::before { content: "▸ "; }
.starts-list li.shown:hover { color: var(--series-current); }
#starts-table tr.shown td { color: var(--series-current); font-weight: 600; }
#starts-table .btn.link { padding: 2px 6px; }
.log li.folded { display: none; }
.swatch.zone { width: 14px; height: 10px; border-radius: 3px; background: repeating-linear-gradient(135deg, var(--ink-3) 0 2px, transparent 2px 5px); }
.chips { display: flex; flex-wrap: wrap; gap: 6px; }
.chip { border: 1px solid var(--line); background: var(--control); border-radius: 999px; padding: 5px 11px; font-size: 12px; cursor: pointer; color: var(--ink); }
.chip.active { background: var(--accent); color: var(--accent-ink); border-color: transparent; }
.bands { display: flex; flex-direction: column; gap: 4px; }
.band { display: grid; grid-template-columns: 1fr 1fr 1fr auto; gap: 6px; align-items: center; font-size: 12px; }
.band input { width: 100%; border: 1px solid var(--input-border); border-radius: 8px; padding: 5px 6px; background: var(--input); text-align: right; font-variant-numeric: tabular-nums; }
.band .x { border: 0; background: var(--control); border-radius: 50%; width: 22px; height: 22px; cursor: pointer; color: var(--ink-2); line-height: 1; }
.band-head { display: grid; grid-template-columns: 1fr 1fr 1fr auto; gap: 6px; font-size: 11px; color: var(--ink-3); padding-right: 28px; }
.band-add { margin-top: 4px; align-self: flex-start; }
#bands2-wrap h4, #bandsG-wrap h4, #tolerances-wrap h4 { margin-top: 14px; }
.band input.neg { color: var(--series-gdd); }
/* free bands (2.17): a band without a target — its value cell says so, the row is dimmed; the Free / Target toggle sits before the × */
.band { grid-template-columns: 1fr 1fr 1fr auto auto; }
.band-head { grid-template-columns: 1fr 1fr 1fr auto auto; padding-right: 0; }
.band-head .free-col { width: 44px; }
.band-head .x-col { width: 22px; }
.band .free-toggle { border: 1px solid var(--line); background: var(--control); border-radius: 999px; width: 44px; height: 22px; font-size: 10px; cursor: pointer; color: var(--ink-2); padding: 0; line-height: 1; }
.band .free-toggle.on { background: color-mix(in srgb, var(--ink-3) 22%, transparent); border-color: transparent; color: var(--ink); }
.band .no-target { display: block; border: 1px dashed var(--input-border); border-radius: 8px; padding: 5px 6px; text-align: center; color: var(--ink-3); font-style: italic; font-variant-numeric: tabular-nums; }
.band.free input { opacity: .55; }
.swatch.free { width: 14px; height: 10px; border-radius: 3px; border: 1px dashed var(--ink-3); background: transparent; }
.target-files { margin-top: 12px; }
.target-files .chips { gap: 6px; }
.start-current .value { font-variant-numeric: tabular-nums; }
/* the project question (2.17): three choices in a row */
dialog.sheet.project-ask { width: min(440px, 92vw); }   /* the sheet's own width rule is more specific than a bare class */
.project-ask .actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 12px; }
.project-ask header { padding-bottom: 0; }
/* Export (2.17.2): a narrow sheet — the two formats as option buttons one under the other, each with its line inside */
dialog.sheet.export-ask { width: min(360px, 92vw); }
.export-choice { display: grid; gap: 8px; margin-top: 8px; }
.export-choice .btn.option { width: 100%; text-align: left; display: grid; gap: 2px; padding: 10px 14px; border-radius: 14px; white-space: normal; height: auto; line-height: 1.3; }
.export-choice .btn.option small { display: block; font-weight: 400; font-size: 11.5px; color: var(--ink-3); }
.export-choice .btn.option.primary small { color: inherit; opacity: 0.85; }
.export-ask .actions { justify-content: flex-end; margin-top: 10px; }
/* the name of a new project (2.17): a compact sheet, the field across its whole width */
#project-name-dialog { width: min(380px, 92vw); }
#project-name-dialog .recipe-wrap { padding-top: 10px; }
.project-name-row { display: grid; grid-template-columns: 1fr; gap: 6px; margin: 0 0 8px; }
.project-name-row > span { font-size: 12px; color: var(--ink-2); }
.project-name-row input { width: 100%; box-sizing: border-box; border: 1px solid var(--input-border); border-radius: 10px; padding: 10px 12px; background: var(--input); color: var(--ink); font: inherit; font-size: 15px; }
.project-name-row input:focus { outline: 2px solid color-mix(in srgb, var(--accent) 45%, transparent); border-color: var(--accent); }
#project-name-dialog .hint { margin: 0 0 4px; }
#project-name-dialog .actions { justify-content: flex-end; }
.errors { background: color-mix(in srgb, var(--bad) 12%, var(--card)); border: 1px solid color-mix(in srgb, var(--bad) 40%, transparent); border-radius: 12px; padding: 10px 12px; font-size: 12px; color: var(--bad); }
.about { font-size: 11px; color: var(--ink-3); padding: 0 4px 8px; }
.sidebar.locked .group { opacity: 0.6; pointer-events: none; }

/* ---------- materials (2.12): the sidebar picks and the material card ---------- */
.row .pick { display: inline-flex; align-items: center; gap: 6px; flex: none; }   /* the pick keeps its width; a long label (Incident medium) wraps instead */
.row .pick select { width: 118px; min-width: 0; }
.row .pick select option.fav { font-weight: 600; }
.row .info { flex: none; width: 22px; height: 22px; border-radius: 50%; border: 1px solid var(--input-border); background: var(--input); color: var(--accent); font: 600 12px/1 var(--font); font-style: italic; cursor: pointer; padding: 0; }
/* the × of an additional material of the task (2.18); greyed while the material has layers in the design */
.row .remove { flex: none; width: 22px; height: 22px; border-radius: 50%; border: 0; background: var(--control); color: var(--ink-2); font: 500 14px/1 var(--font); cursor: pointer; padding: 0; }
.row .remove:hover:not(:disabled) { color: var(--bad); }
.row .remove:disabled { opacity: 0.35; cursor: default; }
#row-mat-add { justify-content: flex-end; }
#row-mat-add > span:first-child { flex: 1; }
.group.inner .pair.one input { width: 122px; }
.row .info:hover { background: color-mix(in srgb, var(--accent) 10%, var(--input)); }
.row.materials-row { justify-content: space-between; }
.row.materials-row .muted { font-size: 12px; font-variant-numeric: tabular-nums; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.row.materials-row .muted b { font-weight: 600; color: var(--ink-2); }
#materials-summary { white-space: normal; line-height: 1.45; }   /* the indices of a task of several materials (2.18) wrap rather than vanish behind an ellipsis */
.material-panel { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-content: start; row-gap: 0; padding-bottom: 0; }
/* the chart, the title line, the source and the partners span both columns; the data and the Scalar/Complex choice sit side by side under the chart */
.material-panel .full { grid-column: 1 / -1; }
.material-panel .mat-head { display: flex; align-items: center; gap: 8px; }
.material-panel .mat-head #mat-table-btn { margin-left: auto; }
.material-panel .mat-head .star { margin-left: 0; }
.material-panel .mat-head h4 { text-transform: none; letter-spacing: 0; font-size: 16px; color: var(--ink); margin: 4px 0 2px; }
.material-panel .mat-head h4 .muted { font-weight: 400; font-size: 13px; }
.material-panel .star { border: 0; background: none; font-size: 20px; line-height: 1; color: var(--ink-3); cursor: pointer; padding: 2px 6px; border-radius: 8px; }
.material-panel .star.on { color: #e8a317; }
.material-panel .star:hover { background: var(--control); }
.material-panel .mat-sub { margin-top: 0; }
.material-panel .rows { margin-top: 4px; }
.material-panel .row { font-size: 12.5px; padding: 5px 0; align-items: flex-start; }
.material-panel .row > span:first-child { flex: none; max-width: 42%; }
.material-panel .row em.value { max-width: 58%; font-size: 12.5px; }
.material-panel .row em.value.ok { color: var(--good); }
.material-panel .row em.value.warn { color: var(--bad); }
.material-panel .row.table-row { display: block; }
.material-panel .row input[type="text"] { flex: 1 1 110px; width: auto; min-width: 0; max-width: 200px; text-align: left; }   /* the name field shrinks with the column and never crosses into the next one */
.material-panel .row select { width: 200px; max-width: 60%; }
.material-panel .row .pair { display: inline-flex; gap: 6px; flex: none; margin-left: auto; }
.material-panel .row .pair input { width: 84px; min-width: 0; }
/* the Scalar n and k fields: the label gives way and the pair of fields drops to its own line when the column is narrow — the fields never leave the card */
.material-panel .row.mat-scalar { flex-wrap: wrap; }
.material-panel .row.mat-scalar > span:first-child { max-width: none; flex: 1 1 150px; }
.material-panel .row.note-row { min-height: 0; padding-top: 0; border-bottom: 0; }
.material-panel .row.note-row + .row { border-top: 1px solid var(--line); }
.mat-table { width: 100%; border-collapse: collapse; font-size: 12px; font-variant-numeric: tabular-nums; }
.mat-table th { font-weight: 500; color: var(--ink-3); text-align: left; padding: 2px 8px 2px 0; }
.mat-table td { padding: 2px 8px 2px 0; color: var(--ink-2); }
.mat-source { font-size: 11.5px; color: var(--ink-3); margin-top: 8px; line-height: 1.4; }
.mat-source .k { font-weight: 600; color: var(--ink-3); text-transform: uppercase; letter-spacing: 0.04em; font-size: 10.5px; }
.mat-source a { color: var(--accent); text-decoration: none; }
.mat-source a:hover { text-decoration: underline; }
#mat-pairs-wrap { margin-top: 10px; }
#mat-pairs .chip { text-align: left; white-space: normal; line-height: 1.3; max-width: 340px; }
#mat-pairs .chip .muted { font-size: 11px; display: block; }
.mat-plot { height: 210px; flex: none; border: 1px solid var(--line); border-radius: 12px; overflow: hidden; margin-top: 6px; }
.material-panel .mat-form { padding-top: 6px; }
.material-panel .mat-info { padding-top: 6px; }
.mat-legend { margin-top: 6px; flex-wrap: wrap; }
.swatch.band { width: 14px; height: 10px; border-radius: 3px; background: color-mix(in srgb, var(--accent) 18%, transparent); border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent); }
.swatch.dashed { height: 0; border-top: 2px dashed var(--series-current); background: none; }
/* the actions stay in view while the card scrolls: a sticky footer over both columns */
.mat-actions { grid-column: 1 / -1; position: sticky; bottom: 0; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 10px; padding: 10px 0 12px; background: var(--card); border-top: 1px solid var(--line); z-index: 1; }
.mat-actions .muted { font-size: 12px; min-width: 0; }
.mat-actions .btn.danger { background: color-mix(in srgb, var(--bad) 14%, var(--control)); color: var(--bad); }
/* the profile as a table (the Material profile dialog): the rows of the spectral range highlighted, its ends and centre marked */
#material-table tr.in-range td { background: color-mix(in srgb, var(--accent) 10%, transparent); }
#material-table tr.mark td { font-weight: 600; }
#material-table tr.mark td:last-child { color: var(--accent); font-weight: 500; }
.hint .warn { color: var(--bad); }
.hint b { color: var(--ink-2); font-weight: 600; }
@media (max-width: 900px) { .material-panel { grid-template-columns: 1fr; } .mat-plot { height: 190px; } }
/* a short screen (a 1366 × 768 laptop): the open card takes still more of the column and its chart is a little lower, so that the data and the Scalar/Complex choice are seen with the chart */
@media (max-height: 820px) { .mat-plot { height: 170px; } .dashboard.material { grid-template-rows: minmax(0, 3.4fr) minmax(0, 0.6fr) minmax(0, 0.6fr); } }
@media (max-width: 1400px) { .row .pick select { width: 104px; } }
@media (max-width: 1279px) { .row .pick select { width: 96px; } }

/* ---------- log ---------- */
.log { list-style: none; margin: 0; padding: 0 16px 12px; overflow: auto; font-size: 12px; display: flex; flex-direction: column; gap: 4px; }
.log li { display: grid; grid-template-columns: 58px minmax(0, 1fr); gap: 8px; padding: 4px 0; border-bottom: 1px solid var(--line); color: var(--ink-2); }
.log li > span:last-child { min-width: 0; overflow-x: auto; }
.log li .tag { font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; border-radius: 6px; padding: 2px 6px; text-align: center; align-self: start; background: var(--control); color: var(--ink-2); }
.log li.needle .tag { background: var(--needle-fill); color: var(--needle); }
.log li.growth .tag { background: color-mix(in srgb, var(--series-current) 18%, transparent); color: var(--series-current); }
.log li.cleanup .tag { background: color-mix(in srgb, var(--ink-3) 18%, transparent); }
.log li.done .tag { background: color-mix(in srgb, var(--good) 18%, transparent); color: var(--good); }
.log li.reject .tag { background: color-mix(in srgb, var(--bad) 14%, transparent); color: var(--bad); }
.log li.compare .tag { background: color-mix(in srgb, var(--mat-h) 16%, transparent); color: var(--mat-h); }
.log li.grid .tag, .log li.dense .tag { background: color-mix(in srgb, var(--good) 14%, transparent); color: var(--good); }
.log li.explore .tag { background: color-mix(in srgb, var(--accent) 14%, transparent); color: var(--accent); }
.log table.cmp { border-collapse: collapse; margin-top: 3px; font-size: 11px; }
.log table.cmp td, .log table.cmp th { padding: 1px 6px 1px 0; text-align: right; color: var(--ink-3); font-weight: 500; white-space: nowrap; vertical-align: top; }
.log table.cmp td:first-child, .log table.cmp th:first-child { white-space: normal; min-width: 72px; }
.log table.cmp td.detail { text-align: left; white-space: normal; min-width: 96px; }
.log table.cmp td:first-child, .log table.cmp th:first-child { text-align: left; }
.log table.cmp tr.chosen td { color: var(--ink); font-weight: 600; }
#card-stats { overflow: auto; }
#card-stats > * { flex: none; }   /* nothing shrinks: a long label or verdict scrolls instead of climbing into the header */
.start-label { margin: 0 16px 6px; font-size: 12px; color: var(--ink-2); display: flex; align-items: baseline; gap: 8px; min-height: 18px; line-height: 1.4; }
.start-label > span:last-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.start-label .badge { font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; border-radius: 6px; padding: 2px 6px; background: var(--control); color: var(--ink-2); flex: none; }
.start-label .badge.multi { background: color-mix(in srgb, var(--accent) 16%, transparent); color: var(--accent); }
.result .check { color: var(--good); }
.result .robust-link { margin-left: 8px; font-weight: 600; white-space: nowrap; }
.result .check.bad { color: var(--bad); }
.log li.check .tag { background: color-mix(in srgb, var(--good) 14%, transparent); color: var(--good); }
.log li.check.bad .tag { background: color-mix(in srgb, var(--bad) 14%, transparent); color: var(--bad); }
#starts-table { width: 100%; border-collapse: collapse; font-size: 13px; font-variant-numeric: tabular-nums; }
#starts-table caption { caption-side: top; text-align: left; font-size: 12px; color: var(--ink-3); padding: 0 0 8px; }
#starts-table th, #starts-table td { padding: 6px 8px; text-align: right; border-bottom: 1px solid var(--line); }
#starts-table th:first-child, #starts-table td:first-child, #starts-table th:last-child, #starts-table td:last-child { text-align: left; }
#starts-table th { color: var(--ink-3); font-weight: 600; font-size: 11px; text-transform: uppercase; letter-spacing: .04em; }
#starts-table tr.best td { color: var(--good); font-weight: 600; }
.log li span.v { font-variant-numeric: tabular-nums; }

/* ---------- dialog ---------- */
dialog.sheet { border: 0; border-radius: 18px; padding: 0; background: var(--card); color: var(--ink); box-shadow: 0 20px 60px rgba(0,0,0,.3); width: min(720px, 92vw); max-height: 85vh; }
dialog.sheet::backdrop { background: rgba(0,0,0,.35); backdrop-filter: blur(4px); }
dialog.sheet header { display: flex; align-items: center; justify-content: space-between; padding: 14px 18px; border-bottom: 1px solid var(--line); }
.recipe-wrap { overflow: auto; max-height: 70vh; padding: 8px 18px 18px; }
#recipe, #material-table { width: 100%; border-collapse: collapse; font-size: 13px; font-variant-numeric: tabular-nums; }
#recipe th, #recipe td, #material-table th, #material-table td { padding: 6px 8px; text-align: right; border-bottom: 1px solid var(--line); }
#recipe th:first-child, #recipe td:first-child, #recipe th:nth-child(2), #recipe td:nth-child(2) { text-align: left; }
#material-table th:last-child, #material-table td:last-child { text-align: left; }
#material-table caption { caption-side: top; text-align: left; font-size: 12px; color: var(--ink-3); padding: 0 0 8px; }
#material-table thead th { position: sticky; top: 0; background: var(--card); }
#recipe th { color: var(--ink-3); font-weight: 600; font-size: 11px; text-transform: uppercase; letter-spacing: .04em; position: sticky; top: 0; background: var(--card); }
#recipe caption { caption-side: top; text-align: left; font-size: 12px; color: var(--ink-3); padding: 0 0 8px; }
#recipe tr.thin td { color: var(--bad); }

/* ---------- wide three columns: larger text ----------
   On a wide screen (≥ 1280 px) the text of the inputs, the Synthesis card, the
   event log and the target tables is one size larger, and the canvases draw
   their tick labels at 12 px. The chart cards keep their headers and their
   row template, so the plots keep their height; the Synthesis card's tiles
   stay within the card (checked at 1280 × 800 … 2560 × 1440, see
   VERIFICATION.md). The compact rules for short windows below override. */
@media (min-width: 1280px) {
  :root { --chart-fs: 12px; }
  /* the chart cards' own headers (title, legend, tools, tabs) keep their size: a wrapped header would take a row from the plot */
  .hint, .about, .errors, .rail .muted { font-size: 14px; }
  .timer, .tooltip { font-size: 13px; }
  .sidebar-bar .sidebar-title, .group h2, .group summary, .panel h4 { font-size: 13px; }
  .row { font-size: 15px; }
  .row em { font-size: 13px; }
  .row input { width: 126px; }   /* the placeholders «900 (λ max)» whole at 15 px */
  .chip { font-size: 14px; }
  .panel .chip { font-size: 12px; }
  .preset-table, .band, .starts-list, .start-label, .result, .log { font-size: 14px; }
  .band-head, .log table.cmp { font-size: 13px; }
  .result .tag, .log li .tag, .start-label .badge { font-size: 11px; }
  .tile .sub { font-size: 13px; }   /* the uppercase labels stay 11 px: «OPTICAL THICKNESS» on one line of a rail tile */
  .tile strong { font-size: clamp(16px, 1.4vw, 22px); }   /* 22 px: «1.260×10⁻¹» fits a tile of the 340 px rail */
  .rail.multi { grid-template-rows: minmax(292px, 1fr) minmax(150px, 0.95fr) minmax(150px, 1fr) minmax(90px, 0.6fr); }   /* 2 × 2 larger tiles and the progress bar whole */
  .rail.multi.gdd, .rail.multi.colortile { grid-template-rows: minmax(352px, 1.1fr) minmax(150px, 0.95fr) minmax(150px, 1fr) minmax(90px, 0.6fr); }
  .rail.robust { grid-template-rows: minmax(292px, 1fr) max-content minmax(150px, 0.9fr) minmax(90px, 0.6fr); }
  .rail.multi.robust { grid-template-rows: minmax(292px, 1fr) minmax(150px, 0.95fr) max-content minmax(150px, 0.9fr) minmax(90px, 0.6fr); }
  .verdict, .robust-summary { font-size: 14px; }
  .verdict .note { font-size: 12px; }
  #robust-table { font-size: 14px; }
  #robust-table th, #robust-table caption { font-size: 12px; }
  #starts-table, #recipe, #material-table { font-size: 14px; }
  #starts-table th, #recipe th, #material-table th, #starts-table caption, #recipe caption, #material-table caption { font-size: 12px; }
  .rail .btn.link { font-size: 13px; }
}

/* ---------- responsive ---------- */
/* «R & GDD» on screens up to 900 px high (1536 × 864 laptops): the three rows of tiles in the rail are tighter still */
@media (max-height: 900px) {
  .rail .tiles.gdd .tile { padding: 5px 10px; }
  .rail .tiles.gdd .tile .k, .rail .tiles.gdd .tile .sub { font-size: 11px; }
  .rail .tiles.gdd .tile strong { font-size: clamp(15px, 1.2vw, 18px); }
}
@media (max-height: 820px) {
  .tile { padding: 7px 10px; gap: 1px; }
  .tile strong { font-size: clamp(14px, 1.25vw, 18px); }
  .tiles { gap: 8px; }
  /* «R & GDD»: three rows of tiles fit the Synthesis card only as one‑line tiles (label, number, note) */
  .rail .tiles.gdd .tile { padding: 5px 9px; gap: 0; }
  .rail .tiles.gdd .tile .k { font-size: 10px; white-space: nowrap; }
  .rail .tiles.gdd .tile .k .long { display: none; }
  .rail .tiles.gdd .tile .k .short { display: inline; }
  .rail .tiles.gdd .tile strong { font-size: 15px; }
  .rail .tiles.gdd .tile .sub { font-size: 10px; }
  .card > header { padding: 9px 14px 4px; }
  .legend { font-size: 11px; gap: 9px; }
  .progress { margin: 8px 16px 4px; }
}
/* short windows: the four tiles stay whole in the Synthesis card during a run (one line each: label, number, note) */
@media (max-height: 760px) {
  .tile { padding: 5px 9px; gap: 0; border-radius: 10px; }
  .tile .k { font-size: 10px; white-space: nowrap; }
  .tile .k .long { display: none; }
  .tile .k .short { display: inline; }
  .tile strong { font-size: 15px; }
  .tile .sub { font-size: 10px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .tiles { gap: 6px; padding: 2px 12px; }
  .start-label { margin-bottom: 3px; }
  .progress { margin: 6px 12px 4px; }
  .rail.multi { grid-template-rows: minmax(206px, 1fr) minmax(150px, 0.95fr) minmax(150px, 1fr) minmax(90px, 0.6fr); }
  .rail.multi.gdd, .rail.multi.colortile { grid-template-rows: minmax(262px, 1.1fr) minmax(150px, 0.95fr) minmax(150px, 1fr) minmax(90px, 0.6fr); }
}
@media (max-width: 900px) { .panel { grid-template-columns: 1fr; } }
@media (max-width: 1600px) {
  /* the brand's subtitle would push the controls into a second row: the name and the version suffice */
  .brand p { display: none; }
}
@media (max-width: 1400px) {
  .topbar { gap: 6px 14px; padding: 7px 16px; }
  /* the controls a little closer together, so that they stay on the brand's row down to about 1280 px */
  .topbar-controls { gap: 6px; }
  .topgroup { gap: 6px; padding-left: 5px; padding-right: 5px; }
  .project-group .btn { padding-left: 11px; padding-right: 11px; }
  .layout { grid-template-columns: 284px minmax(0, 1fr) 308px; gap: 14px; }
  .layout.inputs-hidden { grid-template-columns: 36px minmax(0, 1fr) 308px; }
  .row select { width: 128px; }
  #card-structure .opt { display: none; }
  .legend { gap: 9px; }
  #merit-legend { gap: 7px; font-size: 11px; }
  #merit-legend .swatch { width: 10px; }
  .tool .long { display: none; }
  .tool .short { display: inline; }
  .rail .tile .k .long { display: none; }   /* the 308 px rail: «OPT. THICKNESS» on one line */
  .rail .tile .k .short { display: inline; }
}
/* compact three columns: laptops at a scaled resolution (1024–1279 px). The
   angle and the target characteristic leave the chart header (they are on
   the Target tab); the inputs fold into the strip when a run starts. */
@media (max-width: 1279px) {
  .layout { grid-template-columns: 236px minmax(0, 1fr) 260px; gap: 12px; padding: 12px; }
  .layout.inputs-hidden { grid-template-columns: 34px minmax(0, 1fr) 260px; }
  #spectrum-tools .tool, #spectrum-tools #gdd-pol { display: none; }   /* the angle, the characteristic and the R & GDD polarization live on the Target tab here */
  .dashboard, .rail { gap: 12px; }
  .topbar { gap: 6px 14px; padding: 8px 16px; }
  .btn { padding: 7px 13px; }
  .segmented button { padding: 5px 10px; }
  .group { padding: 10px 12px; }
  .row select { width: 118px; }
  .row input { width: 92px; }
  /* the 236 px sidebar: a row whose switch does not fit beside its label even with the label's words wrapped (Type:
     Single · QW stack · Chirped) puts the switch on a second line, right‑aligned, instead of running out of the card;
     a label that can wrap its words (Outer layer at the incident medium · H | L) keeps the switch beside it */
  /* the four types share the width of the 236 px card on their own line */
  #start-type { flex: 1 1 100%; }
  #start-type button { flex: 1 1 auto; min-width: 0; padding: 4px 4px; font-size: 11px; overflow: hidden; text-overflow: ellipsis; }
  .topbar-controls { --top-h: 34px; }
  .card > header { padding: 9px 12px 4px; gap: 10px; }
  .tiles { padding: 4px 12px; gap: 8px; }
  .result, .start-label, .progress, .starts-list, .verdict, .robust-actions { margin-left: 12px; margin-right: 12px; }
  .group.inner { padding-left: 12px; padding-right: 12px; }
  .log { padding: 0 12px 10px; }
}
/* short screens: tighter chrome so that three chart rows still fit */
@media (max-height: 760px) {
  .topbar { padding: 6px 16px; }
  .layout { padding: 10px; gap: 10px; }
  .dashboard, .rail { gap: 10px; }
  /* 2.11: the needle derivative keeps a readable height on a short screen (an iPad in Safari: 700–740 px) — its header may
     take two rows here, so the bottom row gets a larger share than in 2.10 and the spectrum gives it up */
  .dashboard, .rail { grid-template-rows: minmax(0, 1.2fr) minmax(0, 0.92fr) minmax(0, 0.98fr); }
  .rail { grid-template-rows: minmax(0, 1.45fr) minmax(0, 0.9fr) minmax(0, 0.95fr); }
  .dashboard.gdd, .rail.gdd { grid-template-rows: minmax(0, 1.6fr) minmax(0, 0.9fr) minmax(0, 1fr); }
  .dashboard.field-on { grid-template-rows: minmax(0, 1fr) minmax(0, 1.5fr) minmax(120px, 0.6fr); }
  .dashboard.gdd.field-on { grid-template-rows: minmax(0, 1.35fr) minmax(0, 1.35fr) minmax(120px, 0.6fr); }
  .rail.gdd { grid-template-rows: minmax(0, 1.9fr) minmax(0, 0.8fr) minmax(0, 0.9fr); }
  .rail.colortile { grid-template-rows: minmax(0, 2fr) minmax(0, 0.8fr) minmax(0, 0.9fr); }
  .sidebar { gap: 8px; }
  .group { padding: 8px 12px; }
  .group h2, .group summary { margin-bottom: 4px; }
  .row { padding: 5px 0; }
  .card > header { padding: 7px 12px 2px; }
  .plot { min-height: 60px; }
}
/* stacked layouts: the page scrolls under the sticky top bar, so a card brought into view keeps clear of it */
@media (max-width: 1023px) { #card-robust, #card-spectrum, #card-stats, #group-materials { scroll-margin-top: calc(var(--topbar-h, 56px) + 8px); } }
@media (max-width: 1023px) {
  .layout, .layout.inputs-hidden { grid-template-columns: 1fr; height: auto; flex: none; }
  body { height: auto; min-height: 100vh; padding-bottom: env(safe-area-inset-bottom, 0px); }
  /* the sidebar dissolves too: its groups become cards of the one column — Materials right under the spectrum card
     (the material card opens there), the other inputs at the end */
  .sidebar { display: contents; }
  .sidebar > .group { order: 20; }
  .sidebar > .about { order: 30; }
  #group-materials { order: 2; }
  #spectrum-tools .tool { display: inline-flex; }
  #spectrum-tools #gdd-pol:not([hidden]) { display: inline-flex; }
  /* the stacked header (2.17.1): the y‑scale switch sits at the right end of the legend's row when it fits there, the angle and
     the characteristic (and the polarization switches) take the next row, right‑aligned, wrapping among themselves on a phone */
  #card-spectrum > header > #yscale { order: 0; margin-left: auto; }
  #spectrum-tools { order: 1; flex-wrap: wrap; justify-content: flex-end; row-gap: 6px; min-width: 0; max-width: 100%; }
  .sidebar-bar, .layout.inputs-hidden .sidebar-bar { display: none; }
  .layout.inputs-hidden .sidebar > :not(.sidebar-bar) { display: revert; }
  /* the two columns dissolve into the layout grid, so the cards can take the reading order:
     spectrum, materials, synthesis (both in view during a run), multi-start, needle, structure, merit, log, the other inputs */
  .dashboard, .rail { display: contents; }
  .card, #card-spectrum, #card-stats, #card-multistart, #card-robust, #card-needle, #card-structure, #card-merit, #card-log { grid-area: auto; min-height: 300px; }
  /* Robustness (2.11) right under Synthesis: the spectrum with its corridor and the yield tiles share one screen */
  #card-spectrum { order: 1; } #card-stats { order: 3; } #card-robust { order: 4; } #card-multistart { order: 5; } #card-needle { order: 6; }
  #card-structure { order: 7; } #card-merit { order: 8; } #card-log { order: 9; }
  /* during a run and after it (until Reset) the Synthesis card moves right under the spectrum and Materials after it, so that
     the spectrum and the result tiles share one screen — as before the material cards (2.12) */
  .layout.run-active #card-stats { order: 2; }
  .layout.run-active #group-materials { order: 3; }
  /* with color targets the Synthesis card carries the Color block under its tiles: during a run the spectrum card gives
     up height so that the spectrum, the tiles and the Color block share one screen (the top bar measured) */
  .layout.run-active.color-on:not(.color-tab) #card-spectrum { min-height: 210px; height: clamp(210px, calc(100vh - var(--topbar-h, 80px) - 300px), 400px); height: clamp(210px, calc(100dvh - var(--topbar-h, 80px) - 300px), 400px); }
  /* the Color tab during a run: the diagram keeps a full height of its own — the screen less the top bar, the card's header,
     the bar, the legend, the Angle row and the Synthesis header with its tiles — so the diagram and the tiles share one screen;
     the palettes and the picker step aside while locked (they serve the pick mode alone, which brings them back) */
  .layout.run-active.color-tab #plot-chroma { height: clamp(160px, calc(100vh - var(--topbar-h, 80px) - 320px), 520px); height: clamp(160px, calc(100dvh - var(--topbar-h, 80px) - 320px), 520px); }
  .layout.run-active .color-side.locked { display: none; }
  /* the Color block of the Synthesis card: the targets side by side (--cv-cols from the number of targets) */
  #cv-rows { display: grid; grid-template-columns: repeat(var(--cv-cols, 1), minmax(0, 1fr)); column-gap: 14px; }
  .color-values .cv-row, .color-values .cv-row.target { border-top: 0; }
  #cv-rows .cv-row.target .val { justify-self: start; text-align: left; }   /* one phrase, no gap: «R 0° ■ → ● ΔE 1.3 ≤ 2.5» (the id outranks the later base rule) */
  #card-robust { min-height: 0; max-height: none; }
  #robust-tiles { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .row select { width: 140px; }
  #card-log, #card-multistart { min-height: 200px; }
  #card-stats { min-height: 0; max-height: 70vh; }
  /* needle derivative and coating structure share one screen: half the viewport each, less the sticky top bar and the gap */
  #card-needle, #card-structure { min-height: 0; height: clamp(160px, calc(50vh - 64px), 300px); }
  /* the field view (2.15) adds a row of tools and a wrapping legend: the card grows with them and keeps a plot of a readable height */
  #card-structure.field-on { height: auto; }
  #card-structure.field-on .plot { flex: none; height: clamp(150px, calc(50vh - 120px), 260px); }
  #card-structure.field-on .field-tools { gap: 4px 10px; }

  /* the four tiles in one row, compact, so that the spectrum and the Synthesis card share one screen during a run */
  .tiles { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; padding: 2px 16px; }
  .tile { padding: 6px 10px; gap: 0; border-radius: 10px; }
  .tile strong { font-size: clamp(14px, 2.2vw, 19px); }
  .tile .sub { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .progress { margin: 8px 16px 6px; }
  .start-label { margin-bottom: 4px; }
  #card-multistart { min-height: 160px; max-height: 320px; }
  /* «R & GDD»: the spectrum card holds two panels, so it is as tall as the viewport allows (300–400 px) while the
     Synthesis card's header, one row of tiles and the progress bar still fit under it on one screen, as in the other
     modes; --topbar-h is the measured height of the (wrapping) top bar, --stack-reserve the room the Synthesis card needs */
  :root { --stack-reserve: 177px; }
  .dashboard.gdd #card-spectrum { min-height: 250px; height: clamp(250px, calc(100vh - var(--topbar-h, 80px) - var(--stack-reserve)), 400px); height: clamp(250px, calc(100dvh - var(--topbar-h, 80px) - var(--stack-reserve)), 400px); }   /* 250 px: a 1000 × 530 window still shows the tiles and the progress bar */
  /* «R & GDD»: the four tiles of every mode come first (visible under the spectrum during a run), the two GDD tiles follow —
     all six in one row of short labels from 768 px up, two rows of three below */
  .tiles.gdd .gdd-tile { order: 1; }
  .tiles.gdd { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .tiles.gdd .tile { padding: 6px 7px; }
  .tiles.gdd .tile .k { font-size: 10px; letter-spacing: 0.02em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .tiles.gdd .tile .k .long { display: none; }
  .tiles.gdd .tile .k .short { display: inline; }
  .tiles.gdd .tile strong { font-size: clamp(13px, 1.9vw, 18px); }
  /* a tablet: the brand and the status share the first row; the controls take the rows below, right‑aligned, wrapping
     among themselves when a row cannot hold them all (an iPad in portrait) */
  .topbar-controls { flex: 1 1 auto; min-width: 0; flex-wrap: wrap; justify-content: flex-end; row-gap: 6px; }
}
@media (max-width: 767px) {
  :root { --stack-reserve: 251px; }   /* two rows of three tiles */
  .tiles.gdd { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  /* a phone: the top bar and the card header wrap into several rows, so the spectrum card is no longer tied to the
     viewport height — the plot keeps a readable height of its own and the page scrolls (two panels in «R & GDD») */
  .legend { flex-wrap: wrap; row-gap: 2px; }
  #card-spectrum { height: auto; }
  #card-spectrum .plot { min-height: 200px; }
  .dashboard.gdd #card-spectrum { height: auto; min-height: 0; }
  .dashboard.gdd #card-spectrum .plot { min-height: 330px; }
}
@media (max-width: 640px) {
  .tiles, #robust-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .layout { padding: 10px; }
  .topbar { padding: 10px 12px; }
  .stage-indicator { order: 3; flex-basis: 100%; }   /* a phone: the status on a row of its own under the controls */
  .topbar-controls { justify-content: flex-start; }   /* the groups stack from the left */
  .topgroup { border-radius: 24px; flex-wrap: wrap; }
}

/* ---------- the text size of a column (2.17.1) ----------
   Two small buttons (a smaller and a larger A) in each column — the inputs' bar, the spectrum card's title row, the
   Synthesis card's header — set the zoom of that column's cards; the charts redraw at the visual size. Kept on the
   device. The stacked layout shows the inputs' pair in the Materials heading (the bar is hidden there). */
:root { --zoom-inputs: 1; --zoom-charts: 1; --zoom-state: 1; }
.sidebar > .group, .sidebar > .about { zoom: var(--zoom-inputs); }
.dashboard > .card { zoom: var(--zoom-charts); }
.rail > .card { zoom: var(--zoom-state); }
.zoom-slot { display: inline-flex; }
.zoom-slot.stacked-only { display: none; }
.zoom-ctl { display: inline-flex; align-items: center; gap: 1px; padding: 1px; border-radius: 999px; background: color-mix(in srgb, var(--control) 70%, transparent); box-shadow: inset 0 0 0 1px var(--line); flex: none; }
.zoom-ctl button { border: 0; background: transparent; color: var(--ink-3); width: 22px; height: 20px; border-radius: 999px; cursor: pointer; font-family: inherit; font-weight: 600; line-height: 1; display: inline-grid; place-items: center; padding: 0; transition: background .15s, color .15s; }
.zoom-ctl button:hover { background: var(--control-active); color: var(--ink); }
.zoom-ctl button:disabled { opacity: .35; cursor: default; background: transparent; }
.zoom-ctl button[data-dir="-1"] { font-size: 10px; }
.zoom-ctl button[data-dir="1"] { font-size: 14px; }
.zoom-ctl .level { display: none; }   /* the level is in the tooltip; the buttons stay two small letters */
.zoom-ctl.changed { background: color-mix(in srgb, var(--accent) 12%, transparent); }   /* a column not at 100 % shows a tinted pill */
#card-spectrum > header > .zoom-slot { margin-left: auto; }
#card-stats > header > .zoom-slot { margin-left: 8px; }   /* after the timer: the pill ends at the right edge of the header, as in the other columns */
#group-materials h2 { display: flex; align-items: center; }
#group-materials h2 .zoom-slot { margin-left: auto; }   /* the stacked layout: the pill at the right edge of the Materials heading, like the pills of the cards */
@media (max-width: 1023px) { .zoom-slot.stacked-only { display: inline-flex; } }

/* ---------- the rows of the centre column (2.17.1) ----------
   A grip in every gap between the three cards: invisible until the pointer is over it (a short pill then), the
   row‑resize cursor as at the edge of a window; dragged with the mouse or a finger. Only in the three‑column layout. */
.dashboard { position: relative; }
.row-grip { position: absolute; left: 0; right: 0; height: 16px; z-index: 3; cursor: row-resize; touch-action: none; display: flex; align-items: center; justify-content: center; outline: none; }
.row-grip i { display: block; width: 44px; height: 4px; border-radius: 2px; background: var(--ink-3); opacity: 0; transition: opacity .15s, background .15s; }
.row-grip:hover i, .row-grip:focus-visible i { opacity: .55; }
.row-grip.dragging i { opacity: 1; background: var(--accent); }
@media (hover: none) { .row-grip i { opacity: .3; } }   /* a touch screen has no hover: the pill is faintly there */
html.row-resizing, html.row-resizing * { cursor: row-resize !important; user-select: none !important; }
@media (max-width: 1023px) { .row-grip { display: none; } }   /* the stacked layout: the cards are not rows of one grid */
/* the stacked layout (2.17.1): a grip along the bottom edge of the spectrum, structure and needle cards sets the card's height */
#card-spectrum, #card-structure, #card-needle { position: relative; }
.card-grip { display: none; position: absolute; left: 0; right: 0; bottom: 0; height: 16px; z-index: 3; cursor: row-resize; touch-action: none; align-items: flex-end; justify-content: center; padding-bottom: 3px; box-sizing: border-box; outline: none; }
.card-grip i { display: block; width: 44px; height: 4px; border-radius: 2px; background: var(--ink-3); opacity: .28; transition: opacity .15s, background .15s; }
.card-grip:hover i, .card-grip:focus-visible i { opacity: .6; }
.card-grip.dragging i { opacity: 1; background: var(--accent); }
@media (max-width: 1023px) {
  .card-grip { display: flex; }
  .card.sized .plot { min-height: 0 !important; flex: 1 1 auto !important; height: auto !important; }   /* a card of a set height: the plot takes what the card gives */
}

/* ---------- the expanded tiles (2.17.1) ----------
   A result tile opens across the card: the full note (no longer one line), a picture, a few lines of detail. */
#tiles .tile { cursor: pointer; transition: background .15s, box-shadow .15s; }
#tiles .tile:hover { background: color-mix(in srgb, var(--control) 85%, transparent); }
#tiles .tile:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--focus); }
.tiles .tile.expanded { grid-column: 1 / -1; background: color-mix(in srgb, var(--control) 70%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 35%, transparent); gap: 4px; }
.tiles .tile.expanded strong { font-size: clamp(20px, 1.8vw, 28px); white-space: normal; }
.tiles .tile.expanded .sub { display: none; }   /* the lines under the picture say it in full */
.tiles .tile.expanded .k .long { display: inline; } .tiles .tile.expanded .k .short { display: none; }
.tile-more { display: none; }
.tiles .tile.expanded .tile-more { display: flex; flex-direction: column; gap: 6px; margin-top: 2px; }
.tile-plot { display: block; width: 100%; height: 88px; }
.tile-plot[data-kind="thickness"], .tile-plot[data-kind="layers"] { height: 68px; }   /* one bar or one strip with its legend */
.tile-plot[data-kind="thickness"][data-rows="2"], .tile-plot[data-kind="layers"][data-rows="2"] { height: 104px; }
.tile-plot[data-kind="thickness"][data-rows="3"], .tile-plot[data-kind="layers"][data-rows="3"] { height: 140px; }
.tile-plot[data-kind="bars"], .tile-plot[data-kind="colors"] { height: 64px; }
.tile-plot[data-kind="bars"][data-rows="2"], .tile-plot[data-kind="colors"][data-rows="2"] { height: 80px; }
.tile-plot[data-kind="bars"][data-rows="3"], .tile-plot[data-kind="colors"][data-rows="3"] { height: 104px; }
.tile-plot[data-kind="bars"][data-rows="4"] { height: 128px; }   /* the Robustness card (2.17.2): the design itself and three percentiles of the tests */
.tile-plot[data-kind="corridor"] { height: 60px; }
.tile-plot[data-kind="yield"] { height: 58px; }   /* the gauge with its ticks above and its counts below */
.tile-plot[data-kind="shares"] { height: 48px; }   /* one row per layer */
.tile-plot[data-kind="shares"][data-rows="2"] { height: 56px; }
.tile-plot[data-kind="shares"][data-rows="3"] { height: 76px; }
.tile-plot[data-kind="shares"][data-rows="4"] { height: 96px; }
.tile-plot[data-kind="shares"][data-rows="5"] { height: 116px; }
.tile-plot[data-kind="shares"][data-rows="6"] { height: 136px; }
#robust-tiles .tile.expanded strong { white-space: normal; }   /* the critical layers wrap when opened */
.tile-plot[hidden] { display: none; }
.tile-lines { font-size: 12px; color: var(--ink-2); line-height: 1.35; display: flex; flex-direction: column; gap: 2px; }
.tile-lines[hidden] { display: none; }
/* the rail with an open tile: the Synthesis card takes the height it needs from the merit history and the log */
.rail.tile-open:not(.multi):not(.robust) { grid-template-rows: minmax(0, 2.6fr) minmax(0, 0.7fr) minmax(0, 0.7fr); }
.rail.tile-open.gdd:not(.multi):not(.robust), .rail.tile-open.colortile:not(.multi):not(.robust) { grid-template-rows: minmax(0, 3fr) minmax(0, 0.6fr) minmax(0, 0.7fr); }   /* the Multi‑start and Robustness rails scroll on their own */
@media (max-width: 1023px) { .tiles .tile.expanded strong { font-size: clamp(18px, 2.6vw, 24px); } .tile-plot { height: 96px; } }

/* ---------- the Event log sheet (2.17.1) ---------- */
#card-log > header.log-head { cursor: pointer; }
#card-log > header.log-head:hover h3 { color: var(--accent); }
#card-log .expand { margin-left: auto; border: 0; background: transparent; color: var(--ink-3); padding: 2px 4px; border-radius: 6px; cursor: pointer; display: inline-flex; align-items: center; }
#card-log .expand:hover { color: var(--accent); background: var(--control); }
dialog.sheet.log-sheet { width: min(1100px, 94vw); max-height: 88vh; display: flex; flex-direction: column; }
dialog.sheet.log-sheet:not([open]) { display: none; }
dialog.sheet.log-sheet > header { flex: none; }
.sheet-actions { display: inline-flex; align-items: center; gap: 10px; }
.log-sheet-body { flex: 1; min-height: 0; display: flex; flex-direction: column; padding: 6px 0 0; }
.log-sheet-body .log { font-size: 13.5px; padding: 0 18px 16px; gap: 6px; max-height: 76vh; }
.log-sheet-body .log li { grid-template-columns: 70px minmax(0, 1fr); padding: 6px 0; }
.log-sheet-body .log li.folded { display: grid; }   /* the large view shows every entry */
.log-sheet-body .log li .tag { font-size: 11px; }
.log-sheet-body .log table.cmp { font-size: 12.5px; }
@media (max-width: 1023px) { #card-log > header.log-head { cursor: default; } #card-log .expand { display: none; } }

/* ---------- Help ----------
   A sheet (dialog) opened by the Help button at the right end of the top bar
   (or ? / F1): contents on the left, the page on the right, the search in the
   header; the search results replace the page while a query is typed. Below
   800 px the contents fold behind the ☰ Contents button. Pages come from
   src/help-content.js, the search from src/help-search.js. */
.help-btn { display: inline-flex; align-items: center; gap: 6px; }
.help-btn .glyph { display: inline-grid; place-items: center; width: 18px; height: 18px; border-radius: 50%; background: var(--accent); color: var(--accent-ink); font-size: 12px; font-weight: 700; line-height: 1; }
dialog.sheet.help { width: min(1180px, 96vw); max-width: none; height: min(880px, 92vh); max-height: 92vh; display: flex; flex-direction: column; overflow: hidden; }
@supports (height: 1dvh) { dialog.sheet { max-height: 85dvh; } dialog.sheet.help { height: min(880px, 92dvh); max-height: 92dvh; } }   /* iOS Safari: 100vh includes the browser bars, 100dvh is what is visible */
dialog.sheet.help:not([open]) { display: none; }
dialog.sheet.help > header { gap: 12px; padding: 12px 16px; flex: none; }
.help-head { display: flex; align-items: center; gap: 10px; min-width: 0; }
.help-head h3 { white-space: nowrap; }
.help-toc { display: none; }
.help-search { flex: 1; display: flex; align-items: center; gap: 6px; min-width: 0; max-width: 620px; background: var(--input); border: 1px solid var(--input-border); border-radius: 999px; padding: 0 8px 0 12px; }
.help-search:focus-within { box-shadow: 0 0 0 3px var(--focus); border-color: var(--accent); }
.help-search-icon { color: var(--ink-3); flex: none; }
.help-search input { flex: 1; min-width: 0; border: 0; outline: 0; background: transparent; padding: 8px 4px; font-size: 14px; }
.help-search input::-webkit-search-cancel-button { display: none; }
.help-clear { border: 0; background: var(--control); color: var(--ink-2); border-radius: 50%; width: 22px; height: 22px; line-height: 1; font-size: 16px; cursor: pointer; }
.help-clear:hover { color: var(--ink); }
.help-body { flex: 1; display: grid; grid-template-columns: 256px minmax(0, 1fr); min-height: 0; }
.help-nav { overflow: auto; border-right: 1px solid var(--line); padding: 12px 10px 20px 14px; font-size: 13px; }
.help-nav h4 { margin: 10px 0 4px; font-size: 11px; text-transform: uppercase; letter-spacing: .05em; color: var(--ink-3); font-weight: 600; }
.help-nav ul { list-style: none; margin: 0; padding: 0; }
.help-nav li a { display: block; padding: 5px 8px; border-radius: 8px; color: var(--ink-2); text-decoration: none; line-height: 1.3; }
.help-nav li a:hover { background: var(--control); color: var(--ink); text-decoration: none; }
.help-nav li a.current { background: var(--accent); color: var(--accent-ink); }
.help-main { min-height: 0; display: flex; flex-direction: column; }
.help-article, .help-results { overflow: auto; padding: 18px 28px 32px; }
.help-article { font-size: 14.5px; line-height: 1.55; max-width: 900px; }
.help-article .help-crumb { font-size: 11px; text-transform: uppercase; letter-spacing: .05em; color: var(--ink-3); font-weight: 600; }
/* the Back button in the sheet header: the previous page, or the result list the page was opened from */
.help-back:disabled { opacity: .45; cursor: default; }
/* the page container takes the focus when the sheet opens (so the arrow keys scroll it): no focus ring around it */
.help-article:focus, .help-article:focus-visible { outline: none; }
.help-article h2 { font-size: 22px; font-weight: 650; letter-spacing: -0.015em; margin: 4px 0 14px; line-height: 1.2; }
.help-article h4 { font-size: 14px; font-weight: 650; margin: 18px 0 6px; }
.help-article p { margin: 0 0 10px; }
.help-article ul, .help-article ol { margin: 0 0 10px; padding-left: 22px; }
.help-article li { margin: 3px 0; }
.help-article b { font-weight: 600; }
.help-article code { font-family: var(--mono); font-size: 0.9em; background: var(--control); border-radius: 5px; padding: 1px 5px; }
.help-article kbd { font-family: var(--font); font-size: 12px; border: 1px solid var(--input-border); border-bottom-width: 2px; border-radius: 6px; padding: 1px 6px; background: var(--card); }
.help-article a { color: var(--accent); }
.help-article mark, .help-results mark { background: color-mix(in srgb, #f0a020 38%, transparent); color: inherit; border-radius: 3px; padding: 0 1px; }
.help-fields { display: grid; grid-template-columns: minmax(150px, 230px) minmax(0, 1fr); gap: 6px 16px; margin: 6px 0 12px; }
.help-fields dt { font-weight: 600; padding: 6px 0; border-top: 1px solid var(--line); }
.help-fields dd { margin: 0; padding: 6px 0; border-top: 1px solid var(--line); color: var(--ink-2); }
.help-fields dd b { color: var(--ink); }
.help-steps li { margin: 6px 0; }
.help-table { border-collapse: collapse; width: 100%; margin: 6px 0 12px; font-size: 13.5px; }
.help-table th, .help-table td { text-align: left; padding: 6px 10px; border-bottom: 1px solid var(--line); vertical-align: top; }
.help-table th { color: var(--ink-3); font-size: 11px; text-transform: uppercase; letter-spacing: .04em; font-weight: 600; }
.help-table td:first-child { white-space: nowrap; color: var(--ink-2); }
.help-tip { margin: 12px 0; padding: 10px 14px; border-left: 3px solid var(--accent); background: color-mix(in srgb, var(--accent) 7%, transparent); border-radius: 0 10px 10px 0; }
.help-ref { font-size: 12.5px; color: var(--ink-3); border-top: 1px solid var(--line); padding-top: 10px; margin-top: 18px; }
/* a file example in the Help (2.16: the layers of a fixed coating) */
.help-code { font: 12px/1.5 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; background: color-mix(in srgb, var(--control) 70%, transparent); border: 1px solid var(--line); border-radius: 8px; padding: 8px 12px; margin: 8px 0 4px; white-space: pre; overflow-x: auto; color: var(--ink); }
.help-related { margin-top: 22px; padding-top: 12px; border-top: 1px solid var(--line); }
.help-related h4 { margin: 0 0 6px; font-size: 11px; text-transform: uppercase; letter-spacing: .05em; color: var(--ink-3); }
.help-related ul { list-style: none; padding: 0; margin: 0; display: flex; flex-wrap: wrap; gap: 6px; }
.help-related li a { display: inline-block; border: 1px solid var(--line); background: var(--control); border-radius: 999px; padding: 4px 11px; font-size: 12.5px; color: var(--ink); }
.help-related li a:hover { text-decoration: none; background: var(--accent); color: var(--accent-ink); border-color: transparent; }
.help-pager { display: flex; justify-content: space-between; gap: 12px; margin-top: 22px; font-size: 13px; }
.help-pager a { max-width: 48%; }
.help-pager .next { text-align: right; margin-left: auto; }
/* search results */
.help-results .help-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
.help-results .help-count { font-size: 12.5px; color: var(--ink-3); margin: 0 0 10px; }
.help-results .help-nores { color: var(--ink-2); }
.help-results .help-suggest { font-size: 13px; color: var(--ink-2); }
.help-list { list-style: none; margin: 0; padding: 0; }
.help-list li { padding: 10px 12px; border-radius: 12px; cursor: pointer; border: 1px solid transparent; }
.help-list li + li { margin-top: 4px; }
.help-list li:hover { background: var(--control); }
.help-list li.selected { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 8%, transparent); }
.help-list .t { font-weight: 600; display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.help-list .g { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-3); }
.help-list .p { font-size: 11px; font-weight: 600; color: #b26a00; background: color-mix(in srgb, #f0a020 18%, transparent); border-radius: 999px; padding: 1px 7px; }
.help-list .s { font-size: 13px; color: var(--ink-2); margin-top: 3px; line-height: 1.45; }
@media (min-width: 1280px) { .help-article { font-size: 15.5px; } .help-nav { font-size: 14px; } .help-table { font-size: 14px; } }
@media (max-width: 800px) {
  dialog.sheet.help { width: 100vw; height: 100vh; max-height: 100vh; max-width: 100vw; border-radius: 0; margin: 0; }
  @supports (height: 1dvh) { dialog.sheet.help { height: 100dvh; max-height: 100dvh; } }
  dialog.sheet.help > header { flex-wrap: wrap; padding-top: calc(12px + env(safe-area-inset-top, 0px)); }
  .help-search { order: 3; flex-basis: 100%; max-width: none; }
  .help-toc { display: inline-block; }
  .help-body { grid-template-columns: minmax(0, 1fr); position: relative; }
  .help-nav { display: none; }
  dialog.sheet.help.toc-open .help-nav { display: block; position: absolute; inset: 0; z-index: 2; background: var(--card); border-right: 0; }
  .help-article, .help-results { padding: 14px 16px 28px; }
  .help-fields { grid-template-columns: 1fr; gap: 0; }
  .help-fields dt { border-top: 1px solid var(--line); padding-bottom: 0; }
  .help-fields dd { border-top: 0; padding-top: 2px; }
  .help-table td:first-child { white-space: normal; }
}

/* the load‑error banner: shown only when the application failed to start (a cached page or script of another build) */
.load-error { position: fixed; top: 0; left: 0; right: 0; z-index: 1000; display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; padding: 10px 16px; background: #fff4e5; color: #7a3d00; border-bottom: 1px solid #f0c080; font-size: 14px; line-height: 1.4; }
.load-error[hidden] { display: none; }
.load-error button { border: 1px solid #d08a2e; background: #fff; color: #7a3d00; border-radius: 999px; padding: 4px 12px; font-size: 13px; cursor: pointer; }
.load-error code { font-size: 11px; color: #a06020; flex-basis: 100%; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .load-error { background: #3a2a10; color: #ffd8a0; border-color: #7a5a20; } :root:not([data-theme="light"]) .load-error button { background: #2a2a2c; color: #ffd8a0; border-color: #a07030; } }

/* ---------- light source / detector and the integrals (2.12.2) ---------- */
.custom-dist { display: flex; flex-direction: column; gap: 6px; margin-top: 6px; padding: 8px 10px; border: 1px solid var(--line); border-radius: 12px; background: color-mix(in srgb, var(--control) 45%, transparent); }
.custom-dist .row { border-bottom: 0; padding: 2px 0; }
.custom-dist .row input { width: 150px; text-align: left; }
.custom-dist textarea { width: 100%; box-sizing: border-box; resize: vertical; min-height: 72px; border: 1px solid var(--input-border); border-radius: 9px; padding: 6px 8px; background: var(--input); color: var(--ink); font: 12px var(--mono); line-height: 1.4; outline: none; }
.custom-dist textarea:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--focus); }
.custom-dist .actions { display: flex; gap: 6px; }
.hint.bad { color: var(--bad); }
.sd-preview { display: block; width: 100%; height: 64px; margin-top: 8px; border-radius: 10px; background: color-mix(in srgb, var(--control) 45%, transparent); }
.swatch.sd { width: 16px; height: 9px; border-radius: 2px; background: var(--source-fill); border-bottom: 2px solid var(--source); }
/* the integral target rows (Target tab): two lines per target — what is integrated and over which range; the value, the tolerance, the two switches */
#integrals-wrap { margin-top: 14px; }
h4.with-switch { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
h4.with-switch .switch-label { display: inline-flex; }
.integrals { display: flex; flex-direction: column; gap: 8px; }
.integral { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 4px 8px; align-items: center; padding: 8px 10px; border: 1px solid var(--line); border-radius: 12px; font-size: 12px; background: color-mix(in srgb, var(--control) 35%, transparent); }
.integral .l1, .integral .l2 { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; min-width: 0; }
.integral .l2 { grid-column: 1; }
.integral .x { grid-column: 2; grid-row: 1 / span 2; border: 0; background: var(--control); border-radius: 50%; width: 22px; height: 22px; cursor: pointer; color: var(--ink-2); line-height: 1; }
.integral label { display: inline-flex; align-items: center; gap: 4px; color: var(--ink-3); white-space: nowrap; }
.integral input[type=number] { width: 64px; border: 1px solid var(--input-border); border-radius: 8px; padding: 4px 6px; background: var(--input); color: var(--ink); text-align: right; font-variant-numeric: tabular-nums; }
.integral select { border: 1px solid var(--input-border); border-radius: 8px; padding: 4px 6px; background: var(--input); color: var(--ink); font-size: 12px; }
.integral input.switch, .iv-row input.switch { width: 30px; height: 18px; border-radius: 9px; }
.integral input.switch::after, .iv-row input.switch::after { width: 14px; height: 14px; }
.integral input.switch:checked::after, .iv-row input.switch:checked::after { transform: translateX(12px); }
.integral .cur { margin-left: auto; color: var(--ink-2); font-variant-numeric: tabular-nums; white-space: nowrap; }
.integral .cur.ok { color: var(--good); }
.integral .cur.bad { color: var(--bad); }
.integral-add { align-self: flex-start; }
/* the integral values of the Synthesis card: a compact list under the tiles */
.integral-values { margin: 2px 16px 6px; padding: 8px 12px 8px; background: color-mix(in srgb, var(--control) 55%, transparent); border-radius: 14px; font-size: 12px; color: var(--ink-2); display: flex; flex-direction: column; gap: 6px; }
.iv-head { display: flex; align-items: center; gap: 10px; }
.iv-head .iv-title { font-size: 11px; color: var(--ink-3); text-transform: uppercase; letter-spacing: 0.04em; font-weight: 600; }
.iv-head .muted { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chip.small { padding: 2px 9px; font-size: 11px; }
.iv-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; padding: 4px 0; border-top: 1px solid var(--line); }
.iv-row:first-child { border-top: 0; }
.iv-row .lbl { font-weight: 600; color: var(--ink); white-space: nowrap; }
.iv-row .meta { color: var(--ink-3); white-space: nowrap; }
.iv-row select, .iv-row input[type=number] { border: 1px solid var(--input-border); border-radius: 8px; padding: 2px 5px; background: var(--input); color: var(--ink); font-size: 11px; }
.iv-row input[type=number] { width: 58px; text-align: right; font-variant-numeric: tabular-nums; }
.iv-row label { display: inline-flex; align-items: center; gap: 3px; color: var(--ink-3); white-space: nowrap; font-size: 11px; }
.iv-row .val { margin-left: auto; font-size: 15px; font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; white-space: nowrap; letter-spacing: -0.01em; }
.iv-row .val.ok { color: var(--good); }
.iv-row .val.bad { color: var(--bad); }
.iv-row .tgt { color: var(--ink-3); white-space: nowrap; }
.iv-row .x { border: 0; background: var(--control); border-radius: 50%; width: 20px; height: 20px; cursor: pointer; color: var(--ink-2); line-height: 1; font-size: 12px; }

/* ===================== Color (2.13) ===================== */
:root { --color-locus: #1d1d1f; --color-target: #0071e3; --color-tol: rgba(0, 113, 227, 0.28); --color-trail: rgba(29, 29, 31, 0.55); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { --color-locus: #f5f5f7; --color-target: #0a84ff; --color-tol: rgba(10, 132, 255, 0.32); --color-trail: rgba(245, 245, 247, 0.55); } }
:root[data-theme="dark"] { --color-locus: #f5f5f7; --color-target: #0a84ff; --color-tol: rgba(10, 132, 255, 0.32); --color-trail: rgba(245, 245, 247, 0.55); }
/* a swatch: the color itself with a thin frame; .big in the Synthesis block, .ring carries the ΔE arc of a target */
.sw { display: inline-block; width: 16px; height: 16px; border-radius: 5px; border: 1px solid var(--line); box-shadow: inset 0 0 0 1px rgba(255,255,255,0.35); vertical-align: middle; flex: none; background: #888; transition: background-color .25s; }
.sw.big { width: 24px; height: 24px; border-radius: 7px; }
.sw.out { box-shadow: inset 0 0 0 1px rgba(255,255,255,0.35), 0 0 0 1px var(--bad); }
.sw-pair { display: inline-flex; align-items: center; gap: 4px; flex: none; }
.sw-pair .arrow { color: var(--ink-3); font-size: 11px; }
/* the ΔE ring around the «now» swatch: an arc that fills as the deviation falls to the tolerance */
.sw-ring { position: relative; width: 30px; height: 30px; flex: none; display: inline-grid; place-items: center; }
.sw-ring .sw { position: relative; z-index: 1; }
.sw-ring::before { content: ""; position: absolute; inset: 0; border-radius: 50%; background: conic-gradient(var(--ring-color, var(--accent)) calc(var(--ring, 0) * 1%), var(--control) 0); -webkit-mask: radial-gradient(circle, transparent 10px, #000 11px); mask: radial-gradient(circle, transparent 10px, #000 11px); transition: --ring .3s; }
.sw-ring.ok::before { --ring-color: var(--good); }
/* the color target rows of the Target tab (the layout of the integral rows) */
.integral.ctarget .l1 .sp { font-weight: 600; color: var(--ink-2); }
.integral.ctarget input[type=number].coord { width: 58px; }
.integral.ctarget .ang { width: 52px; }
.integral.ctarget .pick { border: 1px solid var(--line); background: var(--control); border-radius: 999px; padding: 2px 9px; font-size: 11px; cursor: pointer; color: var(--accent); }
.integral.ctarget .cur { display: inline-flex; align-items: center; gap: 6px; }
/* the field targets (2.15): the same rows as the color targets */
.integral.ftarget .l1 .sp { font-weight: 600; color: var(--ink-2); }
.integral.ftarget input[type=number].short { width: 58px; }
.integral.ftarget input[type=number].lam { width: 66px; }
.integral.ftarget .ang { width: 52px; }
.integral.ftarget .op { color: var(--ink-2); font-weight: 600; }
/* the Color block of the Synthesis card */
.color-values .cv-row { display: flex; align-items: center; gap: 8px; padding: 3px 0; border-top: 1px solid var(--line); min-width: 0; }
/* a note that does not fit scrolls slowly back and forth (text-indent is animated, the text stays on one line) */
.marquee { text-overflow: clip !important; animation: marquee var(--mq-dur, 8s) ease-in-out infinite alternate; }
@keyframes marquee { 0%, 18% { text-indent: 0; } 82%, 100% { text-indent: var(--mq-shift, 0); } }
@media (prefers-reduced-motion: reduce) { .marquee { animation: none; text-overflow: ellipsis !important; } }
/* a target row: the label, the two swatches and the deviation on one line, the target and the current coordinates under them — the same alignment in every color space */
.color-values .cv-row.target { display: grid; grid-template-columns: auto auto minmax(0, 1fr); grid-template-areas: "lbl pair val" "meta meta meta"; align-items: center; column-gap: 8px; row-gap: 0; }
.color-values .cv-row.target .lbl { grid-area: lbl; min-width: 0; }
.color-values .cv-row.target .sw-pair { grid-area: pair; }
.color-values .cv-row.target .val { grid-area: val; justify-self: end; margin-left: 0; white-space: pre-line; text-align: right; line-height: 1.2; font-size: 13px; }
.color-values .cv-row.target .meta { grid-area: meta; font-size: 11px; }
.color-values { padding-top: 6px; padding-bottom: 6px; margin-bottom: 4px; }
.color-values .cv-row:first-child { border-top: 0; }
.color-values .lbl { font-weight: 600; color: var(--ink); white-space: nowrap; min-width: 44px; }
.color-values .meta { color: var(--ink-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; flex: 1; font-variant-numeric: tabular-nums; }
.color-values .val { margin-left: auto; font-size: 14px; font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; white-space: nowrap; }
.color-values .val.ok { color: var(--good); }
.color-values .val.bad { color: var(--bad); }
.color-values .cv-row.none .lbl { color: var(--ink-3); }
.tile.color-tile strong.ok { color: var(--good); }
.tile.field-tile strong.ok { color: var(--good); }
.tile.field-tile strong.bad { color: var(--bad); }
/* the Color tab: the diagram with its bar and the angle row at the left, the palettes and the picker at the right */
.color-panel { grid-template-columns: minmax(0, 1fr) minmax(148px, 176px); grid-template-rows: minmax(0, 1fr); align-content: stretch; row-gap: 0; column-gap: 12px; overflow: auto; }   /* a very short card scrolls rather than cutting the Angle row */
.color-main { display: flex; flex-direction: column; gap: 6px; min-width: 0; min-height: 0; }
.color-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; font-size: 12px; min-width: 0; }   /* wraps only when the column is too narrow for one line */
.color-bar .tool { display: inline-flex; align-items: center; gap: 6px; color: var(--ink-3); }
.color-bar select { border: 1px solid var(--input-border); border-radius: 8px; padding: 3px 6px; background: var(--input); color: var(--ink); font-size: 12px; max-width: 128px; min-width: 0; }
.color-bar .chip { flex: none; }
.color-bar #color-readout { margin-left: auto; font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
#plot-chroma { position: relative; flex: 1 1 auto; min-height: 60px; border-radius: 14px; overflow: hidden; background: color-mix(in srgb, var(--control) 35%, transparent); }
.color-main > .color-bar, .color-main > .color-legend, .color-main > .color-angle { flex: none; }
#plot-chroma canvas { cursor: default; }
#tt-chroma { position: fixed; z-index: 60; }   /* the diagram's tooltip leaves the diagram's box: above the pointer, never under it */
.color-angle { display: flex; flex-wrap: nowrap; align-items: center; gap: 6px 8px; font-size: 12px; min-width: 0; }
.color-angle input[type=range] { flex: 1; min-width: 80px; max-width: 260px; height: 18px; margin: 0; accent-color: var(--accent); }
.color-angle > * { flex: none; }
.color-angle input[type=range] { flex: 1 1 auto; }
.color-angle .qty { display: inline-flex; align-items: center; gap: 4px; }
/* the legend under the diagram: every target — its color (◆) and the design's color (●) with the distance, live during a run */
.color-legend { display: flex; flex-wrap: nowrap; gap: 4px 14px; font-size: 12px; color: var(--ink-2); min-height: 18px; overflow-x: auto; scrollbar-width: thin; }   /* one line, however many targets: the Angle row under it is never pushed out */
.color-legend .item { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; }
.color-legend .item .lbl { font-weight: 600; color: var(--ink); }
.color-legend .item .sw { width: 14px; height: 14px; border-radius: 4px; border: 1px solid var(--line); box-shadow: inset 0 0 0 1px rgba(255,255,255,0.35); display: inline-block; }
.color-legend .item .sw.diamond { transform: rotate(45deg) scale(0.8); border-radius: 2px; border-color: var(--color-target, var(--accent)); }
.color-legend .item .sw.circle { border-radius: 50%; }
.color-legend .item .dist { font-variant-numeric: tabular-nums; }
.color-legend .item .dist.ok { color: var(--good); font-weight: 600; }
.color-legend .item .dist.bad { color: var(--bad); }
.color-side { display: flex; flex-direction: column; gap: 5px; min-width: 0; min-height: 0; overflow: auto; padding-right: 2px; }
.color-side h4 { font-size: 11px; margin: 2px 0 0; }
/* outside the pick mode («Pick…» of the Target tab) the palettes and the picker only show what they offer */
.color-side.locked .palettes, .color-side.locked .picker { opacity: 0.45; pointer-events: none; }
.color-side h4 .muted { font-weight: 400; }
.palettes { display: flex; flex-direction: column; gap: 4px; }
.palette .name { font-size: 10px; color: var(--ink-3); margin-bottom: 2px; }
.palette .chips { display: flex; flex-wrap: wrap; gap: 4px; padding-bottom: 1px; }
.palette .pchip { flex: none; width: 20px; height: 20px; border-radius: 6px; border: 1px solid var(--line); box-shadow: inset 0 0 0 1px rgba(255,255,255,0.35); cursor: pointer; padding: 0; transition: transform .15s; }
.palette .pchip:hover, .palette .pchip:focus-visible { transform: scale(1.12); outline: 2px solid var(--accent); outline-offset: 1px; }
.picker { display: flex; flex-direction: column; gap: 6px; font-size: 12px; }
.picker-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.picker-row input[type=text] { width: 76px; border: 1px solid var(--input-border); border-radius: 8px; padding: 3px 6px; background: var(--input); color: var(--ink); font-family: var(--mono); font-size: 12px; }
.picker-image { position: relative; min-height: 48px; border: 1px dashed var(--input-border); border-radius: 12px; display: grid; place-items: center; overflow: hidden; background: color-mix(in srgb, var(--control) 35%, transparent); }
.picker-image.has { border-style: solid; }
.picker-image canvas { display: block; max-width: 100%; max-height: 180px; cursor: crosshair; }
.picker-image .placeholder { font-size: 11px; color: var(--ink-3); text-align: center; padding: 10px; }
.picker-image.over { border-color: var(--accent); }
@media (max-width: 1023px) {
  .color-panel { grid-template-columns: 1fr; grid-template-rows: auto auto; overflow: auto; align-content: start; }
  .color-side { overflow: visible; }
  /* the diagram's height follows the screen: the (measured, wrapping) top bar, the card's header and tabs, the bar, the
     legend and the Angle row stay on one screen with it (a tall screen caps it at 520 px, a very short one keeps 160 px) */
  #plot-chroma { flex: none; width: 100%; max-width: none; aspect-ratio: auto; height: clamp(160px, calc(100vh - var(--topbar-h, 80px) - 215px), 520px); height: clamp(160px, calc(100dvh - var(--topbar-h, 80px) - 215px), 520px); margin: 0; }
  .palette .pchip { width: 28px; height: 28px; border-radius: 8px; }
  .tiles.with-color { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}
/* a phone: the color deviation stays in the Color block under the tiles, the row keeps its four tiles */
@media (max-width: 599px) {
  .tile.color-tile, .tile.field-tile { display: none; }   /* a phone: the color deviation stays in the Color block, the peak field in the caption of the Coating structure card */
  .tiles.with-color { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  /* four narrow tiles: the short labels on one line, whatever the height of the screen, so the row keeps one height */
  .tiles.with-color .tile .k { font-size: 10px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .tiles.with-color .tile .k .long { display: none; }
  .tiles.with-color .tile .k .short { display: inline; }
  /* two targets side by side on a phone: the distance moves under the swatches, the coordinates under it */
  #cv-rows.multi .cv-row.target { grid-template-columns: auto minmax(0, 1fr); grid-template-areas: "lbl pair" "val val" "meta meta"; }
  #cv-rows.multi .cv-row.target .val { font-size: 12.5px; }
}
/* a phone during a run with color targets: the spectrum card is short, so its (locked) tools rows step aside until Reset and
   the chart keeps its height; the spectrum, the tiles and the Color block then share one screen */
@media (max-width: 599px) { .layout.run-active.color-on #spectrum-tools { display: none; } }

/* ===================================================================== */
/*  Stacks (2.16): the editor in the Coating structure card, the scheme   */
/* ===================================================================== */
/* the editor replaces the chart while it is open: the rows run along the light, from the incident medium to the exit; a
   medium row is a tinted band, a face row carries the coating chip, its state and the medium it lies on */
#card-structure.stack-edit .plot, #card-structure.stack-edit .field-tools, #card-structure.stack-edit #structure-view, #card-structure.stack-edit #structure-legend { display: none; }
#card-structure.stack-on #structure-view, #card-structure.stack-on .field-tools { display: none; }
/* the title block of the Coating structure card: the title, and under it — with a stack — the Edit stack button */
#card-structure > header .title-block { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; }
#card-structure > header .title-block h3 { margin: 0; }
#card-structure > header #btn-stack { margin-left: 0; background: color-mix(in srgb, var(--accent) 14%, var(--control)); border-color: color-mix(in srgb, var(--accent) 40%, transparent); }   /* at the left edge, under the title */
.stack-editor { flex: 1; min-height: 0; overflow: auto; padding: 4px 16px 12px; display: flex; flex-direction: column; gap: 0; }
.stack-editor .se-row { display: flex; align-items: center; gap: 8px; padding: 5px 4px; min-height: 34px; border-bottom: 1px solid var(--line); font-size: 12.5px; flex-wrap: wrap; }
.stack-editor .se-row.se-fixed { color: var(--ink-3); justify-content: space-between; }
.stack-editor .se-row.se-fixed .note { font-size: 11.5px; }
.stack-editor .se-row.se-medium { background: color-mix(in srgb, var(--control) 60%, transparent); border-radius: 8px; border-bottom: 0; margin: 2px 0; padding: 5px 8px; }
.stack-editor .se-row select, .stack-editor .se-row input { border: 1px solid var(--input-border); border-radius: 8px; padding: 4px 7px; background: var(--input); font-size: 12px; color: var(--ink); outline: none; max-width: 190px; }
.stack-editor .se-row select:focus, .stack-editor .se-row input:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--focus); }
.stack-editor .se-row .chip { padding: 4px 10px; }
.stack-editor .se-row .chip.coating { font-weight: 600; border-color: color-mix(in srgb, var(--accent) 45%, transparent); }
.stack-editor .se-row .chip.coating.selected { background: var(--accent); color: var(--accent-ink); border-color: transparent; }
.stack-editor .se-row .chip.coating.fixed { opacity: 0.8; }
.stack-editor .se-row .chip.coating.hidden-state { text-decoration: line-through; opacity: 0.6; }
.stack-editor .se-row .bare { color: var(--ink-3); font-style: italic; }
.stack-editor .se-row .on { color: var(--ink-3); font-size: 11.5px; }
.stack-editor .se-row .spacer { flex: 1; }
.stack-editor .se-row .info { width: 22px; height: 22px; border-radius: 50%; border: 1px solid var(--input-border); background: var(--input); color: var(--accent); font: 600 12px/1 var(--font); font-style: italic; cursor: pointer; padding: 0; flex: none; }
.stack-editor .se-row .x { border: 0; background: var(--control); border-radius: 50%; width: 24px; height: 24px; cursor: pointer; color: var(--ink-2); line-height: 1; flex: none; }
.stack-editor .se-row .x:disabled { opacity: 0.4; cursor: default; }
.stack-editor .se-actions { display: flex; align-items: center; gap: 8px; padding: 10px 4px 4px; flex-wrap: wrap; }
.stack-editor .se-actions .note { color: var(--ink-3); font-size: 11.5px; margin-left: auto; text-align: right; }
.stack-editor .hint.bad { color: var(--bad, #c0392b); margin: 2px 4px 0; }
/* the chips of the needle card (one per synthesized coating) */
.chips.small .chip { padding: 3px 9px; font-size: 11.5px; }
/* three columns: while the editor is open the structure card takes the height its rows need and the column scrolls, so
   that the editor is never squeezed; with a stack drawn the structure card is a little taller than usual (the names of
   the coatings above the bars), as with the field view */
.dashboard.stack-edit { grid-template-rows: minmax(220px, 1.1fr) minmax(max-content, 1fr) minmax(160px, 0.5fr); overflow-y: auto; overflow-x: hidden; }
#card-structure.stack-on #structure-opt { display: none; }
.dashboard.stack-edit #card-structure { min-height: max-content; }
.dashboard.stack-on:not(.stack-edit) { grid-template-rows: minmax(0, 1.12fr) minmax(0, 1.3fr) minmax(160px, 0.62fr); }
@media (max-width: 1023px) { .dashboard.stack-edit #card-structure { min-height: 300px; height: auto; } }
