/* benchstamp.css — page-scoped LAYOUT for the BenchStamp desktop-instrument shell.
 *
 * benchstamp.theme.css is variables-only (by its own contract). This file holds
 * the layout rules: BenchStamp is a desktop instrument (design/ §0), so its work
 * surface — not the page — owns the vertical space. The platform frame runs
 * document-flow by default (class.ui.css PAGE-FRAME block); these rules are scoped
 * to `body[data-system="benchstamp"]` so that global default is untouched.
 *
 * The fill chain (design/ §4): stage → page-host → _renderTabs wrappers →
 * control-stage all grow to fill, so module pages reach the footer with no white
 * gulf. Mirrors the per-system fill pattern (EthiKit/RiverHealth/NeuroPlay/PublonPress). */

/* The body is display:block by default, so a flex child can't grow in it — make
   it a flex column first (this is the link that actually unlocks the fill). */
body[data-system="benchstamp"] .ui-pageframe-body {
    display: flex; flex-direction: column; min-height: 0;
}

/* Stage fills the body; every wrapper between it and the content is a flex column
   that grows. (The generic .ui wrapper between stage and content is display:block
   by default, which would pin content to its min-height — force it to flex.) */
body[data-system="benchstamp"] .ui-pageframe-stage,
body[data-system="benchstamp"] .ui-pageframe-stage > .ui,
body[data-system="benchstamp"] .ui-hub-page-host {
    display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0;
}

/* The control-stage is a CSS grid; give its single row a flex track so the two
   columns stretch to the grown height (grid implicit rows are content-sized). */
body[data-system="benchstamp"] .ui-control-stage {
    flex: 1 1 auto; min-height: 0; grid-template-rows: minmax(0, 1fr);
}

/* A utility wrapper used by _renderTabs as the stage host. */
body[data-system="benchstamp"] .ui-pageframe-stage .ui-flex-1 { min-height: 0; }

/* ── F2 — pane shell (design/ §0) ──────────────────────────────────────────
   The work surface is one continuous set of panes divided by 1px hairlines, not
   floating cards on an exposed page. Kill the grid gap; hairline between the
   control column and the stage; give the stage a surface that fills (so short
   content like the Methods scope-matrix leaves pane-surface, not page, below it);
   flatten content cards into flat pane sections (no shadow, no rounding) — object
   cards keep a hairline for separation but lose the web-card elevation. */
body[data-system="benchstamp"] .ui-control-stage { gap: 0; }
body[data-system="benchstamp"] .ui-control-stage-control {
    border-right: 1px solid var(--ui-gray-200, #e5e7eb);
    padding-right: var(--ui-space-3);
}
body[data-system="benchstamp"] .ui-control-stage-stage {
    padding-left: var(--ui-space-4);
    background: var(--ui-surface, #fff);
}
/* Flatten elevation on every card inside the work surface — regions read as
   panes, object cards read as dense flat tiles. Hairline kept for separation. */
body[data-system="benchstamp"] .ui-control-stage .ui-card {
    box-shadow: none; border-radius: 0;
}
/* The region-level cards (direct content of a pane) shed their box entirely and
   sit on the pane surface, so the central visual fills edge-to-edge. */
body[data-system="benchstamp"] .ui-control-stage-stage > .ui > .ui-card,
body[data-system="benchstamp"] .ui-control-stage-stage > .ui-card {
    border: none; background: transparent; padding-left: 0; padding-right: 0;
}

/* F2b — central visual fills the pane height (design/ §3/§4). The kanban chart
   frame already fills (height:100% chain), but the `.ui-kanban` wrap inside it
   has no flex-grow, so it sized to content and left white below. Make the wrap
   grow; its `align-items:stretch` then makes the lanes full-height columns (the
   correct board look — full-height drop zones). Page-scoped to BenchStamp. */
body[data-system="benchstamp"] .ui-kanban { flex: 1 1 auto; min-height: 0; }

/* ── F3/F4 — config-driven instrument chrome (the service opts in via
   `integratedChrome:'instrument'`; these style the variant it emits) ──────── */
/* F4: metrics as a 24px status bar pinned to the page's bottom edge (design/
   §0 micro-3) instead of a top strip — flat, hairline-topped, never grows. */
body[data-system="benchstamp"] .ui-int-statusbar {
    flex: 0 0 auto; min-height: 24px;
    padding: 4px 12px; margin: 0;
    border-top: 1px solid var(--ui-gray-200, #e5e7eb);
    background: var(--ui-gray-50, #f9fafb);
    font-size: var(--ui-text-xs, 11px);
}
/* F3: create-buttons as a compact toolbar at the top of the list column, reading
   as the list's own chrome rather than a fat button row on its own line. */
body[data-system="benchstamp"] .ui-int-toolbar { margin-bottom: 6px; }
body[data-system="benchstamp"] .ui-int-toolbar .ui-btn {
    flex: 0 0 auto;   /* override services' ui-flex-1 so buttons size to content */
    padding: 3px 8px; font-size: var(--ui-text-xs, 11px); border-radius: var(--ui-radius-base, 4px);
}

/* ── Three-workspace area tabs (2026-06-12 rebuild) ────────────────────────
   Areas are a tab strip at the TOP of the workspace (design §0/§9: navigation
   in the top strip, not a side rail); the stage fills below. */
/* Area tabs = the SECOND tab level, a tabset at the top of the workspace BODY
   (design §20) — the nav bar keeps only the workspace tabs. The stage fills below. */
body[data-system="benchstamp"] .bs-ws-nav { flex: 0 0 auto; border-bottom: 1px solid var(--ui-gray-200, #e5e7eb); margin-bottom: var(--ui-space-2); }
/* Workflow workbench (shared ui-cw-workbench, 3-pane flex row) overflows at
   1440px — its 3 panes sum past the viewport, pushing the instance-detail pane
   off-screen-right so it reads as a gulf. Page-scoped only (AutoScholar's own
   width is untouched): wrap so the Processes list + the instance detail share
   the top row, with the wide WIP board dropping full-width below. Paired with the
   service's auto-select-first-instance, the detail now reads populated on entry. */
body[data-system="benchstamp"] .ui-cw-workbench { flex-wrap: wrap; }
body[data-system="benchstamp"] .ui-cw-pane-left   { order: 0; }
body[data-system="benchstamp"] .ui-cw-pane-right  { order: 1; flex: 1 1 360px; min-width: 0; }
body[data-system="benchstamp"] .ui-cw-pane-center { order: 2; flex: 1 1 100%; }
/* The workspace stage fills below the area tabs. */
body[data-system="benchstamp"] .bs-ws-stage { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; min-width: 0; }
/* The control-stage's stage column fills and scrolls — so the Lineage graph
   (central element) and the dossier below it flow at natural height, the column
   scrolling when together they exceed the viewport. */
body[data-system="benchstamp"] .bs-ws-stage .ui-control-stage-stage { overflow: auto; min-height: 0; }
body[data-system="benchstamp"] .bs-ws-stage .ui-chart-host { min-height: 360px; }

/* ── Lineage: graph on top (dominant central element), dossier below ────────
   Natural-height flow — a forced percentage split left a white gap, so sizing
   is left to content; a hairline separates the dossier from the graph. */
body[data-system="benchstamp"] .bs-lin-graph { flex: 0 0 auto; display: flex; flex-direction: column; }
body[data-system="benchstamp"] .bs-lin-dossier {
    flex: 0 0 auto; display: block;
    border-top: 1px solid var(--ui-gray-200, #e5e7eb);
    padding-top: var(--ui-space-3); margin-top: var(--ui-space-2);
}
body[data-system="benchstamp"] .bs-lin-dossier .ui-card { display: block; }

/* Lineage control column = Project / Samples accordion. The open pane's body
   scrolls so a long project list or specimen tree stays inside the column. */
body[data-system="benchstamp"] .ui-control-stage-control .ui-accordion { display: flex; flex-direction: column; min-height: 0; }
body[data-system="benchstamp"] .ui-control-stage-control .ui-accordion-item.ui-active { display: flex; flex-direction: column; min-height: 0; flex: 1 1 auto; }
body[data-system="benchstamp"] .ui-control-stage-control .ui-accordion-body { overflow: auto; min-height: 0; }
body[data-system="benchstamp"] .bs-dossier-grid {
    display: grid; grid-template-columns: repeat(3, 1fr);
    gap: var(--ui-space-2) var(--ui-space-4); margin-top: var(--ui-space-1);
}
/* Dossier as a parallel facet surface (design §2b): header + two packed columns. */
body[data-system="benchstamp"] .bs-dossier-head {
    padding: 2px 2px 6px; margin-bottom: var(--ui-space-2);
    border-bottom: 1px solid var(--ui-gray-200, #e5e7eb);
}
body[data-system="benchstamp"] .bs-dossier-facets { column-count: 2; column-gap: var(--ui-space-3); }
@media (max-width: 1180px) { body[data-system="benchstamp"] .bs-dossier-facets { column-count: 1; } }
body[data-system="benchstamp"] .bs-dossier-facets > * {
    break-inside: avoid; -webkit-column-break-inside: avoid; display: block; width: 100%;
    margin: 0 0 var(--ui-space-3) !important;
}
body[data-system="benchstamp"] .bs-lin-flagrow {
    padding: 4px 0; border-bottom: 1px solid var(--ui-gray-100, #f1f5f9);
}
body[data-system="benchstamp"] .bs-lin-flagrow-sel {
    background: var(--ui-gray-50, #f9fafb); padding-left: 6px; border-left: 3px solid var(--hp-accent, #1565C0);
}

/* ── Hazard flag chips (data-driven semantic palette, mirrors _renderHazards) ── */
body[data-system="benchstamp"] .bs-haz-flag {
    display: inline-block; padding: 1px 8px; border-radius: 999px;
    font-size: var(--ui-text-xs, 11px); font-weight: 600; white-space: nowrap;
}
body[data-system="benchstamp"] .bs-haz-none      { background: #94a3b81a; color: #64748b; border: 1px solid #cbd5e1; }
body[data-system="benchstamp"] .bs-haz-chemical  { background: #6366f11a; color: #6366f1; border: 1px solid #6366f1; }
body[data-system="benchstamp"] .bs-haz-biohazard { background: #db27771a; color: #db2777; border: 1px solid #db2777; }
body[data-system="benchstamp"] .bs-haz-radio     { background: #eab3081a; color: #a16207; border: 1px solid #eab308; }
body[data-system="benchstamp"] .bs-haz-pyro      { background: #dc26261a; color: #dc2626; border: 1px solid #dc2626; }
body[data-system="benchstamp"] .bs-haz-cryogenic { background: #06b6d41a; color: #0891b2; border: 1px solid #06b6d4; }

/* ── Storage area = location tree (fills) above the hazard inventory ────────
   (2026-06-13 streamline: the Hazards tab folded in here.) */
body[data-system="benchstamp"] .bs-storage-stack {
    flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; overflow: auto; gap: var(--ui-space-3);
}
body[data-system="benchstamp"] .bs-storage-stack > .bs-stack-loc { flex: 1 1 auto; min-height: 360px; }
body[data-system="benchstamp"] .bs-storage-stack > .bs-stack-haz {
    flex: 0 0 auto; border-top: 1px solid var(--ui-gray-200, #e5e7eb); padding-top: var(--ui-space-3);
}

/* ── Sub-tabs (Sign-off) — a compact segmented pill row, lighter than the
   workspace area tabs so the nested switch doesn't read as a third nav bar. ── */
body[data-system="benchstamp"] .bs-subwrap { flex: 1 1 auto; min-height: 0; }
body[data-system="benchstamp"] .bs-subtabs {
    flex: 0 0 auto; padding: var(--ui-space-1) 0 var(--ui-space-2);
}
body[data-system="benchstamp"] .bs-subtabs .ui-tabs {
    display: inline-flex; gap: 2px; padding: 2px; border-radius: 999px;
    background: var(--ui-gray-100, #f1f5f9);
}
body[data-system="benchstamp"] .bs-subtabs .ui-tab {
    border: none; border-radius: 999px; padding: 3px 14px; font-size: var(--ui-text-xs, 11px);
}
body[data-system="benchstamp"] .bs-subtabs .ui-tab-active {
    background: var(--ui-surface, #fff); box-shadow: var(--ui-shadow-sm, 0 1px 2px rgba(0,0,0,.08));
}

/* Sample-lineage graph — matrix colour legend strip above the canvas. */
body[data-system="benchstamp"] .bs-graph-legend {
    display: flex; flex-wrap: wrap; gap: 4px 14px; padding: 2px 4px 8px;
    font-size: var(--ui-text-xs, 11px); color: var(--ui-gray-600, #475569);
}
body[data-system="benchstamp"] .bs-graph-legkey { display: inline-flex; align-items: center; gap: 5px; text-transform: capitalize; }
body[data-system="benchstamp"] .bs-graph-legkey i { width: 11px; height: 11px; border-radius: 999px; display: inline-block; border: 1px solid rgba(0,0,0,.15); }
body[data-system="benchstamp"] .bs-graph-leg-haz i { background: transparent; border: 2px solid #dc2626; }

/* Certificate of Analysis — on-screen document (mirrors the print layout). */
body[data-system="benchstamp"] .bs-coa { background:#fff; padding:20px 24px; max-width:760px; }
body[data-system="benchstamp"] .bs-coa-head { display:flex; justify-content:space-between; align-items:flex-start; border-bottom:3px solid var(--hp-accent,#1565C0); padding-bottom:10px; }
body[data-system="benchstamp"] .bs-coa-lab { font-size:20px; font-weight:800; }
body[data-system="benchstamp"] .bs-coa-sub { font-size:12px; color:var(--ui-gray-500,#475569); letter-spacing:.08em; text-transform:uppercase; }
body[data-system="benchstamp"] .bs-coa-qr { text-align:right; }
body[data-system="benchstamp"] .bs-coa-qr img { width:72px; height:72px; image-rendering:pixelated; }
body[data-system="benchstamp"] .bs-coa-num { font-weight:700; font-size:12px; }
body[data-system="benchstamp"] .bs-coa-meta { width:100%; margin:14px 0; border-collapse:collapse; font-size:12px; }
body[data-system="benchstamp"] .bs-coa-meta td { padding:3px 6px; }
body[data-system="benchstamp"] .bs-coa-meta td:nth-child(odd) { color:var(--ui-gray-500,#64748b); width:80px; }
body[data-system="benchstamp"] .bs-coa-results { width:100%; border-collapse:collapse; font-size:12px; margin-top:8px; }
body[data-system="benchstamp"] .bs-coa-results th { background:var(--ui-gray-100,#f1f5f9); text-align:left; padding:6px 8px; border:1px solid var(--ui-gray-300,#cbd5e1); }
body[data-system="benchstamp"] .bs-coa-results td { padding:6px 8px; border:1px solid var(--ui-gray-200,#e2e8f0); }
body[data-system="benchstamp"] .bs-coa-sign { display:flex; gap:60px; margin-top:40px; }
body[data-system="benchstamp"] .bs-coa-sigline { border-top:1px solid #0f172a; padding-top:4px; font-weight:600; font-size:12px; min-width:200px; }
body[data-system="benchstamp"] .bs-coa-sigrole { font-size:10px; color:var(--ui-gray-500,#64748b); }
body[data-system="benchstamp"] .bs-coa-foot { margin-top:28px; font-size:10px; color:var(--ui-gray-500,#64748b); border-top:1px solid var(--ui-gray-200,#e2e8f0); padding-top:8px; }
body[data-system="benchstamp"] .bs-coa-doc { flex:1 1 auto; min-height:0; }

/* Results control chart (R3). */
body[data-system="benchstamp"] .bs-result-chart .ui-rb-chart { height: 320px; width: 100%; }

/* Dossier results table + spec-flag chips. */
/* Process map (vis-network) — the shared .ui-chart-graph defaults to a tall
   clamp height that leaves the single-row flow bottom-anchored with a big blank.
   Pin it to a compact height so the flow fills the box. Scoped to the map host. */
.pf-stepmap-host .ui-chart, .pf-stepmap-host .ui-chart-frame { height: 220px !important; min-height: 0 !important; }
/* Lineage control-panel sample section — the selected sample's facts + QR in the
   free space below the project/samples accordion. Divider sets it off; the QR card
   sits flush to the narrow control column. */
body[data-system="benchstamp"] .bs-lin-ctl-sample { margin-top: var(--ui-space-3); padding-top: var(--ui-space-3); border-top: 1px solid var(--ui-gray-200, #e5e7eb); }
body[data-system="benchstamp"] .bs-lin-ctl-facts { margin-bottom: var(--ui-space-1); }
body[data-system="benchstamp"] .bs-lin-ctl-sample .ui-card { margin-top: var(--ui-space-2) !important; }
/* Record-pane context panel — the related rows under the edit form. A divider
   sets it off; titles are compact. (design §21: fill purposefully.) */
body[data-system="benchstamp"] .bs-rel-panel { margin-top: var(--ui-space-3); padding-top: var(--ui-space-3); border-top: 1px solid var(--ui-gray-200, #e5e7eb); }
body[data-system="benchstamp"] .bs-rel-title { color: var(--ui-gray-700, #334155); }
body[data-system="benchstamp"] .bs-result-table { width: 100%; border-collapse: collapse; }
body[data-system="benchstamp"] .bs-result-table th { text-align: left; font-weight: 600; color: var(--ui-gray-500, #64748b); border-bottom: 1px solid var(--ui-gray-200, #e5e7eb); padding: 3px 8px; }
body[data-system="benchstamp"] .bs-result-table td { padding: 3px 8px; border-bottom: 1px solid var(--ui-gray-100, #f1f5f9); }
body[data-system="benchstamp"] .bs-rflag { display: inline-block; padding: 0 7px; border-radius: 999px; font-size: var(--ui-text-xs, 11px); font-weight: 600; white-space: nowrap; }
body[data-system="benchstamp"] .bs-rflag-ok        { background: #16a34a1a; color: #16a34a; border: 1px solid #16a34a; }
body[data-system="benchstamp"] .bs-rflag-high      { background: #dc26261a; color: #dc2626; border: 1px solid #dc2626; }
body[data-system="benchstamp"] .bs-rflag-low       { background: #ea580c1a; color: #ea580c; border: 1px solid #ea580c; }
body[data-system="benchstamp"] .bs-rflag-outlier   { background: #9333ea1a; color: #9333ea; border: 1px solid #9333ea; }
body[data-system="benchstamp"] .bs-rflag-nocontrol { background: #64748b1a; color: #64748b; border: 1px solid #64748b; }
body[data-system="benchstamp"] .bs-rflag-pending   { background: #94a3b81a; color: #94a3b8; border: 1px solid #cbd5e1; }

/* Dossier QR panel — keep the sample QR a tidy fixed size. */
body[data-system="benchstamp"] .bs-qr-img { flex: 0 0 auto; }
body[data-system="benchstamp"] .bs-qr-img img { width: 96px; height: 96px; image-rendering: pixelated; display: block; }

/* About meta-workspace overview scrolls within its area stage. */
body[data-system="benchstamp"] .bs-about-scroll { flex: 1 1 auto; min-height: 0; overflow: auto; }

/* Sign-off = the two release gates as parallel columns (Approvals | Review).
   Each column is a compact record-stage; on a narrow viewport they stack. */
body[data-system="benchstamp"] .bs-signoff-cols > * { min-width: 0; }
@media (max-width: 1100px) { body[data-system="benchstamp"] .bs-signoff-cols { flex-wrap: wrap; } }

/* ── Compact list anatomy, system-wide (design §0 desktop-instrument) ──────────
   The shared ListLayout's `compact` flag is opt-in (default off). Rather than
   thread `compact:true` through every call site — including the shared Analysis
   service views (procedure/runbook/qc/capability) BenchStamp does not own — we
   force the one-line compact anatomy on EVERY list inside this system. Page-
   scoped, additive: mirrors `.ui-bind-list--compact` (class.ui.css) so a list
   reads as a single dense row (small avatar, inline title·subtitle, tight pad)
   instead of the roomy two-line record tier. */
body[data-system="benchstamp"] .ui-bind-list-row { padding: 2px var(--ui-space-2); gap: var(--ui-space-2); }
body[data-system="benchstamp"] .ui-bind-list-row .ui-avatar { width: 1.35rem; height: 1.35rem; font-size: 0.58rem; flex: 0 0 auto; }
body[data-system="benchstamp"] .ui-bind-list-head { flex-direction: row; align-items: baseline; gap: var(--ui-space-2); min-width: 0; }
body[data-system="benchstamp"] .ui-bind-list-head .ui-text-sm { font-size: var(--ui-text-xs, 11px); }
body[data-system="benchstamp"] .ui-bind-list-pills { transform: scale(0.85); transform-origin: right center; }
body[data-system="benchstamp"] .ui-bind-list-row .ui-icon-btn { padding: 0; width: 1.25rem; height: 1.25rem; }

/* ── Analysis shared-service views — quiet the chrome the non-instrument
   services (runbook/qc/capability) emit so they read like the rest of the
   system: the top metric strip flattened to a hairline status line, the orphan
   "+ X" create buttons sized to content, sub-tabs as a quiet underline (not a
   third nav bar), and the §4 white gulf below short central content closed by
   letting the stage stop at its content. Scoped under .bs-ws-stage so the
   workspace area-nav (.bs-ws-nav) is never touched. */
body[data-system="benchstamp"] .bs-ws-stage .ui-metric-chip { font-size: var(--ui-text-xs, 11px); }
body[data-system="benchstamp"] .bs-ws-stage .ui-tabs .ui-btn,
body[data-system="benchstamp"] .bs-ws-stage > .ui > .ui-flex > .ui-btn {
    flex: 0 0 auto; padding: 3px 10px; font-size: var(--ui-text-xs, 11px);
}

/* ── Quality & Trust (C3) — out-of-spec triage queue rows ── */
body[data-system="benchstamp"] .bs-q-row {
    padding: 6px 10px; gap: 8px; cursor: pointer;
    border-bottom: 1px solid var(--ui-gray-200, #e5e7eb);
}
body[data-system="benchstamp"] .bs-q-row:hover { background: var(--ui-gray-50, #f8fafc); }
body[data-system="benchstamp"] .bs-q-row-sel { background: var(--ui-primary-50, #eff6ff); }
body[data-system="benchstamp"] .bs-q-head { margin-bottom: 4px; }

/* ── Materials (C4) — reagent picker in the result modal ── */
body[data-system="benchstamp"] .bs-reagent-sec { border-top: 1px solid var(--ui-gray-200, #e5e7eb); }
body[data-system="benchstamp"] .bs-reagent-pick { max-width: 240px; }
body[data-system="benchstamp"] .bs-reagent-qty { max-width: 90px; }
body[data-system="benchstamp"] .bs-reagent-chip { cursor: pointer; }

/* ── Component landing grid ── */
body[data-system="benchstamp"] .bs-comp-root { padding: 16px; }
body[data-system="benchstamp"] .bs-comp-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 12px; }
body[data-system="benchstamp"] .bs-comp-planned { opacity: 0.7; }

/* P3 live-capture streaming chart — the central element of the capture area. */
.bs-capture-chart { min-height: 340px; }

/* ── Document-flow areas (nav-bar component) ───────────────────────────────
   No flex-1 / min-height:0 / overflow here — the content GROWS the page so the
   footer is pushed down and the PAGE scrolls. Multi-column via a responsive grid. */
.bs-ws-flow { display: flex; flex-direction: column; }
.bs-area-flow { display: flex; flex-direction: column; gap: var(--ui-space-3, 12px); padding: var(--ui-space-4, 16px); }
.bs-area-flow .bs-datatable { width: 100%; }
.bs-grid { display: grid; gap: var(--ui-space-3, 12px); grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); align-items: start; }
.bs-grid-2 { display: grid; gap: var(--ui-space-3, 12px); grid-template-columns: 1fr 1fr; align-items: start; }
.bs-grid-3 { display: grid; gap: var(--ui-space-3, 12px); grid-template-columns: 2fr 1fr; align-items: start; }
.bs-grid-side { display: grid; gap: var(--ui-space-3, 12px); grid-template-columns: 300px 1fr; align-items: start; }
@media (max-width: 980px) { .bs-grid-2, .bs-grid-3, .bs-grid-side { grid-template-columns: 1fr; } }
.bs-span-all { grid-column: 1 / -1; }
/* ── Densified area chrome (nav-bar tabs + filled stages) ──────────────────── */
.bs-area { padding: var(--ui-space-3, 12px); gap: var(--ui-space-2, 8px); }
.bs-area-head { margin-bottom: var(--ui-space-1, 4px); }
.bs-metric-chip {
    display: inline-flex; align-items: baseline; gap: 4px;
    padding: 2px 9px; border-radius: 999px; font-size: var(--ui-text-xs, 0.72rem);
    background: var(--ui-gray-100, #f1f3f5); color: var(--ui-gray-700, #495057);
    border: 1px solid var(--ui-gray-200, #e5e7eb); white-space: nowrap;
}
.bs-metric-chip b { font-size: var(--ui-text-sm, 0.8rem); color: var(--ui-gray-900, #1a1f24); }
.bs-metric-high   { background: var(--ui-danger-soft, #fde8e8); border-color: var(--ui-danger-200, #f5c2c2); color: var(--ui-danger-700, #b42318); }
.bs-metric-high b { color: var(--ui-danger-700, #b42318); }
.bs-metric-pending{ background: var(--ui-warn-soft, #fff4e0); border-color: var(--ui-warn-200, #ffe0a8); color: var(--ui-warn-800, #92590b); }
.bs-metric-pending b { color: var(--ui-warn-800, #92590b); }
.bs-metric-ok     { background: var(--ui-success-soft, #e6f6ec); border-color: var(--ui-success-200, #bfe6cd); color: var(--ui-success-800, #1f7a3d); }
.bs-metric-ok b   { color: var(--ui-success-800, #1f7a3d); }
/* Guidance hint — a one-line "what this is + what to do" under an area header. */
.bs-guide { display: block; margin: 2px 0 12px; padding: 7px 11px; border-radius: var(--ui-radius-md, 6px);
    background: var(--ui-accent-soft, #eef4fb); border: 1px solid var(--ui-accent-200, #cfe0f5);
    color: var(--ui-gray-700, #495057); line-height: 1.45; }
.bs-guide-icon { margin-right: 4px; }
.bs-guide b, .bs-guide code { color: var(--ui-gray-900, #1a1f24); }
/* Overview "needs attention" rows — compact, flat, clickable (navigate on click). */
.bs-attn-row.ui-card { padding: 7px 10px; box-shadow: none; cursor: pointer; margin-bottom: 4px; }
.bs-attn-row.ui-card:hover { background: var(--ui-gray-50, #f8f9fa); border-color: var(--ui-accent-200, #cfe0f5); }
.bs-attn-row .ui-flex-1 { min-width: 0; }
.bs-clip { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Compact status row — for the Overview roster / environment panels. */
.bs-srow { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 4px 0; border-bottom: 1px solid var(--ui-gray-100, #f3f4f6); }
.bs-srow:last-child { border-bottom: 0; }
.bs-srow .bs-clip { min-width: 0; flex: 1; }
/* Embedded documentation screenshot (in-component About). */
.bs-doc-img { max-width: 100%; border: 1px solid var(--ui-gray-200, #e5e7eb); border-radius: var(--ui-radius-lg, 6px); margin-top: 8px; }

/* Dense clickable table rows (management surfaces: rules, etc.) */
.bs-table-rows tbody tr { cursor: pointer; transition: background var(--ui-transition-fast, 120ms); }
.bs-table-rows tbody tr:hover { background: var(--ui-primary-soft, #eef4ff); }
.bs-row-actions { text-align: right; width: 1%; white-space: nowrap; }
.bs-table-rows .bs-row-del { opacity: 0; background: transparent; border: 0; }
.bs-table-rows tbody tr:hover .bs-row-del { opacity: 0.7; }
.bs-table-rows .bs-row-del:hover { opacity: 1; }

/* In-component documentation tab bar (Bench Bridge About). */
.bs-doc-tabs { border-bottom: 1px solid var(--ui-gray-200, #e5e7eb); margin-bottom: var(--ui-space-2, 8px); }

/* Quality cockpit — compact 5×5 risk heatmap (cells reuse bs-rflag tones) */
.bs-heatmap { border-collapse: separate; border-spacing: 3px; margin-top: 4px; }
.bs-heatmap .bs-hm-cell { width: 30px; height: 24px; text-align: center; vertical-align: middle; padding: 0; }

/* Quality cockpit — ISO 17025 clause-conformity tiles */
.bs-clause-tile { display: inline-flex; align-items: center; gap: 6px; padding: 5px 9px; border: 1px solid var(--ui-gray-200); border-radius: var(--ui-radius-md); cursor: pointer; }
.bs-clause-tile:hover { background: var(--ui-gray-50); }

/* Phase 4 — customer-PO drawdown bar (Jobs surface). */
body[data-system="benchstamp"] progress.bs-drawdown { width: 100%; height: 14px; border-radius: 999px; overflow: hidden; }
body[data-system="benchstamp"] progress.bs-drawdown::-webkit-progress-bar { background: var(--ui-gray-200, #e5e7eb); border-radius: 999px; }
body[data-system="benchstamp"] progress.bs-drawdown::-webkit-progress-value { background: #2563eb; border-radius: 999px; }
body[data-system="benchstamp"] progress.bs-drawdown::-moz-progress-bar { background: #2563eb; border-radius: 999px; }

/* Trend sparkline (Quality P5) — spaced block glyphs for month-over-month reads. */
.bs-spark { letter-spacing: var(--ui-space-1, .15em); line-height: 1; }

/* Management-review pack (Quality P6) — print collapses chrome to the pack only. */
@media print {
  .bs-noprint, .ui-hub-nav, .ui-tabbar, .ui-pageframe-nav, nav, .ui-nav { display: none !important; }
  .bs-brief { max-width: 100%; }
  .bs-brief .type-card, .bs-brief .ui-card { break-inside: avoid; box-shadow: none; }
}

/* Utilisation bar (Instruments L14/P5) — the fill width is the datum (data-viz). */
.bs-util-bar { display: inline-block; width: 90px; height: 8px; background: var(--ui-gray-200, #e5e7eb); border-radius: var(--ui-radius-sm, 3px); vertical-align: middle; overflow: hidden; margin-left: var(--ui-space-1, 4px); }
.bs-util-fill { display: block; height: 100%; background: var(--ui-primary, #2563eb); }
