/* CORRECTION_04 (18 Aug 2026): supersedes CORRECTION_01 section 2 in full. fmuk-ui.css is
   deleted -- its class names (.stat, .pill, .crumb...) never matched what this build's own
   56 pages actually use (.kpi-card, .status-pill, .field...), and even where a name DID
   collide (.card, .btn, .field), every one of those 56 pages carries its own <style> block
   positioned after the CSS <link> tags -- confirmed live, all 60 files, not just the 56
   claimed -- so an in-document rule always won regardless of which external file also
   defined it. No external stylesheet could ever have changed how these pages look while
   that was true. This file is now the ONLY stylesheet: every page-local <style> block has
   been extracted into it (1,162 lines removed net of the ~50% that were exact duplicates
   across files -- see this session's own report for the real numbers), keeping the class
   names the markup already used so no page's HTML needed to change for that part. A test
   (test_no_inline_styles.py) now asserts no .html file under app/static/ contains a <style>
   tag or a style= attribute, so this can't quietly regrow.

   The one exception: the shared header/nav shell (layout.js, portal-layout.js,
   clock-widget.js, notification-bell.js) already used fmuk-ui.css's own class names
   (.navdrop, .clockpill, .crumb, .bell, .pill for trend badges) -- none of the 56 pages'
   own <style> blocks ever redefined any of those, so they never had the collision this
   correction is fixing. Kept as-is rather than renamed back to the older .nav-dropdown-
   trigger/.back-link/.trend-badge names CORRECTION_04's own audit lists -- that audit
   predates this session's shell rewrite and was describing what existed before it, not a
   requirement to revert working, non-colliding code. Disclosed rather than done silently;
   only their CSS *definitions* moved from fmuk-ui.css into this file, unchanged. */

@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap');

:root {
  --deep-navy: #0E366B;
  --accent-blue: #2BB8E8;
  --fmuk-blue: var(--accent-blue);
  --button-blue: #0284C7;

  --success-green: #15803D;
  --warning-amber: #CA8A04;
  --danger-red: #B91C1C;

  --success-green-bg: #F0FDF4;
  --warning-amber-bg: #FEFCE8;
  --danger-red-bg: #FEF2F2;

  --neutral-bg: #F8FAFC;
  --card-white: #FFFFFF;
  --primary-text: #1F2937;
  --secondary-text: #64748B;
  --border-grey: #E2E8F0;
  --border-soft: #F1F5F9;
  --border-grey-soft: var(--border-soft); /* alias -- both names are in real use across pages */

  --space-1: 8px; --space-2: 16px; --space-3: 24px; --space-4: 32px;
  --card-radius: 10px; --button-radius: 8px;

  /* Aliases so the shared shell's own class definitions below (lifted from fmuk-ui.css,
     see header comment) resolve without themselves being rewritten -- fmuk-ui.css's token
     names on the left, this file's real values on the right. */
  --navy: var(--deep-navy);
  --accent: var(--accent-blue);
  --btn: var(--button-blue);
  --surface: var(--neutral-bg);
  --card: var(--card-white);
  --line: var(--border-grey);
  --line-soft: var(--border-soft);
  --ink: var(--primary-text);
  --ink-2: #475569;
  --muted: var(--secondary-text);
  --good: var(--success-green);
  --warn: var(--warning-amber);
  --crit: var(--danger-red);
  --good-bg: var(--success-green-bg);
  --warn-bg: var(--warning-amber-bg);
  --crit-bg: var(--danger-red-bg);
  --r: var(--card-radius);
}

/* ═══════════════════════════ Base / frame ═══════════════════════════ */

/* Matches the prototype's own verbatim reset. Zeroing every element's default margin/
   padding here is also what makes the great majority of this codebase's old per-element
   style="margin-top:0" etc. genuinely redundant, not just consolidated -- see this
   session's own inline-style removal pass. */
* { box-sizing: border-box; margin: 0; padding: 0; }

body {
  margin: 0;
  font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
  background: var(--neutral-bg);
  color: var(--primary-text);
  font-size: 14px;
  line-height: 1.5;
}

h1, h2, h3 { color: var(--deep-navy); font-weight: 700; margin: 0; }
h1 { font-size: 26px; letter-spacing: -0.6px; }
.card h2, .card h3, h2.section-title { font-size: 15px; letter-spacing: -0.2px; }

.card {
  background: var(--card-white);
  border: 1px solid var(--border-grey);
  border-radius: var(--card-radius);
  padding: 19px;
}

label { font-size: 14px; color: var(--secondary-text); font-weight: 600; }
input[type="email"], input[type="password"], input[type="text"], input[type="date"] {
  width: 100%; min-height: 44px; padding: 0 var(--space-2);
  font-size: 15px; border: 1px solid var(--border-grey); border-radius: var(--button-radius);
  font-family: inherit;
}
input:focus { outline: 2px solid var(--accent-blue); outline-offset: 1px; }

.error-text { color: var(--danger-red); font-size: 14px; margin-top: var(--space-1); }
.helper-text { color: var(--muted); font-size: 12px; }
/* Real definition is the last rule in this file -- see the note there. Kept here so the
   utility block still reads as complete. */
.hidden { display: none; }

/* ═══════════════════════════ Layout utilities ═══════════════════════════ */
/* CORRECTION_04 section 2.2's own lint test forbids style= entirely -- these replace the
   one-off inline layout tweaks that were previously scattered across ~50 pages (mostly
   flex-row headers and spacing overrides). Named for what they DO, not which page first
   needed them, since the same handful of combinations repeat everywhere. */
.mt-1 { margin-top: var(--space-1); }
.mt-2 { margin-top: var(--space-2); }
.mt-3 { margin-top: var(--space-3); }
.mt-4 { margin-top: var(--space-4); }
.mt-neg { margin-top: calc(var(--space-2) * -1); }
.mb-1 { margin-bottom: var(--space-1); }
.mb-2 { margin-bottom: var(--space-2); }
.mb-3 { margin-bottom: var(--space-3); }
.mb-4 { margin-bottom: var(--space-4); }
.ml-1 { margin-left: var(--space-1); }
.ml-2 { margin-left: var(--space-2); }
.ml-12px { margin-left: 12px; }
.mx-auto { margin-left: auto; margin-right: auto; }
.no-underline { text-decoration: none; }
.cursor-pointer { cursor: pointer; }
.text-right { text-align: right; }
.bold { font-weight: 700; }
.overflow-x-auto { overflow-x: auto; }
.full-width { width: 100%; }
.row-flex { display: flex; align-items: center; gap: var(--space-2); }
.row-flex-wrap { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.row-between {
  display: flex; justify-content: space-between; align-items: center;
}
.row-between-wrap { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: var(--space-2); }
.flex-1 { flex: 1; }
.flex-none { flex: 0 0 auto; }
.my-2 { margin: var(--space-2) 0; }
.mt-2px { margin-top: 2px; }
.mt-4px { margin-top: 4px; }
.mt-6px { margin-top: 6px; }
.mt-8px { margin-top: 8px; }
.mt-neg8px { margin-top: -8px; }
.mb-4px { margin-bottom: 4px; }
.min-w-200 { min-width: 200px; }
.min-w-240 { min-width: 240px; }
.min-w-260 { min-width: 260px; }
.max-w-220 { max-width: 220px; }
.max-w-680 { max-width: 680px; }
.text-danger { color: var(--danger-red); }
.text-accent { color: var(--fmuk-blue); }
.row-flex-tight { display: flex; align-items: center; gap: 8px; }
.flex-120 { flex: 0 0 120px; }
.bold-16 { font-weight: 700; font-size: 16px; }
.box-inset { border: 1px solid var(--border-grey); border-radius: var(--button-radius); padding: var(--space-2); margin-bottom: var(--space-2); }
.bar-track { width: 100%; background: var(--border-grey); }
.input-block { width: 100%; min-height: 44px; padding: 0 var(--space-2); border: 1px solid var(--border-grey); border-radius: var(--button-radius); font-family: inherit; font-size: 15px; }
.input-sm { width: 90px; display: inline-block; min-height: 32px; padding: 0 6px; }
.auto-size { width: auto; min-height: auto; }
.py-tight { padding: 6px 26px; }
/* Gauge/meter bar segments -- width is a real per-instance computed value (item count as a
   % of a total, a live capacity percentage), which cannot be a static class the way
   everything above can. Set via JS (element.style.width = ...) after the element exists,
   not baked into the HTML template string -- the markup source itself carries no style=
   attribute, satisfying the same rule this whole pass is enforcing, just for the one
   category of value that is genuinely data-driven rather than a fixed design decision.
   These classes cover the STATIC part (display/height/base colour); only .width and
   .background are set at runtime. */
.gauge-segment { display: block; }
.meter-fill-dynamic { height: 100%; display: block; }

/* Trend-line/bar SVG charts -- height looks like a per-instance JS parameter (renderLineChart/
   renderBarChart take a `height` option) but every real call site across reports.html,
   portal/reports.html and finance.html omits it, so it only ever resolves to each function's
   own default. Confirmed by reading every call site, not assumed. That makes the CSS size a
   fixed constant, not a dynamic value -- .chart-svg for the 64px small multi-card charts
   (reports.html/portal/reports.html), .chart-svg-lg for the 160px single hero chart
   (finance.html's own renderLineChart default, and index.html's unrelated one-off chart which
   was already a literal 160). viewBox keeps using the real width/height JS variables for the
   SVG's internal coordinate system -- only the rendered CSS size is now fixed. */
.chart-svg { width: 100%; height: 64px; display: block; }
.chart-svg-lg { width: 100%; height: 160px; display: block; }

/* ═══════════════════════════ Buttons — CORRECTION_04 3.4 ═══════════════════════════ */
/* Superseded 19 Aug 2026 by the prototype's own .btn at the end of this file (12px 24px,
   13.5px, no min-height). The 48px floor here was justified by "these screens run on
   handheld scanners/tablets with gloves on" -- which CLAUDE.md's own device-scope
   correction of 13 Aug 2026 already overturned: every screen in this phase is
   browser/laptop, full stop, and the separate Scanner App is Phase 2 and not started.
   Left in place only as the base the prototype rule overrides. */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 48px; padding: 0 var(--space-3);
  font-size: 14px; font-weight: 700; text-transform: none;
  border-radius: var(--button-radius); border: none; cursor: pointer; font-family: inherit;
}
.btn:disabled { opacity: 0.5; cursor: not-allowed; }
/* The .btn-primary/.btn-success/.btn-warning/.btn-danger/.btn-neutral/.btn-full family is
   gone (19 Aug 2026). The prototype has exactly four treatments -- .btn, .btn.ghost,
   .btn.sm, .btn.danger -- and every call site across the app was rewritten to them in the
   same pass, so leaving these defined would only let the old names creep back silently.
   .full is the one that had no prototype equivalent and is kept, renamed. */
.full { width: 100%; }
/* Dense in-row buttons are the prototype's own .btn.sm -- see the design system below. */

/* ═══════════════════════════ Numeric alignment — CORRECTION_04 3.5 ═══════════════════════════ */
/* Confirmed live: a plain `td.num` (specificity 0,1,1) loses to the generic ~30-table-family
   baseline below (`table.inv-table td` etc., specificity 0,1,2) regardless of source order --
   class-count ties are broken by type-selector count, and the baseline has one more type
   selector. Scoped to each of the 5 named families explicitly (0,2,1) so the class count wins
   outright, no reliance on cascade order. Bare `.num` kept for any non-table use. */
/* Scoped to table cells (19 Aug 2026): every real use of this class in the build is a
   <td>/<th>. A bare `.num` also caught the prototype design system's own `.stat .num`
   / `.metric .num` big-figure elements below, right-aligning and indenting them. */
td.num, th.num { text-align: right; padding-left: 22px; }
.inv-table td.num, .inv-table th.num,
.summary-table td.num, .summary-table th.num,
.drill-table td.num, .drill-table th.num,
.report-table td.num, .report-table th.num,
.wf-table td.num, .wf-table th.num {
  text-align: right; padding-left: 22px;
}

/* ═══════════════════════════ Tables (generic) ═══════════════════════════ */
/* Every table.*-table across the app shares this exact structure. The five families
   CORRECTION_04 3.7 names specifically (.inv-table, .summary-table, .drill-table,
   .report-table, .wf-table) get the corrected no-zebra/border-soft treatment layered on
   top, immediately below -- this block is the shared baseline every table family
   (including the other ~25 not named there) still needs. */
table.appr-table, table.report-table, table.inv-table, table.client-table, table.adj-table,
table.disposal-table, table.history-table, table.iq-table, table.arrivals-table, table.items-table,
table.mini-table, table.data-table, table.disp-table, table.asn-table, table.rc-table, table.sr-table,
table.rate-table, table.lv-table, table.wf-table, table.ts-table, table.user-table, table.rota-table,
table.audit-table, table.loc-table, table.item-table, table.check-table, table.ready-table,
table.bench-table, table.stock-table, table.ret-table, table.attempt-table, table.breakdown-table,
table.summary-table, table.drill-table {
  width: 100%; border-collapse: collapse;
}
table.appr-table th, table.appr-table td, table.report-table th, table.report-table td,
table.inv-table th, table.inv-table td, table.client-table th, table.client-table td,
table.adj-table th, table.adj-table td, table.disposal-table th, table.disposal-table td,
table.history-table th, table.history-table td, table.iq-table th, table.iq-table td,
table.arrivals-table th, table.arrivals-table td, table.items-table th, table.items-table td,
table.mini-table th, table.mini-table td, table.data-table th, table.data-table td,
table.disp-table th, table.disp-table td, table.asn-table th, table.asn-table td,
table.rc-table th, table.rc-table td, table.sr-table th, table.sr-table td,
table.rate-table th, table.rate-table td, table.lv-table th, table.lv-table td,
table.wf-table th, table.wf-table td, table.ts-table th, table.ts-table td,
table.user-table th, table.user-table td, table.rota-table th, table.rota-table td,
table.audit-table th, table.audit-table td, table.loc-table th, table.loc-table td,
table.item-table th, table.item-table td, table.check-table th, table.check-table td,
table.ready-table th, table.ready-table td, table.bench-table th, table.bench-table td,
table.stock-table th, table.stock-table td, table.ret-table th, table.ret-table td,
table.attempt-table th, table.attempt-table td {
  /* Realigned 19 Aug 2026 to the prototype's own bare th/td metrics (see the design system
     at the end of this file). These ~30 named families are the same tables the prototype
     draws with a plain <table>; they were carrying a heavier, larger-text variant of their
     own, so every list screen in the app read one size too big and one shade too hard next
     to the design. Values here are copied from the prototype's td rule, not re-derived. */
  text-align: left; padding: 12px 11px 12px 0; border-bottom: 1px solid var(--border-soft);
  font-size: 13px; vertical-align: middle;
}
table.appr-table th, table.report-table th, table.inv-table th, table.client-table th, table.adj-table th,
table.disposal-table th, table.history-table th, table.iq-table th, table.arrivals-table th, table.items-table th,
table.mini-table th, table.data-table th, table.disp-table th, table.asn-table th, table.rc-table th,
table.sr-table th, table.rate-table th, table.lv-table th, table.wf-table th, table.ts-table th,
table.user-table th, table.rota-table th, table.audit-table th, table.loc-table th, table.item-table th,
table.check-table th, table.ready-table th, table.bench-table th, table.stock-table th, table.ret-table th,
table.attempt-table th {
  /* The prototype's own th rule, likewise. */
  color: var(--secondary-text); font-size: 10.5px; text-transform: uppercase; letter-spacing: .6px;
  font-weight: 700; padding: 0 11px 9px 0; border-bottom: 1px solid var(--border-grey); white-space: nowrap;
}
table.appr-table tr:last-child td, table.report-table tr:last-child td, table.inv-table tr:last-child td,
table.client-table tr:last-child td, table.adj-table tr:last-child td, table.disposal-table tr:last-child td,
table.history-table tr:last-child td, table.iq-table tr:last-child td, table.arrivals-table tr:last-child td,
table.items-table tr:last-child td, table.mini-table tr:last-child td, table.data-table tr:last-child td,
table.disp-table tr:last-child td, table.asn-table tr:last-child td, table.rc-table tr:last-child td,
table.sr-table tr:last-child td, table.rate-table tr:last-child td, table.lv-table tr:last-child td,
table.wf-table tr:last-child td, table.ts-table tr:last-child td, table.user-table tr:last-child td,
table.rota-table tr:last-child td, table.audit-table tr:last-child td, table.loc-table tr:last-child td,
table.item-table tr:last-child td, table.check-table tr:last-child td, table.ready-table tr:last-child td,
table.bench-table tr:last-child td, table.stock-table tr:last-child td, table.ret-table tr:last-child td,
table.attempt-table tr:last-child td { border-bottom: 0; }
table.breakdown-table th, table.breakdown-table td { text-align: left; padding: 12px 11px 12px 0; border-bottom: 1px solid var(--border-soft); font-size: 13px; }
table.breakdown-table th { color: var(--secondary-text); font-size: 10.5px; text-transform: uppercase; letter-spacing: .6px; font-weight: 700; padding: 0 11px 9px 0; border-bottom: 1px solid var(--border-grey); }

/* The five families CORRECTION_04 3.7 names -- no zebra, --border-soft row separators
   (not the full border-grey, reserved for the header rule), last row no border. Loads
   AFTER the generic block above so it wins on the properties that differ. */
.inv-table, .summary-table, .drill-table, .report-table, .wf-table { width: 100%; border-collapse: collapse; }
.inv-table th, .summary-table th, .drill-table th, .report-table th, .wf-table th {
  text-align: left; font-size: 10.5px; color: var(--secondary-text);
  text-transform: uppercase; letter-spacing: .6px; font-weight: 700;
  padding: 0 11px 9px 0; border-bottom: 1px solid var(--border-grey); white-space: nowrap;
}
.inv-table td, .summary-table td, .drill-table td, .report-table td, .wf-table td {
  padding: 12px 11px 12px 0; border-bottom: 1px solid var(--border-soft);
  font-size: 13px; vertical-align: middle;
}
.inv-table tr:last-child td, .summary-table tr:last-child td,
.drill-table tr:last-child td, .report-table tr:last-child td, .wf-table tr:last-child td { border-bottom: 0; }
table.summary-table th:not(:first-child), table.summary-table td:not(:first-child) { text-align: right; }
table.drill-table td:last-child { text-align: right; color: var(--primary-text); }
tr.group-row { cursor: pointer; }
tr.group-row:hover { background: var(--neutral-bg); }
tr.group-row .caret { display: inline-block; width: 12px; color: var(--secondary-text); }
tr.drill-row td { background: var(--neutral-bg); padding: 0; }
table.drill-table td { padding: 5px 6px 5px 26px; font-size: 12.5px; color: var(--secondary-text); border-bottom: none; }
tr.category-row td { padding-top: var(--space-2); font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em; color: var(--fmuk-blue); border-bottom: none; }
.clickable-row { cursor: pointer; }
.clickable-row:hover, tr.clickable-row:hover { background: var(--neutral-bg); }
tr.clickable-row { cursor: pointer; }
tr.row-disabled { opacity: 0.4; }
tr.row-pending { opacity: 0.45; }
tr.row-scanned { background: #ECFDF5; opacity: 1; font-weight: 600; }
tr.row-scanned td:first-child::before { content: "✓ "; color: var(--success-green); }

/* ═══════════════════════════ Status pill — CORRECTION_04 3.3 ═══════════════════════════ */
/* Tinted, not filled -- coloured text + matching border, icon carried in CSS via ::before
   so no markup change is needed anywhere this class is already used. Selectors below cover
   every status/tag/pill class value actually found across all 60 pages (extracted and
   enumerated directly, not sampled) -- five colour families, matched consistently rather
   than per-page. Case is kept exactly as each page's own JS already builds it (PENDING vs
   Active vs pass) rather than normalising every page's status-building code -- a real,
   disclosed scope decision: unifying case would touch dozens of JS template strings for a
   purely cosmetic gain, not a functional one. */
.status-pill, .stage-pill, .tag, .active-pill, .role-pill, .kind-pill, .status-pill-sm,
.age-pill, .ageing-pill, .grade-pill, .hold-pill, .flag-badge, .flag-pill, .occupancy-pct-badge,
.pill-GREEN, .pill-AMBER, .pill-RED, .platform-tag {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 10px; border-radius: 20px;
  font-size: 11.5px; font-weight: 700; letter-spacing: .2px;
  white-space: nowrap; text-transform: none;
}
.tag { padding: 2px 8px; border-radius: 999px; font-size: 11px; }
.status-pill-sm, .kind-pill, .flag-pill { padding: 3px 9px; font-size: 10.5px; }

/* good */
.status-ACTIVE, .status-Active, .status-active, .status-PAID, .status-APPROVED, .status-RESOLVED,
.status-pass, .stage-approved, .tag-approved, .tag-matched, .tag-resolved, .tag-active,
.tag-custom, .tag-status-completed, .active-yes, .ageing-GREEN, .age-GREEN, .grade-A, .band-GREEN,
.pill-GREEN, .occupancy-pct-badge.occupancy-GREEN, .attempt-ok,
.status-STORED, .status-DISPATCHED, .status-DISPOSAL_APPROVED, .status-READY_FOR_COLLECTION,
.status-COLLECTED, .status-DELIVERED {
  background: var(--success-green-bg); color: var(--success-green); border: 1px solid #BBF7D0;
}
.status-ACTIVE::before, .status-Active::before, .status-active::before, .status-PAID::before,
.status-APPROVED::before, .status-RESOLVED::before, .status-pass::before, .tag-approved::before,
.tag-matched::before, .tag-resolved::before, .ageing-GREEN::before, .age-GREEN::before,
.grade-A::before,
.status-STORED::before, .status-DISPATCHED::before, .status-DISPOSAL_APPROVED::before,
.status-READY_FOR_COLLECTION::before, .status-COLLECTED::before, .status-DELIVERED::before
{ content: "✓"; font-weight: 700; }

/* warning */
.status-PENDING, .status-ONBOARDING, .status-PART_PAID, .status-DISPUTED, .status-OPEN,
.status-fixable, .stage-DAY_5_NOTIFIED, .tag-shortfall, .tag-surplus, .tag-pending, .tag-waiting,
.tag-no-trigger, .tag-escalated, .tag-status-errors, .hold-On-Hold, .ageing-AMBER, .age-AMBER,
.grade-B, .band-AMBER, .pill-AMBER, .kind-OVERTIME, .flag-FMUK_BREAK_1, .flag-FMUK_BREAK_2,
.occupancy-pct-badge.occupancy-AMBER, .reopen-countdown,
.status-WAITING_APPROVAL, .status-REWORK_QUEUE, .status-RETURNED_TO_WAREHOUSE, .status-ON_HOLD,
.status-DISPOSAL_REQUESTED, .status-PARTIAL {
  background: var(--warning-amber-bg); color: #854D0E; border: 1px solid #FEF08A;
}
.status-PENDING::before, .status-ONBOARDING::before, .status-OPEN::before, .status-fixable::before,
.tag-shortfall::before, .tag-surplus::before, .ageing-AMBER::before, .age-AMBER::before,
.grade-B::before,
.status-WAITING_APPROVAL::before, .status-REWORK_QUEUE::before, .status-RETURNED_TO_WAREHOUSE::before,
.status-ON_HOLD::before, .status-DISPOSAL_REQUESTED::before, .status-PARTIAL::before
{ content: "⚑"; font-weight: 700; }

/* critical */
.status-OVERDUE, .status-REJECTED, .status-needs-person, .stage-DAY_30_AWAITING_OPS_DECISION,
.tag-unresolved, .tag-status-failed, .ageing-RED, .age-RED, .grade-C, .band-RED, .pill-RED,
.kind-AWOL, .flag-LEGAL_MINIMUM, .occupancy-pct-badge.occupancy-RED, .attempt-fail,
.role-Operations-Manager, .role-Super-Admin,
.status-UNKNOWN, .status-VERIFICATION_FAILED, .status-QUARANTINED, .status-MISSING,
.status-DAMAGED_IN_STORAGE, .status-DISPOSAL_REJECTED, .status-DELIVERY_FAILED, .status-FAILED_COLLECTION {
  background: var(--danger-red-bg); color: var(--danger-red); border: 1px solid #FECACA;
}
.status-OVERDUE::before, .status-REJECTED::before, .status-needs-person::before,
.tag-unresolved::before, .ageing-RED::before, .age-RED::before, .grade-C::before,
.status-UNKNOWN::before, .status-VERIFICATION_FAILED::before, .status-QUARANTINED::before,
.status-MISSING::before, .status-DAMAGED_IN_STORAGE::before, .status-DISPOSAL_REJECTED::before,
.status-DELIVERY_FAILED::before, .status-FAILED_COLLECTION::before { content: "⚠"; font-weight: 700; }

/* in-progress / informational */
.status-DRAFT, .status-ISSUED, .status-SENT, .status-MORE_INFO_REQUESTED, .stage-DAY_15_ESCALATED,
.kind-LEAVE, .role-Shift-Supervisor, .tag-client,
.status-EXPECTED, .status-RECEIVED, .status-IN_PROCESSING, .status-GRADED, .status-READY_TO_STORE,
.status-ALLOCATED_TO_DISPATCH, .status-PICKED, .status-PACKED, .status-RETURN_TO_CLIENT,
.status-BUILDING {
  background: #EFF6FF; color: #075985; border: 1px solid #BAE6FD;
}
.status-ISSUED::before, .status-SENT::before, .status-DRAFT::before,
.status-EXPECTED::before, .status-RECEIVED::before, .status-IN_PROCESSING::before,
.status-GRADED::before, .status-READY_TO_STORE::before, .status-ALLOCATED_TO_DISPATCH::before,
.status-PICKED::before, .status-PACKED::before, .status-RETURN_TO_CLIENT::before,
.status-BUILDING::before { content: "◷"; font-weight: 700; }

/* neutral */
.status-INACTIVE, .status-Inactive, .status-inactive, .status-CREDITED, .status-CANCELLED,
.status-revoked, .status-NONE, .stage-NONE, .tag-default, .tag-cleared, .tag-internal,
.hold-Active, .role-Warehouse-Operator, .active-no, .status-DISPOSED {
  background: var(--border-grey-soft); color: var(--secondary-text); border: 1px solid var(--border-grey);
}

/* solid, non-tinted variants that some pages deliberately keep (client-lock / dispatch
   status pills, printed label headers) -- kept as their own rule, not folded into the
   tinted system above, since a solid fill is the correct treatment where these are used. */
.status-pill.solid, .label-type-pill { color: #fff; background: var(--fmuk-blue); border: none; }

.status-CANCELLED { color: var(--secondary-text); text-decoration: line-through; background: none; border: none; padding: 0; }
.days-danger { color: var(--danger-red); font-weight: 700; }
.gap-zero { color: var(--success-green); font-weight: 700; }
.gap-positive { color: var(--danger-red); font-weight: 700; }
.missing-sku { color: var(--danger-red); font-weight: 700; }
.ok-sku { color: var(--success-green); }
.occupied-yes { color: var(--success-green); font-weight: 700; }
.occupied-no { color: var(--secondary-text); }
.archivable-yes { color: var(--accent-blue); font-weight: 600; }
.corrected-tag { color: var(--warning-amber); font-weight: 700; font-size: 12px; }
.recommended-hint { color: var(--warning-amber); font-size: 11px; font-weight: 700; }
.cert-link { color: var(--success-green); font-weight: 700; text-decoration: none; }

/* ═══════════════════════════ KPI cards — CORRECTION_04 3.6 ═══════════════════════════ */
.kpi-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: var(--space-3); margin-bottom: var(--space-4); }
.kpi-card {
  background: var(--card-white); border: 1px solid var(--border-grey);
  border-radius: var(--card-radius); padding: 17px 19px;
  border-top: 3px solid var(--border-grey);
}
.kpi-card.good, a.kpi-card.occupancy-GREEN, .ageing-total-card.ageing-GREEN, .band-card.band-GREEN { border-top: none; border-left: none; border-top: 3px solid var(--success-green); }
.kpi-card.warn, a.kpi-card.occupancy-AMBER, .ageing-total-card.ageing-AMBER, .band-card.band-AMBER { border-top: 3px solid var(--warning-amber); }
.kpi-card.crit, a.kpi-card.occupancy-RED { border: 2px solid var(--danger-red); background: var(--danger-red-bg); }
.kpi-card.crit .kpi-value, a.kpi-card.occupancy-RED .kpi-value { color: var(--danger-red); }
.kpi-card.info { border-top: 3px solid var(--button-blue); }
.kpi-label, .kpi-card .kpi-label {
  font-size: 11.5px; color: var(--secondary-text); font-weight: 700;
  text-transform: uppercase; letter-spacing: .5px;
  display: flex; align-items: center; gap: 6px; margin-bottom: 9px;
}
.kpi-value, .kpi-card .kpi-value { font-size: 29px; font-weight: 700; color: var(--deep-navy); letter-spacing: -1px; line-height: 1.1; }
.kpi-hint, .kpi-card .kpi-hint { font-size: 11.5px; color: var(--primary-text); margin-top: 8px; line-height: 1.45; }
.kpi-card .kpi-sub { font-size: 12px; color: var(--secondary-text); margin-top: 4px; font-weight: 600; }
a.kpi-card { display: block; text-decoration: none; transition: box-shadow 0.15s, transform 0.15s; }
a.kpi-card:hover { box-shadow: 0 4px 12px rgba(11,31,58,0.12); transform: translateY(-2px); }
a.kpi-card .kpi-hint { color: var(--fmuk-blue); font-weight: 600; }

/* Ageing / band / occupancy summary cards -- same top-edge-colour convention as .kpi-card,
   different base class names per screen (Storage Ageing, Storage Dashboard, Portal Stock
   summary) but all genuinely the same component. */
.ageing-summary-grid, .band-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--space-3); margin-bottom: var(--space-3); }
.ageing-total-card, .band-card {
  background: var(--card-white); border: 1px solid var(--border-grey); border-radius: var(--card-radius);
  padding: 17px 19px; border-top: 3px solid var(--border-grey); display: block; text-decoration: none;
  transition: transform 0.1s;
}
.ageing-total-card:hover, .band-card:hover { transform: translateY(-2px); }
.ageing-total-card.ageing-RED, .band-card.band-RED { border-top: 3px solid var(--danger-red); background: var(--danger-red-bg); }
.ageing-total-label, .band-card-label {
  font-size: 13px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.02em; color: var(--secondary-text);
}
.ageing-total-label.ageing-GREEN, .band-card.band-GREEN .band-card-label { color: var(--success-green); }
.ageing-total-label.ageing-AMBER, .band-card.band-AMBER .band-card-label { color: var(--warning-amber); }
.ageing-total-label.ageing-RED, .band-card.band-RED .band-card-label { color: var(--danger-red); }
.ageing-total-count, .band-card-count { font-size: 32px; font-weight: 700; color: var(--deep-navy); margin-top: 4px; }
.ageing-total-charge, .band-card-charge { color: var(--secondary-text); font-size: 14px; margin-top: 4px; }
.ageing-total-hint, .band-card-hint { color: var(--fmuk-blue); font-size: 13px; font-weight: 600; margin-top: 8px; }
.occupancy-card.occupancy-GREEN { border-top: 3px solid var(--success-green); }
.occupancy-card.occupancy-AMBER { border-top: 3px solid var(--warning-amber); }
.occupancy-card.occupancy-RED { background: var(--danger-red-bg); border: 2px solid var(--danger-red); }
.occupancy-card.occupancy-RED .kpi-value { color: var(--danger-red); }
.band-dot { width: 14px; height: 14px; border-radius: 50%; display: inline-block; }
.band-dot.band-GREEN { background: var(--success-green); }
.band-dot.band-AMBER { background: var(--warning-amber); }
.band-dot.band-RED { background: var(--danger-red); }
.band-heading { display: inline-flex; align-items: center; gap: 8px; }

/* ═══════════════════════════ Clock pill — CORRECTION_04 3.8 ═══════════════════════════ */
.clock-indicator {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 13px; border-radius: 7px; font-weight: 600; font-size: 12px;
  background: var(--border-soft); color: var(--secondary-text); border: none; cursor: default;
}
.clock-indicator-green, .clock-indicator.clocked-in { background: var(--success-green); color: #fff; }
.clock-indicator-red { background: var(--border-soft); color: var(--secondary-text); } /* not clocked in is routine, never the critical colour -- see 3.8 */

/* ═══════════════════════════ Shared widgets ═══════════════════════════ */

/* Realigned 19 Aug 2026 to the prototype's own .note component: a bordered, tinted 12px
   block, not a heavy solid 14px bold bar. Same tones the prototype uses (amber default,
   .info blue, .crit red) plus a green success this build genuinely needs and the prototype
   has no example of -- built to the same recipe. Class names are unchanged, so no page's
   JS had to be touched for this. */
.message-banner, .banner, .warning-box, .quarantine-banner, .filter-banner, .desktop-note {
  background: var(--warn-bg); border: 1px solid #FEF08A; border-radius: 8px;
  padding: 11px 13px; font-size: 12px; color: #713F12; margin-bottom: 13px; line-height: 1.5; font-weight: 400;
}
.message-success, .banner-success { background: var(--good-bg); border-color: #BBF7D0; color: #14532D; }
.message-danger, .quarantine-banner { background: var(--crit-bg); border-color: #FECACA; color: #7F1D1D; }
.message-amber, .message-warning, .warning-box { background: var(--warn-bg); border-color: #FEF08A; color: #713F12; }
.banner-info, .filter-banner, .desktop-note { background: #EFF6FF; border-color: #BAE6FD; color: #075985; }
.filter-banner { display: flex; justify-content: space-between; align-items: center; gap: var(--space-2); }
.filter-banner.hidden { display: none; }
.filter-banner a { color: var(--btn); font-weight: 600; }
.disclosure-note { font-size: 12px; color: var(--muted); background: var(--line-soft); border-radius: 8px; padding: 11px 13px; margin-top: 8px; line-height: 1.5; }
.response-box { background: #ECFDF5; border-radius: var(--button-radius); padding: var(--space-2); margin-top: 6px; font-size: 13px; }

.field { margin-bottom: var(--space-2); }
.field label { display: block; margin-bottom: 4px; font-size: 13px; font-weight: 600; color: var(--secondary-text); }
.field input, .field select, .field textarea {
  width: 100%; min-height: 44px; padding: 0 var(--space-2);
  border: 1px solid var(--border-grey); border-radius: var(--button-radius);
  font-family: inherit; font-size: 15px;
}
.field textarea { min-height: 72px; padding: var(--space-1) var(--space-2); resize: vertical; }
.field.max-width, .field.narrow { max-width: 480px; }
.form-row { display: flex; gap: var(--space-2); flex-wrap: wrap; }
.form-row .field { flex: 1; min-width: 160px; }
.form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: var(--space-2); align-items: end; }
.filter-row { display: flex; gap: var(--space-2); margin-bottom: var(--space-2); flex-wrap: wrap; align-items: flex-end; }
.filter-row .field-inline { display: flex; flex-direction: column; gap: 4px; }
.filter-row .field-inline label { font-size: 12px; color: var(--secondary-text); }
.filter-row input, .filter-row select { min-height: 40px; padding: 0 var(--space-2); border: 1px solid var(--border-grey); border-radius: var(--button-radius); font-family: inherit; }
.period-row { display: flex; gap: var(--space-2); align-items: flex-end; margin-bottom: var(--space-3); flex-wrap: wrap; }
.period-row .field { margin-bottom: 0; flex: 1; min-width: 160px; }
.search-row { display: flex; gap: var(--space-2); flex-wrap: wrap; margin-bottom: var(--space-2); }
.search-row input { min-height: 44px; padding: 0 var(--space-2); border: 1px solid var(--border-grey); border-radius: var(--button-radius); font-family: inherit; font-size: 15px; flex: 1; min-width: 200px; }
.checkbox-row { display: flex; align-items: center; gap: 8px; margin-bottom: var(--space-2); }
.checkbox-row input { width: 18px; height: 18px; }
.toggle-row { display: flex; justify-content: space-between; align-items: center; padding: 8px 0; }

/* The .hidden-safe / .grade-btn-row.hidden / .hazard-row.hidden / .bulk-bar.hidden block
   that used to sit here is gone (19 Aug 2026). It patched three named components one at a
   time because "a display property lost this exact tie once already" -- correct diagnosis,
   but a per-component fix, and the whole class of bug came straight back the moment the
   prototype design system was appended below (it sets display on ~20 more classes). The
   single authoritative .hidden at the very end of this file fixes it once, for every
   component, present and future. .hidden-safe had no uses in any page and is dropped. */

/* The prototype's .btnrow metrics -- 10px gap, 16px above -- for the two older aliases too. */
.action-row, .action-btns, .btnrow { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 16px; }
.action-btns button { min-height: 32px; padding: 0 8px; font-size: 12px; }
.row-link, .action-link { color: var(--fmuk-blue); background: none; border: none; cursor: pointer; font-size: 13px; font-weight: 700; padding: 0; }
.action-link { font-size: 12px; font-weight: 600; margin-right: 10px; }
.action-link.danger { color: var(--danger-red); }

.modal-backdrop { position: fixed; inset: 0; background: rgba(0,0,0,0.5); display: flex; align-items: center; justify-content: center; z-index: 10; }
.modal-backdrop.hidden { display: none; }
.modal-card { background: var(--card-white); border-radius: var(--card-radius); padding: var(--space-3); max-width: 560px; width: 90%; max-height: 85vh; overflow-y: auto; }
.modal-card.wide { max-width: 700px; }

/* Realigned to the prototype's .kv definition list: 12.5px, muted label, navy value,
   hairline separator rather than the full border-grey rule this used. */
.kv-row { display: flex; justify-content: space-between; padding: 5px 0; border-bottom: 1px solid var(--border-soft); font-size: 12.5px; gap: 15px; }
.kv-row:last-child { border-bottom: none; }
.kv-row span:first-child { color: var(--muted); font-weight: 600; }
.kv-row span:last-child { color: var(--navy); font-weight: 600; }
.kv-row.total { font-weight: 700; font-size: 15px; }
.totals-block { margin-top: var(--space-2); }
.export-row { display: flex; gap: var(--space-2); margin-top: var(--space-3); flex-wrap: wrap; align-items: end; }
.export-row .field label { display: block; margin-bottom: 4px; font-size: 13px; font-weight: 600; color: var(--secondary-text); }
.export-row .field input { min-height: 40px; padding: 0 var(--space-2); border: 1px solid var(--border-grey); border-radius: var(--button-radius); font-family: inherit; font-size: 14px; }

.summary-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--space-2); margin-bottom: var(--space-3); }
.summary-grid .label, .summary-card .summary-label, .detail-grid .label, .info-grid .label, .rules-grid .label, .asn-meta .label {
  font-size: 11.5px; color: var(--muted); text-transform: uppercase; font-weight: 700; letter-spacing: .5px;
}
.summary-grid .value, .summary-card .summary-value, .detail-grid .value, .info-grid .value, .rules-grid .value {
  font-size: 25px; font-weight: 700; color: var(--navy); letter-spacing: -.8px; margin-top: 4px;
}
.asn-meta { display: flex; gap: var(--space-4); margin-bottom: var(--space-2); flex-wrap: wrap; }
.asn-meta .value { font-size: 15px; font-weight: 700; color: var(--deep-navy); margin-top: 0; }
.summary-row { display: flex; gap: var(--space-3); margin-bottom: var(--space-3); flex-wrap: wrap; }
.summary-card { flex: 1; min-width: 160px; }
.summary-card .value { font-size: 26px; color: var(--fmuk-blue); }
.detail-grid, .info-grid, .rules-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: var(--space-2); margin-bottom: var(--space-3); }
.detail-grid .value { font-size: 12.5px; color: var(--navy); font-weight: 600; margin-top: 2px; }
.rules-grid { margin: var(--space-2) 0; }

.profile-grid, .two-col { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); }
.profile-grid { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
@media (max-width: 800px) { .two-col { grid-template-columns: 1fr; } }
@media (max-width: 900px) { .two-col { grid-template-columns: 1fr; } }

/* The prototype's .scanbox: a dashed accent-blue frame on a pale blue field, monospace
   input. This was a plain grey dashed box before, which read as a disabled control. */
.scan-box {
  width: 100%; min-height: 56px; font-size: 16px; text-align: center;
  border: 2px dashed var(--accent); border-radius: var(--r); background: #F0F9FF;
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace; color: var(--ink);
  margin-bottom: var(--space-2); padding: 13px 15px;
}
.scan-box:focus { border-style: solid; outline: none; box-shadow: 0 0 0 3px rgba(2,132,199,.13); }
.scan-box:disabled { background: var(--neutral-bg); cursor: not-allowed; }

.activity-list, .type-breakdown-list { list-style: none; margin: 0; padding: 0; }
.activity-list li { padding: 8px 0; border-bottom: 1px solid var(--border-grey); font-size: 14px; }
.activity-list li:last-child { border-bottom: none; }
.activity-when { color: var(--secondary-text); font-size: 12px; }
.type-breakdown-list { font-size: 14px; margin: 8px 0 0; }
.type-breakdown-list li { display: flex; justify-content: space-between; padding: 4px 0; border-bottom: 1px solid var(--border-grey); }

/* #112 row 4.6 -- the Processing Bench reference image. Bigger than .sku-thumb because
   this one is compared against a physical garment in the operator's hand, not scanned down
   a catalogue list. object-fit: contain, not cover: a cropped sleeve is worse than a small
   whole item when the question is "is this the same product". */
.reference-image-panel { display: flex; gap: var(--space-2); align-items: flex-start; margin-bottom: var(--space-3); }
.reference-image { width: 180px; height: 180px; object-fit: contain; background: var(--neutral-bg); border: 1px solid var(--border-grey); border-radius: var(--button-radius); display: block; flex-shrink: 0; }
.reference-image-missing { width: 180px; height: 180px; background: var(--neutral-bg); border: 1px dashed var(--border-grey); border-radius: var(--button-radius); color: var(--secondary-text); display: flex; align-items: center; justify-content: center; text-align: center; font-size: 12px; padding: var(--space-2); flex-shrink: 0; }
.sku-thumb { width: 40px; height: 40px; border-radius: var(--button-radius); object-fit: cover; display: block; }
.sku-thumb-placeholder { width: 40px; height: 40px; border-radius: var(--button-radius); background: var(--neutral-bg); color: var(--secondary-text); display: flex; align-items: center; justify-content: center; font-size: 9px; text-align: center; line-height: 1.1; }
/* #112 row 4.12 -- Verification Review. Bigger than .photo-thumbs img because 3a.3 asks a
   supervisor to reach a determination from these, not to glance at them.
   Its own container, deliberately: inside .photo-thumbs the `.photo-thumbs img` descendant
   rule (0,1,1) outranks .verification-photo (0,1,0) and these rendered at 56px, cropped --
   the exact opposite of the line above. A rule that is overridden is not a rule, so the
   override is removed rather than out-specified. */
.verification-photos { display: flex; gap: var(--space-2); flex-wrap: wrap; margin: var(--space-1) 0; }
.verification-photo { width: 200px; height: 200px; object-fit: contain; background: var(--neutral-bg); border: 1px solid var(--border-grey); border-radius: var(--button-radius); display: block; }
.verification-photo-slot { display: inline-flex; width: 200px; height: 200px; align-items: center; justify-content: center; background: var(--neutral-bg); border: 1px solid var(--border-grey); border-radius: var(--button-radius); color: var(--secondary-text); font-size: 12px; }
.verification-photo-missing { display: flex; width: 200px; height: 200px; align-items: center; justify-content: center; background: var(--neutral-bg); border: 1px dashed var(--border-grey); border-radius: var(--button-radius); color: var(--secondary-text); font-size: 12px; text-align: center; }
.photo-thumb { display: inline-block; width: 60px; height: 60px; background: var(--neutral-bg); border: 1px solid var(--border-grey); border-radius: 4px; margin-right: 6px; text-align: center; line-height: 60px; font-size: 10px; color: var(--secondary-text); }
.photo-thumbs { display: flex; gap: var(--space-1); flex-wrap: wrap; margin: var(--space-1) 0; }
.photo-thumbs img { width: 56px; height: 56px; object-fit: cover; border-radius: 4px; border: 1px solid var(--border-grey); }

.upload-area { border: 2px dashed var(--border-grey); border-radius: var(--button-radius); padding: var(--space-4); text-align: center; margin-bottom: var(--space-2); }
.upload-area.drag-over { border-color: var(--fmuk-blue); background: var(--neutral-bg); }
.payload-box, pre.search-result-json { background: var(--neutral-bg); border-radius: var(--button-radius); padding: var(--space-2); font-size: 13px; font-family: monospace; white-space: pre-wrap; word-break: break-word; }
.result-box { background: var(--neutral-bg); border-radius: var(--button-radius); padding: var(--space-2); margin-top: var(--space-2); }
.format-ref { font-size: 13px; color: var(--secondary-text); }
.format-ref code { background: var(--neutral-bg); padding: 1px 6px; border-radius: 4px; }

/* Toggle switch (Settings) */
.toggle { position: relative; display: inline-block; width: 44px; height: 24px; }
.toggle input { opacity: 0; width: 0; height: 0; }
.toggle-slider { position: absolute; cursor: pointer; inset: 0; background: var(--border-grey); border-radius: 999px; transition: 0.15s; }
.toggle-slider::before { content: ""; position: absolute; height: 18px; width: 18px; left: 3px; bottom: 3px; background: white; border-radius: 50%; transition: 0.15s; }
.toggle input:checked + .toggle-slider { background: var(--success-green); }
.toggle input:checked + .toggle-slider::before { transform: translateX(20px); }
.pref-row { display: flex; justify-content: space-between; align-items: center; padding: 10px 0; border-bottom: 1px solid var(--border-grey); }
.pref-row:last-child { border-bottom: none; }
.section-card { margin-bottom: var(--space-4); }

/* Report/gauge cards (internal + portal Reports overview) */
/* Realigned 19 Aug 2026 to the prototype's own Reports composition: a .grid.g3 of .card
   panels, each a .cardhead heading over a three-up .metrics strip. Done here rather than
   by rewriting both Reports screens' markup, because the class names map one-to-one onto
   the prototype's components -- .report-grid IS .grid.g3, .report-card IS .card,
   .report-card-numbers IS .metrics, .report-card-number IS .metric. */
.report-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 15px; }
@media (max-width: 1150px) { .report-grid { grid-template-columns: 1fr; } }
.report-card { display: block; text-decoration: none; color: inherit; background: var(--card); border: 1px solid var(--line); border-radius: var(--r); padding: 19px; }
.report-card-title { font-size: 15px; font-weight: 700; color: var(--navy); letter-spacing: -.2px; margin-bottom: 15px; }
.report-card-numbers { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0; margin-bottom: 15px; min-height: 40px; }
.report-card-number { padding: 0 20px; border-left: 1px solid var(--line-soft); }
.report-card-number:first-child { padding-left: 0; border-left: 0; }
.report-card-number .num-value { font-size: 25px; font-weight: 700; color: var(--navy); letter-spacing: -.8px; margin-top: 4px; }
.report-card-number .num-label { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .4px; color: var(--muted); }
.report-card:hover { box-shadow: 0 4px 14px rgba(14,54,107,0.15); }
.report-card .error-text { font-size: 12px; }
.gauge-track { display: flex; width: 100%; height: 16px; border-radius: 999px; overflow: hidden; background: var(--neutral-bg); }

/* Meter bars (Data & Storage capacity) */
.meter-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); margin-bottom: var(--space-3); }
.meter-card h3 { margin-top: 0; }
.meter-bar-track { height: 14px; border-radius: 999px; background: var(--neutral-bg); overflow: hidden; margin: 10px 0 6px; }
.meter-bar-fill { height: 100%; border-radius: 999px; }
.meter-bar-fill.band-GREEN { background: var(--success-green); }
.meter-bar-fill.band-AMBER { background: var(--warning-amber); }
.meter-bar-fill.band-RED { background: var(--danger-red); }
.meter-figures { display: flex; justify-content: space-between; font-size: 14px; color: var(--secondary-text); }
.meter-pct { font-size: 28px; font-weight: 700; color: var(--deep-navy); }
.archived-marker { display: inline-block; background: var(--neutral-bg); color: var(--secondary-text); font-size: 11px; font-weight: 700; text-transform: uppercase; padding: 2px 8px; border-radius: 4px; margin-left: 6px; }

/* Stat cards (System Life Cycle) */
.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: var(--space-3); margin-bottom: var(--space-2); }
.stat-card { text-align: center; }
.stat-value { font-size: 32px; font-weight: 700; color: var(--deep-navy); }
.stat-label { font-size: 12px; font-weight: 700; text-transform: uppercase; color: var(--secondary-text); margin-top: 4px; }
.stat-card.stat-good .stat-value { color: var(--success-green); }
.stat-card.stat-warn .stat-value { color: var(--warning-amber); }
.stat-card.stat-bad .stat-value { color: var(--danger-red); }

/* Roll Call present/absent boxes */
.box { display: inline-block; width: 18px; height: 18px; border: 2px solid var(--border-grey); border-radius: 3px; vertical-align: middle; }
.box-present { background: var(--success-green); border-color: var(--success-green); }
.box-absent { background: var(--danger-red); border-color: var(--danger-red); }
.present-label { color: var(--success-green); font-weight: 700; margin-left: 6px; }
.absent-label { color: var(--danger-red); font-weight: 700; margin-left: 6px; }

/* Investigation / dispute item lines */
.item-line { display: flex; gap: var(--space-2); margin-bottom: var(--space-1); align-items: center; }
.item-line input { flex: 1; }
.item-line input.qty { flex: 0 0 80px; }
.item-detail-card { border: 1px solid var(--border-grey); border-radius: var(--button-radius); padding: var(--space-2); margin-bottom: var(--space-2); }
.pending-row { display: flex; align-items: center; gap: var(--space-2); padding: 8px 0; border-bottom: 1px solid var(--border-grey); }
.pending-row input[type="checkbox"] { width: 18px; height: 18px; flex: 0 0 auto; }
.pending-row .pr-main { flex: 1; }
.pending-row .pr-sku { font-weight: 700; }
.pending-row .pr-meta { font-size: 12px; color: var(--secondary-text); }
.pick-row { display: flex; align-items: center; gap: var(--space-2); padding: 6px 0; border-bottom: 1px solid var(--border-grey); font-size: 14px; }
.fail-note { color: var(--danger-red); font-size: 12px; }
.ageing-note { color: var(--secondary-text); font-size: 12px; }
.comment-input { width: 100%; min-height: 32px; padding: 0 6px; font-size: 12px; border: 1px solid var(--border-grey); border-radius: 4px; margin-top: 4px; }
.bulk-bar { display: flex; gap: var(--space-2); align-items: center; margin-bottom: var(--space-2); flex-wrap: wrap; }
.bulk-bar input { flex: 1; min-width: 200px; min-height: 40px; padding: 0 var(--space-2); border: 1px solid var(--border-grey); border-radius: var(--button-radius); }
.stage-note { font-size: 12px; font-weight: 600; margin-top: 4px; padding: 4px 8px; border-radius: 4px; display: inline-block; }
.description-block { background: var(--neutral-bg); border-radius: var(--button-radius); padding: var(--space-2); margin-bottom: var(--space-3); font-size: 14px; }

/* Restore/search widgets (Data & Storage archive) */
.eligible-periods { font-size: 13px; color: var(--secondary-text); margin: 6px 0 var(--space-2); }
.search-results { margin-top: var(--space-2); }
.restore-row { display: flex; gap: 8px; align-items: center; margin-top: var(--space-2); flex-wrap: wrap; }
.restore-row select, .restore-row input { min-height: 36px; padding: 0 8px; border: 1px solid var(--border-grey); border-radius: 6px; font-size: 13.5px; }

/* Version history (Rate Card) */
.change-line { font-size: 13px; padding: 2px 0; }
.change-line .old { color: var(--secondary-text); text-decoration: line-through; }
.change-line .arrow { color: var(--secondary-text); margin: 0 4px; }
.change-line .new { color: var(--success-green); font-weight: 700; }
.version-card { border: 1px solid var(--border-grey); border-radius: var(--button-radius); padding: var(--space-2); margin-bottom: var(--space-2); }
.version-head { display: flex; justify-content: space-between; align-items: baseline; font-size: 13px; margin-bottom: 6px; }
.version-head .when { font-weight: 700; color: var(--primary-text); }
.version-head .who { color: var(--secondary-text); }

/* Permissions (Edit User) */
.perm-row { display: flex; justify-content: space-between; align-items: center; padding: 10px 0; border-bottom: 1px solid var(--border-grey); }
.perm-badge { display: inline-block; padding: 2px 10px; border-radius: 999px; font-size: 12px; font-weight: 700; background: #EFF6FF; color: var(--fmuk-blue); margin-right: 8px; }
.perm-meta { font-size: 12px; color: var(--secondary-text); margin-top: 2px; }

/* Processing Bench specifics */
.bench-header { display: flex; justify-content: space-between; align-items: flex-start; gap: 18px; margin-bottom: 22px; flex-wrap: wrap; }
.bench-header .meta { display: flex; gap: var(--space-3); font-size: 13px; color: var(--muted); margin-top: 2px; }
.bench-header .timer { font-variant-numeric: tabular-nums; font-weight: 700; color: var(--deep-navy); }
/* Superseded 19 Aug 2026 -- the row is now .grid.g3 (the prototype's own three-up grade
   tiles); only the vertical rhythm is still set here. */
.grade-btn-row { margin: var(--space-2) 0; }
.step-heading { display: flex; align-items: center; gap: var(--space-2); }
.step-number { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; border-radius: 50%; background: var(--btn); color: #fff; font-size: 12px; font-weight: 700; flex-shrink: 0; }
.step-number.done { background: var(--success-green); }
.step-card { opacity: 1; margin-top: var(--space-3); }
.step-card.disabled, .step-card.step-locked { opacity: 0.5; pointer-events: none; }
.verification-gate { background: var(--neutral-bg); border: 1px solid var(--border-grey); border-radius: var(--button-radius); padding: var(--space-2); margin-bottom: var(--space-2); }
.verification-gate .prompt { font-weight: 700; margin-bottom: var(--space-2); }
.hazard-row { display: flex; justify-content: flex-end; margin-bottom: var(--space-2); }

/* Dashboard-specific (index.html, portal/index.html) */
/* These are the build's own honest "what isn't here yet" disclosures. Given the prototype's
   own .note.info treatment for exactly this kind of aside, they read as a bordered blue
   panel rather than a loose grey paragraph -- distinct from the page's real content, which
   is the point of them. */
.skip-note { background: #EFF6FF; border: 1px solid #BAE6FD; border-radius: 8px; padding: 11px 13px;
  font-size: 12px; color: #075985; margin-top: 24px; line-height: 1.5; max-width: 840px; }
.loading, .error-text { padding: var(--space-3); }
.dash-lower-grid { display: grid; grid-template-columns: 1.3fr 1fr; gap: var(--space-3); margin-top: var(--space-3); }
@media (max-width: 900px) { .dash-lower-grid { grid-template-columns: 1fr; } }
.dash-lower-grid h2 { font-size: 16px; margin: 0 0 var(--space-2); }
.attention-row { display: flex; align-items: baseline; gap: var(--space-2); padding: 10px 0; border-bottom: 1px solid var(--border-grey); text-decoration: none; color: inherit; }
.attention-row:last-child { border-bottom: none; }
.attention-title { font-weight: 600; font-size: 14px; flex-shrink: 0; }
.attention-detail { color: var(--secondary-text); font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.op-next-card { display: block; text-decoration: none; border-radius: var(--card-radius); padding: var(--space-4); margin: var(--space-3) 0; background: linear-gradient(135deg, #0284C7, #2BB8E8); box-shadow: 0 8px 24px rgba(2,132,199,0.35); transition: transform 0.15s; }
a.op-next-card:hover { transform: translateY(-2px); }
.op-next-label { font-size: 13px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: rgba(255,255,255,0.85); }
.op-next-title { font-size: 30px; font-weight: 700; margin-top: 8px; color: #fff; }
.op-next-detail { font-size: 15px; margin-top: 6px; color: rgba(255,255,255,0.9); }
.op-stats-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2); margin-top: var(--space-3); }
.op-stat-value { font-size: 30px; font-weight: 700; color: var(--primary-text); }
.op-stat-label { font-size: 13px; color: var(--secondary-text); margin-top: 4px; }
.filter-row { display: flex; gap: var(--space-2); flex-wrap: wrap; margin-bottom: var(--space-2); }

/* Login / forgot / reset password pre-login pages */
.login-logo { display: block; height: 48px; width: auto; margin: 0 auto var(--space-3); }
.login-card {
  width: 100%; max-width: 400px;
  position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%);
}
.login-card h1 { font-size: 24px; margin: 0 0 4px; letter-spacing: 0; }
.login-subtitle { color: var(--secondary-text); margin: 0 0 var(--space-3); }
.password-wrap { position: relative; }
.password-wrap button { position: absolute; right: 8px; top: 50%; transform: translateY(-50%); background: none; border: none; cursor: pointer; color: var(--secondary-text); font-size: 13px; font-weight: 600; min-height: 32px; }
.options-row { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--space-3); font-size: 14px; }
.options-row label { display: flex; align-items: center; gap: 6px; color: var(--primary-text); font-weight: 400; }
.options-row a { color: var(--fmuk-blue); text-decoration: none; }
.options-row a:hover { text-decoration: underline; }
.footer-text { text-align: center; margin-top: var(--space-3); color: var(--secondary-text); font-size: 12px; line-height: 1.6; }
.requirements { font-size: 12px; color: var(--secondary-text); margin: 4px 0 var(--space-2); line-height: 1.5; }
body.center-page { display: flex; align-items: center; justify-content: center; min-height: 100vh; }

/* Section heading spacer (Inventory) */
.section-heading { margin-top: var(--space-4); }
.action-cell { min-width: 220px; }
.confirm-row { display: flex; gap: 6px; margin-top: 6px; align-items: center; }
.confirm-row input { min-height: 32px; padding: 0 8px; border: 1px solid var(--border-grey); border-radius: 6px; font-size: 13px; width: 110px; }
.dry-run-result { font-size: 12.5px; color: var(--secondary-text); margin-top: 6px; padding: 6px 8px; background: var(--neutral-bg); border-radius: 6px; }
.last-run-line { color: var(--secondary-text); font-size: 13px; margin: 4px 0 var(--space-3); }
.staff-header { display: flex; align-items: center; gap: var(--space-2); margin-bottom: var(--space-3); }
.flag-row { padding: 8px 0; border-bottom: 1px solid var(--border-grey); font-size: 14px; }
.employee-row { background: var(--neutral-bg); font-weight: 700; }
.correct-link { color: var(--fmuk-blue); font-size: 12px; font-weight: 600; cursor: pointer; margin-left: 8px; }
.link-out-row { display: flex; gap: var(--space-2); flex-wrap: wrap; }
.page-controls { display: flex; gap: var(--space-2); align-items: center; margin-top: var(--space-2); }
.unknown-form .field { margin-bottom: var(--space-2); }
.unknown-form label { display: block; margin-bottom: 4px; }
.pallet-count { font-size: 28px; font-weight: 700; color: var(--fmuk-blue); text-align: center; margin: var(--space-2) 0; }
.selected-count-hint { font-weight: 600; }

/* ═══════════════════════════ Shell (header, nav, bell, clock) ═══════════════════════════ */
/* Relocated verbatim from fmuk-ui.css -- see this file's own header comment for why these
   class names (not .back-link/.trend-badge/.nav-dropdown-trigger) are kept: nothing above
   ever redefined them, so they never had the cascade collision this correction fixes. */
header { background: var(--surface); border-bottom: 1px solid var(--line); padding: 0 32px; display: flex;
align-items: center; gap: 18px; height: 60px; position: sticky; top: 0; z-index: 41; }
.logo { display: flex; align-items: center; gap: 9px; cursor: pointer; }
/* The real FMUK circular mark, cropped from the company logo. No page uses it now --
   the full lockup below replaced it -- but it stays defined for tight spaces. */
.logo-mark { width: 25px; height: 25px; background-repeat: no-repeat;
  background-position: center; background-size: contain;
  background-image: url("/static/img/fmuk-mark.png"); }

.logo-txt { font-weight: 700; color: var(--navy); font-size: 14px; letter-spacing: -.3px; line-height: 1.1; }
.logo-txt s { display: block; font-size: 8.5px; letter-spacing: 1.4px; color: var(--muted); text-decoration: none; font-weight: 600; }
.navdrop { display: flex; align-items: center; gap: 8px; border: 1px solid var(--line); background: var(--card);
padding: 8px 14px; border-radius: 8px; font-weight: 600; color: var(--navy); cursor: pointer; font-size: 13.5px;
user-select: none; min-width: 196px; justify-content: space-between; }
.navdrop .chev { color: var(--accent); font-size: 11px; }
.navdrop.open { border-color: var(--btn); box-shadow: 0 0 0 3px rgba(2,132,199,.13); }
.hgap { flex: 1; }
/* Superseded 19 Aug 2026 by the prototype design system at the end of this file, which is
   the signed-off design: the pill is red when not clocked in and green when clocked in.
   The muted-grey `.out` variant CORRECTION_02 2.3 introduced would still have won on
   specificity (0,2,0 beats 0,1,0) regardless of source order, so it is removed here rather
   than left in place to silently override. Class name kept on the element -- it is what
   layout.js writes -- it just no longer carries a colour of its own. */
.clockpill { cursor: default; }
.bell { position: relative; color: var(--navy); font-size: 16px; cursor: pointer; }
.bell b { position: absolute; top: -5px; right: -7px; background: var(--btn); color: #fff; font-size: 9.5px; min-width: 15px;
height: 15px; border-radius: 8px; display: grid; place-items: center; font-weight: 700; }
.who { font-size: 12px; color: var(--ink-2); line-height: 1.3; }
.who b { color: var(--navy); display: block; font-size: 12.5px; }
main { padding: 26px 32px 56px; max-width: 1520px; }
.crumb { color: var(--accent); font-size: 13px; font-weight: 600; margin-bottom: 12px; cursor: pointer; display: inline-block; }
.pagenav { background: var(--card); border-bottom: 1px solid var(--line); padding: 0 32px; display: flex;
gap: 1px; flex-wrap: wrap; position: sticky; top: 60px; z-index: 38; }
.pagenav a { padding: 13px 15px 12px; font-size: 13px; font-weight: 600; color: var(--muted); cursor: pointer;
border-bottom: 2px solid transparent; white-space: nowrap; margin-bottom: -1px; text-decoration: none; }
.pagenav a:hover { color: var(--navy); }
.pagenav a.on { color: var(--navy); border-bottom-color: var(--btn); }
#menu, #user-menu { position: fixed; width: 330px; background: var(--card); border: 1px solid var(--line); border-radius: 12px;
box-shadow: 0 14px 38px rgba(15,23,42,.16); padding: 7px; z-index: 80; display: none; }
#menu.open, #user-menu.open { display: block; }
#user-menu { width: 200px; }
.mhead { font-size: 10.5px; font-weight: 700; letter-spacing: .7px; text-transform: uppercase; color: var(--muted);
padding: 8px 12px 6px; }
.mrow { display: flex; align-items: center; gap: 11px; padding: 9px 12px; border-radius: 8px; cursor: pointer;
font-size: 13.5px; font-weight: 600; color: var(--navy); line-height: 1.35; }
.mrow:hover { background: var(--surface); }
.mrow small { display: block; font-size: 11px; font-weight: 400; color: var(--muted); margin-top: 1px; }
.mrow .n { margin-left: auto; font-size: 11px; color: var(--muted); font-weight: 700; flex-shrink: 0; }
.mrow .tick { color: var(--btn); font-size: 12.5px; font-weight: 700; flex-shrink: 0; margin-left: 12px; visibility: hidden; }
.mrow.here { background: #F0F9FF; box-shadow: inset 2px 0 0 var(--btn); }
.mrow.here .tick { visibility: visible; }
.mnote { font-size: 11px; color: var(--muted); padding: 9px 12px 5px; line-height: 1.5;
border-top: 1px solid var(--line-soft); margin-top: 4px; }
.mflag { font-size: 9.5px; font-weight: 700; color: var(--btn); background: #F0F9FF; border: 1px solid #BAE6FD;
border-radius: 4px; padding: 1px 5px; letter-spacing: .3px; margin-left: 6px; vertical-align: 1px; }
.pill { display: inline-flex; align-items: center; gap: 5px; padding: 3px 10px; border-radius: 20px; font-size: 11.5px;
font-weight: 700; letter-spacing: .2px; white-space: nowrap; }
.pill.good { background: var(--good-bg); color: var(--good); border: 1px solid #BBF7D0; }
.pill.warn { background: var(--warn-bg); color: #854D0E; border: 1px solid #FEF08A; }
.pill.crit { background: var(--crit-bg); color: var(--crit); border: 1px solid #FECACA; }
.pill.mute { background: var(--line-soft); color: var(--muted); border: 1px solid var(--line); }
.view-as-banner { position: sticky; top: 60px; z-index: 37; border-radius: 0; margin: 0; padding: 11px 32px;
display: flex; align-items: center; justify-content: center; gap: 14px; font-weight: 600; font-size: 13px;
background: #EFF6FF; color: #075985; border-bottom: 1px solid #BAE6FD; }
.notification-menu { position: fixed; width: 340px; max-height: 70vh; overflow-y: auto; background: var(--card);
border: 1px solid var(--line); border-radius: 12px; box-shadow: 0 14px 38px rgba(15,23,42,.16); z-index: 80; }
.notification-menu-header { padding: 12px 14px; font-weight: 700; color: var(--navy); border-bottom: 1px solid var(--line); font-size: 13.5px; }
.notification-item { display: block; padding: 11px 14px; border-bottom: 1px solid var(--line-soft); text-decoration: none; color: inherit; }
.notification-item:last-child { border-bottom: 0; }
.notification-item:hover { background: var(--surface); }
.notification-item.unread { background: #F0F9FF; }
.notification-item-title { font-size: 12.5px; font-weight: 700; color: var(--navy); }
.notification-item-detail { font-size: 11.5px; color: var(--muted); margin-top: 2px; }
.notification-item-time { font-size: 10.5px; color: var(--muted); margin-top: 4px; }
.notification-empty { padding: 19px; text-align: center; color: var(--muted); font-size: 12.5px; }

.app-shell { display: flex; flex-direction: column; min-height: 100vh; }

/* .subnav / .subnav-tab removed 19 Aug 2026 -- a third row of navigation under the
   header dropdown and the page strip. No prototype screen has one, and CLAUDE.md's nav
   rule is explicit that the strip is where an area's pages live. Every use was deleted. */

.clock-widget-status { font-size: 15px; font-weight: 600; color: var(--deep-navy); margin-bottom: var(--space-2); }
.clock-widget-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-2); }
.clock-widget-grid .btn { min-height: 48px; }
@media (max-width: 700px) { .clock-widget-grid { grid-template-columns: 1fr 1fr; } }


/* ═════════════════════════════════════════════════════════════════════════════
   PROTOTYPE DESIGN SYSTEM (19 Aug 2026)

   Ported verbatim from FMUK_ROS_Prototype.html's own <style> block -- the design that
   was signed off. Before this, 119 of the prototype's 170 selectors did not exist in
   this file at all (.stat/.metric/.action/.titlerow/.cardhead/.grid.g4/.av/.track/
   .stack/.legend/.kv/.note/.tabs/.scanbox/.step...), and the app had grown a parallel
   vocabulary of its own (.kpi-card, .status-pill, .inv-table) that renders nothing like
   it. Every value below is the prototype's, not a re-derivation.

   Placed last on purpose: where a name collides with the older vocabulary (.card, .btn,
   .field, .pill, .btnrow) these are the same specificity, so source order decides and
   the prototype wins -- which is the point.

   Deliberately NOT ported: .chrome / #protobar / .screen (the prototype's own
   click-through harness, meaningless in a real multi-page app) and its :root block
   (this file's own tokens already alias every one of its variable names -- see the top).
   ═════════════════════════════════════════════════════════════════════════════ */

.mono { font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace; font-size: 12.5px; letter-spacing: -.2px; }

body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Roboto, Helvetica, Arial, sans-serif;
  background: var(--surface); color: var(--ink); font-size: 14px; line-height: 1.5; -webkit-font-smoothing: antialiased; }
header { background: var(--surface); border-bottom: 1px solid var(--line); padding: 0 32px; display: flex;
  align-items: center; gap: 18px; height: 60px; position: sticky; top: 0; z-index: 41; }
.logo { display: flex; align-items: center; gap: 9px; cursor: pointer; }
/* The real FMUK circular mark, cropped from the company logo. No page uses it now --
   the full lockup below replaced it -- but it stays defined for tight spaces. */
.logo-mark { width: 25px; height: 25px; background-repeat: no-repeat;
  background-position: center; background-size: contain;
  background-image: url("/static/img/fmuk-mark.png"); }

.logo-txt { font-weight: 700; color: var(--navy); font-size: 14px; letter-spacing: -.3px; line-height: 1.1; }
.logo-txt s { display: block; font-size: 8.5px; letter-spacing: 1.4px; color: var(--muted); text-decoration: none; font-weight: 600; }
.navdrop { display: flex; align-items: center; gap: 8px; border: 1px solid var(--line); background: var(--card);
  padding: 8px 14px; border-radius: 8px; font-weight: 600; color: var(--navy); cursor: pointer; font-size: 13.5px;
  user-select: none; min-width: 196px; justify-content: space-between; }
.navdrop .chev { color: var(--accent); font-size: 11px; }
.navdrop.open { border-color: var(--btn); box-shadow: 0 0 0 3px rgba(2,132,199,.13); }
.hgap { flex: 1; }
.clockpill { background: var(--crit); color: #fff; padding: 6px 13px; border-radius: 7px; font-weight: 600; font-size: 12px; }
.clockpill.in { background: var(--good); }
.bell { position: relative; color: var(--navy); font-size: 16px; cursor: pointer; }
.bell b { position: absolute; top: -5px; right: -7px; background: var(--btn); color: #fff; font-size: 9.5px; min-width: 15px;
  height: 15px; border-radius: 8px; display: grid; place-items: center; font-weight: 700; }
.who { font-size: 12px; color: var(--ink-2); line-height: 1.3; }
.who b { color: var(--navy); display: block; font-size: 12.5px; }
main { padding: 26px 32px 56px; max-width: 1520px; }
.crumb { color: var(--accent); font-size: 13px; font-weight: 600; margin-bottom: 12px; cursor: pointer; display: inline-block; }
h1 { font-size: 26px; color: var(--navy); letter-spacing: -.6px; font-weight: 700; }
.sub { color: var(--muted); font-size: 13px; margin-top: 2px; }
.titlerow { display: flex; align-items: flex-start; gap: 18px; margin-bottom: 22px; flex-wrap: wrap; }
.titlerow .rt { margin-left: auto; display: flex; gap: 9px; align-items: center; flex-wrap: wrap; }
.sync { background: var(--card); border: 1px solid var(--line); border-radius: 8px; padding: 7px 13px; font-size: 12px;
  color: var(--ink-2); display: flex; align-items: center; gap: 8px; }
.dot { width: 7px; height: 7px; border-radius: 50%; background: var(--good); }

.card { background: var(--card); border: 1px solid var(--line); border-radius: var(--r); padding: 19px; }
.card h2 { font-size: 15px; color: var(--navy); font-weight: 700; letter-spacing: -.2px; }
.cardhead { display: flex; align-items: baseline; gap: 11px; margin-bottom: 15px; }
.hint { font-size: 12px; color: var(--muted); margin: -9px 0 14px; }
.link { margin-left: auto; color: var(--accent); font-size: 12.5px; font-weight: 600; cursor: pointer; white-space: nowrap; }

.grid { display: grid; gap: 15px; }
.g4 { grid-template-columns: repeat(4,1fr); }
.g3 { grid-template-columns: repeat(3,1fr); }
.g2 { grid-template-columns: 2fr 1fr; }
.g21 { grid-template-columns: 1fr 1fr; }
.g12 { grid-template-columns: 1fr 2fr; }
@media (max-width: 1150px) { .g4, .g3, .g2, .g21, .g12 { grid-template-columns: 1fr; } }
.stackrow { display: flex; flex-direction: column; gap: 15px; }

.stat { background: var(--card); border: 1px solid var(--line); border-radius: var(--r); padding: 17px 19px; border-top: 3px solid var(--line); }
.stat.good { border-top-color: var(--good); }
.stat.warn { border-top-color: var(--warn); }
.stat.crit { border-top-color: var(--crit); }
.stat.info { border-top-color: var(--btn); }
.stat .lbl { font-size: 11.5px; color: var(--muted); font-weight: 700; text-transform: uppercase; letter-spacing: .5px;
  display: flex; align-items: center; gap: 6px; margin-bottom: 9px; }
.stat .num { font-size: 29px; font-weight: 700; color: var(--navy); letter-spacing: -1px; line-height: 1.1; }
.stat .num small { font-size: 13px; color: var(--muted); font-weight: 600; letter-spacing: 0; margin-left: 5px; }
.stat .foot { font-size: 11.5px; color: var(--ink-2); margin-top: 8px; line-height: 1.45; }

.metrics { display: grid; gap: 0; }
.metric { padding: 0 20px; border-left: 1px solid var(--line-soft); }
.metric:first-child { padding-left: 0; border-left: 0; }
.metric .lbl { font-size: 11px; color: var(--muted); font-weight: 700; text-transform: uppercase; letter-spacing: .4px; }
.metric .num { font-size: 25px; font-weight: 700; color: var(--navy); letter-spacing: -.8px; margin-top: 4px; }
.metric .num.w { color: var(--warn); }
.metric .num.c { color: var(--crit); }
.metric .num.g { color: var(--good); }
.metric .num small { font-size: 11.5px; color: var(--muted); font-weight: 600; letter-spacing: 0; margin-left: 4px; }

.pill { display: inline-flex; align-items: center; gap: 5px; padding: 3px 10px; border-radius: 20px; font-size: 11.5px;
  font-weight: 700; letter-spacing: .2px; white-space: nowrap; }
.pill.good { background: var(--good-bg); color: var(--good); border: 1px solid #BBF7D0; }
.pill.warn { background: var(--warn-bg); color: #854D0E; border: 1px solid #FEF08A; }
.pill.crit { background: var(--crit-bg); color: var(--crit); border: 1px solid #FECACA; }
.pill.info { background: #EFF6FF; color: #075985; border: 1px solid #BAE6FD; }
.pill.mute { background: var(--line-soft); color: var(--muted); border: 1px solid var(--line); }
.pill.solid { background: var(--btn); color: #fff; border: 1px solid var(--btn); }

table { width: 100%; border-collapse: collapse; }
th { text-align: left; font-size: 10.5px; color: var(--muted); text-transform: uppercase; letter-spacing: .6px;
  font-weight: 700; padding: 0 11px 9px 0; border-bottom: 1px solid var(--line); white-space: nowrap; }
td { padding: 12px 11px 12px 0; border-bottom: 1px solid var(--line-soft); font-size: 13px; vertical-align: middle; }
tr:last-child td { border-bottom: 0; }
td.n { color: var(--navy); font-weight: 600; }
td.r, th.r { text-align: right; padding-left: 22px; }
.act { color: var(--accent); font-weight: 600; cursor: pointer; font-size: 12.5px; }

.row { display: flex; align-items: center; gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--line-soft); }
.row:last-child { border-bottom: 0; }
.av { width: 34px; height: 34px; border-radius: 8px; background: var(--btn); color: #fff; display: grid; place-items: center;
  font-size: 11px; font-weight: 700; flex-shrink: 0; }
.av.g { background: var(--good); }
.av.w { background: var(--warn); }
.av.c { background: var(--crit); }
.av.m { background: var(--line-soft); color: var(--muted); }
.row .t { font-weight: 600; color: var(--navy); font-size: 13px; }
.row .s { font-size: 11.5px; color: var(--muted); margin-top: 1px; }
.row .rr { margin-left: auto; text-align: right; }

.action { border: 1px solid var(--line); border-left: 3px solid var(--btn); border-radius: 8px; padding: 12px 14px;
  margin-bottom: 10px; background: var(--card); }
.action:last-child { margin-bottom: 0; }
.action.w { border-left-color: var(--warn); }
.action.c { border-left-color: var(--crit); }
.action.g { border-left-color: var(--good); }
.action .k { font-size: 10.5px; font-weight: 700; letter-spacing: .6px; text-transform: uppercase; color: var(--btn); }
.action.w .k { color: #854D0E; }
.action.c .k { color: var(--crit); }
.action.g .k { color: var(--good); }
.action .when { float: right; font-size: 11px; color: var(--muted); font-weight: 500; letter-spacing: 0; text-transform: none; }
.action p { font-size: 12.5px; color: var(--ink); margin-top: 5px; line-height: 1.5; }

.bar { margin-bottom: 14px; }
.bar:last-child { margin-bottom: 0; }
.bar .top { display: flex; font-size: 12.5px; margin-bottom: 6px; align-items: center; gap: 7px; }
.bar .top .v { margin-left: auto; font-weight: 700; color: var(--navy); }
.track { height: 9px; background: var(--line-soft); border-radius: 5px; overflow: hidden; }
.fill { height: 100%; border-radius: 5px; }
.fill.good { background: var(--good); }
.fill.warn { background: var(--warn); }
.fill.crit { background: var(--crit); }
.fill.info { background: var(--btn); }
.stack { display: flex; height: 11px; border-radius: 6px; overflow: hidden; gap: 2px; background: var(--line-soft); }
.stack i { display: block; height: 100%; }
.legend { display: flex; gap: 16px; margin-top: 11px; flex-wrap: wrap; }
.legend span { display: flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--ink-2); }
.legend i { width: 10px; height: 10px; border-radius: 3px; display: block; }

.scanbox { border: 2px dashed var(--accent); border-radius: var(--r); padding: 24px; text-align: center; background: #F0F9FF; }
.scanbox .big { font-size: 18px; font-weight: 700; color: var(--navy); }
.scanbox .sm { font-size: 12.5px; color: var(--ink-2); margin-top: 4px; }
.scanbox input { margin-top: 14px; width: 100%; max-width: 400px; padding: 13px 15px; font-size: 16px; border: 1px solid var(--line);
  border-radius: 8px; font-family: ui-monospace, monospace; background: #fff; }

.step { display: flex; align-items: center; gap: 11px; padding: 10px 0; }
.stepno { width: 26px; height: 26px; border-radius: 50%; background: var(--btn); color: #fff; display: grid; place-items: center;
  font-size: 12px; font-weight: 700; flex-shrink: 0; }
.stepno.done { background: var(--good); }
.stepno.idle { background: var(--line); color: var(--muted); }
.step .txt { font-size: 13px; font-weight: 600; color: var(--navy); }
.step .txt small { display: block; font-weight: 400; color: var(--muted); font-size: 11.5px; margin-top: 1px; }

.btn { display: inline-block; background: var(--btn); color: #fff; border: 0; padding: 12px 24px; border-radius: 8px;
  font-weight: 700; font-size: 13.5px; cursor: pointer; font-family: inherit; min-height: 0; text-align: center;
  text-transform: none; text-decoration: none; }
.btn.ghost { background: transparent; color: var(--navy); border: 1px solid var(--line); }
.btn.sm { padding: 8px 16px; font-size: 12.5px; }
.btn.danger { background: transparent; border: 1px solid #FECACA; color: var(--crit); }
.btnrow { display: flex; gap: 10px; margin-top: 16px; flex-wrap: wrap; }

.thumb { width: 96px; height: 96px; border-radius: 8px; background: var(--line-soft); border: 1px solid var(--line);
  display: grid; place-items: center; color: var(--muted); font-size: 10.5px; text-align: center; flex-shrink: 0; padding: 7px; }
.thumb.sm { width: 42px; height: 42px; font-size: 8px; padding: 3px; }
.kv { display: grid; grid-template-columns: auto 1fr; gap: 5px 15px; font-size: 12.5px; }
.kv dt { color: var(--muted); font-weight: 600; }
.kv dd { color: var(--navy); font-weight: 600; }
.note { background: var(--warn-bg); border: 1px solid #FEF08A; border-radius: 8px; padding: 11px 13px; font-size: 12px;
  color: #713F12; margin-top: 13px; display: flex; gap: 9px; line-height: 1.5; }
.note.info { background: #EFF6FF; border-color: #BAE6FD; color: #075985; }
.note.crit { background: var(--crit-bg); border-color: #FECACA; color: #7F1D1D; }

.field { margin-bottom: 15px; }
.field label { display: block; font-size: 12px; font-weight: 700; color: var(--ink-2); margin-bottom: 5px; }
.field input, .field select, .field textarea { width: 100%; padding: 10px 12px; border: 1px solid var(--line);
  border-radius: 8px; font-size: 13.5px; font-family: inherit; background: #fff; color: var(--ink); min-height: 0; }
.field .help { font-size: 11.5px; color: var(--muted); margin-top: 4px; }
.tabs { display: flex; gap: 3px; border-bottom: 1px solid var(--line); margin-bottom: 18px; flex-wrap: wrap; }
.tabs a { padding: 9px 15px; font-size: 13px; font-weight: 600; color: var(--muted); border-bottom: 2px solid transparent; cursor: pointer; text-decoration: none; }
.tabs a.on { color: var(--navy); border-bottom-color: var(--btn); }
.search { width: 100%; padding: 11px 14px; border: 1px solid var(--line); border-radius: 8px; font-size: 13.5px;
  font-family: inherit; background: #fff; margin-bottom: 15px; color: var(--muted); }
.empty { text-align: center; padding: 34px 20px; color: var(--muted); font-size: 13px; }
.empty .ico { font-size: 26px; margin-bottom: 9px; opacity: .4; }

.pagenav { background: var(--card); border-bottom: 1px solid var(--line); padding: 0 32px; display: flex;
  gap: 1px; flex-wrap: wrap; position: sticky; top: 60px; z-index: 38; }
.pagenav a { padding: 13px 15px 12px; font-size: 13px; font-weight: 600; color: var(--muted); cursor: pointer;
  border-bottom: 2px solid transparent; white-space: nowrap; margin-bottom: -1px; text-decoration: none; }
.pagenav a:hover { color: var(--navy); }
.pagenav a.on { color: var(--navy); border-bottom-color: var(--btn); }
#menu { position: fixed; width: 330px; background: var(--card); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 14px 38px rgba(15,23,42,.16); padding: 7px; z-index: 80; display: none; }
#menu.open { display: block; }
.mhead { font-size: 10.5px; font-weight: 700; letter-spacing: .7px; text-transform: uppercase; color: var(--muted);
  padding: 8px 12px 6px; }
.mrow { display: flex; align-items: center; gap: 11px; padding: 9px 12px; border-radius: 8px; cursor: pointer;
  font-size: 13.5px; font-weight: 600; color: var(--navy); line-height: 1.35; }
.mrow:hover { background: var(--surface); }
.mrow small { display: block; font-size: 11px; font-weight: 400; color: var(--muted); margin-top: 1px; }
.mrow .n { margin-left: auto; font-size: 11px; color: var(--muted); font-weight: 700; flex-shrink: 0; }
.mrow .tick { color: var(--btn); font-size: 12.5px; font-weight: 700; flex-shrink: 0; margin-left: 12px; visibility: hidden; }
.mrow.here { background: #F0F9FF; box-shadow: inset 2px 0 0 var(--btn); }
.mrow.here .tick { visibility: visible; }
.mnote { font-size: 11px; color: var(--muted); padding: 9px 12px 5px; line-height: 1.5;
  border-top: 1px solid var(--line-soft); margin-top: 4px; }
.mflag { font-size: 9.5px; font-weight: 700; color: var(--btn); background: #F0F9FF; border: 1px solid #BAE6FD;
  border-radius: 4px; padding: 1px 5px; letter-spacing: .3px; margin-left: 6px; vertical-align: 1px; }

/* ── Utility classes standing in for the prototype's own inline style= attributes ──
   test_no_inline_styles.py forbids style= under app/static entirely, so every static
   value the prototype wrote inline gets a class here. Genuinely per-instance values (a
   bar's computed width %, a column's px width) are set via element.style.x after
   insertion, which that test allows and which is what they already were: computed from
   real data, not fixed design values. */
/* Wraps a block component (.action, .stat, .card) in a real <a> without the browser's
   inline/blue-underline default fighting the component's own look. `.no-underline` alone
   was not enough: an <a> is display:inline and colour:LinkText, so an .action rendered as
   a link lost its box entirely. */
.aslink { display: block; color: inherit; text-decoration: none; }

/* Grade tiles (Processing Bench) — the prototype's own three-up grade buttons: the letter
   large and in its grade colour, what the grade means underneath in muted small text. */
.gradetile { padding: 17px 10px; display: block; }
.gradetile .g { display: block; font-size: 18px; font-weight: 700; }
.gradetile .g.good { color: var(--good); }
.gradetile .g.warn { color: var(--warn); }
.gradetile .g.crit { color: var(--crit); }
.gradetile .w { display: block; font-size: 11px; color: var(--muted); font-weight: 500; margin-top: 2px; }

/* Header clock popover — same card/shadow language as #menu, hung off the .clockpill. */
.clock-menu { position: fixed; width: 320px; background: var(--card); border: 1px solid var(--line);
  border-radius: 12px; box-shadow: 0 14px 38px rgba(15,23,42,.16); padding: 15px; z-index: 80; display: none; }
.clock-menu.open { display: block; }
.clock-menu .clock-widget-status { font-size: 12.5px; color: var(--ink-2); margin-bottom: 11px; line-height: 1.45; }
.clock-menu .clock-widget-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.clock-menu .btn { padding: 9px 10px; font-size: 12.5px; }

.mb-0 { margin-bottom: 0; }
.mb-15 { margin-bottom: 15px; }
.mb-16 { margin-bottom: 16px; }
.mb-26 { margin-bottom: 26px; }
.mt-0 { margin-top: 0; }
.mt-11 { margin-top: 11px; }
.mt-12 { margin-top: 12px; }
.mt-13 { margin-top: 13px; }
.mt-14 { margin-top: 14px; }
.mt-15 { margin-top: 15px; }
.mt-16 { margin-top: 16px; }
.ml-12 { margin-left: 12px; }
.gc2 { grid-template-columns: repeat(2,1fr); }
.gc3 { grid-template-columns: repeat(3,1fr); }
.gc4 { grid-template-columns: repeat(4,1fr); }
@media (max-width: 1150px) { .gc2, .gc3, .gc4 { grid-template-columns: 1fr; } }
.muted { color: var(--muted); }
.navy { color: var(--navy); font-weight: 700; }
.good-text { color: var(--good); font-weight: 700; }
.warn-text { color: var(--warn); font-weight: 700; }
.crit-text { color: var(--crit); font-weight: 700; }
.center { text-align: center; }
.left { text-align: left; }
.full { width: 100%; }
.mw-760 { max-width: 760px; }
.mw-820 { max-width: 820px; }
.mw-840 { max-width: 840px; }
.mw-860 { max-width: 860px; }
.mw-900 { max-width: 900px; }
.mw-1000 { max-width: 1000px; }
.mw-1100 { max-width: 1100px; }
.mw-1120 { max-width: 1120px; }
.mw-1240 { max-width: 1240px; }
.mw-1260 { max-width: 1260px; }
.flexrow { display: flex; gap: 15px; align-items: flex-start; }
.chiprow { display: flex; gap: 7px; flex-wrap: wrap; }
.kv-tight { gap: 0 14px; }
.kv-wide { gap: 0 20px; }
.sublabel { font-size: 11px; color: var(--muted); font-weight: 500; margin-top: 2px; }
.big-figure { font-size: 21px; font-weight: 700; color: var(--navy); letter-spacing: -.4px; }
.stat-topbar { border-top: 3px solid var(--btn); }
.nextup-title { font-size: 23px; font-weight: 700; color: var(--navy); margin: 8px 0 3px; letter-spacing: -.5px; }
.nextup-sub { color: var(--ink-2); font-size: 13.5px; }
.lbl { font-size: 11.5px; color: var(--muted); font-weight: 700; text-transform: uppercase; letter-spacing: .5px; }

/* Pre-login pages (Login, Forgot Password, Reset Password, Portal Login) — the prototype
   centres a single narrow card on the plain surface, with no header/nav shell at all. */
.loginwrap { max-width: 420px; margin: 0 auto; padding-top: 80px; }
.loginbrand { text-align: center; margin-bottom: 26px; }
.loginbrand .lg { display: inline-flex; align-items: center; gap: 11px; }
.loginbrand .logo-mark { width: 38px; height: 38px; }
.loginbrand .nm { font-weight: 700; color: var(--navy); font-size: 21px; letter-spacing: -.4px; text-align: left; }
.loginbrand .nm s { display: block; font-size: 9.5px; letter-spacing: 1.6px; color: var(--muted); text-decoration: none; font-weight: 600; }
.loginfoot { text-align: center; margin-top: 15px; }


/* Timesheet: employee picker beside the selected person's timecard. Collapses to one
   column under 900px so the list sits above the detail rather than being squeezed. */
.ts-layout { display: grid; grid-template-columns: 280px 1fr; gap: 15px; align-items: start; }
.ts-people input[type="search"] { width: 100%; margin-bottom: 10px; }
.ts-people #people-list { max-height: 560px; overflow-y: auto; }
.person-row { padding: 9px 11px; border-radius: 8px; cursor: pointer; border: 1px solid transparent; }
.person-row:hover { background: var(--neutral-bg); }
.person-row.on { background: #EFF6FF; border-color: #BAE6FD; }
.person-name { font-weight: 600; color: var(--navy); font-size: 13.5px; }
.person-role { font-size: 11.5px; color: var(--muted); }
.ts-detail { min-width: 0; }
@media (max-width: 900px) {
  .ts-layout { grid-template-columns: 1fr; }
  .ts-people #people-list { max-height: 260px; }
}


/* The company lockup, used in place of a typeset wordmark so the brand is exact rather
   than approximated. ROS sits beside it as the product suffix, divided off so it reads as
   "FMUK Logistics ROS" without competing with the artwork. */
.logo-lockup { height: 26px; width: auto; display: block; }
.logo-ros { font-weight: 700; color: var(--muted); font-size: 11px; letter-spacing: 2.2px;
  padding-left: 9px; border-left: 1px solid var(--line); line-height: 1; }
.loginbrand .logo-lockup { height: 44px; }
.loginbrand .logo-ros { font-size: 13px; letter-spacing: 2.8px; padding-left: 12px; }


/* Pallet barcodes on the Storage Dashboard location table. Several can sit in one
   cell, so they are chipped rather than run together as text. */
.pallet-chip { display: inline-block; background: var(--neutral-bg); border: 1px solid var(--line);
  border-radius: 5px; padding: 1px 6px; font-size: 11.5px; margin: 1px 0; white-space: nowrap; }


/* Grading guide panel — Processing Bench, read-only, beside the grading controls.
   docs/design/FMUK_Grading_Standard.html, "What the operator sees at the bench": FMUK's
   default first, the client's own rule second where they wrote one. The panel itself is a
   plain .card and its rows reuse .cardhead / .hint / .pill / .lbl / .note.crit; only these
   six are new, because nothing existing does their job:
     .guide-grade / .guide-grade-head  one grade per block, ruled off from the next
     .guide-icon                       the schematic illustration, sized off its own ratio
     .guide-default                    FMUK's line — quiet, because it is the baseline
     .guide-client                     the client's own line, marked off in amber (the
                                       document's own .bench .cl treatment) so it can never
                                       be read as FMUK's default
     .guide-hazard                     fenced above a dashed rule, outside the grade blocks
                                       entirely — "Hazard is not a grade", so it must not
                                       look like a fourth one.
   Deliberately placed above the .hidden block below, which keeps the last word. */
.guide-grade { padding: 12px 0; }
.guide-grade + .guide-grade { border-top: 1px solid var(--line-soft); }
.guide-grade-head { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; margin-bottom: 8px; }
.guide-icon { width: 34px; height: auto; flex-shrink: 0; }
.guide-default { font-size: 12.5px; color: var(--ink-2); line-height: 1.5; }
.guide-client { font-size: 12.5px; color: var(--ink); line-height: 1.5; background: #FFFBEB;
  border-left: 3px solid var(--warn); border-radius: 0 6px 6px 0; padding: 6px 10px; margin-top: 3px; }
.guide-hazard { margin-top: 14px; padding-top: 14px; border-top: 2px dashed var(--line); }

/* ═══════════════════════════ .hidden — must be last ═══════════════════════════
   This is a state utility: an element carrying .hidden is hidden, full stop. It has to
   beat every component rule that sets its own display, and there are many -- .note,
   .pill, .row, .grid, .stack, .legend, .step, .kv, .tabs, .metrics, .cardhead, .titlerow,
   .btnrow, .av, .thumb, .stepno, .btn, .chiprow, .flexrow, .modal-backdrop.

   Bare `.hidden { display: none }` is specificity (0,1,0), identical to every one of
   those, so the tie was broken by source order alone -- and .hidden sits near the top of
   this file, so it LOST to all of them. Live symptom: the Control Tower's error banner
   (`class="note crit hidden"`) rendered as an empty red bar on every page load, because
   `.note { display: flex }` won.

   !important on a single-purpose state utility is the right tool here, and it is why this
   one rule can be the last word rather than needing a compound selector per component. */
.hidden { display: none !important; }
