/* =============================================================================
   quote.css — page-scoped styles for /quote ONLY (QCSS gate 1, 2026-07-12).
   Extracted BYTE-FAITHFULLY from quote.html’s inline <style> (was lines 59–1081).
   Loads AFTER tokens.css / theme.css / complexity.css — same cascade slot the
   inline block occupied. Contains the /quote ROLE WALLS (.eng-only/.admin-only/
   .eng-plus gate, body[data-role] reveals, body.provider-deal-view reshape) —
   they must stay pure CSS: quote.js expects role-hidden controls to EXIST in the
   DOM. Do NOT merge into theme.css (43 generic selectors would leak site-wide).
   ============================================================================= */

/* S1 (2026-07-12): the inline :root token copy was removed — tokens.css is the
   single source of truth (and the CTA gradient now follows the theme). */

*,*::before,*::after{box-sizing:border-box}
html,body{margin:0;padding:0}
body{
  background:var(--bg-page);
  color:var(--text);
  font-family:var(--font-sans);
  font-size:var(--fs-sm);
  line-height:1.5;
  font-feature-settings:"cv11","ss01","ss03";
  -webkit-font-smoothing:antialiased;
  min-height:100vh;
  /* S11 (Igor 2026-07-12): decorative corner orbs removed — flat background. */
}

/* ─────────── Header ─────────── */
.hdr{
  position:sticky; top:0; z-index:40;
  background:var(--bg-header);
  backdrop-filter:blur(10px);
  -webkit-backdrop-filter:blur(10px);
  border-bottom:1px solid var(--border-subtle);
}
.hdr-inner{
  max-width:1400px; margin:0 auto;
  display:flex; align-items:center; justify-content:space-between;
  height:var(--header-h); padding:0 var(--space-6);
}
.logo{ font-weight:var(--fw-extrabold); font-size:1.12rem; letter-spacing:-.01em; color:var(--text-strong); }
.logo b{ color:var(--accent); font-weight:var(--fw-bold); }
.hdr-nav{ display:flex; align-items:center; gap:var(--space-2); }
.hdr-nav .pill{
  font-size:var(--fs-xs); color:var(--text-muted);
  padding:6px 10px; border-radius:var(--radius-pill);
  border:1px solid transparent;
}
.hdr-nav .pill.active{
  color:var(--text-strong); border-color:var(--border);
  background:rgba(30,41,59,.5);
}
.hdr-user{
  display:flex; align-items:center; gap:var(--space-3);
  font-size:var(--fs-xs); color:var(--text-muted);
}
.avatar{
  width:28px; height:28px; border-radius:var(--radius-pill);
  background:linear-gradient(135deg,#334155,#1e293b);
  border:1px solid var(--border);
  display:grid; place-items:center;
  font-size:var(--fs-2xs); color:var(--text-mid); font-weight:var(--fw-semibold);
}

/* ─────────── Layout shell ─────────── */
.page{
  max-width:1400px; margin:0 auto;
  /* T7 — top padding shrunk from var(--space-8): the title row is gone, the
     workspace starts right under the header so the 3D preview stays visible. */
  padding:var(--space-2) var(--space-6) var(--space-16);
}
/* T7 — slim provisional home for #quoteStatus (right-aligned, near-zero height;
   the old .page-title/.crumbs row it replaces is removed). */
.page-topline{
  display:flex; justify-content:flex-end; align-items:center;
  min-height:20px; margin-bottom:var(--space-2);
  color:var(--text-muted); font-size:var(--fs-sm);
}
/* Override theme.css .status block/margins inside the topline: one compact chip,
   not a full-width band. Status writers replace className with `status <kind>` on
   every write, so the override keys off the container + id, never the class. */
.page-topline #quoteStatus{
  display:inline-block; width:auto; margin:0; padding:3px 10px;
  font-size:var(--fs-sm); line-height:1.35;
}
/* The quote number next to the Parts heading must not wrap («КП — новое»). */
#partsPanelHint{ white-space:nowrap; }

/* ─────────── Role-based reveal ─────────── */
.eng-only, .admin-only, .eng-plus{ display:none !important; }
body[data-role="engineer"] .eng-only,
body[data-role="engineer"] .eng-plus,
body[data-role="admin"] .eng-only,
body[data-role="admin"] .eng-plus,
body[data-role="admin"] .admin-only{ display:revert !important; }
/* specific display values */
body[data-role="engineer"] .extras-col,
body[data-role="admin"] .extras-col{ display:grid; }
body[data-role="engineer"] .history-col,
body[data-role="admin"] .history-col{ display:block; }
body[data-role="engineer"] .statusbar,
body[data-role="admin"] .statusbar{ display:flex; }
body[data-role="engineer"] .eng-section,
body[data-role="admin"] .eng-section{ display:grid; }
body[data-role="admin"] .admin-section{ display:grid; }
/* AR2-S10 — 'advanced' is a promoted customer with the EXTENDED calc VIEW: it must
   see the cost breakdown (#breakdownSection) + the precision-features strip, which live
   in .eng-section panels. Those panels are also .eng-only (display:none !important), and
   the S5/S6 JS + backend margin-strip were built for advanced-sees-breakdown — but this
   CSS role-wall was never extended to advanced, so the panels stayed hidden (Igor's
   "advanced still shows the customer view"). Reveal ONLY the .eng-section panels for
   advanced (NOT .eng-plus engineer actions, NOT .admin-only debug/complexity, NOT the
   eng-only layout chrome). Safe by construction: margin renders "—" (value stripped
   server-side, _strip_advanced_money), the breakdown's EOS cells are read-only
   (eosCanEdit excludes advanced), the nested row-4 complexity + Debug JSON keep their own
   walls. Higher specificity + !important beats the .eng-only display:none !important. */
body[data-role="advanced"] .eng-section{ display:grid !important; }
/* AR2-S12 — narrow the S10 reveal: the .eng-section eng-params panel also holds the
   ENGINEER edit-controls (complexity dial + setups/shifts/machines steppers) in the
   .row-4:has(.cpxd) row. advanced can ORDER, so leaving those editable is a
   price-manipulation vector (lower complexity/more machines → lower price → order at it).
   Hide that row for advanced — the precision-features strip (a legit customer spec, sibling
   BEFORE this row) and the cost breakdown stay visible. Identity row (Material/Qty) is not a
   .row-4 so it's untouched. */
body[data-role="advanced"] .row-4:has(.cpxd){ display:none !important; }
/* AR2-S12 — Igor: allow 'advanced' to pick the Technology (CNC vs sheet_cut) — a legit
   customer spec (it selects the real manufacturing method, not a markup). Reveal the
   eng-only Technology segment in the identity row. */
body[data-role="advanced"] .pnl-id-tech{ display:revert !important; }
body[data-role="engineer"] .row-4,
body[data-role="admin"] .row-4{ display:grid; }
body[data-role="engineer"] .part-meta-extra,
body[data-role="admin"] .part-meta-extra{ display:flex; }

/* ─────────── Layout: role-responsive workspace ─────────── */
.workspace{
  display:grid;
  /* default (customer): main + sticky aside */
  grid-template-columns: minmax(0,1fr) minmax(320px, 380px);
  gap:var(--space-6);
  align-items:start;
}
body[data-role="engineer"] .workspace,
body[data-role="admin"] .workspace{
  grid-template-columns: 280px minmax(0,1fr) 360px;   /* HC: history is now a fixed drawer, not a 4th column */
}
body[data-role="engineer"][data-history="open"] .workspace,
body[data-role="admin"][data-history="open"] .workspace{
  --history-w: 280px;
}
@media (max-width:1400px){
  body[data-role="engineer"] .workspace,
  body[data-role="admin"] .workspace{
    grid-template-columns: 260px minmax(0,1fr) 340px;
  }
  body[data-role="engineer"] .history-col,
  body[data-role="admin"] .history-col{ grid-column: 1 / -1; }
}
@media (max-width:1100px){
  body[data-role="engineer"] .workspace,
  body[data-role="admin"] .workspace{
    grid-template-columns: 1fr;
  }
  body[data-role="engineer"] .extras-col,
  body[data-role="admin"] .extras-col{ display:none !important; }
}
@media (max-width:1000px){
  .workspace{ grid-template-columns: 1fr; }
}

/* page max-width grows for eng/admin */
body[data-role="engineer"] .page,
body[data-role="admin"] .page{ max-width:1720px; }
body[data-role="engineer"] .hdr-inner,
body[data-role="admin"] .hdr-inner{ max-width:1720px; }

.extras-col{ display:none; gap:var(--space-4); align-self:start; position:sticky; top:calc(var(--header-h) + var(--space-4));
  max-height: calc(100vh - var(--header-h) - var(--space-6));
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  padding-right: 2px; }
/* HC — history is a fixed, click-through overlay; children (tab/scrim/panel) are
   themselves fixed, so this is out of the workspace grid flow and reserves nothing. */
.history-col{ display:none; position:fixed; inset:0; z-index:60; pointer-events:none; }

/* ─────────── Status bar (eng+admin) ─────────── */
.statusbar{
  display:none; align-items:center; gap:var(--space-2); flex-wrap:wrap;
  padding:var(--space-3) var(--space-4);
  background:var(--bg-surface); border:1px solid var(--border-subtle);
  border-radius:var(--radius-lg);
  margin-bottom:var(--space-5);
  font-size:var(--fs-xs);
}
.sb-badge{
  display:inline-flex; align-items:center; gap:6px;
  padding:4px 9px; border-radius:var(--radius-pill);
  font-family:var(--font-mono); font-size:var(--fs-2xs);
  color:var(--text-mid); border:1px solid var(--border); background:var(--bg-sunken);
}
.sb-badge .dt{
  width:6px; height:6px; border-radius:50%; background:var(--text-subtle);
}
.sb-badge.ok{ color:var(--accent-faint); border-color:var(--accent); background:var(--accent-bg); }
.sb-badge.ok .dt{ background:var(--accent-soft); box-shadow:0 0 0 2px var(--accent-bg); }
.sb-badge.warn{ color:var(--warn); border-color:var(--warn-border); background:var(--warn-bg); }
.sb-badge.warn .dt{ background:var(--warn-bright); }
.statusbar .spacer{ flex:1; }

/* ─────────── Inline eng/admin section ─────────── */
.eng-section, .admin-section{ display:none; gap:var(--space-4); padding-top:var(--space-4); border-top:1px dashed var(--border); margin-top:var(--space-1); }
.section-divider{
  display:flex; align-items:center; gap:var(--space-3);
  font-size:var(--fs-2xs); text-transform:uppercase; letter-spacing:.12em;
  color:var(--text-subtle); font-weight:var(--fw-semibold);
}
.section-divider .line{ flex:1; height:1px; background:var(--border-subtle); }
.section-divider .chip{ display:inline-flex; align-items:center; gap:5px; padding:2px 8px; border:1px solid var(--border); border-radius:var(--radius-pill); font-family:var(--font-mono); font-size:.66rem; color:var(--text-muted); background:var(--bg-sunken); letter-spacing:.04em; }
.section-divider .chip.eng{ color:var(--accent-2-soft); border-color:rgba(59,130,246,.35); background:rgba(59,130,246,.08); }
.section-divider .chip.admin{ color:var(--warn-bright); border-color:var(--warn-border); background:var(--warn-bg); }

.row-4{ grid-template-columns:repeat(4,minmax(0,1fr)); }
@media (max-width:900px){ .row-4{ grid-template-columns:1fr 1fr; } }

/* T4 EOS — editable price cells + layer popover */
.eos-td{ padding:0 !important; text-align:right; }
.eos-cell{ display:inline-flex; align-items:center; justify-content:flex-end; gap:4px; min-width:48px; padding:4px 10px; border-radius:var(--radius-sm,4px); cursor:text; font-variant-numeric:tabular-nums; transition:background .12s ease; }
.eos-cell:hover{ background:rgba(148,163,184,.12); box-shadow:inset 0 0 0 1px var(--border,#334155); }
.eos-cell .eos-pen{ order:1; opacity:0; color:var(--text-subtle,#64748b); display:inline-flex; transition:opacity .12s; }
.eos-cell:hover .eos-pen{ opacity:1; }
.eos-cell .eos-num{ order:2; }
.eos-cell.ov{ color:var(--accent-soft,#60a5fa); font-weight:var(--fw-semibold,600); cursor:pointer; }
.eos-cell.ov:hover{ background:var(--accent-bg,rgba(59,130,246,.1)); box-shadow:inset 0 0 0 1px var(--accent,#3b82f6); }
.eos-cell.ov .eos-pen{ display:none; }
.eos-cell.ov::before{ content:"M"; order:0; font-family:var(--font-mono,monospace); font-size:.56rem; font-weight:700; color:#fff; background:var(--accent,#3b82f6); border-radius:3px; padding:0 3px; line-height:1.5; }
.eos-input{ width:74px; text-align:right; padding:2px 6px; background:var(--bg-sunken,#0f172a); border:1px solid var(--accent,#3b82f6); border-radius:var(--radius-sm,4px); color:var(--text,#e2e8f0); font:inherit; font-variant-numeric:tabular-nums; outline:none; box-shadow:0 0 0 3px var(--accent-bg,rgba(59,130,246,.12)); }
.eos-pop{ position:fixed; z-index:300; width:260px; background:var(--bg-elevated,#1e293b); border:1px solid var(--border-strong,#334155); border-radius:var(--radius-md,8px); box-shadow:0 16px 40px rgba(0,0,0,.5); overflow:hidden; font-size:var(--fs-xs,.78rem); }
.eos-pop-hd{ display:flex; align-items:center; gap:8px; padding:9px 12px; border-bottom:1px solid var(--border-subtle,rgba(148,163,184,.15)); font-weight:var(--fw-semibold,600); }
.eos-pop-r{ margin-left:auto; font-family:var(--font-mono,monospace); font-size:var(--fs-2xs,.7rem); color:var(--text-subtle,#64748b); }
.eos-pop-layer{ display:flex; align-items:center; gap:8px; padding:8px 12px; }
.eos-pop-layer.active{ background:rgba(59,130,246,.08); }
.eos-pop-layer .eos-lx{ width:20px; height:20px; flex:none; display:grid; place-items:center; border-radius:4px; font-family:var(--font-mono,monospace); font-size:.58rem; font-weight:700; }
.eos-pop-layer .eos-lx.auto{ background:rgba(148,163,184,.16); color:var(--text-muted,#94a3b8); }
.eos-pop-layer .eos-lx.man{ background:var(--accent-bg,rgba(59,130,246,.12)); color:var(--accent-soft,#60a5fa); border:1px solid var(--accent,#3b82f6); }
.eos-pop-layer .eos-lk{ color:var(--text-mid,#cbd5e1); }
.eos-pop-layer .eos-lv{ margin-left:auto; font-family:var(--font-mono,monospace); font-variant-numeric:tabular-nums; }
.eos-pop-ft{ padding:8px 12px; border-top:1px solid var(--border-subtle,rgba(148,163,184,.15)); }

/* W2/T15c — per-part kebab popover (body-appended, survives parts-list re-render) */
.part-menu{ position:fixed; z-index:320; width:260px; background:var(--bg-elevated,#1e293b); border:1px solid var(--border-strong,#334155); border-radius:var(--radius-md,8px); box-shadow:0 16px 40px rgba(0,0,0,.5); overflow:hidden; font-size:var(--fs-xs,.78rem); }
.part-menu-bd{ padding:6px; display:flex; flex-direction:column; gap:2px; }
.part-menu .pm-sec-t{ padding:6px 8px 2px; font-size:var(--fs-2xs,.7rem); text-transform:uppercase; letter-spacing:.04em; color:var(--text-subtle,#64748b); font-weight:var(--fw-semibold,600); }
.part-menu .pm-empty{ padding:10px 12px; color:var(--text-muted,#94a3b8); }
.part-menu .pm-files{ display:flex; flex-direction:column; gap:2px; max-height:180px; overflow:auto; }
.part-menu .pm-file{ display:flex; align-items:center; gap:4px; }
.part-menu .pm-fname{ flex:1; min-width:0; display:flex; align-items:center; gap:8px; justify-content:space-between; padding:7px 8px; background:transparent; border:none; border-radius:var(--radius-sm,6px); color:var(--text,#e2e8f0); cursor:pointer; text-align:left; font-size:inherit; }
.part-menu .pm-fname:hover{ background:rgba(148,163,184,.12); }
.part-menu .pm-fn{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.part-menu .pm-fsz{ flex:none; font-family:var(--font-mono,monospace); font-size:var(--fs-2xs,.7rem); color:var(--text-subtle,#64748b); }
.part-menu .pm-del{ flex:none; width:24px; height:24px; border:none; background:transparent; color:var(--text-subtle,#64748b); border-radius:var(--radius-sm,6px); cursor:pointer; }
.part-menu .pm-del:hover{ background:var(--danger-bg, rgba(239,68,68,.15)); color:var(--danger,#ef4444); }
.part-menu .pm-attach,.part-menu .pm-qa{ display:block; width:100%; text-align:left; padding:8px 10px; background:transparent; border:none; border-radius:var(--radius-sm,6px); color:var(--text,#e2e8f0); cursor:pointer; font-size:var(--fs-xs,.78rem); }
.part-menu .pm-attach:hover,.part-menu .pm-qa:hover{ background:rgba(59,130,246,.14); }
.part-menu .pm-attach{ color:var(--accent,#3b82f6); font-weight:var(--fw-semibold,600); }
.part-menu .pm-sep{ height:1px; margin:4px 6px; background:var(--border-subtle,rgba(148,163,184,.15)); }
/* SA-2c — «Объём и заготовка…» kebab action flash-highlights the per-position
   volume/stock editor block so the engineer sees WHERE the bound controls live. */
@keyframes mpFlash{ 0%{ outline-color:rgba(59,130,246,.9); background:rgba(59,130,246,.14); }
  70%{ outline-color:rgba(59,130,246,.55); background:rgba(59,130,246,.07); }
  100%{ outline-color:transparent; background:transparent; } }
.mp-inline.mp-flash{ outline:2px solid transparent; outline-offset:4px; border-radius:8px;
  animation:mpFlash 2.2s ease-out 1; }
/* W4/T16 — DFM reason / advisory notes in the customer price slot */
.dfm-notes{ margin:8px 0 0; padding-left:18px; font-size:var(--fs-xs,.78rem); line-height:1.4; }
.dfm-notes li{ margin:2px 0; }
.dfm-reasons{ color:var(--warning,#f59e0b); }
.dfm-advisories{ color:var(--text-muted,#94a3b8); }

.inline-details{
  border:1px solid var(--border-subtle); border-radius:var(--radius-md);
  background:var(--bg-sunken);
  overflow:hidden;
}
.inline-details summary{
  list-style:none; cursor:pointer;
  padding:10px 12px;
  display:flex; align-items:center; gap:var(--space-2);
  font-size:var(--fs-xs); font-weight:var(--fw-medium); color:var(--text-mid);
}
.inline-details summary::-webkit-details-marker{ display:none; }
.inline-details summary:hover{ background:rgba(30,41,59,.3); color:var(--text-strong); }
.inline-details summary .caret{ width:12px; height:12px; display:grid; place-items:center; color:var(--text-subtle); transition: transform var(--duration-fast); }
.inline-details[open] summary .caret{ transform:rotate(90deg); color:var(--text); }
.inline-details[open] summary{ border-bottom:1px solid var(--border-subtle); }
.inline-details .dbody{ padding:var(--space-4); display:grid; gap:var(--space-3); }

/* QP1-1: removed the dead .debug-wrap/.debug/.debug-hdr/.debug-body ruleset — it
   styled only the deleted #debugPanel mock. The live admin debug uses
   .inline-details .dbody (above) + inline styles in renderDebugSections(). */

/* Stock type panel — expand-on-select cards */
.stock-types{ display:grid; gap:var(--space-2); }
.stock-card{
  border:1px solid var(--border); border-radius:var(--radius-md);
  background:var(--bg-surface); overflow:hidden;
  transition: border-color var(--duration-fast), background var(--duration-fast);
}
.stock-card:hover{ border-color:var(--border-strong); }
.stock-card.on{ border-color:var(--accent); background:var(--accent-bg-soft); }
.stock-card .stock-head{
  display:flex; align-items:center; gap:var(--space-3);
  padding:10px 12px; cursor:pointer; user-select:none;
}
.stock-card input[type="radio"]{
  appearance:none; width:14px; height:14px; border-radius:50%;
  border:1.5px solid var(--border-strong); background:transparent;
  display:grid; place-items:center; margin:0; flex:none;
}
.stock-card input[type="radio"]:checked{ border-color:var(--accent); }
.stock-card input[type="radio"]:checked::after{ content:""; width:6px; height:6px; border-radius:50%; background:var(--accent-soft); }
.stock-card .nm{ font-size:var(--fs-sm); color:var(--text-strong); font-weight:var(--fw-medium); flex:1; }
.stock-card .sz{ font-family:var(--font-mono); font-size:var(--fs-2xs); color:var(--text-subtle); }
.stock-card .src-badge{
  display:inline-flex; padding:1px 6px; border-radius:var(--radius-pill);
  font-family:var(--font-mono); font-size:.62rem; letter-spacing:.05em;
  border:1px solid var(--border-subtle); background:var(--bg-sunken); color:var(--text-subtle);
}
.stock-card .src-badge.auto{ color:var(--accent-2-soft); border-color:rgba(59,130,246,.3); background:rgba(59,130,246,.08); }
.stock-dims{
  display:none; grid-template-columns:1fr 1fr; gap:var(--space-2);
  padding:0 12px 12px; border-top:1px dashed var(--border-subtle); padding-top:var(--space-3);
}
.stock-card.on .stock-dims{ display:grid; }
/* RANK-3: ranked stock-candidate chips (primary + feasible alternates). */
.stock-alt-chips{ display:flex; flex-wrap:wrap; gap:var(--space-2); margin-bottom:var(--space-2); }
.stock-alt-chips[hidden]{ display:none; }
.stock-alt-chip{ display:inline-flex; align-items:center; gap:6px; padding:4px 10px; border:1px solid var(--border-strong); border-radius:999px; background:var(--surface); color:var(--text-strong); font-size:var(--fs-xs); font-family:inherit; line-height:1.4; cursor:pointer; }
.stock-alt-chip:hover{ border-color:var(--accent); }
.stock-alt-chip.on{ border-color:var(--accent); background:var(--accent-bg-soft); }
.stock-alt-chip .dim,.stock-alt-chip .tag{ font-family:var(--font-mono); font-size:var(--fs-2xs); color:var(--text-subtle); }
.stock-dims label{ display:grid; gap:4px; font-size:var(--fs-2xs); color:var(--text-muted); }
.stock-dims .span-2{ grid-column:1 / -1; }
.stock-dims input{
  padding:7px 9px; font-size:var(--fs-xs); width:100%;
  background:var(--bg-elevated); color:var(--text); border:1px solid var(--border);
  border-radius:var(--radius-sm); font-variant-numeric:tabular-nums; font-family:var(--font-mono); outline:none;
}
.stock-dims input:focus{ border-color:var(--accent); box-shadow:0 0 0 2px var(--accent-bg); }

/* Sheet-cut panel: hidden by default, shown when tech=sheet_cut */
.sheet-panel{ display:none; }
body[data-tech="sheet_cut"] .sheet-panel{ display:block; }

/* DXF-THK: customer-visible sheet thickness row — same tech gate as .sheet-panel.
   The wrapper toggles display; the inner .field keeps its own layout. */
.cust-sheet-thk{ display:none; }
body[data-tech="sheet_cut"] .cust-sheet-thk{ display:block; }

/* Custom material/finish expandable */
.custom-expand{ border:1px solid var(--border-subtle); border-radius:var(--radius-md); background:var(--bg-sunken); padding:var(--space-3); display:none; gap:var(--space-3); }
.custom-expand.on{ display:grid; }
.custom-trigger{ background:transparent; border:none; color:var(--accent-soft); font-size:var(--fs-xs); font-weight:var(--fw-medium); cursor:pointer; padding:0; display:inline-flex; align-items:center; gap:4px; font-family:var(--font-sans); text-decoration:none; }
.custom-trigger:hover{ color:var(--accent-faint); }
.custom-trigger .caret{ transition:transform var(--duration-fast); display:inline-grid; place-items:center; }
.custom-trigger.on .caret{ transform:rotate(90deg); }

/* Extra finish rows */
.finish-row{ display:grid; grid-template-columns:1fr 90px auto; gap:var(--space-3); align-items:end; }
.finish-row .del{ width:32px; height:32px; border:1px solid var(--border-subtle); border-radius:var(--radius-sm); background:transparent; color:var(--text-muted); cursor:pointer; display:grid; place-items:center; }
.finish-row .del:hover{ border-color:var(--danger); color:var(--danger); }
.btn-add{ background:transparent; color:var(--text-muted); border:1px dashed var(--border-strong); border-radius:var(--radius-md); padding:8px 12px; font-size:var(--fs-xs); font-weight:var(--fw-medium); cursor:pointer; font-family:var(--font-sans); }
.btn-add:hover{ color:var(--accent-faint); border-color:var(--accent); background:var(--accent-bg-soft); }
.btn-add[disabled]{ opacity:.4; cursor:not-allowed; }

/* Viewer face-layer toggles */
.viewer-toggles{ display:flex; flex-wrap:wrap; gap:6px; padding:var(--space-3) 0 0; border-top:1px solid var(--border-subtle); margin-top:var(--space-3); }
.layer-tog{ display:inline-flex; align-items:center; gap:6px; padding:5px 9px; border:1px solid var(--border); border-radius:var(--radius-pill); font-size:var(--fs-2xs); color:var(--text-mid); cursor:pointer; background:var(--bg-sunken); transition:border-color var(--duration-fast), color var(--duration-fast), background var(--duration-fast); }
.layer-tog input{ appearance:none; width:0; height:0; margin:0; padding:0; position:absolute; opacity:0; }
.layer-tog .dt{ width:8px; height:8px; border-radius:50%; background:var(--text-subtle); transition:background var(--duration-fast), box-shadow var(--duration-fast); }
.layer-tog.on{ color:var(--text-strong); border-color:var(--border-strong); background:var(--bg-elevated); }
.layer-tog[data-k="cy"].on .dt{ background:#4dc766; box-shadow:0 0 0 3px rgba(77,199,102,.22); }
.layer-tog[data-k="pl"].on .dt{ background:#737380; box-shadow:0 0 0 3px rgba(115,115,128,.22); }
.layer-tog[data-k="hl"].on .dt{ background:#ff3333; box-shadow:0 0 0 3px rgba(255,51,51,.22); }
.layer-tog[data-k="pk"].on .dt{ background:#ff8c1a; box-shadow:0 0 0 3px rgba(255,140,26,.22); }
.layer-tog[data-k="pr"].on .dt{ background:#f5cc1a; box-shadow:0 0 0 3px rgba(245,204,26,.22); }
.layer-tog[data-k="tr"].on .dt{ background:#80d3ff; box-shadow:0 0 0 3px rgba(128,211,255,.22); }
.layer-tog[data-k="sh"].on .dt{ background:#bf73ff; box-shadow:0 0 0 3px rgba(191,115,255,.22); }
.layer-tog[data-k="ce"].on .dt{ background:#ff1a8c; box-shadow:0 0 0 3px rgba(255,26,140,.22); } /* F4.3 — LAYER_COLORS.concave_edge [1.0,.1,.55] */

/* Checkbox (region toggles, feedback) */
.check{ display:flex; align-items:center; gap:8px; font-size:var(--fs-xs); color:var(--text-mid); cursor:pointer; padding:6px 8px; border-radius:var(--radius-sm); }
.check:hover{ background:rgba(30,41,59,.35); color:var(--text-strong); }
.check input{ appearance:none; width:14px; height:14px; border-radius:3px; border:1.5px solid var(--border-strong); background:transparent; display:grid; place-items:center; margin:0; flex:none; }
.check input:checked{ background:var(--accent); border-color:var(--accent); }
.check input:checked::after{ content:""; width:4px; height:7px; border:solid #062e24; border-width:0 2px 2px 0; transform:rotate(45deg) translate(-1px,-1px); }

/* Region row: checkbox + pill inline */
.regions-row{ display:flex; gap:var(--space-2); flex-wrap:wrap; align-items:stretch; }
.region-pick{ position:relative; display:flex; align-items:center; gap:8px; padding:10px 12px; border:1px solid var(--border); border-radius:var(--radius-lg); background:var(--bg-surface); cursor:pointer; min-width:140px; }
.region-pick:hover{ border-color:var(--border-strong); }
.region-pick.on{ border-color:var(--accent); background:var(--accent-bg-soft); }
.region-pick input{ appearance:none; width:14px; height:14px; border-radius:3px; border:1.5px solid var(--border-strong); background:transparent; display:grid; place-items:center; margin:0; flex:none; }
.region-pick input:checked{ background:var(--accent); border-color:var(--accent); }
.region-pick input:checked::after{ content:""; width:4px; height:7px; border:solid #062e24; border-width:0 2px 2px 0; transform:rotate(45deg) translate(-1px,-1px); }
.region-pick .flag{ font-size:var(--fs-2xs); text-transform:uppercase; letter-spacing:.08em; color:var(--text-muted); display:block; }
.region-pick .v{ font-size:var(--fs-base); font-weight:var(--fw-bold); font-variant-numeric:tabular-nums; color:var(--text-strong); display:block; }
.region-pick.usa .v{ color:var(--accent-soft); }
.region-pick.eu .v{ color:var(--accent-2-soft); }
.region-pick.china .v{ color:var(--warn-bright); }

/* Detail tables */
.detail-tbl{ width:100%; border-collapse:collapse; font-size:var(--fs-xs); font-variant-numeric:tabular-nums; }
.detail-tbl th, .detail-tbl td{ padding:7px 10px; text-align:right; border-bottom:1px solid var(--border-subtle); }
.detail-tbl th:first-child, .detail-tbl td:first-child{ text-align:left; color:var(--text-muted); }
.detail-tbl th{ font-weight:var(--fw-medium); color:var(--text-subtle); text-transform:uppercase; letter-spacing:.08em; font-size:var(--fs-3xs); }
.detail-tbl td{ color:var(--text-mid); }
.detail-tbl tfoot td{ font-weight:var(--fw-semibold); color:var(--text-strong); border-top:1px solid var(--border); border-bottom:none; }

/* Part-row extra meta (eng/admin) */
.part-meta-extra{ display:none; align-items:center; gap:8px; margin-top:4px; }
.sig-chip{ display:inline-flex; align-items:center; gap:4px; font-family:var(--font-mono); font-size:var(--fs-3xs); color:var(--text-subtle); border:1px solid var(--border-subtle); border-radius:var(--radius-sm); padding:1px 6px; background:var(--bg-sunken); }
.group-chip{ display:inline-flex; align-items:center; gap:4px; font-size:var(--fs-3xs); color:var(--accent-2-soft); border:1px solid rgba(59,130,246,.3); border-radius:var(--radius-sm); padding:1px 6px; background:rgba(59,130,246,.06); cursor:pointer; }
.group-chip:hover{ background:var(--info-bg, rgba(59,130,246,.12)); } /* qcss2: exact --info-bg */

/* ─────────── History DRAWER (engineer + admin) ─────────── */
/* Edge tab (closed), scrim + sliding panel (open). All fixed; data-history on
   <body> drives state. Vertical scroll only — no 4th-column horizontal scroll. */
.history-tab{
  display:none; position:fixed; right:0; top:50%; transform:translateY(-50%);
  flex-direction:column; align-items:center; gap:10px;
  width:34px; padding:var(--space-4) 0; pointer-events:auto;
  border:1px solid var(--border); border-right:none;
  border-radius:var(--radius-lg) 0 0 var(--radius-lg);
  background:var(--bg-surface); color:var(--text-muted); cursor:pointer;
  writing-mode:vertical-rl; z-index:61;
}
body[data-history="closed"] .history-tab{ display:flex; }
.history-tab:hover{ color:var(--text-strong); border-color:var(--border-strong); }
.history-tab .lbl{ font-size:var(--fs-xs); font-weight:var(--fw-semibold); letter-spacing:.08em; text-transform:uppercase; transform:rotate(180deg); }
.history-tab .chev{ transform:rotate(180deg); writing-mode:horizontal-tb; }

.hist-scrim{
  position:fixed; inset:0; background:rgba(2,6,23,.55);
  -webkit-backdrop-filter:blur(3px); backdrop-filter:blur(3px);
  opacity:0; pointer-events:none; transition:opacity var(--duration-base) var(--ease); z-index:60;
}
body[data-history="open"] .hist-scrim{ opacity:1; pointer-events:auto; }

.history-panel{
  position:fixed; top:0; right:0; bottom:0; width:min(440px,92vw);
  background:var(--bg-surface); border-left:1px solid var(--border-strong);
  transform:translateX(100%); transition:transform var(--duration-slow) var(--ease);
  z-index:62; display:flex; flex-direction:column; gap:0; padding:0; pointer-events:auto;
}
body[data-history="open"] .history-panel{ transform:translateX(0); }

.history-hdr{ display:flex; align-items:center; gap:12px; padding:var(--space-4) var(--space-5); border-bottom:1px solid var(--border-subtle); }
.history-hdr h3{ margin:0; font-size:var(--fs-base); font-weight:var(--fw-bold); color:var(--text-strong); }
.history-hdr .close-btn{ margin-left:auto; background:transparent; border:1px solid var(--border); color:var(--text-muted); cursor:pointer; width:30px; height:30px; border-radius:var(--radius-md); display:grid; place-items:center; font-size:var(--fs-base); line-height:1; }
.history-hdr .close-btn:hover{ color:var(--text-strong); background:var(--bg-elevated); border-color:var(--border-strong); }

.history-deal{ display:flex; gap:8px; padding:var(--space-3) var(--space-5); border-bottom:1px solid var(--border-subtle); background:var(--bg-sunken); }
.history-deal .input{ flex:1; padding:8px 11px; font-family:var(--font-mono); font-size:var(--fs-xs); }

.hist-selbar{ display:flex; align-items:center; gap:12px; padding:0 var(--space-5); max-height:0; overflow:hidden; background:var(--accent-bg); color:var(--accent-faint); font-size:var(--fs-xs); border-bottom:1px solid transparent; transition:max-height var(--duration-base) var(--ease), padding var(--duration-base) var(--ease); }
.hist-selbar.show{ max-height:64px; padding-top:var(--space-3); padding-bottom:var(--space-3); border-bottom-color:var(--border-subtle); }
.hist-selbar .n{ font-family:var(--font-mono); font-weight:var(--fw-semibold); }
.hist-selbar #btnRestoreSelected{ margin-left:auto; width:auto; margin-top:0; }

.history-list{ flex:1; display:grid; gap:4px; align-content:start; overflow-y:auto; overflow-x:hidden; padding:var(--space-3) var(--space-4); }
.grp-label{ font-family:var(--font-mono); font-size:var(--fs-3xs); letter-spacing:.10em; text-transform:uppercase; color:var(--text-subtle); padding:var(--space-3) var(--space-2) 4px; }
.hrow{ display:grid; grid-template-columns:18px 40px minmax(0,1fr) auto; gap:10px; align-items:center; padding:9px 10px; border-radius:var(--radius-md); border:1px solid transparent; cursor:pointer; transition:background var(--duration-fast) var(--ease), border-color var(--duration-fast) var(--ease); }
.hrow:hover{ background:var(--bg-elevated); border-color:var(--border-subtle); }
.hrow.sel{ background:var(--accent-bg); border-color:var(--border); }
.hrow.sel .row-restore{ max-height:48px; }
.hrow > input[type="checkbox"]{ width:15px; height:15px; accent-color:var(--accent); cursor:pointer; margin:0; }
.hrow .thumb{ width:40px; height:40px; border-radius:var(--radius-md); overflow:hidden; background:var(--bg-sunken); border:1px solid var(--border-subtle); display:grid; place-items:center; }
.hrow .thumb img{ width:40px; height:40px; object-fit:cover; }
.hrow .meta{ min-width:0; }
.hrow .nm{ font-size:var(--fs-xs); color:var(--text-strong); font-weight:var(--fw-semibold); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.hrow .nm .rev-badge{ font-family:var(--font-mono); font-size:var(--fs-3xs); color:var(--text-subtle); font-weight:400; margin-left:5px; }
.hrow .sub{ font-family:var(--font-mono); font-size:var(--fs-3xs); color:var(--text-subtle); margin-top:2px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.hrow .price{ text-align:right; }
.hrow .price .v{ font-family:var(--font-mono); font-size:var(--fs-xs); font-weight:var(--fw-semibold); color:var(--text-strong); font-variant-numeric:tabular-nums; }
.hrow .price .rg{ font-size:var(--fs-3xs); color:var(--text-subtle); margin-top:1px; }
.hrow .row-restore{ grid-column:1 / -1; max-height:0; overflow:hidden; transition:max-height var(--duration-base) var(--ease); }
.hrow:hover .row-restore{ max-height:48px; }
.hrow .row-restore button{ margin-top:8px; width:100%; }
#btnRefreshHistory{ padding:var(--space-3) var(--space-5) !important; border-top:1px solid var(--border-subtle); }

/* Body compact/cozy density toggle */
body[data-density="compact"] .panel{ padding:var(--space-4); }
body[data-density="compact"] .panel-hdr{ padding:var(--space-3) var(--space-4); }
body[data-density="compact"] .panel-body{ padding:var(--space-4); }

/* ─────────── Panel ─────────── */
.panel{
  background:var(--gradient-panel);
  border:1px solid var(--border);
  border-radius:var(--radius-xl);
  overflow:hidden;
  transition: border-color var(--duration-base) var(--ease);
}
.panel + .panel{ margin-top:var(--space-4); }
.panel:hover{ border-color:var(--border-strong); }

.panel-hdr{
  display:flex; align-items:center; gap:var(--space-3);
  padding:var(--space-4) var(--space-5);
  border-bottom:1px solid var(--border-subtle);
  user-select:none;
}
.panel-hdr.clickable{ cursor:pointer; }
.panel-hdr.clickable:hover{ background:rgba(30,41,59,.35); }
.panel-hdr h2{
  flex:1; margin:0;
  font-size:var(--fs-base); font-weight:var(--fw-semibold);
  color:var(--text-strong); letter-spacing:-.005em;
}
.panel-hdr .hint{
  font-size:var(--fs-xs); color:var(--text-muted); font-weight:var(--fw-medium);
}
.panel-hdr .badge{
  display:inline-flex; align-items:center; gap:4px;
  padding:2px 8px; border-radius:var(--radius-pill);
  font-size:var(--fs-2xs); font-weight:var(--fw-medium);
  color:var(--text-muted); border:1px solid var(--border);
  background:rgba(30,41,59,.5);
}
.panel-hdr .badge.ok{ color:var(--accent-faint); border-color:var(--accent); background:var(--accent-bg); }
.panel-hdr .badge.warn{ color:var(--warn); border-color:var(--warn-border); background:var(--warn-bg); }

.chev{
  width:22px; height:22px; border-radius:var(--radius-sm);
  display:grid; place-items:center;
  color:var(--text-muted);
  transition: transform var(--duration-base) var(--ease), color var(--duration-fast);
}
.panel-hdr.clickable:hover .chev{ color:var(--text); }
.panel[data-open="true"] .chev{ transform:rotate(90deg); }

.panel-body{
  padding:var(--space-5);
  display:grid;
  gap:var(--space-5);
}

/* Collapse animation — clip container */
.collapse{
  display:grid;
  grid-template-rows:1fr;
  transition: grid-template-rows var(--duration-slow) var(--ease),
              opacity var(--duration-base) var(--ease);
  opacity:1;
}
.panel[data-open="false"] .collapse{
  grid-template-rows:0fr;
  opacity:0;
}
.collapse > .collapse-inner{
  min-height:0; overflow:hidden;
}

/* ─────────── Forms ─────────── */
.field{ display:grid; gap:var(--space-2); }
.label{
  font-size:var(--fs-xs); font-weight:var(--fw-medium);
  color:var(--text-muted); letter-spacing:.01em;
}
.input,
.select,
.textarea{
  width:100%;
  padding:10px 12px;
  background:var(--bg-surface);
  color:var(--text);
  border:1px solid var(--border);
  border-radius:var(--radius-md);
  font:var(--fs-sm)/1.4 var(--font-sans);
  transition: border-color var(--duration-fast), box-shadow var(--duration-fast), background var(--duration-fast);
}
.input::placeholder,.textarea::placeholder{ color:var(--text-subtle); }
.input:hover, .select:hover, .textarea:hover{ border-color:var(--border-strong); }
.input:focus, .select:focus, .textarea:focus{
  outline:none;
  border-color:var(--accent);
  box-shadow:0 0 0 3px var(--accent-bg);
  background:var(--bg-elevated);
}
.select{ appearance:none; -webkit-appearance:none;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%2394a3b8' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:right 12px center;
  padding-right:36px;
}
.textarea{ min-height:72px; resize:vertical; font:var(--fs-sm)/1.5 var(--font-sans); }

.row{ display:grid; gap:var(--space-3); }
/* DR-3.7: compact, uniform chip row — overrides .row's vertical grid (the cause of the
   one-chip-per-line stack) into a clean horizontal pill row. */
.row.chips{ display:flex; flex-wrap:wrap; gap:var(--space-2); align-items:center; }
.row-2{ grid-template-columns:1fr 1fr; }

/* W11 — sheet-cut panel redesign: one straight value column, tiered groups.
   Scoped to #sheetInputs so it can't collide with the global .row/.field grid. */
#sheetInputs .sh-group{ display:flex; flex-direction:column; }
#sheetInputs .sh-group + .sh-group{ margin-top:var(--space-2); padding-top:var(--space-3); border-top:1px solid var(--border-subtle); }
#sheetInputs .sh-cap{ font-family:var(--font-mono); font-size:var(--fs-3xs); letter-spacing:.06em; text-transform:uppercase; color:var(--text-subtle); margin-bottom:var(--space-1); }
#sheetInputs .sh-cap .price{ color:var(--accent-soft,#7ea9ff); }
#sheetInputs .sh-row{ display:grid; grid-template-columns:1fr auto; column-gap:var(--space-3); align-items:baseline; min-height:29px; padding:5px 0; }
#sheetInputs .sh-row + .sh-row:not(.inp-row){ border-top:1px solid var(--border-subtle); }
#sheetInputs .sh-row.inp-row{ align-items:center; min-height:0; padding:4px 0; }
#sheetInputs .sh-lab{ font-size:var(--fs-xs); color:var(--text-muted); line-height:1.2; min-width:0; }
#sheetInputs .sh-lab .sub{ display:block; font-size:var(--fs-3xs); color:var(--text-subtle); font-family:var(--font-mono); margin-top:1px; letter-spacing:.02em; }
#sheetInputs .sh-val{ font-family:var(--font-mono); font-variant-numeric:tabular-nums; font-size:var(--fs-xs); color:var(--text); text-align:right; white-space:nowrap; justify-self:end; }
#sheetInputs .sh-val .u{ color:var(--text-subtle); font-size:var(--fs-2xs); margin-left:4px; }
#sheetInputs .sh-inp{ justify-self:end; width:110px; }
#sheetInputs .sh-inp .input{ width:100%; text-align:right; font-family:var(--font-mono); font-size:var(--fs-xs); padding:6px 9px; }
#sheetInputs .sh-inp .select{ width:100%; font-size:var(--fs-xs); padding:6px 9px; }
#sheetInputs .sh-check{ display:flex; align-items:center; gap:8px; font-size:var(--fs-xs); color:var(--text-mid); cursor:pointer; margin-bottom:var(--space-1); }
#sheetInputs .eos-cell{ min-width:0; padding:2px 6px; }
.row-3{ grid-template-columns:repeat(3,minmax(0,1fr)); }
.row-hero{ grid-template-columns: 1fr 120px; gap:var(--space-3); align-items:end; }
@media (max-width:640px){
  .row-2,.row-3{ grid-template-columns:1fr; }
  .row-hero{ grid-template-columns:1fr; }
}

/* Combobox */
.combo{ position:relative; }
.combo-list{
  position:absolute; top:calc(100% + 4px); left:0; right:0; z-index:20;
  max-height:260px; overflow:auto;
  background:var(--bg-elevated);
  border:1px solid var(--border-strong);
  border-radius:var(--radius-md);
  margin:0; padding:4px; list-style:none;
}
.combo-list li{
  padding:8px 10px; border-radius:var(--radius-sm);
  color:var(--text-mid); cursor:pointer;
  font-size:var(--fs-sm);
}
.combo-list li:hover, .combo-list li[aria-selected=true]{
  background:var(--accent-bg); color:var(--accent-faint);
}

/* Upload zone */
.upload{
  display:flex; align-items:center; gap:var(--space-4);
  padding:var(--space-6);
  border:1.5px dashed var(--border-strong);
  border-radius:var(--radius-xl);
  background:rgba(2,6,23,.25);
  cursor:pointer;
  transition: border-color var(--duration-base), background var(--duration-base);
}
.upload:hover{ border-color:var(--accent); background:var(--accent-bg-soft); }
.upload-ic{
  width:44px; height:44px; flex:none;
  display:grid; place-items:center;
  border-radius:var(--radius-lg);
  background:var(--bg-elevated);
  border:1px solid var(--border);
  color:var(--text-muted);
}
.upload-body{ flex:1; }
.upload strong{
  display:block; color:var(--text-strong);
  font-size:var(--fs-base); font-weight:var(--fw-semibold);
}
.upload > .upload-body > span{ display:block; color:var(--text-muted); font-size:var(--fs-xs); margin-top:2px; }
.upload .kbd{ display:inline-block; width:auto; margin:0 1px; }
.upload .kbd{
  font-family:var(--font-mono); font-size:var(--fs-2xs);
  padding:2px 6px; border:1px solid var(--border); border-radius:4px;
  background:var(--bg-sunken); color:var(--text-mid);
}

/* ─────────── Bulk upload progress (Eng-6 PL4 c) ─────────── */
.bulk-progress{ margin-top:var(--space-3); padding:var(--space-3); border:1px solid var(--border-subtle); border-radius:var(--radius-md); background:var(--bg-sunken); font-size:var(--fs-xs); color:var(--text-mid); }
.bulk-progress-header{ display:flex; justify-content:space-between; align-items:center; margin-bottom:var(--space-2); color:var(--text-strong); font-weight:500; }
.bulk-progress-bar{ height:6px; background:rgba(148,163,184,.15); border-radius:var(--radius-pill); overflow:hidden; }
.bulk-progress-bar > div{ height:100%; background:var(--accent); transition:width var(--duration-fast); }
.bulk-progress-errors{ margin-top:var(--space-2); display:grid; gap:2px; }
.bulk-error-line{ font-size:var(--fs-2xs); color:var(--warn); padding:2px 0; }
/* WAVE D / D1 (audit S2-2) — name of the file currently being analyzed. */
.bulk-progress-file{ margin-top:var(--space-2); font-size:var(--fs-2xs); color:var(--text-muted);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.bulk-progress-file:empty{ display:none; }

/* WAVE D / D1 — upload placeholder + durable failure rows in the parts list.
   `.busy` is the neutral third rung next to theme.css's .warn / .danger badges:
   a row that is still being analyzed is neither a warning nor an error. */
.part-status-badge.busy{
  color:var(--text-muted);
  background:rgba(148,163,184,.14);
  border:1px solid rgba(148,163,184,.32);
}
.part[data-part-busy="1"]{ opacity:.72; }
/* A status row shows its quantity but offers no stepper — there is nothing to reprice
   yet, and hydrating the panel from such a row would reset the requirement selects the
   REST of the batch is being uploaded with. */
.part-qty-inert{ color:var(--text-muted); font-size:var(--fs-2xs); justify-self:center; }
.part-error{
  margin-top:2px; font-size:var(--fs-2xs); color:var(--danger);
  display:flex; align-items:baseline; gap:var(--space-2); flex-wrap:wrap;
}
.part-help-btn{
  border:1px solid var(--accent); background:transparent; color:var(--accent);
  border-radius:var(--radius-xs); padding:1px 8px; font-size:var(--fs-2xs);
  cursor:pointer; white-space:nowrap;
}
/* Tint on hover rather than inverting to a solid accent fill: --accent is a light green
   in the dark themes and a dark green in the light one, so a single inverted text colour
   would fail contrast in one of them. The tint keeps the already-legible accent text. */
.part-help-btn:hover{ background:rgba(16,185,129,.12); }

/* ─────────── Part list ─────────── */
.partlist{ display:grid; gap:var(--space-3); }
.part{
  display:grid;
  /* P2.3b P6 — last 32px column holds the × delete button (hover/selected only). */
  grid-template-columns: 28px 64px 1fr 110px 140px 32px 32px;
  gap:var(--space-4);
  align-items:center;
  padding:var(--space-3) var(--space-4);
  background:var(--bg-surface);
  border:1px solid var(--border);
  border-radius:var(--radius-lg);
  transition: border-color var(--duration-fast), background var(--duration-fast);
}
/* P2.3b P6 — delete button: hidden by default, revealed on row hover/select.
   Shadow rows don't render the button at all (guard in row template). */
.part-del-btn{
  background:transparent; border:none; cursor:pointer;
  color:var(--text-subtle); padding:4px; border-radius:var(--radius-sm);
  display:grid; place-items:center;
  opacity:0; transition:opacity var(--duration-fast), color var(--duration-fast), background var(--duration-fast);
}
.part:hover .part-del-btn, .part.selected .part-del-btn{ opacity:1; }
.part-del-btn:hover{ color:var(--danger); background:var(--bg-sunken); }
.part-del-btn:focus-visible{ opacity:1; outline:2px solid var(--accent); outline-offset:2px; }
.part:hover{ border-color:var(--border-strong); background:var(--bg-elevated); }
.part.selected{ border-color:var(--accent); background:var(--accent-bg-soft); }
.part-idx{ font-size:var(--fs-2xs); color:var(--text-subtle); font-variant-numeric:tabular-nums; }
.part-thumb{
  width:64px; height:64px; border-radius:var(--radius-md);
  background:
    linear-gradient(135deg, rgba(96,165,250,.14), rgba(52,211,153,.12)),
    var(--bg-elevated);
  border:1px solid var(--border);
  display:grid; place-items:center;
  color:var(--text-subtle);
  overflow:hidden;
}
/* P2.3b P5 — real thumbnails (captured from the live viewer after upload). */
.part-thumb.has-thumb{
  background:#111827;  /* matches viewer canvas background so the thumb blends */
  padding:0;
}
.part-thumb.has-thumb img{
  width:100%; height:100%; object-fit:contain; display:block;
}
.part-meta{ min-width:0; display:grid; gap:2px; }
.part-name{
  color:var(--text-strong); font-size:var(--fs-sm); font-weight:var(--fw-semibold);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.part-spec{ color:var(--text-muted); font-size:var(--fs-xs); }
.part-spec .dot{ opacity:.5; margin:0 6px; }
/* P2.3a P7 — dimensions + weight line. Sits between filename and spec summary;
   visually lighter than the spec line so it reads as neutral metadata, not a
   callout. Chip separator is implicit via inline gap. */
.part-dims{
  display:flex; flex-wrap:wrap; gap:8px;
  font-size:var(--fs-2xs); color:var(--text-subtle);
  font-variant-numeric:tabular-nums;
  margin:2px 0;
}
.part-dims .part-dim,
.part-dims .part-weight{ white-space:nowrap; }
.part-dims .part-weight{ color:var(--text-muted); }
.part-qty{
  display:flex; align-items:center; gap:4px;
  border:1px solid var(--border); border-radius:var(--radius-md);
  overflow:hidden; background:var(--bg-surface);
}
.part-qty button{
  width:28px; height:28px; background:transparent; border:none;
  color:var(--text-muted); cursor:pointer; font-size:var(--fs-base);
}
.part-qty button:hover{ color:var(--accent); background:var(--accent-bg-soft); }
.part-qty input{
  width:100%; border:none; background:transparent; color:var(--text-strong);
  text-align:center; font-size:var(--fs-sm); font-weight:var(--fw-semibold);
  height:28px; padding:0; font-variant-numeric:tabular-nums;
  outline:none;
}
.part-price{ text-align:right; }
.part-price .v{
  color:var(--accent-soft); font-weight:var(--fw-bold); font-size:var(--fs-base);
  font-variant-numeric:tabular-nums;
}
.part-price .s{ color:var(--text-subtle); font-size:var(--fs-2xs); }
.part-act{
  width:28px; height:28px; border-radius:var(--radius-sm);
  background:transparent; border:1px solid transparent; color:var(--text-muted);
  cursor:pointer; display:grid; place-items:center;
}
.part-act:hover{ border-color:var(--border); color:var(--text); background:var(--bg-elevated); }

@media (max-width:720px){
  .part{ grid-template-columns: 20px 48px 1fr; grid-template-rows:auto auto; row-gap:var(--space-2); }
  .part-qty{ grid-column:1 / -1; }
  .part-price{ grid-column:1 / -1; text-align:left; }
  .part-act{ position:absolute; right:var(--space-4); top:var(--space-3); }
  /* P2.3b P6 — on narrow viewports tuck the delete button into the same corner
     as the kebab, shifted left by one button width so they don't overlap. */
  .part-del-btn{ position:absolute; right:calc(var(--space-4) + 32px); top:var(--space-3); }
}

/* ─────────── Price summary ─────────── */
.price-hero{
  padding:var(--space-6);
  border:1px solid var(--border);
  background:var(--bg-surface);
  border-radius:var(--radius-xl);
  display:grid; gap:var(--space-5);
}
.price-eyebrow{
  display:flex; align-items:center; justify-content:space-between;
  font-size:var(--fs-2xs); color:var(--text-muted);
  text-transform:uppercase; letter-spacing:.09em;
}
.price-eyebrow .live{
  display:inline-flex; align-items:center; gap:6px;
  color:var(--accent-soft); text-transform:none; letter-spacing:normal;
  font-size:var(--fs-xs); font-weight:var(--fw-medium);
}
.live::before{
  content:""; width:6px; height:6px; border-radius:50%;
  background:var(--accent-soft); box-shadow:0 0 0 3px var(--accent-bg);
  animation: pulse 1.8s ease-in-out infinite;
}
@keyframes pulse{ 50%{ opacity:.4; } }

.price-big{
  font-size:var(--fs-2xl); line-height:1;
  font-weight:var(--fw-extrabold); color:var(--accent-soft);
  font-variant-numeric:tabular-nums; letter-spacing:-.02em;
}
.price-big .per{
  font-size:var(--fs-lg); font-weight:var(--fw-medium); color:var(--text-muted);
  margin-left:4px;
}
.price-meta{
  display:grid; grid-template-columns:repeat(3,1fr); gap:var(--space-3);
  padding-top:var(--space-4);
  border-top:1px solid var(--border-subtle);
}
.price-meta .k{ color:var(--text-subtle); font-size:var(--fs-2xs); text-transform:uppercase; letter-spacing:.08em; }
.price-meta .v{ color:var(--text-strong); font-size:var(--fs-sm); font-weight:var(--fw-semibold); margin-top:2px; font-variant-numeric:tabular-nums; }

/* P2.3a — multi-part deal total block. Sits below the single-part price hero and
   surfaces the sum across all priced parts + max lead time. Visually secondary to
   the hero so the per-part selected price stays the primary focal point. */
.deal-total{
  margin-top:var(--space-4);
  padding:var(--space-4) var(--space-5);
  border:1px solid var(--border-subtle);
  background:var(--bg-surface-muted, var(--bg-surface));
  border-radius:var(--radius-lg);
  display:grid; gap:var(--space-2);
}
.deal-total-head{
  display:flex; align-items:baseline; justify-content:space-between;
  gap:var(--space-3);
  font-size:var(--fs-2xs); color:var(--text-muted);
  text-transform:uppercase; letter-spacing:.08em;
}
.deal-total-label{ font-weight:var(--fw-medium); }
.deal-total-lead{ text-transform:none; letter-spacing:normal; font-size:var(--fs-xs); color:var(--text-subtle); }
.deal-total-value{
  font-size:var(--fs-xl); line-height:1;
  font-weight:var(--fw-bold); color:var(--text-strong);
  font-variant-numeric:tabular-nums; letter-spacing:-.01em;
}
.deal-total-note{
  font-size:var(--fs-2xs); color:var(--warn, var(--text-muted));
  margin-top:2px;
}

/* Price breaks */
.breaks{ display:grid; gap:0; font-size:var(--fs-sm); }
.breaks .row{
  display:grid;
  grid-template-columns: 1fr 1fr 1fr 1fr;
  padding:10px 12px;
  border-radius:var(--radius-md);
  font-variant-numeric:tabular-nums;
  color:var(--text-mid);
  transition: background var(--duration-fast);
}
.breaks .row.h{ color:var(--text-subtle); font-size:var(--fs-2xs); text-transform:uppercase; letter-spacing:.08em; padding-bottom:6px; border-bottom:1px solid var(--border-subtle); border-radius:0; margin-bottom:4px; }
.breaks .row:not(.h):hover{ background:rgba(30,41,59,.45); }
/* P2.3a P6 — qty-break rows are clickable; show the affordance. */
.breaks .row.row-click{ cursor:pointer; }
.breaks .row.row-click:focus-visible{ outline:2px solid var(--accent-soft); outline-offset:2px; }
.breaks .row.cur{
  background:var(--accent-bg);
  color:var(--text-strong);
}
.breaks .row.cur .pv{ color:var(--accent-soft); font-weight:var(--fw-bold); }
.breaks .ta-r{ text-align:right; }

/* CTA stack */
.ctas{ display:grid; gap:var(--space-3); }
/* W10/T20 — order-time Mode A/B pick */
.lt-mode-pick{ display:flex; flex-direction:column; gap:6px; font-size:var(--fs-xs);
  color:var(--text-muted,#8b93a7); padding:2px 2px 0; }
.lt-mode-opt{ display:flex; align-items:center; gap:7px; cursor:pointer; }
.lt-mode-opt input{ accent-color:var(--accent,#2563eb); margin:0; }
.lt-mode-opt input:checked + span{ color:var(--text,#e5e9f2); font-weight:600; }
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
  padding:12px 18px; border-radius:var(--radius-md);
  font:var(--fw-semibold) var(--fs-sm)/1 var(--font-sans);
  cursor:pointer; border:1px solid transparent;
  transition: background var(--duration-base) var(--ease),
              border-color var(--duration-fast), color var(--duration-fast), transform var(--duration-fast);
  text-decoration:none;
}
.btn:active{ transform: translateY(1px); }
.btn-primary{
  background:var(--accent-strong); color:var(--accent-text,#fff);
}
.btn-primary:hover{ background:var(--accent); }
.btn-gradient{
  background:var(--gradient-cta); color:var(--accent-text,#fff); padding:14px 20px;
  font-size:var(--fs-base);
}
.btn-gradient:hover{ filter:brightness(1.08); }
.btn-ghost{
  background:transparent; color:var(--text); border-color:var(--border);
}
.btn-ghost:hover{ border-color:var(--border-strong); background:var(--bg-elevated); }
.btn-link{
  background:transparent; color:var(--text-muted); padding:8px 10px;
  font-weight:var(--fw-medium);
}
.btn-link:hover{ color:var(--accent); }
.btn-sm{ padding:6px 10px; font-size:var(--fs-xs); }

/* ─────────── Region pills ─────────── */
.regions{ display:flex; gap:var(--space-2); flex-wrap:wrap; }
.region{
  padding:10px 14px; border:1px solid var(--border); border-radius:var(--radius-lg);
  background:var(--bg-surface);
  display:grid; gap:2px; min-width:88px;
  cursor:pointer;
  transition: border-color var(--duration-fast), background var(--duration-fast);
}
.region:hover{ border-color:var(--border-strong); }
.region.active{ border-color:var(--accent); background:var(--accent-bg-soft); }
.region .flag{ font-size:var(--fs-2xs); text-transform:uppercase; letter-spacing:.08em; color:var(--text-muted); }
.region .v{ font-size:var(--fs-md); font-weight:var(--fw-bold); font-variant-numeric:tabular-nums; color:var(--text-strong); }
.region.usa   .v{ color:var(--accent-soft); }
.region.eu    .v{ color:var(--accent-2-soft); }
.region.china .v{ color:var(--warn-bright); }

/* ─────────── Custom note ─────────── */
.warn-inline{
  display:flex; align-items:center; gap:8px;
  font-size:var(--fs-xs); color:var(--warn);
  padding:8px 10px; border-radius:var(--radius-md);
  background:var(--warn-bg); border:1px solid var(--warn-border);
}

/* ─────────── Tabs variant ─────────── */
.tabs{
  display:flex; gap:4px;
  padding:4px; border-radius:var(--radius-md);
  background:var(--bg-sunken); border:1px solid var(--border-subtle);
  width:fit-content; margin-bottom:var(--space-5);
}
.tabs[hidden]{ display:none !important; }
.tabs button{
  padding:8px 14px; border:none; background:transparent;
  color:var(--text-muted); font:var(--fw-medium) var(--fs-xs)/1 var(--font-sans);
  border-radius:var(--radius-sm); cursor:pointer;
  transition: background var(--duration-fast), color var(--duration-fast);
}
.tabs button:hover{ color:var(--text); }
.tabs button.active{ background:var(--bg-elevated); color:var(--text-strong); box-shadow: inset 0 0 0 1px var(--border); }

/* Account + policy small panel (eng+admin) */
.acct{
  padding:var(--space-3) var(--space-4);
  border:1px solid var(--border-subtle); border-radius:var(--radius-md);
  background:var(--bg-sunken);
  font-size:var(--fs-xs); color:var(--text-muted);
  display:grid; gap:6px;
}
.acct .row{ display:flex; justify-content:space-between; gap:8px; }
.acct .row b{ color:var(--text-mid); font-weight:var(--fw-medium); }
.acct .row .val{ color:var(--text-strong); font-family:var(--font-mono); font-size:var(--fs-2xs); }

/* Feedback panel (admin-only) specifics */
.fb-checks{ display:grid; grid-template-columns:1fr 1fr; gap:4px; }

/* Floating Tweaks panel */
.tweaks{
  position:fixed; right:var(--space-5); bottom:var(--space-5);
  width:280px; z-index:80;
  background:var(--bg-elevated);
  border:1px solid var(--border-strong);
  border-radius:var(--radius-xl);
  padding:var(--space-4);
  font-size:var(--fs-xs);
  display:none;
  box-shadow: 0 10px 30px -10px rgba(0,0,0,.5);
}
.tweaks.open{ display:grid; gap:var(--space-3); }
.tweaks h4{
  margin:0 0 var(--space-1); font-size:var(--fs-xs); font-weight:var(--fw-semibold);
  color:var(--text-muted); text-transform:uppercase; letter-spacing:.08em;
}
.tweaks .seg{
  display:grid; grid-auto-flow:column; grid-auto-columns:1fr;
  gap:2px; padding:3px; background:var(--bg-sunken);
  border-radius:var(--radius-md); border:1px solid var(--border-subtle);
}
.tweaks .seg button{
  padding:6px 8px; border:none; background:transparent;
  color:var(--text-muted); font:var(--fw-medium) var(--fs-2xs)/1 var(--font-sans);
  border-radius:var(--radius-sm); cursor:pointer;
}
.tweaks .seg button.active{ background:var(--bg-surface); color:var(--text-strong); box-shadow: inset 0 0 0 1px var(--border); }

/* Right-column sticky */
.side{ position:sticky; top:calc(var(--header-h) + var(--space-4)); display:grid; gap:var(--space-4);
  /* S-ergo (2026-07-12): the rail is taller than the viewport on real quotes —
     give it its OWN scroll so the 3D viewer and part info are always reachable
     without scrolling the whole page. Popovers are position:fixed → unaffected. */
  max-height: calc(100vh - var(--header-h) - var(--space-6));
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  align-content: start;
  padding-right: 2px; }
/* QP1-3b: under-viewer part-info block — hidden until renderQuoteHeader() fills it. */
#resultBox:empty{ display:none; }

/* Viewer placeholder */
.viewer{
  aspect-ratio: 4/3;
  border-radius:var(--radius-xl);
  border:1px solid var(--border);
  background: var(--viewer-bg, #0d1526); /* S11: neutral flat viewer bed */
  display:grid; place-items:center; overflow:hidden;
  position:relative;
}
.viewer-ghost{
  width:60%; max-width:220px; aspect-ratio:1; opacity:.55;
}
.viewer-legend{
  position:absolute; left:10px; bottom:10px; right:10px;
  display:flex; flex-wrap:wrap; gap:4px 10px;
  font-size:var(--fs-3xs); color:var(--text-muted);
}
.viewer-legend span::before{
  content:"●"; margin-right:4px;
}
.viewer-legend .hl::before{ color:#ff3333; }
.viewer-legend .pk::before{ color:#ff8c1a; }
.viewer-legend .pr::before{ color:#f5cc1a; }
.viewer-legend .tr::before{ color:#80d3ff; }
.viewer-legend .sh::before{ color:#bf73ff; }
.viewer-legend .cy::before{ color:#4dc766; }
.viewer-legend .pl::before{ color:#737380; }

/* Section-anchor mode: hide section body via display none; used by "off" mode */
.panel[data-open="false"][data-mode="hidden"] .panel-body{ display:none; }

/* S-P1-h (Igor 2026-07-08) — provider «перейти в саму сделку» INSPECT view (/quote?pr_restore_deal):
   restore + rotate 3D + себестоимость only. Hide the order/recalc/export CTAs, the customer
   price-total banner, and the price eyebrow (the hero shows COST, not price). Gated on the body
   class set only when a provider opens the deal — customer/engineer/normal flows are unaffected. */
body.provider-deal-view #btnRecalc,
body.provider-deal-view #customerCtaBudgetary,
/* BETA-TRIAGE R3: the job-sheet download joins the hide list — the inspect view must not
   grow staff document controls. */
body.provider-deal-view #btnDlJobSheet,
body.provider-deal-view #dealTotalBlock,
/* the price hero (a customer element the engineer surface doesn't populate) and the ENGINEER
   breakdown (region-compare + debug JSON — internal tooling, and no-data once price is stripped)
   are hidden: the part-card already shows the provider's себестоимость (per-piece + ×qty), and the
   full cost-component breakdown lives on the provider board. The inspect view = geometry + 3D + cost. */
body.provider-deal-view #customerPriceHero,
body.provider-deal-view #breakdownSection{ display:none !important; }

/* BETA-TRIAGE R3 (R2 review, CONFIRMED): a REAL provider (incl. trial elevation, whose
   roleForView spoofs data-role="engineer" and would win the .eng-plus reveal) must not see
   the staff document buttons at all — visible dead controls are an inspect-contract
   regression. quote.js applyRoleBodyClass stamps body.real-provider from currentUser.role
   (the unspoofable string); class+id outranks the equally-!important .eng-plus reveal by
   source order AND specificity. */
body.real-provider #customerCtaBudgetary,
body.real-provider #btnDlJobSheet{ display:none !important; }

/* ============================================================================
   ERGO Stage A (2026-07-12) — selected-part strip · viewer-first rail · filter.
   Additive only; the role walls above are untouched.
   ============================================================================ */
.sel-strip{ display:flex; align-items:center; gap:10px; padding:9px 12px;
  background:var(--gradient-panel); border:1px solid var(--border,#334155);
  border-radius:var(--radius-xl,12px); }
.sel-strip[hidden]{ display:none; }
.ss-thumb{ width:38px; height:38px; flex:none; border-radius:var(--radius-md,8px);
  background:#111827; /* matches viewer canvas so thumbs blend */
  display:grid; place-items:center; overflow:hidden;
  border:1px solid var(--border-subtle); color:var(--text-subtle); }
.ss-thumb img{ width:100%; height:100%; object-fit:contain; display:block; }
.ss-thumb svg{ opacity:.7; }
.ss-meta{ min-width:0; flex:1; display:grid; gap:2px; }
.ss-name{ font-weight:var(--fw-semibold,600); font-size:var(--fs-xs,.78rem); color:var(--text-strong);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.ss-sub{ font-size:var(--fs-2xs,.72rem); color:var(--text-muted);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; font-variant-numeric:tabular-nums; }
.ss-price{ text-align:right; flex:none; display:grid; justify-items:end; }
.ss-unit{ font-weight:var(--fw-extrabold,800); font-variant-numeric:tabular-nums;
  color:var(--accent-soft); font-size:var(--fs-md,1.05rem); line-height:1.15; }
.ss-per{ font-size:var(--fs-3xs,.70rem); color:var(--text-subtle); }

.part-filter-wrap{ margin: 0 0 var(--space-3,12px); }
.part-filter-wrap[hidden]{ display:none; }
#partFilter{ margin-top:0; }
.part[data-filter-hidden="1"]{ display:none !important; }

/* part-info panel hides itself while renderQuoteHeader has not filled #resultBox
   (mirrors the old #resultBox:empty behavior at the panel level). */
.part-info-panel:has(#resultBox:empty){ display:none; }

/* ============================================================================
   BENCH — «Верстак» (concept 2a, Igor 2026-07-12). The zoned workbench grid.
   Scope: html[data-qlayout="bench"], SCREEN >=1281px only — print and narrow
   viewports always use the classic flow below/above. NO DOM was moved for this:
   .main becomes display:contents and the grid places the SAME panels into named
   zones. Every rule here is additive and inert while data-qlayout="classic".
   Zones: list = #p-parts · config = #p-specs · detail = #p-price (EOS tables +
   T12 flip charts get the full-width band) · proof = .side · extras (eng/admin).
   Zoom: html[data-qzoom="…"] expands ONE zone to the whole workspace (the same
   panels; hidden zones keep state — display:none, no unmount).
   ============================================================================ */
.zone-zoom{ display:none; }   /* visible only in bench (rule below) */
.zone-bar{ display:none; }
.page-topline{ display:flex; align-items:center; gap:var(--space-3); }
#qlayoutToggle{ font-size:var(--fs-2xs); color:var(--text-subtle); }
#qlayoutToggle:hover{ color:var(--text); }
.zone-restore{ font-size:var(--fs-2xs); color:var(--accent-soft); }
.zone-restore[hidden]{ display:none !important; }
.side-scroll{ display:contents; }   /* classic: the wrapper dissolves — zero layout change */
.extras-sheet{ display:contents; }  /* classic: same trick for the extras drawer shell */
.extras-tab, .extras-scrim{ display:none; }

/* ═══════════ EXTRAS DRAWER AT NARROW WIDTHS (Igor 2026-08-17) ═══════════
   Below the bench threshold the eng/admin extras column was killed outright
   (rule at line ~165: display:none !important), because as an IN-FLOW grid item
   at one-column widths it becomes a panel tower shoved ABOVE Parts. The side
   effect was that the whole engineer toolbox — #cutEnvPanel (cutting modes) and
   #pdfParsePanel (RFQ parse) — vanished for anyone on a tablet or a half-screen
   window, with no way in and no explanation. Measured on the stand at 1024x768,
   role=admin, BEFORE this block: .extras-col display:none / 0x0 / offsetParent
   null; #extrasTab ITSELF display:none / offsetParent null (the opener was
   invisible too); a forced extrasTab.click() flipped body[data-extras] to
   "open" and changed nothing at all.
   The fix is the drawer bench already has, not a "widen your window" apology:
   same tab + scrim + sheet + body[data-extras="open"] contract, driven by the
   SAME handlers (quote.js setupBenchLayout — they never read width or layout).
   Three deliberate scoping choices:
     · `screen` — print keeps the old path (the display:none !important above
       still wins on paper), so printing at narrow page widths is unchanged;
     · NOT keyed on data-qlayout — <html> can carry qlayout="bench" down here
       (that attribute has no width gate; the bench BLOCK is min-width:1281px),
       so keying on it would leave classic-at-1024 exactly as broken as before;
     · role-scoped, mirroring the rule it overrides — customers keep the base
       .extras-col display:none and never get a tab.
   The four data-qzoom hide-lists need no counterpart: zoom lives only inside
   the >=1281px bench block, so it cannot re-hide this column. */
@media screen and (max-width:1100px){
  body[data-role="engineer"] .extras-col,
  body[data-role="admin"] .extras-col{
    display:block !important;
    position:fixed; top:0; left:0; right:0; bottom:0; width:100vw; height:100vh; z-index:56;
    padding:0; margin:0; border:0; background:transparent;
    max-height:none; overflow:visible; pointer-events:none;
  }
  body[data-role="engineer"] .extras-tab,
  body[data-role="admin"] .extras-tab{
    display:flex; align-items:center; gap:6px;
    position:absolute; left:0; top:calc(var(--header-h) + 96px);
    pointer-events:auto; cursor:pointer;
    writing-mode:vertical-rl; transform:rotate(180deg);
    padding:12px 7px; border:1px solid var(--border); border-left:0;
    border-radius:0 var(--radius-md) var(--radius-md) 0;
    background:var(--bg-elevated); color:var(--text-muted);
    font-family:inherit; font-size:var(--fs-3xs); font-weight:var(--fw-semibold);
    letter-spacing:.12em; text-transform:uppercase;
  }
  body[data-role="engineer"] .extras-tab:hover,
  body[data-role="admin"] .extras-tab:hover{ color:var(--text); border-color:var(--border-strong); }
  body[data-role="engineer"] .extras-scrim,
  body[data-role="admin"] .extras-scrim{
    display:block; position:absolute; top:0; left:0; width:100%; height:100%;
    background:rgba(2,6,23,.45); opacity:0; pointer-events:none;
    transition:opacity var(--duration-base) var(--ease);
  }
  body[data-role="engineer"] .extras-sheet,
  body[data-role="admin"] .extras-sheet{
    display:grid; gap:var(--space-4); align-content:start;
    grid-auto-rows:max-content;   /* BENCH-6a: panels keep content height, the drawer scrolls */
    position:absolute; left:0; top:calc(var(--header-h) + 6px);
    height:calc(100vh - var(--header-h) - 12px);
    width:min(360px, 82vw);
    transform:translateX(calc(-100% - 16px));
    transition:transform var(--duration-slow) var(--ease);
    pointer-events:auto;
    padding:var(--space-3);
    background:var(--bg-surface);
    border:1px solid var(--border); border-left:0;
    border-radius:0 var(--radius-2xl) var(--radius-2xl) 0;
    box-shadow:var(--shadow-lg);
    overflow:hidden auto; overscroll-behavior:contain; scrollbar-width:thin;
  }
  /* Role in the selector on purpose: the closed-state rules above are already
     0-2-1, so the open state needs 0-3-1 to win without relying on order. */
  body[data-role="engineer"][data-extras="open"] .extras-scrim,
  body[data-role="admin"][data-extras="open"] .extras-scrim{ opacity:1; pointer-events:auto; }
  body[data-role="engineer"][data-extras="open"] .extras-sheet,
  body[data-role="admin"][data-extras="open"] .extras-sheet{ transform:translateX(0) !important; }
  /* Same tightening bench applies (quote.css ~1333): the panels were laid out
     for a 280px in-flow track, the drawer is 360px. */
  .extras-col .panel-body{ padding:var(--space-3) var(--space-3); }
}

@media screen and (min-width:1281px){
  /* ---- shell: page = viewport column, workspace = the flexing grid ---- */
  :root[data-qlayout="bench"] main.page{
    height: calc(100dvh - var(--header-h));
    display:flex; flex-direction:column; overflow:hidden;
    padding-bottom: var(--space-3);
  }
  :root[data-qlayout="bench"] .workspace{
    flex:1 1 auto; min-height:0;
    display:grid; gap:var(--space-3);
    grid-template-columns: minmax(260px,320px) minmax(0,1fr) minmax(320px,380px);
    grid-template-rows: minmax(0,1.1fr) minmax(0,0.9fr);
    /* BENCH-3 (Igor): detail sits UNDER config at the SAME width; proof is a full-
       height column — the 3D viewer and the price hero are both whole again. */
    grid-template-areas: "list config proof" "list detail proof";
    align-items:stretch;
  }
  /* BENCH-4 — eng/admin use the SAME 3-column grid as customer: the extras column
     became a slide-in drawer (below), so Parts keeps one width across roles. */

  /* ---- the .main wrapper dissolves; its panels become grid items ---- */
  :root[data-qlayout="bench"] .workspace > .main{ display:contents; }
  :root[data-qlayout="bench"] #p-parts{ grid-area:list; }
  :root[data-qlayout="bench"] #p-specs{ grid-area:config; }
  :root[data-qlayout="bench"] #p-price{ grid-area:detail; }
  :root[data-qlayout="bench"] .side{ grid-area:proof; }
  :root[data-qlayout="bench"] .extras-col{ grid-area:extras; }

  /* ---- one scroll owner per zone; unstick the rails (bench owns height) ---- */
  :root[data-qlayout="bench"] :is(#p-parts, #p-specs, #p-price){
    overflow:hidden auto; min-height:0; margin:0;
    overscroll-behavior:contain; scrollbar-width:thin;
  }
  /* BENCH-4 — extras drawer (history pattern): fixed shell, tab, scrim, sliding sheet.
     The ROLE GATE stays intact: the fixed-shell override below wins over the base
     display:none, so non-eng/admin roles are re-gated explicitly right after. */
  :root[data-qlayout="bench"] body:not([data-role="engineer"]):not([data-role="admin"]) .extras-col{
    display:none !important;
  }
  :root[data-qlayout="bench"] .extras-col{
    position:fixed; top:0; left:0; right:0; bottom:0; width:100vw; height:100vh; z-index:56;
    display:block; padding:0; margin:0; border:0; background:transparent;
    max-height:none; overflow:visible; pointer-events:none;
  }
  :root[data-qlayout="bench"] .extras-tab{
    display:flex; align-items:center; gap:6px;
    position:absolute; left:0; top:calc(var(--header-h) + 96px);
    pointer-events:auto; cursor:pointer;
    writing-mode:vertical-rl; transform:rotate(180deg);
    padding:12px 7px; border:1px solid var(--border); border-left:0;
    border-radius:0 var(--radius-md) var(--radius-md) 0;
    background:var(--bg-elevated); color:var(--text-muted);
    font-family:inherit; font-size:var(--fs-3xs); font-weight:var(--fw-semibold);
    letter-spacing:.12em; text-transform:uppercase;
  }
  :root[data-qlayout="bench"] .extras-tab:hover{ color:var(--text); border-color:var(--border-strong); }
  :root[data-qlayout="bench"] .extras-scrim{
    display:block; position:absolute; top:0; left:0; width:100%; height:100%;
    background:rgba(2,6,23,.45); opacity:0; pointer-events:none;
    transition:opacity var(--duration-base) var(--ease);
  }
  :root[data-qlayout="bench"] .extras-sheet{
    display:grid; gap:var(--space-4); align-content:start;
    /* BENCH-6a fix (Igor 2026-07-13): the drawer has a DEFINITE height and the
       panels use overflow:hidden (collapse clip), so their automatic minimum size
       is 0 — a plain auto-row grid then COMPRESSES the panels to fit the fixed
       height, clipping panel content (Stock's "Manual position"/Create button and
       the expanded Sheet-cut inputs were cut off, unreachable). Pin each panel row
       to its content height so panels stay whole and the drawer scrolls instead. */
    grid-auto-rows:max-content;
    position:absolute; left:0; top:calc(var(--header-h) + 6px);
    height:calc(100vh - var(--header-h) - 12px);
    width:min(360px, 82vw);
    transform:translateX(calc(-100% - 16px));
    transition:transform var(--duration-slow) var(--ease);
    pointer-events:auto;
    padding:var(--space-3);
    background:var(--bg-surface);
    border:1px solid var(--border); border-left:0;
    border-radius:0 var(--radius-2xl) var(--radius-2xl) 0;
    box-shadow:var(--shadow-lg);
    overflow:hidden auto; overscroll-behavior:contain; scrollbar-width:thin;
  }
  :root[data-qlayout="bench"] body[data-extras="open"] .extras-scrim{ opacity:1; pointer-events:auto; }
  :root[data-qlayout="bench"] body[data-extras="open"] .extras-sheet{ transform:translateX(0) !important; }
  /* BENCH-2 — the proof zone pins zone-bar + strip + 3D panel; ONLY the rest scrolls
     (.side-scroll). The 3D viewer never leaves the screen (Igor 2026-07-12). */
  :root[data-qlayout="bench"] .side{
    position:static; top:auto; max-height:none; min-height:0;
    display:flex; flex-direction:column; gap:var(--space-3);
    overflow:hidden;
  }
  :root[data-qlayout="bench"] .side > *{ flex:0 0 auto; min-height:0; }
  :root[data-qlayout="bench"] .side > .side-scroll{
    display:grid; gap:var(--space-3); align-content:start;
    flex:1 1 auto; min-height:0;
    overflow:hidden auto; overscroll-behavior:contain; scrollbar-width:thin;
    padding-right:2px;
  }
  :root[data-qlayout="bench"] .side #viewerContainer{ height:clamp(200px, 26vh, 330px); }
  /* panel headers stay pinned while a zone scrolls */
  :root[data-qlayout="bench"] :is(#p-parts, #p-specs, #p-price) > .panel-hdr{
    position:sticky; top:0; z-index:5;
    background:var(--bg-surface);
    border-bottom:1px solid var(--border-subtle);
  }

  /* ---- bench-only chrome ---- */
  :root[data-qlayout="bench"] .zone-zoom{
    display:inline-grid; place-items:center;
    width:24px; height:24px; padding:0; margin-left:auto;
    border:1px solid var(--border); border-radius:var(--radius-sm,6px);
    background:transparent; color:var(--text-subtle); cursor:pointer;
    flex:none;
  }
  :root[data-qlayout="bench"] .zone-zoom:hover{ color:var(--text); border-color:var(--border-strong); }
  :root[data-qlayout="bench"] .panel-hdr .zone-zoom + .chev{ margin-left:8px; }
  :root[data-qlayout="bench"] .zone-bar{
    display:flex; align-items:center; gap:var(--space-2);
    padding:6px 10px;
    border:1px solid var(--border-subtle); border-radius:var(--radius-lg,10px);
    background:var(--bg-sunken);
    font-size:var(--fs-2xs); color:var(--text-subtle);
    text-transform:uppercase; letter-spacing:.07em;
  }
  :root[data-qlayout="bench"] .zone-bar .zone-zoom{ margin-left:auto; }
  /* tabs mode is meaningless inside the zoned grid — collapse mode still works */
  :root[data-qlayout="bench"] #tabs{ display:none !important; }

  /* ---- zoom: one zone takes the whole workspace; others hide (state kept) ---- */
  :root[data-qlayout="bench"][data-qzoom] .workspace{
    grid-template-columns: minmax(0,1fr) !important;
    grid-template-rows: minmax(0,1fr) !important;
  }
  :root[data-qlayout="bench"][data-qzoom="list"]   .workspace{ grid-template-areas:"list" !important; }
  :root[data-qlayout="bench"][data-qzoom="config"] .workspace{ grid-template-areas:"config" !important; }
  :root[data-qlayout="bench"][data-qzoom="detail"] .workspace{ grid-template-areas:"detail" !important; }
  :root[data-qlayout="bench"][data-qzoom="proof"]  .workspace{ grid-template-areas:"proof" !important; }
  :root[data-qlayout="bench"][data-qzoom="list"]   :is(#p-specs,#p-price,.side,.extras-col){ display:none !important; }
  :root[data-qlayout="bench"][data-qzoom="config"] :is(#p-parts,#p-price,.side,.extras-col){ display:none !important; }
  :root[data-qlayout="bench"][data-qzoom="detail"] :is(#p-parts,#p-specs,.side,.extras-col){ display:none !important; }
  :root[data-qlayout="bench"][data-qzoom="proof"]  :is(#p-parts,#p-specs,#p-price,.extras-col){ display:none !important; }
  /* zoomed proof: give the viewer room to breathe */
  :root[data-qlayout="bench"][data-qzoom="proof"] .side #viewerContainer{ height:auto; min-height:56vh; }

  /* ---- BENCH-2 · in-section ergonomics ---- */
  /* Stock type (extras): the ACTIVE card keeps its full dim form; the other six
     collapse to one wrapping row of compact type-chips — no more 7-card tower. */
  :root[data-qlayout="bench"] #stockTypeCards{ display:flex; flex-wrap:wrap; gap:6px; }
  :root[data-qlayout="bench"] #stockTypeCards .stock-card{ flex:0 1 auto; }
  :root[data-qlayout="bench"] #stockTypeCards .stock-card.on{ flex:1 1 100%; order:-1; }
  :root[data-qlayout="bench"] #stockTypeCards .stock-card:not(.on) .stock-head{
    padding:5px 10px; gap:6px;
  }
  :root[data-qlayout="bench"] #stockTypeCards .stock-card:not(.on) :is(.sz, .src-badge, input[type="radio"]){
    display:none;
  }
  :root[data-qlayout="bench"] #stockTypeCards .stock-card:not(.on) .nm{
    font-size:var(--fs-2xs); color:var(--text-muted); white-space:nowrap;
  }
  :root[data-qlayout="bench"] #stockTypeCards .stock-card:not(.on):hover .nm{ color:var(--text); }

  /* Panels breathe tighter on the bench — the zones are the frame now. */
  :root[data-qlayout="bench"] :is(#p-specs, #p-price) .panel-body{
    padding:var(--space-3) var(--space-4);
  }
  :root[data-qlayout="bench"] .extras-col .panel-body{
    padding:var(--space-3) var(--space-3);
  }

  /* ---- BENCH-3 · in-section ergonomics (Igor pass 2) ---- */
  /* Specs triplet (roughness · tolerance · threads): the 3-col row collides at
     column width — stack the fields; segmented radios get the full line. */
  :root[data-qlayout="bench"] #p-specs .pnl-spec{
    grid-template-columns: minmax(0,1.05fr) minmax(0,1.35fr) minmax(0,.6fr);
    gap:var(--space-2);
  }
  :root[data-qlayout="bench"] #p-specs .pnl-seg{ flex-wrap:wrap; }
  /* BENCH-6 (Igor): Ra options as two even columns — reads calmer than a 3+1 wrap. */
  :root[data-qlayout="bench"] #p-specs .pnl-seg[data-seg="generalRoughnessKey"]{
    display:grid; grid-template-columns:1fr 1fr;
  }
  /* BENCH-6 — the "apply to subsequent" checkbox lives in the identity row (JS moves
     it in bench; returned in classic): compact two-line label, bottom-aligned. */
  :root[data-qlayout="bench"] .pnl-id{ align-items:end; }
  :root[data-qlayout="bench"] .pnl-id .check{
    font-size:var(--fs-2xs); color:var(--text-muted);
    line-height:1.35; max-width:300px; align-self:end; padding-bottom:8px;
  }

  /* Upload zone: vertical compact — nothing gets cut at list width. */
  :root[data-qlayout="bench"] #p-parts .upload{
    flex-direction:column; align-items:stretch; text-align:center;
    gap:var(--space-2); padding:var(--space-4) var(--space-3);
  }
  :root[data-qlayout="bench"] #p-parts .upload-ic{ margin:0 auto; width:36px; height:36px; }
  :root[data-qlayout="bench"] #p-parts .upload > .upload-body > strong{ font-size:var(--fs-xs); }
  :root[data-qlayout="bench"] #p-parts .upload > .upload-body > span{ font-size:var(--fs-2xs); }
  :root[data-qlayout="bench"] #p-parts .upload .btn{ width:100%; justify-content:center; }

  /* Part rows: the classic single-line grid can't carry name + dims + qty + price
     at list width — reuse the proven stacked form (same as the 720px rules). */
  /* S13 (Igor 2026-07-14) — compact card cleanup for the narrow Parts panel:
     (a) drop the 20px line-number COLUMN (it + its 16px gap shoved the thumb + info
         right) — the position number rides as a small corner badge on the thumbnail;
     (b) the kebab + delete were auto-flowing onto a 4th row — pin them to the card's
         top-right corner instead so the row count drops and nothing wraps. */
  :root[data-qlayout="bench"] #p-parts .part{
    position: relative;
    grid-template-columns: 64px minmax(0,1fr);   /* thumb · meta (idx is now a badge) */
    grid-template-rows: auto auto;
    column-gap: var(--space-3);
    row-gap: var(--space-2);
  }
  :root[data-qlayout="bench"] #p-parts .part-idx{
    position:absolute; top:calc(var(--space-3) + 3px); left:calc(var(--space-4) + 3px); z-index:2;
    min-width:14px; height:15px; line-height:15px; padding:0 4px;
    text-align:center; border-radius:999px;
    background:rgba(2,6,23,.72); color:var(--text-mid);
    font-size:10px; font-weight:var(--fw-semibold);
  }
  /* SA-4c (Igor: номера позиций не видны на светлой теме) — the pill keeps its
     hardcoded dark chrome, but var(--text-mid) resolves DARK on morning
     (#334155 on rgba(2,6,23,.72) ≈ 1.1:1). Force the theme-stable inverse. */
  :root[data-theme="morning"][data-qlayout="bench"] #p-parts .part-idx{
    color: var(--text-inverse);
  }
  :root[data-qlayout="bench"] #p-parts .part-meta{ padding-right:30px; }  /* clear the corner actions */
  :root[data-qlayout="bench"] #p-parts .part-qty{ grid-column:1 / -1; }
  :root[data-qlayout="bench"] #p-parts .part-price{ grid-column:1 / -1; text-align:left; }
  :root[data-qlayout="bench"] #p-parts .part-act{ position:absolute; right:var(--space-2); top:var(--space-2); z-index:2; }
  /* S14 (Igor) — stack the delete ✕ BELOW the kebab (same right edge), not to its left. */
  :root[data-qlayout="bench"] #p-parts .part-del-btn{ position:absolute; right:var(--space-2); top:calc(var(--space-2) + 30px); z-index:2; }
  :root[data-qlayout="bench"] #p-parts .part-meta-extra{ flex-wrap:wrap; }

  /* ---- BENCH-4 · proof-zone polish (Igor pass 3) ---- */
  /* Price hero: tighter frame, no inner scroll needed. */
  :root[data-qlayout="bench"] .side .price-hero{ padding:var(--space-4) var(--space-5); }
  /* LT mode pick: one compact left-aligned line per mode (no ragged two-line wrap). */
  :root[data-qlayout="bench"] .lt-mode-pick{
    flex-direction:row; flex-wrap:wrap; justify-content:flex-start;
    gap:6px 16px; text-align:left;
  }
  :root[data-qlayout="bench"] .lt-mode-opt{ white-space:nowrap; }
  /* BENCH-6 (Igor): the sticky CTA base painted a black band over the hero —
     removed; the full-height proof column keeps the CTA on screen by itself. */

  /* 3D panel: the zone-bar already names this zone — drop the panel's own header
     row; the canvas gets the space. The in-canvas text legend duplicates the layer
     pills — hidden; the pills become color DOTS (native title = hover description). */
  :root[data-qlayout="bench"] .side > section.panel:first-of-type > .panel-hdr{ display:none; }
  :root[data-qlayout="bench"] #viewerLegend{ display:none !important; }
  :root[data-qlayout="bench"] .viewer-legend{ display:none !important; }
  :root[data-qlayout="bench"] .viewer-toggles{ gap:8px; }
  :root[data-qlayout="bench"] .viewer-toggles .layer-tog{
    width:22px; height:22px; padding:0; gap:0;
    justify-content:center; border-radius:50%;
  }
  :root[data-qlayout="bench"] .viewer-toggles .layer-tog > span[data-i18n]{ display:none; }
}

/* SA-4c (Igor: «требования сливаются» на светлой теме) — morning's
   --text-subtle (#7c8aa0) is 3.54:1 on the white card, below AA for the
   fs-2xs metadata ramp. Scoped override (NOT a tokens.css change — zero
   blast radius on marketing pages): step these surfaces up to --text-muted
   (#5b6b7f, 5.45:1). Dark themes are untouched. */
:root[data-theme="morning"] .part-idx,
:root[data-theme="morning"] .part-dims,
:root[data-theme="morning"] .part-price .s{
  color: var(--text-muted);
}

/* ═══════════════════════════════════════════════════════════════════════════
   SA-REFINE — parse-result INSPECTOR (Igor 2026-07-19)

   A full-viewport layer, because the surface it replaces is a FIXED 280px grid
   track (.extras-col) that wraps an 11-column / 860px-min table to 2-3 words
   per cell. The visual language deliberately mirrors the bench extras drawer
   (scrim + elevated sheet + Esc) so this reads as the same «Инструменты» layer
   expanded, not as a foreign modal. Colours come from tokens only, so both
   themes follow automatically.
   ═══════════════════════════════════════════════════════════════════════════ */
.pi-layer{ position:fixed; inset:0; z-index:80; }
.pi-layer[hidden]{ display:none; }
.pi-scrim{ position:absolute; inset:0; background:rgba(2,6,23,.55); }
.pi-sheet{
  position:absolute; inset:calc(var(--header-h) + 8px) 12px 12px;
  display:flex; flex-direction:column; min-height:0;
  background:var(--bg-surface); color:var(--text);
  border:1px solid var(--border); border-radius:var(--radius-2xl);
  box-shadow:var(--shadow-lg); overflow:hidden;
}
.pi-hdr{
  display:flex; align-items:center; gap:var(--space-3);
  padding:var(--space-3) var(--space-4);
  border-bottom:1px solid var(--border); flex:0 0 auto;
}
.pi-hdr h2{ margin:0; font-size:var(--fs-sm); }
.pi-hdr .pi-sub{ color:var(--text-muted); font-size:var(--fs-2xs); flex:1 1 auto; min-width:0; }
.pi-close{ background:none; border:0; color:var(--text-muted); cursor:pointer; font-size:var(--fs-md); padding:2px 6px; }
.pi-close:hover{ color:var(--text); }
/* one scroll owner: the sheet is pinned, only the list moves */
.pi-body{ flex:1 1 auto; min-height:0; overflow:auto; padding:var(--space-3) var(--space-4); overscroll-behavior:contain; }

.pi-row{
  border:1px solid var(--border-subtle); border-radius:var(--radius-md);
  margin-bottom:var(--space-2); background:var(--bg-sunken);
}
.pi-row.flagged{ border-color:var(--warn, #f59e0b); }
.pi-row-hdr{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; padding:8px 10px; cursor:pointer; }
.pi-chev{ transition:transform var(--duration-base) var(--ease); color:var(--text-muted); }
.pi-row.on .pi-chev{ transform:rotate(90deg); }
.pi-file{ font-weight:var(--fw-semibold); font-size:var(--fs-xs); overflow-wrap:anywhere; }
.pi-mini{ color:var(--text-muted); font-size:var(--fs-2xs); }
.pi-detail{ display:none; }
/* the expand zone — same idiom as the stock cards, but it finally has room */
.pi-row.on .pi-detail{
  display:grid; gap:var(--space-3); padding:0 10px 10px;
  grid-template-columns:repeat(auto-fit, minmax(320px, 1fr));
}
.pi-grp{ border-top:1px solid var(--border-subtle); padding-top:8px; min-width:0; }
.pi-grp h4{
  margin:0 0 6px; font-size:var(--fs-2xs); text-transform:uppercase;
  letter-spacing:.08em; color:var(--text-muted);
}

/* raw → mapped, the core of the whole surface */
.pi-f{
  display:grid; grid-template-columns:minmax(88px,auto) 1fr 12px 1fr;
  gap:2px 8px; align-items:baseline; padding:3px 0; font-size:var(--fs-2xs);
}
.pi-f.warn .pi-f-map{ color:var(--warn, #f59e0b); }
.pi-f-l{ color:var(--text-muted); }
.pi-f-raw{ font-family:var(--font-mono, ui-monospace, monospace); overflow-wrap:anywhere; opacity:.85; }
.pi-f-arr{ color:var(--text-subtle); }
.pi-f-map{ font-weight:var(--fw-semibold); overflow-wrap:anywhere; }
.pi-f-n{ grid-column:2 / -1; color:var(--text-subtle); }
.pi-sub2{
  margin-top:6px; color:var(--text-muted); font-size:var(--fs-3xs);
  text-transform:uppercase; letter-spacing:.06em;
}
.pi-note{ margin-top:6px; font-size:var(--fs-2xs); color:var(--text-muted); }
.pi-none{ font-size:var(--fs-2xs); color:var(--text-subtle); padding:4px 0; }

.pi-cands{ width:100%; border-collapse:collapse; font-size:var(--fs-2xs); margin-top:2px; }
.pi-cands td{ padding:2px 4px; border-top:1px solid var(--border-subtle); }
.pi-cands tr.on{ background:rgba(148,163,184,.14); font-weight:var(--fw-semibold); }
.pi-c-id{ width:52px; color:var(--text-muted); }
.pi-c-n{ overflow-wrap:anywhere; }
.pi-c-s{ width:56px; text-align:right; font-variant-numeric:tabular-nums; }
.pi-c-m{ width:16px; text-align:center; }

.pi-open-row{
  background:none; border:1px solid var(--border-subtle); border-radius:4px;
  color:var(--text-muted); cursor:pointer; font-size:var(--fs-3xs);
  padding:0 4px; line-height:1.5;
}
.pi-open-row:hover{ color:var(--text); border-color:var(--border-strong); }

@media (max-width: 900px){
  .pi-sheet{ inset:calc(var(--header-h) + 4px) 4px 4px; }
  .pi-row.on .pi-detail{ grid-template-columns:1fr; }
}

/* ═══ WAVE K / K1+K2 — main-part (assembly) mode ═══════════════════════════════ */
/* The row grid gains a 30px column ONLY when the list carries data-asm (set by
   renderAssemblyBar for engineer/admin/advanced). Customer lists keep the pre-wave
   7-column template untouched. */
.partlist[data-asm="1"] .part{ grid-template-columns: 30px 28px 64px 1fr 110px 140px 32px 32px; }
.part-asm{ display:flex; flex-direction:column; align-items:center; gap:6px; }
.part-asm-empty{ min-height:1px; }
.part-asm .asm-inc{ margin:0; cursor:pointer; accent-color:var(--accent); }
.asm-main{
  background:transparent; border:none; cursor:pointer; padding:2px;
  color:var(--text-subtle); border-radius:var(--radius-sm);
  display:grid; place-items:center;
}
.asm-main:hover{ color:var(--warn-bright, #f59e0b); }
.asm-main.is-main{ color:var(--warn-bright, #f59e0b); }
.part-asm-note{ font-size:var(--fs-3xs); color:var(--warn-bright, #f59e0b); margin-top:2px; }
.asm-bar{
  display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  padding:7px 10px; margin-bottom:8px;
  border:1px dashed var(--border-strong); border-radius:var(--radius-md);
  background:var(--bg-elevated); font-size:var(--fs-2xs);
}
.asm-bar[hidden]{ display:none; }
.asm-bar-t{ font-weight:var(--fw-semibold); }
.asm-bar-main{ color:var(--warn-bright, #f59e0b); font-weight:var(--fw-semibold); }
.asm-bar-hint{ color:var(--text-muted); flex:1 1 auto; }

/* ═══ WAVE K / K3 — aggregated-material hint ═══════════════════════════════════ */
/* AR2-S10 reveals every .eng-section to 'advanced'; the volume hint is a staff-only
   cost figure (endpoint 403s advanced), so this wrapper opts back OUT for them. */
body[data-role="advanced"] .matagg-wrap{ display:none !important; }
.matagg-box{ display:flex; flex-direction:column; gap:8px; margin-top:8px; font-size:var(--fs-2xs); }
.matagg-box:empty{ display:none; }
.matagg-g{ border:1px solid var(--border); border-radius:var(--radius-md); padding:7px 10px; background:var(--bg-surface); }
.matagg-h{ font-weight:var(--fw-semibold); }
.matagg-m{ color:var(--text-muted); margin-top:2px; overflow-wrap:anywhere; }
.matagg-n{ margin-top:4px; }
.matagg-foot{ color:var(--text-subtle); font-size:var(--fs-3xs); }
.matagg-warn{ margin-top:4px; color:var(--warn-bright, #f59e0b); }
.part-asm-note.danger{ color:var(--danger, #ef4444); }

/* ═══════════ ENG-LANE (2026-08-14) — cutting-modes panel #cutEnvPanel ═══════════ */
/* Контр-стена (паттерн BETA-TRIAGE R3, ср. body.real-provider выше): roleForView
   спуфится — триал-провайдер И deal-inspect несут data-role=engineer и выигрывают
   .eng-plus-reveal, но физику себестоимости РЕАЛЬНЫЙ провайдер видеть не должен.
   body.real-provider штампуется из currentUser.role (SA-3a, неспуфится); бэкенд
   403-ит по реальной роли — CSS здесь лишь гасит мёртвые контролы. */
body.real-provider #cutEnvPanel{ display:none !important; }

#cutEnvPanel .panel-body{ display:grid; }
.cutenv-grid{ display:grid; grid-template-columns:minmax(200px,2fr) 1fr 1.3fr; gap:var(--space-2); }
.cutenv-machine{ display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:var(--space-2); margin-top:4px; }
.cutenv-field{ display:flex; flex-direction:column; gap:2px; min-width:0; }
.cutenv-field input, .cutenv-field select{ width:100%; min-width:0; }
@media (max-width:760px){ .cutenv-grid, .cutenv-machine{ grid-template-columns:1fr 1fr; } }
.cutenv-src{ font-size:var(--fs-xs); color:var(--text-mid); min-height:1em; }
.cutenv-src.table{ color:var(--warn-bright, #f59e0b); }
.cutenv-sliders{ display:grid; grid-template-columns:1fr 1fr; gap:var(--space-3); }
.cutenv-slider input[type="range"]{ width:100%; accent-color:var(--accent); }
.cutenv-sv{ font-family:var(--font-mono); font-variant-numeric:tabular-nums; color:var(--text-strong); }
.cutenv-status{ font-size:var(--fs-xs); color:var(--text-subtle); min-height:1em; }
.cutenv-status.err{ color:var(--danger, #ef4444); }
.cutenv-sol{ font-size:var(--fs-2xs); color:var(--text-muted); font-family:var(--font-mono); overflow-wrap:anywhere; }
.cutenv-out{ display:grid; gap:3px; font-size:var(--fs-xs); }
.cutenv-row{ display:grid; grid-template-columns:minmax(150px,auto) minmax(90px,auto) 1fr; gap:var(--space-2); align-items:baseline; }
.cutenv-row .v{ font-family:var(--font-mono); font-variant-numeric:tabular-nums; color:var(--text-strong); text-align:right; white-space:nowrap; }
.cutenv-row .n{ font-size:var(--fs-2xs); color:var(--text-subtle); }
.cutenv-badges{ display:flex; flex-wrap:wrap; gap:var(--space-2); align-items:center; }
.cutenv-fzwrap{ display:grid; gap:2px; }
.cutenv-fzbar{ position:relative; height:8px; border-radius:var(--radius-pill); background:var(--bg-sunken); border:1px solid var(--border-subtle); }
.cutenv-fzbar .band{ position:absolute; top:0; bottom:0; background:var(--ok-bg); border-left:1px solid var(--ok-border); border-right:1px solid var(--ok-border); }
.cutenv-fzbar .mark{ position:absolute; top:-3px; width:2px; height:14px; background:var(--accent-strong); border-radius:1px; }
.cutenv-fzbar .mark.out{ background:var(--warn-bright, #f59e0b); }
.cutenv-envnote{ font-size:var(--fs-2xs); color:var(--text-subtle); }
.cutenv-sweep{ display:grid; grid-template-columns:repeat(21,10px); grid-auto-rows:10px; gap:1px; margin-top:4px; width:max-content; }
.cutenv-cell{ border-radius:1px; background:var(--bg-sunken); cursor:pointer; }
.cutenv-cell.ok{ background:var(--ok-border); }
.cutenv-cell.band{ background:var(--warn-border); }
.cutenv-cell.bad{ background:var(--danger-border); }
.cutenv-cell.cur{ outline:2px solid var(--accent-strong); outline-offset:0; }
.cutenv-legend{ display:flex; gap:var(--space-3); font-size:var(--fs-2xs); color:var(--text-subtle); margin-top:4px; flex-wrap:wrap; }
.cutenv-legend > span{ display:inline-flex; align-items:center; gap:4px; }
.cutenv-dot{ display:inline-block; width:8px; height:8px; border-radius:2px; }
.cutenv-dot.ok{ background:var(--ok-border); }
.cutenv-dot.band{ background:var(--warn-border); }
.cutenv-dot.bad{ background:var(--danger-border); }
.cutenv-warn{ font-size:var(--fs-2xs); color:var(--warn-bright, #f59e0b); }
