/* Wizard chrome on top of tokens.css (UI_GUIDELINES §3–§6). No
   frameworks; AA contrast; opaque surfaces so contrast holds in
   daylight on site.

   D206 "RazeForce command centre": DemSim is a RazeForce product, so
   the console IS the product identity — near-black page, #111111
   panels, bone text, ONE brand red (hot-red on dark), Archivo Black
   for short headlines only, figures in tabular mono. The simulation
   canvas no longer sits as a dark lens in a light page; the whole app
   is the instrument. Colour changes are instant (0ms = snappy); motion
   is opacity/transform only, 0.12s fast / 0.2s base, never springy;
   engineering data never animates.

   The PAPER family (D194's drafting-paper neutrals) is not gone — it is
   scoped to `[data-theme='light']` and used by the client-facing
   deliverables, which get printed. See tokens.json's comment. */

* { box-sizing: border-box; }
/* the hidden attribute must win over element display rules (e.g.
   `label { display: flex }`), so toggling `.hidden` reliably shows/hides */
[hidden] { display: none !important; }
body {
  margin: 0; 
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-family); font-size: var(--font-size-md);
  min-height: 100vh; display: flex; flex-direction: column;
}
main { flex: 1; padding: var(--space-5); max-width: 1100px;
       width: 100%; margin: 0 auto; z-index: 1; }
/* Display face on headlines ONLY (D206) — Archivo Black is a poster
   face, unreadable as body copy. It is a short-string face: screen
   titles and step numerals, nothing that wraps. */
h1 { font-size: var(--font-size-xl); margin: 0 0 var(--space-4);
  font-family: var(--font-display); font-weight: 400;
  letter-spacing: -0.01em; line-height: 1.15;
  text-transform: uppercase; }
h2 { font-size: var(--font-size-lg); margin: 0 0 var(--space-2);
  font-weight: 650; letter-spacing: -0.01em; }
.mono { font-family: var(--font-mono); }
.hint { color: var(--muted); font-size: var(--font-size-sm); }
.spacer { flex: 1; }

.topbar {
  display: flex; align-items: center; gap: var(--space-4);
  flex-wrap: wrap; row-gap: var(--space-2);   /* the key field drops
    cleanly on narrow screens instead of floating detached (D142) */
  padding: var(--space-3) var(--space-5);
  background: var(--elevated);
  border-bottom: 1px solid var(--border);
  box-shadow: var(--shadow-sm); position: sticky; top: 0; z-index: 30;
}
/* the wordmark as a title-block stamp: spaced caps, drawing-set voice.
   The drawn logo (D200) supersedes the text treatment on the masthead;
   the type rules stay because brand.js falls back to a text company
   name, and the deliverable pages share this voice. */
.brand { font-weight: 700; letter-spacing: 0.16em;
  text-transform: uppercase; font-size: var(--font-size-sm);
  display: inline-flex; align-items: center; }
/* Two contexts, two sizes. On a DOCUMENT (the method-statement cover,
   the report) the wordmark is a masthead and gets a fixed 24px; in an
   app TOPBAR it is chrome and tracks the type scale so it stays in
   proportion to the badge beside it. `currentColor` does the theming. */
.brand-mark { height: 24px; width: auto; display: block; }
.topbar .brand-mark { height: 1.15em; }
/* white-label: the contractor's company + logo take the masthead
   (brand.js); the tier badge, pack chip and disclaimer are untouched */
.brand.branded { display: inline-flex; align-items: center;
  gap: var(--space-2); letter-spacing: normal; text-transform: none;
  font-size: inherit; }
.brand-logo { height: 28px; width: auto; max-width: 200px;
  display: block; }
.brand-name { font-weight: 700; }
#brand-meta { margin: var(--space-2) 0 0; }

/* branding editor dialog */
#brand-dialog { border: 1px solid var(--muted);
  border-radius: var(--radius-md); background: var(--surface);
  color: var(--text); max-width: 460px; width: 92%; padding: 0; }
#brand-dialog form { display: flex; flex-direction: column;
  gap: var(--space-3); padding: var(--space-5); margin: 0; }
#brand-dialog::backdrop { background: rgba(0, 0, 0, 0.55); }
#brand-dialog h2 { margin: 0; }
#brand-logo-preview { display: inline-flex; align-items: center; }
#brand-logo-preview img { max-height: 40px; width: auto; }
#brand-accent { width: 56px; height: 32px; padding: 2px; }

/* Rule 1: the tier badge is prominent on every screen — never styled
   to be ignorable. */
.tier-badge {
  padding: 2px var(--space-3); border-radius: var(--radius-sm);
  font-size: var(--font-size-sm); font-weight: 600; color: #111;
  background: var(--color-tier-L0); cursor: help;
  /* inset ring so L0-grey can never dissolve into the topbar — the one
     badge an engineer's sign-off leans on (rule 1) */
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.12);
}
.tier-badge[data-tier="L1"] { background: var(--color-tier-L1); }
.tier-badge[data-tier="L2"] { background: var(--color-tier-L2); }
.tier-badge[data-tier="L3"] { background: var(--color-tier-L3); }
.chip {
  padding: 2px var(--space-2); border-radius: var(--radius-sm);
  background: var(--surface); border: 1px solid var(--border);
  font-size: var(--font-size-xs); color: var(--text);
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
}
.key-label { font-size: var(--font-size-xs); color: var(--muted);
  display: flex; gap: var(--space-2); align-items: center; }

#steps ol {
  display: flex; gap: var(--space-5); list-style: none;
  margin: 0 auto; padding: var(--space-3) var(--space-5);
  max-width: 1100px; counter-reset: step;
}
#steps li { counter-increment: step; color: var(--muted);
  font-size: var(--font-size-sm); }
#steps li::before { content: counter(step) ". "; }
#steps li.current { color: var(--text); font-weight: 600; }
#steps li.done { color: var(--color-accent); }

.cards { display: flex; gap: var(--space-5); flex-wrap: wrap; }
#jump-card { margin-bottom: var(--space-4);
  border: 1px solid var(--color-accent); }
#jump-input { flex: 1; min-width: 200px; }
#chimney-card { margin-top: var(--space-4); }
#parametric-form { display: flex; flex-direction: column; gap: var(--space-3); }
.chimney-grid { display: grid; gap: var(--space-2);
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); }
.target-picker { display: flex; flex-direction: column; gap: var(--space-2);
  margin: var(--space-2) 0; }
.target-picker .check { display: flex; align-items: center; gap: var(--space-2); }
.target-plan-row { background: var(--surface); border-radius: var(--radius-md);
  border: 1px solid var(--border); padding: var(--space-3);
  margin-bottom: var(--space-3); }
.target-plan-row h3 { margin: 0 0 var(--space-2); font-size: var(--font-size-md); }
#chimney-list { list-style: none; margin: var(--space-3) 0 0; padding: 0;
  display: flex; flex-direction: column; gap: var(--space-1); }
#chimney-list li { display: flex; align-items: center; gap: var(--space-2);
  font-size: var(--font-size-sm); }
.chimney-row.selected { border-color: var(--color-danger); }
/* Opaque surfaces on purpose (D65): translucency made real contrast
   unpredictable and washed out in daylight on site. */
.card {
  background: var(--surface);
  border-radius: var(--radius-lg);
  padding: var(--space-4); flex: 1 1 320px;
  display: flex; flex-direction: column; gap: var(--space-3);
  border: 1px solid var(--border); box-shadow: var(--shadow-sm);
}
label { display: flex; flex-direction: column; gap: var(--space-1);
  font-size: var(--font-size-sm); }
input, textarea, select {
  /* a field is a CUT-OUT, darker than the panel it sits in, with a
     bright enough edge to read at arm's length on a site tablet
     (WCAG 1.4.11 >=3:1). Both values are theme-bound so the printed
     deliverables' paper fields still work. */
  background: var(--field); color: var(--text);
  border: 1px solid var(--field-border);
  border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-3); font: inherit;
  min-height: 40px;                     /* touch target on a site tablet */
}
input:hover, textarea:hover, select:hover { border-color: var(--muted); }
input:focus-visible, textarea:focus-visible, select:focus-visible,
button:focus-visible, [data-mode-btn]:focus-visible {
  outline: 2px solid var(--color-accent); outline-offset: 1px;
  border-color: var(--color-accent); }

/* ONE primary button. Everything else is secondary or quiet — when
   every control glows, nothing is the next step. Primary is a hot-red
   fill with bone text; secondary (`.ghost`) is a raised dark panel with
   the bright border. No blue anywhere (D206). */
button {
  background: var(--color-accent); color: var(--color-rf-offWhite);
  border: 1px solid transparent;
  border-radius: var(--radius-md); padding: var(--space-2) var(--space-4);
  font: inherit; font-weight: 600; cursor: pointer; min-height: 40px;
  transition: background var(--motion-fast) linear;
}
button:hover:not(:disabled) { background: var(--color-accentHover); }
/* the only button motion: a 1px machine press. */
button:active:not(:disabled) { transform: translateY(1px); }
button.ghost { background: var(--elevated); color: var(--text);
  border: 1px solid var(--border-bright); font-weight: 500; }
button.ghost:hover:not(:disabled) {
  border-color: var(--color-accent); color: var(--color-rf-offWhite); }
button:disabled { opacity: 0.45; cursor: not-allowed; }

/* was `.ai-glow` — an AI-assisted action is a quiet secondary, not a
   neon focal point competing with "Run the study" */
button.ai-glow {
  background: var(--color-accentSoft); color: var(--color-accentText);
  border: 1px solid var(--color-accent); font-weight: 600;
}
button.ai-glow:hover:not(:disabled) {
  background: var(--color-accent); color: var(--color-rf-offWhite);
}

/* ---------------------------------------------- study modes & modules */
.mode-switch { display: grid; gap: var(--space-3); margin: 0 0 var(--space-4);
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.mode-switch [data-mode-btn] {
  display: flex; flex-direction: column; gap: var(--space-1);
  align-items: flex-start; text-align: left;
  background: var(--elevated); color: var(--text);
  border: 2px solid var(--border); border-radius: var(--radius-md);
  padding: var(--space-4); font-weight: 500; }
.mode-switch [data-mode-btn]:hover { border-color: var(--muted); }
.mode-switch [data-mode-btn].active {
  border-color: var(--color-accent); background: var(--color-accentSoft); }
.mode-switch .mode-title { font-weight: 700; font-size: var(--font-size-md); }
.mode-switch [data-mode-btn].active .mode-title { color: var(--color-accent); }
.mode-switch .mode-desc { font-size: var(--font-size-sm); color: var(--muted); }
.mode-switch [data-mode-btn].active .mode-desc { color: var(--text); }

#module-picker { margin: 0 0 var(--space-5); display: flex;
  flex-direction: column; gap: var(--space-4); }
/* the TITLE-BLOCK rule (D194 signature): every group header is a drawing
   title block — 12px caps over a full-width hairline. Applied here, the
   method families, the rail title and table headers; nowhere else caps. */
.module-group h3 { margin: 0 0 var(--space-2); font-size: var(--font-size-xs);
  text-transform: uppercase; letter-spacing: 0.08em; color: var(--muted);
  font-weight: 600; border-bottom: 1px solid var(--border);
  padding-bottom: var(--space-1); }
.module-grid { display: grid; gap: var(--space-2);
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.module-card { flex-direction: row; align-items: flex-start;
  gap: var(--space-3); padding: var(--space-3);
  background: var(--elevated); border: 1px solid var(--border);
  border-radius: var(--radius-md); cursor: pointer; font-size: inherit; }
.module-card:hover { border-color: var(--muted); }
.module-card.on { border-color: var(--color-accent);
  background: var(--color-accentSoft);
  /* selection ring: 1px border + 1px inset = a 2px machined ring with
     zero layout shift */
  box-shadow: inset 0 0 0 1px var(--color-accent); }
.module-card input { min-height: 0; margin-top: 3px; flex: 0 0 auto; }
.module-icon { font-size: var(--font-size-lg); line-height: 1;
  color: var(--muted); flex: 0 0 auto; }
.module-card.on .module-icon { color: var(--color-accent); }
.module-body { display: flex; flex-direction: column; gap: 2px; }
.module-label { font-weight: 600; }
.module-desc { font-size: var(--font-size-sm); color: var(--muted); }
.module-cost { font-size: var(--font-size-xs); color: var(--color-warn); }

.module-panel { border-top: 1px solid var(--border);
  padding-top: var(--space-4); margin-top: var(--space-4); }
.module-panel > h2 { font-size: var(--font-size-md); }
.field-grid { display: grid; gap: var(--space-3);
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }
.result-block { margin-top: var(--space-3); padding: var(--space-3);
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-sm); font-size: var(--font-size-sm); }

/* ------------------------------------------------- drill & charge plan */
.blast-pattern { border: 1px solid var(--border); border-radius: var(--radius-md);
  padding: var(--space-3); margin-bottom: var(--space-3);
  background: var(--elevated); }
.blast-head { display: flex; align-items: center; justify-content: space-between;
  margin-bottom: var(--space-2); }
.blast-head .blast-del { min-height: 28px; padding: 0 var(--space-3);
  line-height: 1; }
.blast-draw { margin-top: var(--space-3); overflow-x: auto; }
.blast-elev { width: 100%; max-width: 560px; height: auto;
  background: var(--bg); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: var(--space-2); }
fieldset { border: 1px solid var(--border); border-radius: var(--radius-sm);
  display: flex; flex-direction: column; gap: var(--space-2); }
fieldset label { flex-direction: row; align-items: center;
  gap: var(--space-2); }

.banner {
  background: var(--elevated); border: 1px solid var(--border);
  border-left: 4px solid var(--color-tier-L0);
  padding: var(--space-3); border-radius: var(--radius-sm);
}
.flow-note { margin: 0 0 var(--space-3); }
.switch-on { margin: var(--space-2) 0 0; padding-left: 1.2rem; }
.switch-on li { margin: 0.15rem 0; }
/* the drawing drop zone — the fastest route to a real plan (D52), so it is
   a visible target, not a passive tip line */
.dropzone {
  display: block; width: 100%; text-align: left; cursor: pointer;
  margin: var(--space-3) 0; padding: var(--space-3);
  background: var(--elevated); color: inherit; font: inherit;
  border: 2px dashed var(--border); border-radius: var(--radius-sm);
}
.dropzone:hover, .dropzone:focus-visible {
  border-color: var(--color-accent, currentColor);
  background: var(--bg);
}
.dropzone-icon { font-size: 1.6rem; display: block; }
.dropzone-main { display: block; font-weight: 600; margin: 0.2rem 0; }
.dropzone-sub { display: block; font-size: 0.9em; opacity: 0.85; }
.copilot-dragging .dropzone {
  border-style: solid; border-color: var(--color-accent, currentColor);
}
#falldir { margin-bottom: var(--space-3); }
#fd-current { margin: 0 0 var(--space-2); }
.fd-ok { color: var(--color-accent); font-weight: 600; }
.fd-bad { color: var(--color-danger); font-weight: 600; }
.fd-alt { margin-right: var(--space-2); }
.fm-canvas { width: 100%; max-width: 520px; height: auto;
  background: var(--bg); border: 1px solid var(--border);
  border-radius: var(--radius-sm); cursor: crosshair; display: block;
  margin: var(--space-2) 0; }
.fm-table { border-collapse: collapse; font-size: var(--font-size-sm); }
.fm-table th, .fm-table td { padding: 2px var(--space-3); text-align: left;
  border-bottom: 1px solid var(--border); }
.switch-detected {
  margin: var(--space-2) 0; padding: var(--space-2);
  background: var(--bg); border: 1px solid var(--border);
  border-radius: var(--radius-sm); font-size: 0.9em;
}
.banner code, .switch-on code {
  background: var(--bg); border: 1px solid var(--border);
  border-radius: 3px; padding: 0.05rem 0.3rem; font-size: 0.92em;
  word-break: break-all;
}
/* the callout pattern on dark (D206): a red-tinted surface, a deep-red
   edge and the READABLE red for text — #C0392B on near-black fails AA
   as type, which is exactly why `--color-dangerText` exists. */
.error {
  background: var(--color-dangerSoft);
  border: 1px solid #5f1010;
  border-left: 4px solid var(--color-danger);
  color: var(--color-dangerText);
  padding: var(--space-3); border-radius: var(--radius-md);
  white-space: pre-wrap;
}

.split { display: flex; gap: var(--space-5); align-items: flex-start;
  flex-wrap: wrap; }
#plan { flex: 1 1 380px; margin: 0; background: var(--surface);
  border-radius: var(--radius-md); padding: var(--space-3);
  border: 1px solid var(--border); box-shadow: var(--shadow-md); }
#plan svg { width: 100%; height: auto; display: block; }
#bldg-list { flex: 1 1 340px; display: flex; flex-direction: column;
  gap: var(--space-3); }
/* Shrinkable at ANY width (D142). The fixed 1fr×4 grid had a min-content
   wider than the step column leaves at laptop widths beside the canvas —
   and the overflow painted UNDER the sticky panel, clipping the very
   inputs (lat/lon, base Ø) the row exists to edit. auto-fit + a real
   minimum wraps instead of overflowing, and min-width:0 lets the tracks
   actually compress. */
.bldg-row { background: var(--elevated); border-radius: var(--radius-md);
  padding: var(--space-3); display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--space-2);
  border: 1px solid var(--border); box-shadow: var(--shadow-sm); }
.bldg-row label { min-width: 0; }
.bldg-row input, .bldg-row select { width: 100%; min-width: 0;
  box-sizing: border-box; }
.bldg-row:hover { border-color: var(--muted); }
.bldg-row.selected { border-color: var(--color-accent); background: var(--color-accentSoft); }
.bldg-row .name { grid-column: 1 / -1; font-weight: 600;
  display: flex; justify-content: space-between; }

/* provenance chips: assumed / provided / confirmed — never a silent
   guess (MASTER_PLAN rule P2, docs/PARAMETERS.md) */
/* styled as inked STAMPS — the assumed/confirmed marks are part of the
   identity (rule 6), never muted */
.prov { font-size: var(--font-size-xs); padding: 0 var(--space-1);
  border-radius: 2px; color: #111; font-weight: 600;
  letter-spacing: 0.04em; text-transform: uppercase;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.12); }
.prov-assumed { background: var(--color-tier-L1); }
.prov-provided { background: var(--color-kind-slab); }
.prov-confirmed { background: var(--color-kind-beam); }
.prov-documented { background: var(--color-tier-L3); }

/* a value read off a drawing, offered beside the field it belongs to and
   applied one at a time (D83) — never written silently */
.proposal { display: inline-flex; align-items: center; gap: var(--space-2);
  margin-top: var(--space-1); padding: 2px var(--space-2);
  border: 1px dashed var(--color-accent); border-radius: var(--radius-sm);
  background: var(--color-accentSoft); font-size: var(--font-size-xs); }
.proposal-val { font-weight: 600; }
.proposal button { min-height: 24px; padding: 0 var(--space-2);
  font-size: var(--font-size-xs); }

.seq-table { border-collapse: collapse; width: 100%;
  font-size: var(--font-size-sm); }
.seq-table th { text-align: left; color: var(--muted);
  font-weight: 600; padding: var(--space-1) var(--space-2);
  font-size: var(--font-size-xs); text-transform: uppercase;
  letter-spacing: 0.08em; border-bottom: 1px solid var(--border); }
.seq-table td { padding: var(--space-1) var(--space-2);
  vertical-align: middle; }
.seq-table input, .seq-table select { width: auto; min-width: 3.5em; }
.seq-table .row-del { padding: 0 var(--space-2); }
.sched-table .sched-cell { cursor: pointer; border-left: 3px solid
  transparent; }
.sched-cell.conf-ok { border-left-color: var(--color-kind-beam); }
.sched-cell.conf-warn { border-left-color: var(--color-tier-L1); }
.sched-cell.conf-bad { border-left-color: var(--color-danger);
  background: color-mix(in srgb, var(--color-danger) 12%, transparent); }
.sched-cell input { width: 100%; min-width: 5em; }
#drawings-card { margin-top: var(--space-5); }
#vib-card { margin-top: var(--space-4);
  border-top: 1px solid var(--muted); padding-top: var(--space-3); }
#vib-receptors { border-collapse: collapse; width: 100%;
  font-size: var(--font-size-sm); }
#vib-receptors th { text-align: left; color: var(--muted);
  font-weight: 600; padding: var(--space-1) var(--space-2);
  font-size: var(--font-size-xs); text-transform: uppercase;
  letter-spacing: 0.08em; border-bottom: 1px solid var(--border); }
#vib-receptors td { padding: var(--space-1) var(--space-2); }
#vib-receptors tr.vib-over td { background: var(--color-dangerSoft);
  font-weight: 600; }
#reality-check-box { margin-top: var(--space-4); }
#reality-check p { margin: var(--space-1) 0;
  font-size: var(--font-size-sm); }
.rc-assumed { color: var(--color-tier-L1); font-weight: 600; }
.rc-provided { color: var(--color-kind-slab); }
.rc-ok { color: var(--color-kind-beam); }
#technique-form { max-width: none; }
#technique-form > label, #technique-form fieldset,
#technique-form details { max-width: 480px; }
#sequence-editor, #preweaken-box { background: var(--surface);
  border-radius: var(--radius-md); padding: var(--space-3); }

#technique-form { display: flex; flex-direction: column;
  gap: var(--space-4); max-width: 480px; }
.nav-row { display: flex; gap: var(--space-3); margin-top: var(--space-4); }

.status { display: grid; grid-template-columns: auto 1fr;
  gap: var(--space-2) var(--space-4); background: var(--elevated);
  padding: var(--space-4); border-radius: var(--radius-md);
  border: 1px solid var(--border); box-shadow: var(--shadow-md);
  max-width: 480px; }
.status dt { color: var(--muted); }
/* instrument readouts (D194): the run's figures are gauges, not prose */
.status dd { margin: 0; font-variant-numeric: tabular-nums;
  font-family: var(--font-mono); font-weight: 600; }

/* Run progress (D72). Real measured progress from the worker — the fill
   only ever moves because a step counter moved, never on a timer. */
.run-phase { font-size: var(--font-size-lg); margin: 0 0 var(--space-3);
  max-width: 480px; }
.run-bar { max-width: 480px; height: 28px; background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  overflow: hidden; margin-bottom: var(--space-4);
  box-shadow: inset 0 1px 2px rgba(24, 20, 16, 0.06); }
.run-bar-fill { height: 100%; width: 0;
  background: var(--color-accent); color: var(--color-rf-offWhite);
  font-size: var(--font-size-sm); line-height: 28px; text-align: right;
  padding-right: var(--space-2); box-sizing: border-box;
  transition: width .4s linear; font-variant-numeric: tabular-nums;
  font-family: var(--font-mono); font-weight: 600; }

/* the queue, with a handle on every job in it (D81) */
.queue-box { max-width: 640px; margin-bottom: var(--space-4);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: var(--space-3); background: var(--surface); }
.queue-box > summary { cursor: pointer; font-weight: 600; }
.queue-rows { list-style: none; margin: var(--space-2) 0 0; padding: 0; }
.queue-row { display: flex; align-items: center; gap: var(--space-3);
  padding: var(--space-2) 0; border-top: 1px solid var(--border); }
.queue-row.mine { font-weight: 600; }
.queue-what { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.queue-place { flex: 0 0 auto; color: var(--muted);
  font-size: var(--font-size-sm); }
.queue-stop { flex: 0 0 auto; }

#viewer { flex: 2 1 520px; aspect-ratio: 16 / 10; border: 0;
  border-radius: var(--radius-lg); background: var(--color-console-bg);
  box-shadow: 0 0 0 1px var(--color-console-border),
    0 0 0 2px var(--border-bright), var(--shadow-md); }
#result-panel { flex: 1 1 300px; display: flex; flex-direction: column;
  gap: var(--space-3); }
#result-metrics, #provenance { display: grid;
  grid-template-columns: auto 1fr; gap: var(--space-1) var(--space-3);
  margin: 0; font-size: var(--font-size-sm); }
#result-metrics dt, #provenance dt { color: var(--muted); }
#result-metrics dd, #provenance dd { margin: 0; text-align: right;
  font-variant-numeric: tabular-nums; font-family: var(--font-mono); }

footer { padding: var(--space-4) var(--space-5);
  background: var(--surface); border-top: 1px solid var(--border); }
.disclaimer { margin: 0; font-size: var(--font-size-sm);
  color: var(--text); }
#attribution { margin: var(--space-2) 0 0; }

svg .bldg { fill: var(--color-kind-slab); stroke: var(--text);
  stroke-width: 0.4; cursor: pointer; }
svg .bldg.selected { fill: var(--color-danger); }
svg .chimney { fill: var(--color-kind-wall); stroke: var(--text);
  stroke-width: 0.4; cursor: pointer; }
svg .chimney.selected { fill: var(--color-danger); }
svg .fell-dir { stroke: var(--color-danger); stroke-width: 0.6;
  stroke-dasharray: 2 1.5; }
svg text { fill: var(--text); font-family: var(--font-family);
  pointer-events: none; }
svg .scale line { stroke: var(--muted); stroke-width: 0.6; }
svg .scale text { fill: var(--muted); }

/* --- safety plan overlay (D28) ----------------------------------- */
#safety-plan svg { width: 100%; height: auto;
  background: color-mix(in srgb, var(--color-kind-beam) 8%, var(--bg)); }
#safety-plan .excl-zone { fill: color-mix(in srgb,
  var(--color-kind-beam) 14%, transparent);
  stroke: var(--color-kind-beam); stroke-width: 0.5;
  stroke-dasharray: 3 2; }
#safety-plan .debris-max { fill: color-mix(in srgb,
  var(--color-danger) 20%, transparent); stroke: var(--color-danger);
  stroke-width: 0.4; }
#safety-plan .debris-p95 { fill: color-mix(in srgb,
  var(--color-danger) 30%, transparent); stroke: none; }
#safety-plan .bldg { fill: var(--color-kind-slab); stroke: var(--text);
  stroke-width: 0.4; cursor: default; }
#safety-plan .bldg.target { fill: var(--color-danger); }
#safety-verdict.ok { color: var(--color-kind-beam); font-weight: 600; }
#safety-verdict.error { color: var(--color-danger); font-weight: 600; }

/* --- proximity / receptor plan (D38) ----------------------------- */
#proximity-box { margin-top: var(--space-4); }
#proximity-plan { margin: var(--space-3) 0; overflow: hidden;
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-console-border);
  box-shadow: 0 0 0 1px var(--border-bright), var(--shadow-md); }
#proximity-plan svg { width: 100%; height: auto; display: block; }
#proximity-table { border-collapse: collapse; width: 100%;
  font-size: var(--font-size-sm); }
#proximity-table th { text-align: left; color: var(--muted);
  font-weight: 600; padding: var(--space-1) var(--space-2);
  font-size: var(--font-size-xs); text-transform: uppercase;
  letter-spacing: 0.08em; border-bottom: 1px solid var(--border); }
#proximity-table td { padding: var(--space-1) var(--space-2); }
#proximity-table td.num { text-align: right;
  font-variant-numeric: tabular-nums; }
/* Dark, satellite-style panel matching the Google-Earth field convention:
 * inner ring yellow (25 m), outer ring green (50 m), white measured lines. */
svg .prox-bg { fill: #12181f; }
svg .prox-bldg { fill: rgba(255, 255, 255, 0.16);
  stroke: rgba(255, 255, 255, 0.6); stroke-width: 0.4; }
svg .prox-target { fill: var(--color-danger); stroke: #fff; stroke-width: 0.3; }
svg .prox-chimney { fill: #ff5a4d; stroke: #fff; stroke-width: 0.3; }
svg .prox-recept { fill: var(--color-tier-L1); stroke: #fff;
  stroke-width: 0.3; }
svg .prox-ring { fill: none; stroke: #cfd8dc; stroke-width: 0.5;
  stroke-dasharray: 3 2; }
svg .prox-ring-inner { stroke: #ffd400; }
svg .prox-ring-outer { stroke: #35c759; }
svg .prox-ringlbl { fill: #cfd8dc; font-weight: 600; paint-order: stroke;
  stroke: #12181f; stroke-width: 1.5px; }
svg .prox-ringlbl-inner { fill: #ffd400; }
svg .prox-ringlbl-outer { fill: #35c759; }
svg .prox-line { stroke: #fff; stroke-width: 0.6; }
svg .prox-dist { fill: #fff; paint-order: stroke; stroke: #12181f;
  stroke-width: 2px; font-weight: 700; }
svg .prox-tgtlbl { fill: #fff; font-weight: 700; paint-order: stroke;
  stroke: #12181f; stroke-width: 2.5px; }
svg .prox-scale line { stroke: #fff; stroke-width: 0.6; }
svg .prox-scale text { fill: #fff; paint-order: stroke; stroke: #12181f;
  stroke-width: 1.5px; }
svg .prox-north line, svg .prox-north path { stroke: #fff; fill: #fff;
  stroke-width: 0.5; }
svg .prox-north text { fill: #fff; font-weight: 700; }
svg .prox-legend-bg { fill: rgba(0, 0, 0, 0.5); rx: 1; }
svg .prox-legtext { fill: #fff; }
/* planned fall corridor (D39) + neighbours it reaches + sim debris reach */
svg .prox-fall { fill: rgba(255, 176, 32, 0.16); stroke: #ffb020;
  stroke-width: 0.5; }
svg .prox-fall-arrow { fill: none; stroke: #ffb020; stroke-width: 0.6; }
svg .prox-fall-head { fill: #ffb020; }
svg .prox-falllbl { fill: #ffb020; font-weight: 700; paint-order: stroke;
  stroke: #12181f; stroke-width: 1.5px; }
svg .prox-debris { fill: none; stroke: #ff8c42; stroke-width: 0.5;
  stroke-dasharray: 1 1.4; }
/* recorded suppression rig (D172) — lock-step with PROX_STYLE */
svg .prox-monitor { fill: rgba(80, 170, 255, 0.18); stroke: #63b3ff;
  stroke-width: 0.5; }
svg .prox-curtain { stroke: #63b3ff; stroke-width: 1.1;
  stroke-dasharray: 2 1.6; }
svg .prox-hit { stroke: #ff4d4d; stroke-width: 1.1; }
svg .prox-line-hit { stroke: #ff6b6b; stroke-width: 0.8; }
svg .prox-dist-hit { fill: #ff8080; }
#proximity-table tr.prox-row-hit td { color: var(--color-danger);
  font-weight: 600; }
.warn-note { margin-top: var(--space-2); padding: var(--space-2);
  border-left: 3px solid var(--color-danger);
  background: var(--color-dangerSoft);
  font-size: var(--font-size-sm); border-radius: var(--radius-sm); }

/* --- AI copilot (D41): the plain-language front door ----------------- */
#copilot-card { border: 1px solid var(--color-accent); }
/* #copilot-intro (D213): a <summary> renders at browser-default weight,
   which visibly shrank the heading versus the plain <h2> it replaced —
   this keeps the assistant screen's look identical. The dock itself
   needs no override: aidock.js collapses the <details>, so there is
   nothing here for #ai-dock to restyle. */
#copilot-intro > summary { font-size: var(--font-size-lg);
  font-weight: 650; letter-spacing: -0.01em; margin: 0 0 var(--space-2);
  cursor: pointer; }
#copilot-intro[open] > summary { margin-bottom: var(--space-2); }
#copilot-intro:not([open]) > summary { margin-bottom: 0; }
.copilot-log { display: flex; flex-direction: column; gap: var(--space-2);
  max-height: 340px; overflow-y: auto; padding: var(--space-2) 0;
  margin: var(--space-2) 0; }
.copilot-msg { max-width: 85%; padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md); font-size: var(--font-size-sm);
  line-height: 1.45; white-space: pre-wrap; }
.copilot-assistant { align-self: flex-start; background: var(--surface);
  border: 1px solid var(--muted); }
.copilot-user { align-self: flex-end; background: var(--color-accent);
  color: var(--color-rf-offWhite); }
#copilot-input { flex: 1; }
#copilot-apply { margin-top: var(--space-2); font-weight: 600;
  background: var(--color-tier-L3); color: #111; }
#copilot-card.copilot-dragging { outline: 2px dashed var(--color-accent);
  outline-offset: 4px; }
.copilot-attach-list { display: flex; flex-wrap: wrap; gap: var(--space-1);
  margin-bottom: var(--space-1); }
.copilot-chip { display: inline-flex; align-items: center; gap: 4px;
  font-size: var(--font-size-sm); background: var(--surface);
  border: 1px solid var(--muted); border-radius: var(--radius-sm);
  padding: 2px 6px; }
.copilot-chip button { border: 0; background: none; cursor: pointer;
  font-size: 1.1em; line-height: 1; color: var(--muted); padding: 0 2px; }

/* --- footprint tracing map (M2b) --------------------------------- */
#trace-panel { margin-top: var(--space-4); }
/* The map is the workhorse surface — give it real screen (D131): it was
   a fixed 440px window in a 900px viewport, which made tracing feel like
   working through a letterbox. Capped so the trace controls stay on
   screen below it inside the sticky canvas (D133). */
#trace-map { position: relative; height: min(55vh, 600px); overflow: hidden;
  border-radius: var(--radius-md); border: 1px solid var(--muted);
  cursor: crosshair; user-select: none;
  /* bare-grid fallback so tracing works when tiles cannot load */
  background:
    linear-gradient(var(--surface) 1px, transparent 1px) 0 0 / 32px 32px,
    linear-gradient(90deg, var(--surface) 1px, transparent 1px)
      0 0 / 32px 32px,
    var(--bg); }
#trace-map.picking { outline: 3px solid var(--color-accent);
  outline-offset: -3px; }
#trace-tiles { position: absolute; inset: 0; }
.trace-tile { position: absolute; width: 256px; height: 256px;
  pointer-events: none; }
.trace-tile.missing { visibility: hidden; }
#trace-svg { position: absolute; inset: 0; width: 100%; height: 100%;
  pointer-events: none; }
#trace-svg .trace-poly { fill: var(--color-kind-slab);
  fill-opacity: 0.45; stroke: var(--text); stroke-width: 1.5; }
#trace-svg .trace-line { fill: none; stroke: var(--color-danger);
  stroke-width: 1.5; stroke-dasharray: 5 3; }
#trace-svg circle { fill: var(--color-danger); }
#trace-svg text { paint-order: stroke; stroke: var(--bg);
  stroke-width: 3px; }
#trace-attrib { position: absolute; right: var(--space-1);
  bottom: var(--space-1); font-size: var(--font-size-sm);
  color: var(--text); background: var(--surface); opacity: 0.85;
  padding: 0 var(--space-1); border-radius: var(--radius-sm); }
#trace-tile-url { width: 100%; font-family: var(--font-mono); }

/* Copilot-first site screen (D46): the five manual intake methods collapse
 * behind one disclosure so a first-timer sees the AI box + one toggle. */
#manual-intake { margin-top: var(--space-4); }
#manual-intake > summary { cursor: pointer; list-style: none;
  padding: var(--space-3) var(--space-4); background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--radius-md);
  font-weight: 600; color: var(--text); }
#manual-intake > summary::-webkit-details-marker { display: none; }
#manual-intake > summary::before { content: "⚙ "; color: var(--muted); }
#manual-intake[open] > summary { margin-bottom: var(--space-4);
  border-color: var(--color-accent); }
#manual-intake > summary:hover { border-color: var(--muted); }

/* Sticky primary action so "Continue / run it" is always reachable on the
 * long Confirm screen without scrolling to the bottom. */
.sticky-actions { position: sticky; bottom: 0; z-index: 20;
  background: linear-gradient(to top, var(--bg) 72%, transparent);
  padding: var(--space-3) 0 var(--space-2); margin-top: var(--space-3); }

/* Premium photoreal render (D45) — the returned MP4 sits under its card. */
.render-video { width: 100%; max-height: 60vh; border-radius: var(--radius-lg);
  border: 1px solid var(--color-console-border);
  box-shadow: 0 0 0 1px var(--border-bright), var(--shadow-md);
  background: var(--color-console-bg); display: block;
  margin-top: var(--space-2); }
#render-card strong { color: var(--color-tier-L3); }

/* crisper progress stepper: a done step reads as completed (✓), the
 * current one is emphasised */
#steps li.done::before { content: "✓ "; color: var(--color-kind-beam); }
#steps li.current { position: relative; }

/* Map-anchored 3D view (D44, scene3d.js) — a WebGL canvas over the
 * satellite site, with a collapse playback bar (shown in replay mode). */
.scene3d-wrap { position: relative; width: 100%; height: 440px;
  max-height: 70vh; border-radius: var(--radius-md); overflow: hidden;
  background: var(--color-console-bg);
  border: 1px solid var(--color-console-border); }
.scene3d-canvas { display: block; width: 100%; height: 100%;
  cursor: grab; touch-action: none; }
.scene3d-canvas:active { cursor: grabbing; }
.scene3d-controls { position: absolute; left: 0; right: 0; bottom: 0;
  display: flex; align-items: center; gap: var(--space-2);
  padding: var(--space-2); background: linear-gradient(to top,
    rgba(10, 12, 18, 0.92) 60%, rgba(10, 12, 18, 0)); }
.scene3d-controls button { flex: 0 0 auto; }
/* the cinematic orbit reads as engaged while it drives the camera */
.scene3d-controls [data-a="orbit"].on {
  background: var(--color-accent); color: var(--color-rf-offWhite);
  border-color: var(--color-accent); }
.scene3d-controls input[type="range"] { flex: 1 1 auto; min-width: 60px; }
.scene3d-controls [data-a="t"] { color: var(--text); font-size:
  var(--font-size-sm); font-variant-numeric: tabular-nums; min-width: 74px; }

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

/* AI Summary card (Wave 1) */
.ai-summary-text {
  background: var(--elevated); padding: var(--space-3);
  border-radius: var(--radius-sm); border: 1px solid var(--border);
  font-size: var(--font-size-sm); line-height: 1.6;
  margin-bottom: var(--space-2); user-select: all;
}

/* Quick-start template buttons (Wave 1) */
.quickstart-grid {
  display: grid; gap: var(--space-3);
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  margin-top: var(--space-3);
}
.quickstart-btn {
  display: flex; flex-direction: column; align-items: center;
  gap: var(--space-1); padding: var(--space-4) var(--space-3);
  background: var(--elevated); border: 1px solid var(--border);
  border-radius: var(--radius-md); cursor: pointer;
  transition: transform 90ms cubic-bezier(0.2, 0, 0, 1);
  color: var(--text); font-family: inherit;
}
.quickstart-btn:hover {
  border-color: var(--color-accent);
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
}
.quickstart-icon { font-size: 2rem; }
.quickstart-label { font-weight: 600; font-size: var(--font-size-md); }
.quickstart-sub { font-size: var(--font-size-xs); color: var(--muted); text-align: center; }

.streetview-wrap { margin-top: var(--space-3); }
.streetview-wrap iframe { width: 100%; border-radius: var(--radius-md); }
.streetview-link { display: inline-block; margin-bottom: var(--space-2); color: var(--color-accent); text-decoration: none; font-weight: 500; }
/* Dashboard Layout */
.dashboard-layout {
  display: flex;
  gap: var(--space-5);
  align-items: flex-start;
  max-width: 1400px;
}
.wizard-panel {
  flex: 1 1 600px;
  min-width: 0;
}
.live-preview-panel {
  /* the CANVAS (D133): the dominant partner now that the satellite map
     lives here — wide enough to trace on, capped so the step column
     keeps a usable ~480px+ on a laptop */
  flex: 0 0 clamp(460px, 44vw, 760px);
  position: sticky;
  top: 80px;
  background: var(--surface);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  /* the LENS bezel (D194): dark glass -> machined dark rim -> warm paper
     hairline -> paper. Two hairlines one pixel apart is the whole
     "instrument set into the sheet" effect — every dark island gets
     exactly this treatment, so they read as ONE component. */
  border: 1px solid var(--color-console-border);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04),
    0 0 0 1px var(--border-bright), var(--shadow-md);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  max-height: calc(100vh - 100px);
  overflow-y: auto;
}
/* The canvas was the ONE dark island in a paper app (D139) and needed a
   token rebind to get there. D206 made the whole console dark, so the
   rebind is gone: the canvas simply inherits, which is the point — one
   instrument, not a lens set into a document. `color-scheme` stays, so
   native pickers and scrollbars match. */
#site-canvas {
  background: var(--bg);
  color: var(--text);
  border-color: var(--border);
  color-scheme: dark;            /* native pickers/scrollbars match */
}
#site-canvas .hint { color: var(--muted); }
#site-canvas input, #site-canvas select, #site-canvas textarea {
  background: var(--elevated); color: var(--text);
  border-color: var(--border);
}
#site-canvas button.ghost { border-color: var(--border); }
/* The tab strip was deliberately PAPER under D194 — light controls on a
   dark instrument. With the console dark end to end that reads as a
   stray light island, so it is now a recessed segmented control: the
   selected tab is the raised plate, the rest are quiet. */
#site-canvas .preview-tabs { gap: var(--space-1);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-md); padding: 3px; }
#site-canvas .preview-tabs button { flex: 1; min-height: 34px;
  border-radius: var(--radius-sm); }
#site-canvas .preview-tabs button.ghost {
  color: var(--muted); border-color: transparent; background: transparent; }
#site-canvas .preview-tabs button.ghost:hover:not(:disabled) {
  background: var(--elevated); color: var(--text);
  border-color: var(--border-bright); }
#site-canvas #trace-map { border-color: var(--border); }
.live-preview-panel figure {
  margin: 0;
  width: 100%;
}
/* the trace panel keeps its ids and class but is no longer a card INSIDE
   a card — and "Hide" is meaningless on a dedicated tab (an empty canvas
   is all it could produce) */
#site-canvas #trace-panel { border: none; padding: 0; box-shadow: none;
  background: transparent; }
#site-canvas #trace-hide { display: none; }
.preview-tabs button {
  flex: 1;
}

.streetview-link:hover { text-decoration: underline; }

/* The three-column layout (rail + steps + canvas) needs ~1250px to give
   the step column a usable width — below that the canvas was starving
   the cards until their inputs painted UNDER it (D142, seen on the
   owner's own deployment). Stack EARLY, not at phone width. */
@media (max-width: 1250px) {
  .dashboard-layout { flex-direction: column; }
  .live-preview-panel {
    flex: none;
    width: 100%;
    position: static;
    max-height: 62vh;
    /* the canvas holds the MAP now (D133) — stacked, it must lead, not
       trail four steps of forms */
    order: -1;
  }
}

/* Feature 3.6: Mobile Field Mode */
@media (max-width: 768px) {
  body {
    font-size: var(--font-size-md, 16px);
  }
  .split {
    flex-direction: column;
  }
  .grid {
    grid-template-columns: 1fr;
  }
  form {
    flex-direction: column;
  }
  .form-row, .nav-row {
    flex-direction: column;
    align-items: flex-start;
  }
  button, select, input[type="text"], input[type="number"], .ai-glow {
    min-height: 48px;
    width: 100%;
    margin-bottom: 8px;
  }
  .topbar {
    flex-direction: column;
    align-items: flex-start;
    padding: var(--space-2);
  }
  main {
    padding: var(--space-2);
  }
  .card, .panel {
    padding: var(--space-3);
  }
}

/* ------------------------------------------ demolition method picker (D66) */
.method-picker { display: flex; flex-direction: column; gap: var(--space-4);
  margin: var(--space-3) 0; }
.method-family h4 { margin: 0 0 var(--space-2); font-size: var(--font-size-xs);
  text-transform: uppercase; letter-spacing: 0.08em; color: var(--muted);
  font-weight: 600; border-bottom: 1px solid var(--border);
  padding-bottom: var(--space-1); }
.method-grid { display: grid; gap: var(--space-2);
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.method-card { flex-direction: row; align-items: flex-start;
  gap: var(--space-3); padding: var(--space-3); cursor: pointer;
  background: var(--elevated); border: 1px solid var(--border);
  border-radius: var(--radius-md); font-size: inherit; }
.method-card:hover { border-color: var(--muted); }
.method-card.on { border-color: var(--color-accent);
  background: var(--color-accentSoft);
  box-shadow: inset 0 0 0 1px var(--color-accent); }
.method-card input { min-height: 0; margin-top: 4px; flex: 0 0 auto; }
.method-body { display: flex; flex-direction: column; gap: 2px; }
.method-label { font-weight: 600; }
.method-desc { font-size: var(--font-size-sm); color: var(--muted); }
.method-caveat { margin: 0; font-size: var(--font-size-sm);
  color: var(--color-warn); }
.method-caveat:empty { display: none; }
.method-params { margin-top: var(--space-2); }

/* ------------------------------------------------------- AI dock (D67) */
#ai-dock {
  position: fixed; right: var(--space-4); bottom: var(--space-4);
  width: min(420px, calc(100vw - 2 * var(--space-4)));
  max-height: min(70vh, 720px); overflow: auto; z-index: var(--z-modal);
  background: var(--elevated); border: 1px solid var(--border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-lg);
  padding: var(--space-3);
}
.ai-dock-head { display: flex; align-items: center; gap: var(--space-2);
  margin-bottom: var(--space-2); }
.ai-dock-head .hint { flex: 1; }
.ai-dock-head button { min-height: 28px; padding: 0 var(--space-3);
  line-height: 1; }
#ai-dock #copilot-card { border: 0; box-shadow: none; padding: 0; }
#ai-dock #copilot-card h2 { font-size: var(--font-size-md); }
@media (max-width: 640px) {
  #ai-dock { right: var(--space-2); left: var(--space-2); bottom: var(--space-2);
    width: auto; max-height: 80vh; }
}

/* --------------------------------------------- site screen flow (D68) */
.site-step { margin: 0 0 var(--space-5); }
.site-step > h2 { display: flex; align-items: center; gap: var(--space-3);
  font-size: var(--font-size-lg); }
.step-n { display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; border-radius: 50%; flex: 0 0 auto;
  background: var(--color-accent); color: var(--color-rf-offWhite);
  font-size: var(--font-size-sm); font-weight: 700; }
#site-jump { flex: 1; min-width: 220px; }
.tool-row { display: flex; flex-wrap: wrap; gap: var(--space-2);
  margin: var(--space-3) 0; }
button.tool { background: var(--elevated); color: var(--text);
  border: 1px solid var(--border); font-weight: 600; }
button.tool:hover:not(:disabled) { border-color: var(--color-accent);
  background: var(--color-accentSoft); color: var(--color-accent); }
#site-inventory { font-size: var(--font-size-md); color: var(--text); }
#other-intake { margin: 0 0 var(--space-5); }
#other-intake > summary { cursor: pointer; padding: var(--space-3) 0;
  color: var(--muted); font-size: var(--font-size-sm); }
#other-intake > summary:hover { color: var(--text); }

/* ------------------------------------ blast sequence planner (D69) */
.bs-groups { display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--space-2); margin: var(--space-3) 0; }
button.bs-group { min-width: 44px; min-height: 36px; padding: 0 var(--space-2);
  background: var(--elevated); color: var(--text);
  border: 2px solid var(--border); font-weight: 700; }
button.bs-group.on { border-color: var(--g, var(--color-accent));
  background: var(--g, var(--color-accent)); color: var(--color-rf-offWhite); }
button.bs-clear { font-weight: 500; }
/* drafting-grid vellum (D194): the planner cards read as gridded sheets —
   the faintest possible 24px grid, character at zero cost; the plan SVG
   itself stays clean paper (figure-ground for the member dots) */
.bs-storey { margin: var(--space-4) 0; padding: var(--space-3);
  border: 1px solid var(--border); border-radius: var(--radius-md);
  background:
    repeating-linear-gradient(0deg, transparent, transparent 23px,
      rgba(24, 20, 16, 0.035) 23px, rgba(24, 20, 16, 0.035) 24px),
    repeating-linear-gradient(90deg, transparent, transparent 23px,
      rgba(24, 20, 16, 0.035) 23px, rgba(24, 20, 16, 0.035) 24px),
    var(--elevated); }
.bs-storey h4 { margin: 0 0 var(--space-2); font-size: var(--font-size-md); }
.bs-plan { width: 100%; max-width: 420px; height: auto; display: block;
  background: var(--bg); border: 1px solid var(--border);
  border-radius: var(--radius-sm); }
.bs-member { cursor: pointer; }
.bs-member:hover circle { stroke-width: 0.35; }
.bs-member:focus-visible { outline: 2px solid var(--color-accent); }
#blastseq-warnings { border-left-color: var(--color-warn); }
/* pre-weakening planner (D193) — shares the member grid, red by cut depth */
.pw-levels { display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--space-2); margin: var(--space-3) 0; }
button.pw-level { min-width: 44px; min-height: 36px; padding: 0 var(--space-2);
  background: var(--elevated); color: var(--text);
  border: 2px solid var(--border); font-weight: 700; }
button.pw-level.on { border-color: var(--pw, var(--color-warn));
  background: var(--pw, var(--color-warn)); color: var(--color-rf-offWhite); }
button.pw-clear { font-weight: 500; }
.pw-plan { width: 100%; max-width: 420px; height: auto; display: block;
  background: var(--bg); border: 1px solid var(--border);
  border-radius: var(--radius-sm); }
.pw-member { cursor: pointer; }
.pw-member:hover circle { stroke-width: 0.35; }
.pw-member:focus-visible { outline: 2px solid var(--color-accent); }
.pw-table-fallback { margin-top: var(--space-3); }
.pw-table-fallback > summary { cursor: pointer; color: var(--muted);
  font-size: var(--font-size-sm); }
.bs-schedule { margin: var(--space-4) 0; padding: var(--space-3);
  border: 1px solid var(--border); border-radius: var(--radius-md);
  background: var(--elevated); }
.bs-schedule h4 { margin: 0 0 var(--space-2); font-size: var(--font-size-md); }
.bs-sched-list { list-style: none; margin: var(--space-2) 0 0; padding: 0;
  display: flex; flex-direction: column; gap: var(--space-2); }
.bs-sched-row { display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: var(--space-2);
  padding: var(--space-2) 0; border-top: 1px solid var(--border); }
.bs-sched-row:first-child { border-top: 0; }
.bs-sched-lead { display: flex; align-items: center; gap: var(--space-2);
  flex-wrap: wrap; }
.bs-sched-grp { display: inline-flex; align-items: center;
  justify-content: center; min-width: 26px; height: 26px; padding: 0 6px;
  border-radius: var(--radius-pill); background: var(--g, var(--color-accent));
  color: var(--color-rf-offWhite); font-weight: 700;
  font-size: var(--font-size-sm); }
.bs-sched-delay { display: inline-flex; align-items: center; gap: 4px;
  color: var(--muted); font-size: var(--font-size-sm); }
.bs-sched-delay input { width: 5em; }
.bs-fire-time { color: var(--muted); font-size: var(--font-size-sm);
  font-variant-numeric: tabular-nums; font-family: var(--font-mono);
  font-weight: 600; }

/* ---------------------------------------------------------- workspace
   The four intake screens are steps of ONE workspace (D73). The rail is
   permanently on the left: the plan outline and the navigation are the
   same object, so the contractor can always see the whole job. */
.ws-grid { display: grid; grid-template-columns: 260px minmax(0, 1fr);
  gap: var(--space-5); align-items: start; }
.ws-steps { min-width: 0; }

.plan-rail { position: sticky; top: var(--space-4);
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-md); padding: var(--space-4); }
.rail-title { font-size: var(--font-size-xs); text-transform: uppercase;
  letter-spacing: 0.08em; color: var(--muted); margin: 0 0 var(--space-3);
  font-weight: 600; border-bottom: 1px solid var(--border);
  padding-bottom: var(--space-1); }
.plan-rail ol { list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: 2px; }

.rail-row { display: flex; gap: var(--space-3); align-items: flex-start;
  padding: var(--space-3); border-radius: var(--radius-sm);
  cursor: pointer; border: 1px solid transparent; }
.rail-row:hover { background: var(--elevated); }
.rail-row:focus-visible { outline: 2px solid var(--color-accent);
  outline-offset: 2px; }
.rail-row.active { background: var(--color-accentSoft);
  border-color: var(--color-accent); }
.rail-mark { flex: 0 0 22px; height: 22px; border-radius: 50%;
  display: grid; place-items: center; font-size: var(--font-size-sm);
  background: var(--elevated); color: var(--muted);
  font-variant-numeric: tabular-nums; }
.rail-row.done .rail-mark { background: var(--color-ok); color: var(--color-rf-offWhite); }
.rail-row.active .rail-mark { background: var(--color-accent); color: var(--color-rf-offWhite); }
.rail-body { display: flex; flex-direction: column; min-width: 0; }
.rail-label { font-weight: 600; }
/* the value is the whole point of the rail — what IS set, or plainly that
   nothing is; never let it be quieter than the label it explains */
.rail-value { font-size: var(--font-size-sm); color: var(--muted);
  font-variant-numeric: tabular-nums; }

.rail-action { margin-top: var(--space-4); padding-top: var(--space-4);
  border-top: 1px solid var(--border); }
.rail-run { width: 100%; }
.rail-run:disabled { opacity: .55; cursor: not-allowed; }

@media (max-width: 900px) {
  .ws-grid { grid-template-columns: 1fr; }
  .plan-rail { position: static; }
}

/* Quick-start is a strip of shortcuts that pre-fill the assistant, not a
   titled card competing with the assistant it feeds (D73). */
.quickstart-strip { margin-bottom: var(--space-4); }
.quickstart-strip .hint { margin-bottom: var(--space-2); }

/* A rail row stating a problem, not progress (D76) — e.g. a target that
   falls outside the working boundary the contractor drew. */
.rail-row.warn .rail-mark { background: var(--color-warn); color: var(--color-rf-offWhite); }
.rail-row.warn .rail-value { color: var(--color-warn); }

/* Position correction on a confirm row (D76/D77) */
/* flexible, never truncated: beside the canvas (D133) the step column is
   narrower, and a fixed 8.5ch pair overflowed under the Move button */
.pos-cell .pos-row { display: flex; gap: var(--space-2); align-items: center;
  flex-wrap: wrap; }
.pos-cell input { flex: 1 1 9ch; width: auto; min-width: 9ch; }
/* A run the contractor should think twice about before starting (D77) */
.cost-long { color: var(--color-warn); }

/* Remove a structure from the plan (D79) — two-step, because losing a
   traced footprint to a stray click is worse than one extra tap. */
.row-del { padding: 2px var(--space-2); font-size: var(--font-size-sm); }
.row-del.armed { background: var(--color-warn); color: var(--color-rf-offWhite);
  border-color: var(--color-warn); }

/* fall-direction dial (D88) — free 360°, not eight buttons */
.fall-cell { min-width: 150px; }
.fall-dial { display: flex; flex-direction: column; align-items: center;
  gap: var(--space-1); }
.fall-dial-face { touch-action: none; cursor: grab;
  border-radius: 50%; }
.fall-dial-face:focus-visible { outline: 2px solid var(--color-accent);
  outline-offset: 2px; }
.fall-dial-face.dragging { cursor: grabbing; }
.fd-ring { fill: var(--surface); stroke: var(--border); stroke-width: 1; }
.fd-tick { stroke: var(--muted); stroke-width: 1; }
.fd-tick-major { stroke: var(--text); stroke-width: 1.5; }
.fd-card { fill: var(--muted); font-size: 11px; font-weight: 600; }
.fd-needle { stroke: var(--color-danger); stroke-width: 3;
  stroke-linecap: round; }
.fd-head { fill: var(--color-danger); }
.fd-hub { fill: var(--text); }
.fall-dial-read { font-size: var(--font-size-sm); font-weight: 600;
  text-align: center; }
.fall-dial-num { width: 5.5em; text-align: center; min-height: 32px;
  padding: 0 var(--space-1); }

/* the drawings route, on the screen the dimensions live on (D99) */
.drawings-cta { border: 1px solid var(--color-accent);
  background: var(--color-accentSoft); margin-bottom: var(--space-4); }
.drawings-cta h2 { font-size: var(--font-size-md); }

/* past studies (D103) */
.studies-rows { list-style: none; margin: var(--space-3) 0; padding: 0; }
.study-row { display: flex; align-items: center; gap: var(--space-3);
  padding: var(--space-3) 0; border-top: 1px solid var(--border); }
.study-row.warn .study-title { color: var(--color-danger); }
.study-main { flex: 1 1 auto; display: flex; flex-direction: column; }
.study-title { font-weight: 600; }

/* drawings kept as a study's evidence (D104) */
.kept-list { list-style: none; margin: var(--space-2) 0 0; padding: 0; }
.kept-row { display: flex; align-items: baseline; gap: var(--space-2);
  padding: var(--space-1) 0; font-size: var(--font-size-sm); }

/* What is switched on for this deployment (D115). Quiet when everything
   is on — it is a diagnostic, not a banner — and never red for a service
   that is merely absent by choice. Durable storage is the exception: an
   instance holding evidence on a disk a redeploy can clear is a fact the
   operator has to see. */
.cap-strip { margin: var(--space-2) 0 0; font-size: var(--font-size-sm); }
.cap-strip > summary { cursor: pointer; color: var(--muted); }
.cap-strip[data-all-on="false"] > summary { color: var(--text); }
/* D217: something is broken and app.js auto-opens the strip for it — read
   as an actionable alert, not fine print, mirroring #manual-intake's own
   disclosure treatment (this file, above) rather than the default marker
   this strip otherwise keeps while everything is working. */
.cap-strip[data-all-on="false"] > summary { list-style: none;
  padding: var(--space-3) var(--space-4); background: var(--surface);
  border: 1px solid var(--color-warn); border-radius: var(--radius-md);
  font-weight: 600; }
.cap-strip[data-all-on="false"] > summary::-webkit-details-marker { display: none; }
.cap-strip[data-all-on="false"] > summary::before { content: "⚠ "; }
.cap-strip ul { margin: var(--space-2) 0 0; padding-left: 1.1em; }
.cap-row { margin: 0 0 var(--space-2); color: var(--muted); }
.cap-row[data-on="true"] { color: var(--text); }
.cap-row[data-on="true"] strong::before { content: "✓ "; }
.cap-row[data-on="false"] strong::before { content: "○ "; }
.cap-row[data-warn="true"] strong { color: var(--color-tier-L1); }
.cap-row[data-warn="true"] strong::before { content: "⚠ "; }

/* Project documents (D122) — a register, not a gallery. What is held and
   what each sheet gave, in the order they arrived. */
.docs-list { list-style: none; margin: var(--space-2) 0; padding: 0; }
.doc-row { border-left: 2px solid var(--muted);
  padding: var(--space-2) 0 var(--space-2) var(--space-3);
  margin: 0 0 var(--space-3); }
.doc-row .doc-name { font-weight: 600; display: block; }
.doc-figs { margin: var(--space-2) 0 0; padding-left: 1.1em;
  font-size: var(--font-size-sm); }
/* a figure whose sheet is gone is the one case where provenance has a
   hole; it is flagged rather than quietly listed like the rest */
.doc-orphan { border-left-color: var(--color-tier-L1); }

/* recorded water monitors (D164) — one card per monitor, fields inline */
.monitor-row { border: 1px solid var(--border); border-radius: 8px;
  padding: var(--space-3); margin: var(--space-3) 0; }
.monitor-head { display: flex; justify-content: space-between;
  align-items: center; margin-bottom: var(--space-2); }
.monitor-field { font-size: var(--font-size-sm); }

/* RazeForce sign-in gate (D204). A full-viewport cover over the booted
   wizard — presentation for the server-side session gate, never the
   enforcement itself. Paper ground so it reads as the app's own front
   door, not an error state. */
/* The sign-in screen is the first thing anyone sees of DemSim, so it
   carries the mark, the one-line pitch and the product's own signature
   event (D211, gatehero.js). Dark ground, hot-red on dark, gold once. */
#rf-gate { position: fixed; inset: 0; z-index: 400;
  background: var(--bg); overflow: hidden; }
/* The hero sits BEHIND the card rather than beside it, so one rule set
   serves phone and desktop — no second layout to keep in step. */
#rf-gate .rf-hero { position: absolute; inset: 0; }
#rf-gate .rf-hero-canvas { width: 100%; height: 100%; display: block; }
/* A scrim so body copy stays AA-legible over the collapse — ONE gradient,
   left to right. Two stacked gradients (a radial vignette as well) each
   looked reasonable and together darkened almost the whole frame, so the
   hero was invisible: opacity multiplies, it does not average. Judged
   from a real screenshot, not from the rule. */
#rf-gate .rf-hero::after { content: ""; position: absolute; inset: 0;
  background: linear-gradient(100deg, var(--bg) 0%, var(--bg) 26%,
    color-mix(in srgb, var(--bg) 55%, transparent) 46%, transparent 66%); }
#rf-gate .rf-gate-inner { position: relative; height: 100%;
  display: flex; flex-direction: column;
  align-items: flex-start; justify-content: center;
  gap: var(--space-4); padding: var(--space-6);
  max-width: 34rem; }
#rf-gate .rf-card { padding: 0; border: 0; background: none;
  text-align: left; max-width: 26rem; }
#rf-gate .rf-gate-brand { display: flex; flex-direction: column;
  align-items: flex-start; gap: 2px; margin-bottom: var(--space-5); }
#rf-gate .rf-gate-brand .brand-mark { height: 2.1rem; width: auto; }
#rf-gate .rf-pitch { font-family: var(--font-display);
  font-size: var(--font-size-xl); line-height: 1.15;
  margin: 0 0 var(--space-4); color: var(--text);
  text-wrap: balance; }
#rf-gate h2 { margin: 0 0 var(--space-2); font-size: var(--font-size-md); }
#rf-gate .hint { margin: 0; max-width: 30rem; }
#rf-gate button { margin: var(--space-4) 0 0; }
#rf-gate .rf-points { list-style: none; margin: var(--space-5) 0 0;
  padding: 0; display: grid; gap: var(--space-2);
  font-size: var(--font-size-sm); color: var(--muted); }
#rf-gate .rf-points li { display: flex; gap: var(--space-2); }
/* a felling-column tick, echoing the wordmark's I */
#rf-gate .rf-points li::before { content: ""; flex: 0 0 3px;
  height: 1.05em; border-radius: 4px;
  background: var(--color-accent); opacity: 0.8; }
#rf-gate .rf-hero-note { position: absolute; left: var(--space-6);
  bottom: var(--space-5); margin: 0;
  font-family: var(--font-mono); font-size: var(--font-size-xs);
  color: var(--muted); opacity: 0.75; max-width: 22rem; }
@media (max-width: 40rem) {
  #rf-gate .rf-hero::after {
    background: linear-gradient(180deg, transparent 0%, var(--bg) 58%); }
  #rf-gate .rf-gate-inner { justify-content: flex-end;
    padding-bottom: var(--space-6); max-width: none; }
  #rf-gate .rf-hero-note { position: static; margin-top: var(--space-3); }
}
.rf-user { font-size: var(--font-size-xs); color: var(--muted);
  white-space: nowrap; }

/* ------------------------------------------- RazeForce chrome (D206) */

/* The drill-and-charge elevation (blastplan.js) is ONE SVG string shown
   both here and in the printed method statement, so its inks are vars
   whose fallbacks are the paper values. On dark, the hole marks take the
   READABLE red (crimson on near-black is nearly invisible) and the
   dimension lines lift to steel. */
:root, :root[data-theme='dark'] {
  --blast-hole: var(--color-dangerText);
  --blast-dim: var(--color-rf-steelGrey);
}
:root[data-theme='light'] {
  --blast-hole: var(--color-rf-crimson);
  --blast-dim: #5a6472;
}

/* The masthead: wordmark over a small-caps sub-brand line. Stacked so the
   two read as one lock-up rather than two labels. */
.brand-lockup { display: inline-flex; flex-direction: column;
  gap: 1px; line-height: 1; }
.brand-sub { font-family: var(--font-family); font-size: 9px;
  letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--color-rf-steelGrey); font-weight: 600; }
.brand-sub .rf-name { color: var(--muted); }

/* The access key is legacy plumbing next to a real sign-in (D204), so it
   sits at the bottom of the hierarchy — muted, quiet, not a control the
   eye lands on. */
#api-key-field { color: var(--color-rf-steelGrey);
  font-size: var(--font-size-xs); }
#api-key-field input { background: var(--bg);
  border-color: var(--border); min-height: 30px;
  font-size: var(--font-size-xs); }
#api-key-field input:hover { border-color: var(--border-bright); }

/* Signed-in identity (D204's #rf-user) reads as a plate, not a button. */
.rf-user { font-family: var(--font-mono);
  color: var(--color-rf-steelGrey);
  border: 1px solid var(--border); border-radius: var(--radius-tag);
  padding: 2px var(--space-2); }
/* #rf-account (D213) shares the plate look but IS clickable — an <a>,
   not `button.ghost` (that class is button-scoped and does nothing on an
   anchor), so its own affordance is set here rather than inherited. */
a#rf-account { text-decoration: none; cursor: pointer; }
a#rf-account:hover { border-color: var(--border-bright); color: var(--text); }

/* Topbar nav: quiet dark buttons that go hot-red on hover/active. */
.topbar button.ghost { border-color: var(--border); }
.topbar button.ghost:hover:not(:disabled),
.topbar button.ghost[aria-expanded="true"] {
  border-color: var(--color-accent); color: var(--color-rf-offWhite);
  background: var(--color-accentSoft); }

/* The step strip: Archivo Black numerals, hot-red for the step you are
   on. An industrial progress bar, not a breadcrumb. */
.rail-mark { font-family: var(--font-display); font-weight: 400;
  border-radius: var(--radius-pill); }
.rail-row.active .rail-mark {
  box-shadow: 0 0 0 3px var(--color-accentSoft); }
.rail-row { border-radius: var(--radius-md); }
.rail-row.active { border-left: 3px solid var(--color-accent); }

/* Gold is a SPARING accent — a hairline on the one thing that is a
   provisional figure, never a fill. */
.chip.assumed, .prov-assumed { border-color: var(--color-rf-gold); }

/* The tier badge (UI rule 1: prominent on every screen, never
   ignorable) was a light pill designed for a paper topbar. On dark it
   read as a stray light island — so it becomes an OUTLINED plate: the
   tier colour carries the meaning as text + ring, not as a slab. */
.tier-badge { color: var(--color-tier-L0);
  background: transparent; border-radius: var(--radius-tag);
  box-shadow: inset 0 0 0 1px currentColor;
  font-family: var(--font-mono); font-weight: 600;
  letter-spacing: 0.02em; }
.tier-badge[data-tier="L1"] { background: transparent;
  color: var(--color-tier-L1); }
.tier-badge[data-tier="L2"] { background: transparent;
  color: var(--color-tier-L2); }
.tier-badge[data-tier="L3"] { background: transparent;
  color: var(--color-tier-L3); }
/* the printed deliverables keep the filled pill — a ring on paper
   reads as a form field, and their ground is light anyway */
:root[data-theme='light'] .tier-badge {
  color: #111; background: var(--color-tier-L0);
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.12); }
:root[data-theme='light'] .tier-badge[data-tier="L1"] {
  background: var(--color-tier-L1); }
:root[data-theme='light'] .tier-badge[data-tier="L2"] {
  background: var(--color-tier-L2); }
:root[data-theme='light'] .tier-badge[data-tier="L3"] {
  background: var(--color-tier-L3); }

/* The step strip is the industrial progress bar: Archivo Black numerals,
   hot-red on the step you are on, a rule under the whole thing so it
   reads as one instrument rather than three words. */
#steps { border-bottom: 1px solid var(--border);
  padding-bottom: var(--space-2); }
#steps li::before { font-family: var(--font-display); font-weight: 400;
  letter-spacing: 0.02em; }
#steps li.current { color: var(--color-accent); }
#steps li.current::before { color: var(--color-accent); }
#steps li.done::before { color: var(--color-okText); }
