/* =============================================================
   CPM ORO X — editorial / private-bank theme
   Parchment background, white surfaces, single terracotta accent.
   Source Serif 4 for headings & key numbers; Inter for everything else.
   ============================================================= */

:root {
  /* Surfaces */
  --bg:           #EDE7D9;    /* page — warm parchment */
  --bg-elev:      #FFFFFF;    /* cards / panels */
  --bg-elev-2:    #F5F0E2;    /* hover tint, faint */
  --bg-sidebar:   #E4DDCB;    /* sidebar — one shade darker than page */

  /* Lines */
  --border:        #E1DBC9;
  --border-strong: #CFC7B1;

  /* Type */
  --text:        #1F1F1F;     /* near-black */
  --text-dim:    #6B6B66;     /* secondary, warm grey */
  --text-muted:  #8B8B82;     /* tertiary */

  /* Brand — used SPARINGLY */
  --accent:      #A85C3A;     /* muted terracotta */
  --accent-soft: #B26D4C;     /* terracotta hover */
  --accent-bg:   rgba(168, 92, 58, 0.08);

  /* Status tones — muted, editorial */
  --green:  #4F7A4A;          /* success / approved */
  --orange: #B0822B;          /* warning / pending */
  --red:    #9C3A2E;          /* error / rejected */
  --blue:   #6B6B66;          /* "in motion" — warm grey, not real blue */

  /* Geometry */
  --radius:    6px;
  --radius-lg: 12px;

  /* Type stacks */
  --font-sans:   "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-serif:  "Source Serif 4", "Source Serif Pro", Georgia, "Times New Roman", serif;
  --font-mono:   "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: 14px;
  line-height: 1.5;
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-serif);
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: var(--text);
}

a {
  color: var(--accent);
  text-decoration: none;
  transition: color 120ms ease;
}
a:hover { color: var(--accent-soft); text-decoration: underline; }

/* ---- App shell ---- */

.app-shell {
  display: grid;
  grid-template-columns: 240px 1fr;
  min-height: 100vh;
}

.sidebar {
  background: var(--bg-sidebar);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  padding: 28px 0 16px;
}

.sidebar-brand {
  /* Centred in the sidebar with breathing room above and below the lockup. */
  padding: 14px 16px 32px;
  margin-bottom: 18px;
  border-bottom: 1px solid var(--border);
  color: var(--accent);
  text-align: center;
}
/* Inline-flex shrinks the lockup to the width of "Alpha", so right-aligning
   "Oro" puts it directly under the right portion of "Alpha" — not at the
   sidebar's edge. align-items: flex-end right-aligns within that tight box.
   The per-line transforms below (on .brand-mark and .brand-name) now do
   the optical-centering work — no container-level translateX needed. */
.brand-stack {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-end;
  max-width: 100%;
}
.brand-mark,
.brand-name {
  display: block;
  font-family: var(--font-serif);
  font-weight: 700;
  /* ~1.5x the previous 38px, with clamp() so a narrow sidebar shrinks gracefully */
  font-size: clamp(40px, 5.2vw, 56px);
  line-height: 0.95;          /* tight but no overlap with the line above */
  letter-spacing: -0.02em;
  color: var(--accent);
  background: transparent;
  padding: 0;
  margin: 0;
  white-space: nowrap;
}
/* Shift "Oro" so its "O" sits under the "a" of "Alpha" — scaled with the font. */
/* Letter-precise alignment: "O" of "Oro" sits under "h" of "Alpha".
   Mirrors the login wordmark's final values, expressed in em so the
   offsets scale with the clamp() font-size (≈50px sidebar vs ≈72px
   login). Alpha -0.17em + Oro +0.39em → 0.56em relative gap, the same
   ~one-char-width shift that lands O under h. Group's net visual
   centerline moves ~0.11em right of the inline-flex natural position
   — matches the login lockup's recentered feel. */
.brand-mark { transform: translateX(-0.31em); }
.brand-name { transform: translateX(0.25em); }

.sidebar-nav {
  flex: 1;
  display: flex;
  flex-direction: column;
  padding: 0 16px;
}

.nav-link {
  display: block;
  padding: 9px 12px;
  margin-bottom: 1px;
  color: var(--text-dim);
  border-radius: 4px;
  text-decoration: none;
  font-size: 13.5px;
  font-weight: 500;
  letter-spacing: 0.005em;
  transition: color 120ms ease, background 120ms ease;
}
.nav-link:hover { color: var(--text); background: transparent; text-decoration: none; }

/* G4 — Expandable nav items. Shared infrastructure for any future nested
   nav (libertad 4 may gain its own nesting later). */
.nav-item-group {
  display: flex;
  flex-direction: column;
  margin-bottom: 1px;
}
.nav-item-row {
  display: flex;
  align-items: center;
}
.nav-item-row > .nav-link { flex: 1; margin-bottom: 0; }
.nav-chevron {
  appearance: none;
  background: transparent;
  border: 0;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  margin-right: 6px;
  color: var(--text-dim);
  border-radius: 3px;
  transition: transform 160ms ease, color 120ms ease, background 120ms ease;
}
.nav-chevron:hover { color: var(--text); background: rgba(0, 0, 0, 0.03); }
.nav-item-group.is-expanded > .nav-item-row > .nav-chevron { transform: rotate(90deg); }
.nav-children {
  list-style: none;
  margin: 0;
  padding: 0;
  overflow: hidden;
  max-height: 0;
  transition: max-height 200ms ease;
}
.nav-item-group.is-expanded > .nav-children { max-height: 600px; }
.nav-children > li { margin: 0; }
.nav-child-link {
  display: block;
  padding: 6px 12px 6px 28px;
  margin: 0;
  color: var(--text-dim);
  text-decoration: none;
  font-size: 12.5px;
  letter-spacing: 0.005em;
  border-radius: 4px;
  transition: color 120ms ease, background 120ms ease;
}
.nav-child-link:hover { color: var(--text); background: transparent; text-decoration: none; }
.nav-child-link.active { color: var(--accent); font-weight: 600; }

.nav-link.active {
  color: var(--accent);
  background: transparent;
  font-weight: 600;
}

.main { display: flex; flex-direction: column; min-width: 0; }

.topbar {
  height: 64px;
  border-bottom: 1px solid var(--border);
  background: var(--bg);
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 14px;
  padding: 0 32px;
}
.topbar-user { text-align: right; line-height: 1.25; }
.user-name { color: var(--text); font-weight: 600; display: block; font-size: 13.5px; }
.user-role { color: var(--text-muted); font-size: 11px; display: block; text-transform: uppercase; letter-spacing: 0.06em; }

.topbar-sep {
  display: inline-block;
  width: 1px;
  height: 28px;
  background: var(--border);
}
.topbar-signout-form { margin: 0; }
.topbar-signout {
  background: transparent;
  border: none;
  color: var(--accent);
  padding: 8px 12px;
  border-radius: var(--radius);
  cursor: pointer;
  font-size: 12.5px;
  font-family: var(--font-sans);
  font-weight: 600;
  letter-spacing: 0.02em;
  transition: background-color 120ms ease, color 120ms ease;
}
.topbar-signout:hover { background: var(--accent-bg); color: var(--accent-soft); }
.topbar-signout:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--accent-bg); }

/* Language toggle (top-right of topbar, before user info). Single <form>
   posts to /i18n/setlang/; <button type="button"> opens the menu while
   <button type="submit"> on each option submits the form. */
.lang-toggle-form {
  position: relative;
  margin: 0;
  display: inline-flex;
  align-items: center;
}
.lang-toggle-form + .lang-toggle-form { margin-left: 8px; }
.lang-toggle-button {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--bg-elev, #FFFFFF);
  border: 1px solid var(--border, #E1DBC9);
  border-radius: 12px;
  color: var(--text, #1F1F1F);
  font-family: var(--font-sans);
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
  padding: 6px 10px;
  cursor: pointer;
  line-height: 1;
}
.lang-toggle-button:hover { background: var(--bg-elev-2, #F6F2E6); }
.lang-toggle-button:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--accent-bg, rgba(168,92,58,0.15)); }
.lang-toggle-caret { font-size: 10px; color: var(--text-dim, #6B6B66); }
.lang-flag {
  display: inline-block;
  vertical-align: middle;
  margin-right: 6px;
  border-radius: 2px;
  box-shadow: 0 0 0 1px rgba(31, 31, 31, 0.08);
  flex-shrink: 0;
}
.lang-toggle-menu {
  position: absolute;
  right: 0;
  top: calc(100% + 6px);
  min-width: 168px;
  background: var(--bg-elev, #FFFFFF);
  border: 1px solid var(--border, #E1DBC9);
  border-radius: 12px;
  padding: 6px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  box-shadow: 0 6px 18px rgba(31, 31, 31, 0.08), 0 1px 2px rgba(31, 31, 31, 0.04);
  z-index: 1000;
}
.lang-toggle-menu[hidden] { display: none; }
.lang-toggle-option {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: transparent;
  border: none;
  color: var(--text, #1F1F1F);
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: 500;
  text-align: left;
  padding: 8px 10px;
  border-radius: 8px;
  cursor: pointer;
}
.lang-toggle-option:hover { background: var(--bg-elev-2, #F6F2E6); }
.lang-toggle-option[aria-checked="true"] { color: var(--accent, #A85C3A); font-weight: 600; }
.lang-toggle-option:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--accent-bg, rgba(168,92,58,0.15)); }

.content {
  flex: 1;
  padding: 36px 48px;
  max-width: 1400px;
  width: 100%;
}

.page-title {
  margin: 0 0 28px;
  font-family: var(--font-serif);
  font-size: 38px;
  font-weight: 600;
  letter-spacing: -0.015em;
  line-height: 1.1;
  color: var(--text);
}
.page-title em { font-style: italic; color: var(--accent); font-weight: 600; }

.placeholder-note { color: var(--text-muted); font-style: italic; margin: 12px 0; }

/* ---- Login page ---- */

.login-page { background: var(--bg); }

.login-shell {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 56px;
}

.login-card {
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 48px 44px;
  width: 460px;
  max-width: 100%;
}

.login-brand { text-align: center; margin-bottom: 40px; }
/* Stacked wordmark: "Alpha" above "Oro", terracotta serif, the second word
   inset to the right so it suspends from the end of the first. */
.login-brand-stack {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-end;          /* Oro right-aligns under "Alpha"'s edge */
  color: var(--accent);
  margin-bottom: 14px;
  /* Visual-centering nudge: Oro hangs from Alpha's right edge so the bounding
     box leans right of its geometric center. Pull the whole stack a hair
     left so the wordmark reads centered inside the card. */
  transform: translateX(-10px);
}
.login-brand-stack > span {
  display: block;
  font-family: var(--font-serif);
  font-weight: 700;
  font-size: clamp(56px, 7vw, 84px);
  line-height: 0.95;              /* tight but no overlap */
  letter-spacing: -0.025em;
  color: var(--accent);
}
/* Letter-precise alignment: "O" of "Oro" sits directly under the "h"
   of "Alpha". The stack is right-edge-aligned (align-items: flex-end),
   so Oro lands with its "O" under Alpha's "p" by default — one full
   character left of where we want it. Splitting the 40px relative
   shift across both lines (Alpha −20, Oro +20) keeps the same 40px
   delta — and therefore the same O-under-h alignment — while pulling
   the wordmark group as a whole 20px leftward so it reads as visually
   centered inside the card. */
.login-brand-stack > span:first-child { transform: translateX(-12px); }
.login-brand-stack > span:last-child  { transform: translateX(28px); }
.login-brand-mark,
.login-brand-name {
  /* Legacy classes kept harmless in case any template still references them. */
  display: inline-block;
  font-family: var(--font-serif);
  font-weight: 700;
  color: var(--accent);
  margin: 0;
}
.login-tagline { color: var(--text-muted); margin: 10px 0 0; font-size: 13px; letter-spacing: 0.02em; }

.login-form { display: flex; flex-direction: column; gap: 18px; }

.form-field { display: flex; flex-direction: column; gap: 6px; }
.form-field span {
  font-size: 11px;
  color: var(--text-dim);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.form-field input,
.form-field select,
.form-field textarea {
  background: var(--bg-elev);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 11px 13px;
  border-radius: var(--radius);
  font-family: var(--font-sans);
  font-size: 14px;
  transition: border-color 120ms ease, box-shadow 120ms ease;
}
.form-field input:focus,
.form-field select:focus,
.form-field textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-bg);
}

.btn-primary {
  background: var(--accent);
  color: #ffffff;
  border: 1px solid var(--accent);
  padding: 12px 24px;
  font-weight: 600;
  border-radius: var(--radius);
  cursor: pointer;
  font-family: var(--font-sans);
  font-size: 14px;
  letter-spacing: 0.005em;
  transition: background 120ms ease, border-color 120ms ease;
}
.btn-primary:hover { background: var(--accent-soft); border-color: var(--accent-soft); }

.btn-secondary {
  background: var(--bg-elev);
  color: var(--text);
  border: 1px solid var(--border);
  padding: 12px 24px;
  border-radius: var(--radius);
  cursor: pointer;
  font-family: var(--font-sans);
  font-size: 14px;
  font-weight: 500;
  transition: border-color 120ms ease, background 120ms ease;
  text-decoration: none;
  display: inline-block;
}
.btn-secondary:hover { background: var(--bg-elev-2); border-color: var(--border-strong); text-decoration: none; color: var(--text); }

.btn-danger {
  background: var(--red);
  color: #ffffff;
  border: 1px solid var(--red);
  padding: 12px 24px;
  border-radius: var(--radius);
  cursor: pointer;
  font-family: var(--font-sans);
  font-size: 14px;
  font-weight: 600;
  transition: filter 120ms ease;
}
.btn-danger:hover { filter: brightness(1.08); }

.form-error {
  background: rgba(156, 58, 46, 0.06);
  border: 1px solid rgba(156, 58, 46, 0.30);
  color: var(--red);
  padding: 10px 12px;
  border-radius: var(--radius);
  font-size: 13px;
}

@media (max-width: 880px) {
  .login-shell { padding: 32px; }
  .app-shell { grid-template-columns: 1fr; }
  .sidebar { display: none; }
  .content { padding: 24px 20px; }
}

/* ---- Tables ---- */

.data-table {
  width: 100%;
  border-collapse: collapse;
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.data-table th,
.data-table td {
  padding: 14px 18px;
  text-align: left;
  border-bottom: 1px solid var(--border);
  font-size: 13.5px;
  color: var(--text);
}
.data-table th {
  background: var(--bg-elev);
  color: var(--text-dim);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 10.5px;
  border-bottom: 1px solid var(--border);
}
.data-table tr:last-child td { border-bottom: none; }
.data-table tr:hover td { background: var(--bg-elev-2); }

/* ============================================================
   Terracotta list-header system — ONE definition reused by every
   list/table in the app.

   The card-list <div class="lib4-list-header-band"> band uses the
   first rule below. True <table class="data-table data-table--terracotta">
   uses the second rule — qualified on the base .data-table class so
   that its specificity (0,0,2,2) wins against any
   .<table-specific> thead th rule defined later in the file (e.g.
   .lib4-table thead th, .users-table thead th, .recon-applied-table th).

   Modifier classes on cells provide alignment:
     - .num / .lib4-num (right-aligned, tabular-nums)
     - .center                                    — status, actions

   The 12px rounded top corners are applied separately to whichever
   element is the visible top edge (the band div for card lists; the
   first/last <th> for tables).

   For pixel-aligned column tracks in card lists, see the
   --lib4-grid-cols CSS-variable plumbing further down (data-grid="…"
   sections). True <table> elements align by nature so they get the
   header styling only; no grid plumbing needed. */
.lib4-list-header-band {
  background: #A85C3A;
  color: #FFFFFF;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: 600;
  padding: 14px 18px;
}
/* Switch the terracotta variant to separate-borders so each <th> can
   carry its own border-radius (in collapse mode cell radii are
   ignored). border-spacing: 0 keeps the visual layout identical to
   the collapse default; the 8px gap below the header pill is provided
   by a parchment-coloured border-bottom on each thead cell (see below).

   Table bg switches from white (--bg-elev, inherited from .data-table)
   to parchment (--bg). Tbody cells get an explicit white bg below, so
   the visible result is: parchment "frame" with a terracotta pill at the
   top + a white rounded "rows card" below. The parchment behind the
   tbody cells is what makes the rounded top corners of the rows card
   visible. */
.data-table.data-table--terracotta { border-collapse: separate; border-spacing: 0; background: var(--bg); }
.data-table.data-table--terracotta tbody td { background: var(--bg-elev); }
.data-table.data-table--terracotta tbody tr:hover td { background: var(--bg-elev-2); }
.data-table.data-table--terracotta tbody tr:first-child td:first-child { border-top-left-radius: 12px; }
.data-table.data-table--terracotta tbody tr:first-child td:last-child  { border-top-right-radius: 12px; }
.data-table.data-table--terracotta tbody tr:last-child  td:first-child { border-bottom-left-radius: 12px; }
.data-table.data-table--terracotta tbody tr:last-child  td:last-child  { border-bottom-right-radius: 12px; }
.data-table.data-table--terracotta thead th {
  background: #A85C3A;
  /* Clip the terracotta bg to the padding-box so the 8px border-bottom
     area below stays free of terracotta. Without this, default
     background-clip:border-box paints terracotta under the border too,
     which (a) makes the visible band asymmetric relative to the
     centered text and (b) defeats any colored border-bottom gap. */
  background-clip: padding-box;
  color: #FFFFFF;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: 600;
  /* Vertical only — horizontal padding inherits from each table's
     own .<x>-table thead th rule so head padding matches body padding
     (otherwise the head shifts wider than the body and columns appear
     misaligned). */
  padding-top: 14px;
  padding-bottom: 14px;
  /* 8px page-parchment strip = the "gap" between the terracotta pill
     and the tbody rows below. Page bg differs from the table's white
     bg, so the strip is visibly distinct against both .card-wrapped
     tables and tables sitting directly on the page. */
  border-bottom: 8px solid var(--bg);
  vertical-align: middle;
}
.data-table.data-table--terracotta thead tr:first-child th:first-child { border-top-left-radius: 12px; border-bottom-left-radius: 12px; }
.data-table.data-table--terracotta thead tr:first-child th:last-child  { border-top-right-radius: 12px; border-bottom-right-radius: 12px; }
/* Global alignment rule: ALL table/grid headers and data cells are
   left-aligned, including numeric columns. tabular-nums is retained
   on numeric helpers so digits still align vertically column-by-column. */
.data-table.data-table--terracotta thead th.num,
.data-table.data-table--terracotta thead th.lib4-num { text-align: left; }
.data-table.data-table--terracotta thead th.center   { text-align: center; }

/* ---- Cards ---- */

.card {
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 24px 28px;
  margin-bottom: 20px;
}
.card-title {
  margin: 0 0 18px;
  font-family: var(--font-sans);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.10em;
  color: var(--text-dim);
}

/* Daily Capital Exposure Trend (CPM dashboard) — editorial heading +
   stacked-bar chart card. The .card above the table also sits 24px from
   the Capital Exposure table thanks to .card's 20px bottom margin plus
   this card's small top breathing room. */
.capital-snapshot-card { margin-top: 4px; }
.capital-snapshot-card .card-title { margin-bottom: 8px; }
.capital-snapshot-headline {
  margin: 0 0 6px;
  font-family: var(--font-serif, "Source Serif 4", Georgia, serif);
  font-weight: 400;
  font-size: 22px;
  line-height: 1.2;
  color: var(--text);
}
.capital-snapshot-headline em {
  color: var(--accent, #A85C3A);
  font-style: italic;
}
.capital-snapshot-sub {
  margin: 0 0 18px;
  color: var(--text-dim);
  font-size: 13px;
}
.capital-snapshot-canvas-wrap {
  position: relative;
  height: 360px;
}
.capital-snapshot-empty {
  min-height: 240px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 24px;
  color: var(--text-dim);
  background: color-mix(in srgb, var(--border) 12%, transparent);
  border: 1px dashed var(--border);
  border-radius: 8px;
}
.capital-snapshot-empty p { margin: 0; font-size: 14px; }
.capital-snapshot-empty p + p { margin-top: 6px; }
.capital-snapshot-empty-hint { font-size: 12px; color: var(--text-dim); max-width: 460px; }

/* ---- Status badges ---- */

.badge {
  display: inline-block;
  padding: 4px 10px;
  border-radius: 4px;
  font-size: 10.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  border: 1px solid;
  font-family: var(--font-sans);
}
.badge-pending  { background: rgba(176, 130, 43, 0.08); color: var(--orange); border-color: rgba(176, 130, 43, 0.28); }
.badge-approved { background: rgba(79, 122, 74, 0.08);  color: var(--green);  border-color: rgba(79, 122, 74, 0.28); }
.badge-progress { background: transparent;               color: var(--text-dim); border-color: var(--border-strong); }
.badge-done     { background: rgba(168, 92, 58, 0.06);  color: var(--accent); border-color: rgba(168, 92, 58, 0.28); }
.badge-rejected { background: rgba(156, 58, 46, 0.08);  color: var(--red);    border-color: rgba(156, 58, 46, 0.28); }
.badge-muted    { background: transparent;               color: var(--text-muted); border-color: var(--border); }

/* ──────────────────────────────────────────────────────────
   Per-stage palette (canonical) — keep ALL stage tinting here.
   The same .stage-<status> class is applied to:
     · partials/status_badge.html  (lot detail status, dashboard exposure)
     · Ore Lots stage filter tabs
   so one stage gets one colour everywhere. Hues are intentionally muted
   to match the editorial palette.
   ──────────────────────────────────────────────────────── */
:root {
  --stage-pending_approval:             #B0822B;  /* gold */
  --stage-approved:                     #4F7A4A;  /* green — Approved for Dispatch */
  --stage-in_transit:                   #A85C3A;  /* terracotta */
  --stage-at_weighbridge_sampling:      #3F6E78;  /* muted teal */
  --stage-in_negotiation:               #7E5C82;  /* muted plum */
  --stage-awaiting_supplier_acceptance: #C26D2A;  /* warm amber */
  --stage-accepted_awaiting_invoice:    #8B5A3C;  /* warm cinnamon — pause point between acceptance and invoice */
  --stage-invoiced_awaiting_tranche_1:  #B07A2B;  /* early-warning amber-gold */
  --stage-invoiced_awaiting_tranche_2:  #5C7A4A;  /* near-close muted green */
  --stage-invoiced_kyc_complete:            #2F5E33;  /* deep forest — closed deal */
  --stage-rejected:                     #9C3A2E;  /* red */
  /* V11 — Truck.status "arrived" lane on the libertad-4 kanban. Muted
     indigo so the lane reads as a settled / handed-off state distinct
     from the in_transit terracotta. */
  --stage-arrived:                      #5C6FA8;  /* muted indigo */
}

/* Badge variants — override the bucketed badge-* background/border/color.
   The bucket class is still applied first (for legacy non-stage statuses);
   the stage class wins because it's defined after. */
.badge.stage-pending_approval             { color: var(--stage-pending_approval);             background: color-mix(in srgb, var(--stage-pending_approval) 10%, transparent);             border-color: color-mix(in srgb, var(--stage-pending_approval) 28%, transparent); }
.badge.stage-approved                     { color: var(--stage-approved);                     background: color-mix(in srgb, var(--stage-approved) 10%, transparent);                     border-color: color-mix(in srgb, var(--stage-approved) 28%, transparent); }
.badge.stage-in_transit                   { color: var(--stage-in_transit);                   background: color-mix(in srgb, var(--stage-in_transit) 10%, transparent);                   border-color: color-mix(in srgb, var(--stage-in_transit) 28%, transparent); }
.badge.stage-at_weighbridge_sampling      { color: var(--stage-at_weighbridge_sampling);      background: color-mix(in srgb, var(--stage-at_weighbridge_sampling) 10%, transparent);      border-color: color-mix(in srgb, var(--stage-at_weighbridge_sampling) 28%, transparent); }
.badge.stage-in_negotiation               { color: var(--stage-in_negotiation);               background: color-mix(in srgb, var(--stage-in_negotiation) 10%, transparent);               border-color: color-mix(in srgb, var(--stage-in_negotiation) 28%, transparent); }
.badge.stage-awaiting_supplier_acceptance { color: var(--stage-awaiting_supplier_acceptance); background: color-mix(in srgb, var(--stage-awaiting_supplier_acceptance) 10%, transparent); border-color: color-mix(in srgb, var(--stage-awaiting_supplier_acceptance) 28%, transparent); }
.badge.stage-accepted_awaiting_invoice    { color: var(--stage-accepted_awaiting_invoice);    background: color-mix(in srgb, var(--stage-accepted_awaiting_invoice) 10%, transparent);    border-color: color-mix(in srgb, var(--stage-accepted_awaiting_invoice) 28%, transparent); }
.badge.stage-invoiced_awaiting_tranche_1  { color: var(--stage-invoiced_awaiting_tranche_1);  background: color-mix(in srgb, var(--stage-invoiced_awaiting_tranche_1) 10%, transparent);  border-color: color-mix(in srgb, var(--stage-invoiced_awaiting_tranche_1) 28%, transparent); }
.badge.stage-invoiced_awaiting_tranche_2  { color: var(--stage-invoiced_awaiting_tranche_2);  background: color-mix(in srgb, var(--stage-invoiced_awaiting_tranche_2) 10%, transparent);  border-color: color-mix(in srgb, var(--stage-invoiced_awaiting_tranche_2) 28%, transparent); }
.badge.stage-invoiced_kyc_complete            { color: var(--stage-invoiced_kyc_complete);            background: color-mix(in srgb, var(--stage-invoiced_kyc_complete) 10%, transparent);            border-color: color-mix(in srgb, var(--stage-invoiced_kyc_complete) 28%, transparent); }
.badge.stage-rejected                     { color: var(--stage-rejected);                     background: color-mix(in srgb, var(--stage-rejected) 10%, transparent);                     border-color: color-mix(in srgb, var(--stage-rejected) 28%, transparent); }

/* ---- Audit timeline ---- */

.audit-event {
  padding: 12px 16px;
  border-left: 2px solid var(--border-strong);
  background: var(--bg);
  margin-bottom: 8px;
  border-radius: 4px;
  font-size: 12px;
}
.audit-event.undo {
  border-left-color: var(--red);
  background: rgba(156, 58, 46, 0.04);
}
.audit-event-action {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--accent);
  font-weight: 600;
  letter-spacing: 0.02em;
}
.audit-event-meta { color: var(--text-muted); font-size: 11px; }
.audit-event-desc { color: var(--text); margin-top: 4px; font-size: 13px; line-height: 1.45; }

/* ---- Misc ---- */

.actions-row { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 14px; }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }

/* ---- KPI strip — editorial typography ---- */

.kpi-strip {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 16px;
  margin-bottom: 32px;
}
/* Force the row to exactly 4 evenly-distributed cards regardless of
   minmax() reflow — used by the dashboard KPI rows. */
.kpi-strip.kpi-strip-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
/* Variant for the CPM Pending Approval page (two large headline cards). */
.kpi-strip.kpi-strip-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }

.kpi {
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 20px 22px 22px;
}
.kpi-label {
  color: var(--text-dim);
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.10em;
  font-weight: 600;
  margin-bottom: 10px;
}
.kpi-value {
  color: var(--text);
  font-family: var(--font-serif);
  font-size: 32px;
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: -0.02em;
}
/* Net Physical Exposure is negative when CPM holds more physical ore
   value than has been advanced — a healthy state. Render in success
   green so the dashboard signals overcoverage rather than alarm. */
.kpi-value.kpi-value-overcovered { color: #4F7A4A; }

/* Financial KPI row — light warm grey so the second dashboard row
   (Advances / Compensated / Net exposures) reads as "money" at a glance,
   distinct from the volumetric top row that stays white. Neutral tone,
   no warm tint. Hairline border, radius, padding, shadow all unchanged. */
.kpi-strip-financial .kpi { background: #F1EEE6; }

/* New centred stack layout: number → label → explanation. The legacy
   left-aligned `.kpi` (without `.kpi-stack`) is kept for any older
   surface that still uses it. */
.kpi.kpi-stack {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 0;
  padding: 22px 18px 20px;
}
.kpi.kpi-stack .kpi-value {
  margin: 0 0 8px;
  font-size: 30px;
}
.kpi.kpi-stack .kpi-label {
  margin: 0 0 4px;
}
.kpi.kpi-stack .kpi-explain {
  color: var(--text-muted);
  font-size: 11.5px;
  font-style: italic;
  letter-spacing: 0.01em;
  line-height: 1.35;
}
.kpi-unit {
  font-family: var(--font-serif);
  font-weight: 500;
  font-size: 0.62em;
  color: var(--text-dim);
  margin-left: 2px;
}

.muted { color: var(--text-muted); }
.dim { color: var(--text-dim); }

/* ---- KV (definition list) used on lot detail & invoice ---- */

.kv {
  display: grid;
  grid-template-columns: 140px 1fr;
  gap: 6px 14px;
  margin: 0;
  font-size: 13.5px;
}
.kv dt { color: var(--text-dim); font-weight: 500; }
.kv dd { margin: 0; color: var(--text); }

/* ---- Forms — compact inputs ---- */

details { margin-top: 6px; }
details summary { outline: none; cursor: pointer; color: var(--text-dim); font-weight: 500; }
details summary:hover { color: var(--text); }
details[open] summary { margin-bottom: 8px; }

.data-table input[type="text"],
.data-table input[type="url"],
.data-table input[type="number"],
.data-table select {
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 4px 8px;
  font-size: 12px;
  color: var(--text);
  font-family: var(--font-sans);
}
.data-table input:focus,
.data-table select:focus { outline: none; border-color: var(--accent); }

textarea, input[type="text"], input[type="url"], input[type="number"],
input[type="email"], input[type="password"], input[type="date"], input[type="datetime-local"], select {
  font-family: var(--font-sans);
}

/* ---- Lot detail layout safety ---- */

@media (max-width: 1400px) { .grid-3 { grid-template-columns: 1fr 1fr; } }
@media (max-width: 1000px) { .grid-3, .grid-2 { grid-template-columns: 1fr; } }


/* =============================================================
   PENDING APPROVAL — same structural design, light-theme palette.
   All styles scoped under .pa-page so app defaults are untouched.
   ============================================================= */

.pa-body {
  background: var(--bg);
}

.pa-page {
  /* Re-map the scoped tokens to the global light palette. */
  --pa-accent:       #A85C3A;
  --pa-accent-soft:  #B26D4C;
  --pa-green:        #4F7A4A;
  --pa-blue:         #6B6B66;   /* no real blue; warm grey for "in motion" */
  --pa-orange:       #B0822B;
  --pa-red:          #9C3A2E;
  --pa-purple:       #6B6B66;   /* drop the purple; muted to warm grey */
  --pa-surface:      #FFFFFF;
  --pa-surface-2:    #FAF5E8;
  --pa-surface-3:    #F0E9D6;
  --pa-line:         #E1DBC9;
  --pa-line-strong:  #CFC7B1;
  --pa-text:         #1F1F1F;
  --pa-text-dim:     #6B6B66;
  --pa-text-mute:    #8B8B82;
  --pa-mono:         "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  --pa-sans:         "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --pa-display:      "Source Serif 4", "Source Serif Pro", Georgia, serif;
  font-family: var(--pa-sans);
  color: var(--pa-text);
}

.pa-page * { box-sizing: border-box; }
.pa-page a { color: inherit; }

/* ── Hero ───────────────────────────────────────────────────── */
.pa-hero {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 24px;
  align-items: flex-end;
  padding: 4px 0 28px;
  margin-bottom: 28px;
  border-bottom: 1px solid var(--pa-line);
}
.pa-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--pa-accent);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.pa-eyebrow-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--pa-accent);
}

.pa-title {
  font-family: var(--pa-display);
  font-weight: 600;
  font-size: clamp(36px, 4.2vw, 52px);
  line-height: 1.06;
  letter-spacing: -0.02em;
  margin: 14px 0 10px;
  color: var(--pa-text);
}
.pa-title em {
  font-style: italic;
  color: var(--pa-accent);
  font-weight: 600;
}
.pa-title-counter {
  display: inline-block;
  margin-left: 14px;
  font-family: var(--pa-mono);
  font-size: 0.34em;
  font-weight: 500;
  color: var(--pa-text-mute);
  vertical-align: middle;
  padding: 4px 10px;
  border: 1px solid var(--pa-line);
  border-radius: 999px;
  letter-spacing: 0.04em;
}
.pa-subtitle {
  margin: 0;
  color: var(--pa-text-dim);
  font-size: 13.5px;
  letter-spacing: 0.005em;
}

.pa-hero-actions { display: flex; gap: 10px; align-items: flex-end; }

/* ── Buttons ────────────────────────────────────────────────── */
.pa-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 18px;
  border-radius: var(--radius);
  font-family: var(--pa-sans);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  border: 1px solid var(--pa-line);
  background: var(--pa-surface);
  color: var(--pa-text);
  text-decoration: none;
  transition: background 120ms ease, border-color 120ms ease;
}
.pa-btn:hover { background: var(--bg-elev-2); border-color: var(--border-strong); text-decoration: none; }
/* The --pa-* tokens are scoped under .pa-page (see line ~850). On pages
   that don't use the pa-page wrapper (notably /ore-lots/) the fallbacks
   to the global --accent / --accent-soft pair keep the terracotta button
   visible — without them background paints to UA default + white text
   reads as transparent. */
.pa-btn-primary { background: var(--pa-accent, var(--accent)); color: #ffffff; border-color: var(--pa-accent, var(--accent)); padding: 12px 24px; font-weight: 600; }
.pa-btn-primary:hover { background: var(--pa-accent-soft, var(--accent-soft)); border-color: var(--pa-accent-soft, var(--accent-soft)); }
/* V1 — muted state for primary buttons whose underlying action is gated
   (e.g. "+ Create Invoice" until at least one Available row is checked).
   The button already toggles the `disabled` attribute via JS; this rule
   gives it an obvious warm-grey paint so the user understands the
   button is inactive at a glance, instead of a barely-faded terracotta.
   Hover cursor flips to not-allowed too. */
.pa-btn-primary:disabled,
.pa-btn-primary[disabled] {
  background: color-mix(in srgb, var(--text-dim) 35%, var(--bg-elev-2));
  border-color: color-mix(in srgb, var(--text-dim) 40%, var(--border));
  color: color-mix(in srgb, var(--text-dim) 75%, transparent);
  cursor: not-allowed;
  opacity: 0.85;
}
.pa-btn-primary:disabled:hover,
.pa-btn-primary[disabled]:hover {
  background: color-mix(in srgb, var(--text-dim) 35%, var(--bg-elev-2));
  border-color: color-mix(in srgb, var(--text-dim) 40%, var(--border));
}
/* `<a class="pa-btn pa-btn-primary">` would otherwise inherit the global
   `a { color: var(--accent) }` rule on hover via the link transition; pin
   the link variant's color to white so the post-WB ACTION-cell links read
   the same as button variants. */
a.pa-btn-primary, a.pa-btn-primary:hover { color: #ffffff; text-decoration: none; }
.pa-btn-ghost { background: transparent; border-color: var(--pa-line); }
.pa-btn-ghost:hover { background: var(--bg-elev-2); }

/* Export menu — disclosure ────────────────────────────────── */
.pa-export { position: relative; }
.pa-export > summary { list-style: none; cursor: pointer; }
.pa-export > summary::-webkit-details-marker { display: none; }
.pa-export-menu {
  position: absolute;
  right: 0;
  top: calc(100% + 8px);
  min-width: 300px;
  background: var(--pa-surface);
  border: 1px solid var(--pa-line);
  border-radius: var(--radius-lg);
  padding: 6px;
  z-index: 20;
}
.pa-export-item {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 14px;
  align-items: center;
  padding: 12px 14px;
  border-radius: 6px;
  color: var(--pa-text);
  text-decoration: none;
}
.pa-export-item:hover { background: var(--bg-elev-2); text-decoration: none; }
.pa-export-item strong { display: block; font-size: 13px; font-weight: 600; }
.pa-export-item small { display: block; color: var(--pa-text-mute); font-size: 11px; margin-top: 2px; }
.pa-export-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px; height: 38px;
  border-radius: 6px;
  font-family: var(--pa-mono);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
  border: 1px solid var(--pa-line);
}
.pa-icon-pdf { background: rgba(156, 58, 46, 0.06); color: var(--pa-red); border-color: rgba(156, 58, 46, 0.25); }
.pa-icon-xls { background: rgba(79, 122, 74, 0.06);  color: var(--pa-green); border-color: rgba(79, 122, 74, 0.25); }

/* ── KPI strip ──────────────────────────────────────────────── */
.pa-kpis {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 16px;
  margin-bottom: 28px;
}
.pa-kpi {
  position: relative;
  padding: 22px 24px 22px;
  background: var(--pa-surface);
  border: 1px solid var(--pa-line);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.pa-kpi::before {
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 2px;
}
.pa-kpi[data-tone="neutral"]::before  { background: var(--pa-accent); }
.pa-kpi[data-tone="ready"]::before    { background: var(--pa-green); }
.pa-kpi[data-tone="late"]::before     { background: var(--pa-orange); }
.pa-kpi[data-tone="progress"]::before { background: var(--pa-blue); }
.pa-kpi[data-tone="age"]::before      { background: var(--border-strong); }

.pa-kpi-label {
  color: var(--pa-text-dim);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.10em;
  text-transform: uppercase;
}
.pa-kpi-value {
  font-family: var(--pa-display);
  font-weight: 600;
  font-size: 40px;
  line-height: 1.05;
  color: var(--pa-text);
  margin: 10px 0 6px;
  letter-spacing: -0.025em;
}
.pa-kpi-unit { font-size: 0.55em; color: var(--pa-text-dim); margin-left: 3px; font-weight: 500; }
.pa-kpi-meta { font-size: 11px; color: var(--pa-text-mute); font-family: var(--pa-mono); }

/* ── Filter shell ───────────────────────────────────────────── */
.pa-filters {
  background: var(--pa-surface);
  border: 1px solid var(--pa-line);
  border-radius: var(--radius-lg);
  padding: 18px 20px 16px;
  margin-bottom: 20px;
  position: sticky;
  top: 0;
  z-index: 10;
}
.pa-filters-row {
  display: grid;
  grid-template-columns: minmax(220px, 360px) 1fr auto auto;
  gap: 12px;
  align-items: center;
}

.pa-search {
  position: relative;
  display: flex;
  align-items: center;
  background: var(--bg-elev-2);
  border: 1px solid var(--pa-line);
  border-radius: var(--radius);
  padding: 0 14px;
  height: 40px;
  color: var(--pa-text-dim);
  transition: border-color 120ms ease, box-shadow 120ms ease;
}
.pa-search:focus-within {
  border-color: var(--pa-accent);
  color: var(--pa-text);
  background: var(--pa-surface);
  box-shadow: 0 0 0 3px var(--accent-bg);
}
.pa-search svg { flex: none; }
.pa-search input {
  flex: 1;
  background: transparent;
  border: none;
  outline: none;
  color: var(--pa-text);
  font-family: var(--pa-sans);
  font-size: 13.5px;
  padding: 0 10px;
}
.pa-search input::placeholder { color: var(--pa-text-mute); }

/* Approval chips ──────────────────────────────────────────── */
.pa-quick-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.pa-chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 32px;
  padding: 0 12px;
  border-radius: var(--radius);
  border: 1px solid var(--pa-line);
  background: var(--pa-surface);
  color: var(--pa-text-dim);
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  user-select: none;
  transition: border-color 120ms ease, color 120ms ease, background 120ms ease;
}
.pa-chip input { position: absolute; opacity: 0; pointer-events: none; }
.pa-chip:hover { color: var(--pa-text); border-color: var(--border-strong); }
.pa-chip-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; opacity: .55; }
.pa-chip.is-on { color: var(--pa-text); border-color: currentColor; background: var(--bg-elev-2); }
.pa-chip-ready_for_approval.is-on    { color: var(--pa-green);  border-color: var(--pa-green);  background: rgba(79, 122, 74, 0.06); }
.pa-chip-kyc_in_progress_late.is-on  { color: var(--pa-orange); border-color: var(--pa-orange); background: rgba(176, 130, 43, 0.06); }
.pa-chip-kyc_in_progress.is-on       { color: var(--pa-accent); border-color: var(--pa-accent); background: var(--accent-bg); }
.pa-chip-awaiting_cpm_review.is-on   { color: var(--pa-text-dim); border-color: var(--border-strong); background: var(--bg-elev-2); }
.pa-chip.is-on .pa-chip-dot { opacity: 1; }

/* Segmented status pair ───────────────────────────────────── */
.pa-segmented {
  display: inline-flex;
  background: var(--bg-elev-2);
  border: 1px solid var(--pa-line);
  border-radius: var(--radius);
  padding: 2px;
  height: 32px;
}
.pa-seg {
  position: relative;
  display: inline-flex;
  align-items: center;
  padding: 0 14px;
  font-size: 12px;
  font-weight: 500;
  border-radius: 4px;
  color: var(--pa-text-mute);
  cursor: pointer;
  height: 100%;
}
.pa-seg input { position: absolute; opacity: 0; pointer-events: none; }
.pa-seg:hover { color: var(--pa-text); }
.pa-seg.is-on { background: var(--pa-surface); color: var(--pa-accent); }

/* Advanced disclosure ─────────────────────────────────────── */
.pa-advanced { margin-top: 14px; border-top: 1px solid var(--pa-line); padding-top: 14px; }
.pa-advanced summary {
  list-style: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  font-size: 12px;
  font-weight: 500;
  color: var(--pa-text-dim);
  user-select: none;
}
.pa-advanced summary::-webkit-details-marker { display: none; }
.pa-advanced[open] summary svg { transform: rotate(180deg); }
.pa-advanced summary svg { transition: transform 160ms ease; }
.pa-advanced-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0,1fr));
  gap: 16px;
  margin-top: 14px;
  align-items: end;
}
.pa-field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.pa-field-wide { grid-column: span 2; }
.pa-field-label { font-size: 10px; font-weight: 600; letter-spacing: 0.10em; color: var(--pa-text-mute); text-transform: uppercase; }
.pa-multi {
  background: var(--pa-surface); color: var(--pa-text); border: 1px solid var(--pa-line);
  border-radius: var(--radius); padding: 6px; font-family: var(--pa-sans); font-size: 12px;
}
.pa-multi:focus { outline: none; border-color: var(--pa-accent); }
.pa-hint { color: var(--pa-text-mute); font-size: 10px; }
.pa-range { display: flex; align-items: center; gap: 6px; }
.pa-range input {
  flex: 1; min-width: 0;
  background: var(--pa-surface); color: var(--pa-text);
  border: 1px solid var(--pa-line); border-radius: var(--radius);
  padding: 8px 10px; font-family: var(--pa-mono); font-size: 12px;
  height: 34px;
}
.pa-range input:focus { outline: none; border-color: var(--pa-accent); box-shadow: 0 0 0 3px var(--accent-bg); }
.pa-range-sep { color: var(--pa-text-mute); font-family: var(--pa-mono); font-size: 12px; }

.pa-advanced-actions {
  grid-column: span 4;
  display: flex; gap: 10px; justify-content: flex-end;
  padding-top: 6px; border-top: 1px solid var(--pa-line); margin-top: 8px;
}

/* Active chips strip ──────────────────────────────────────── */
.pa-active-chips {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--pa-line);
}
.pa-active-label {
  color: var(--pa-text-mute); font-size: 10.5px; font-weight: 600;
  letter-spacing: 0.10em; text-transform: uppercase; margin-right: 4px;
}
.pa-active-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 8px 4px 10px; border-radius: 4px;
  background: var(--accent-bg); color: var(--pa-accent);
  border: 1px solid rgba(168, 92, 58, 0.30);
  font-size: 12px; font-weight: 500;
}
.pa-chip-x {
  display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px; border-radius: 50%;
  color: var(--pa-accent); background: transparent;
  font-size: 13px; font-weight: 600; line-height: 1;
  text-decoration: none;
}
.pa-chip-x:hover { background: rgba(156, 58, 46, 0.10); color: var(--pa-red); text-decoration: none; }
.pa-clear { color: var(--pa-text-mute); font-size: 12px; margin-left: 6px; }
.pa-clear:hover { color: var(--pa-red); }

/* ── Table ──────────────────────────────────────────────────── */
.pa-table-wrap {
  background: var(--pa-surface);
  border: 1px solid var(--pa-line);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.pa-table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 13.5px; }
.pa-table thead th {
  position: sticky; top: 0;
  background: var(--pa-surface);
  padding: 14px 18px;
  text-align: left;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--pa-text-dim);
  border-bottom: 1px solid var(--pa-line);
  white-space: nowrap;
}
.pa-table thead th.pa-num { text-align: left; }
.pa-table thead th.pa-kyc-th { text-align: left; width: 120px; }
.pa-table thead th.pa-action-th { width: 60px; }
.pa-sort {
  color: inherit; text-decoration: none;
  display: inline-flex; align-items: center; gap: 4px; cursor: pointer;
}
.pa-sort:hover { color: var(--pa-text); text-decoration: none; }
.pa-sort.is-active { color: var(--pa-accent); }
.pa-arrow { font-size: 9px; opacity: 0.9; }

.pa-row td {
  padding: 14px 18px;
  border-bottom: 1px solid var(--pa-line);
  vertical-align: middle;
  color: var(--pa-text);
}
.pa-row:hover td { background: var(--bg-elev-2); }
.pa-row:last-child td { border-bottom: none; }
.pa-num { text-align: left; }
.pa-mono { font-family: var(--pa-mono); font-variant-numeric: tabular-nums; font-size: 12.5px; }

.pa-lot-link {
  font-family: var(--pa-mono); font-weight: 600;
  color: var(--pa-accent); text-decoration: none;
  font-size: 13px;
}
.pa-lot-link:hover { color: var(--pa-accent-soft); text-decoration: underline; }
.pa-lot-meta { color: var(--pa-text-mute); font-size: 11px; margin-top: 2px; font-family: var(--pa-mono); }

/* KYC ring ─────────────────────────────────────────────────── */
.pa-kyc-cell { width: 110px; }
.pa-ring {
  position: relative;
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  min-width: 90px;
}
.pa-ring-svg { width: 48px; height: 48px; }
.pa-ring-svg circle { transition: stroke-dasharray 300ms ease, stroke-dashoffset 300ms ease; }
.pa-ring-text {
  position: absolute; inset: 0; top: 12px;
  display: flex; align-items: baseline; justify-content: center;
  font-family: var(--pa-mono);
  pointer-events: none;
}
.pa-ring-text strong { font-size: 13px; color: var(--pa-text); font-weight: 700; }
.pa-ring-text span { font-size: 9px; color: var(--pa-text-mute); }
.pa-ring-legend {
  display: inline-flex; align-items: center; gap: 4px;
  font-family: var(--pa-mono); font-size: 9px; color: var(--pa-text-mute);
}
.pa-dot { display: inline-block; width: 5px; height: 5px; border-radius: 50%; margin-right: 1px; margin-left: 3px; }
.pa-dot-green { background: var(--pa-green); }
.pa-dot-blue  { background: var(--pa-accent); }   /* "uploaded" → terracotta accent */
.pa-dot-red   { background: var(--pa-red); }

/* Readiness pill ──────────────────────────────────────────── */
.pa-readiness {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.06em;
  padding: 4px 10px; border-radius: 999px;
  border: 1px solid currentColor;
  text-transform: uppercase;
}
.pa-readiness-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.pa-readiness-ready_for_approval   { color: var(--pa-green);  background: rgba(79, 122, 74, 0.06); }
.pa-readiness-kyc_in_progress_late { color: var(--pa-orange); background: rgba(176, 130, 43, 0.06); }
.pa-readiness-kyc_in_progress      { color: var(--pa-accent); background: var(--accent-bg); }
.pa-readiness-awaiting_cpm_review  { color: var(--pa-text-dim); background: var(--bg-elev-2); }

/* Row action ──────────────────────────────────────────────── */
.pa-action-cell { text-align: left; padding-right: 18px; width: 60px; }
.pa-row-action {
  display: inline-flex; align-items: center; gap: 4px;
  color: var(--pa-text-dim); font-size: 12px; font-weight: 500;
  padding: 6px 10px; border-radius: 4px;
  text-decoration: none;
  opacity: 0.7;
  transition: opacity 100ms ease, color 100ms ease, background 100ms ease;
}
.pa-row:hover .pa-row-action { opacity: 1; color: var(--pa-accent); }
.pa-row-action:hover { background: var(--accent-bg); text-decoration: none; }

/* Empty state ─────────────────────────────────────────────── */
.pa-empty td { padding: 0; }
.pa-empty-inner {
  display: flex; flex-direction: column; align-items: center; gap: 12px;
  padding: 72px 20px; color: var(--pa-text-dim);
}
.pa-empty-inner h3 { margin: 0; font-family: var(--pa-display); font-weight: 600; color: var(--pa-text); }
.pa-empty-inner p { margin: 0; color: var(--pa-text-mute); font-size: 13px; }

/* Footer ─────────────────────────────────────────────────── */
.pa-footer {
  display: flex; justify-content: space-between; align-items: center;
  margin-top: 16px; padding: 4px 4px;
  color: var(--pa-text-mute); font-size: 12px; font-family: var(--pa-mono);
}
.pa-footer strong { color: var(--pa-text-dim); font-weight: 600; }
.pa-footer-exports { display: flex; gap: 16px; }
.pa-footer-link { color: var(--pa-text-dim); text-decoration: none; }
.pa-footer-link:hover { color: var(--pa-accent); }

/* Responsive ─────────────────────────────────────────────── */
@media (max-width: 1280px) {
  .pa-kpis { grid-template-columns: repeat(3, 1fr); }
  .pa-filters-row { grid-template-columns: 1fr; }
  .pa-quick-chips { justify-content: flex-start; }
  .pa-advanced-grid { grid-template-columns: repeat(2, 1fr); }
  .pa-advanced-actions { grid-column: span 2; }
}
@media (max-width: 720px) {
  .pa-kpis { grid-template-columns: repeat(2, 1fr); }
  .pa-table thead { display: none; }
  .pa-table, .pa-table tbody, .pa-table tr, .pa-table td { display: block; width: 100%; }
  .pa-row td { border-bottom: none; padding: 6px 14px; }
  .pa-row { border-bottom: 1px solid var(--pa-line); padding: 10px 0; }
}

/* ──────────────────────────────────────────────────────────
   Users page — title row + full-width table + action stack
   ──────────────────────────────────────────────────────── */
.users-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 22px;
}
.users-head .page-title { margin: 0; }
.users-table-card { padding: 0; overflow: hidden; }
.users-table tbody td { padding: 12px 16px; vertical-align: middle; }
.users-table thead th { padding: 12px 16px; }
.users-table .users-actions-th { width: 180px; text-align: left; }
.users-table .users-actions-cell { text-align: left; }
.users-actions-stack {
  display: inline-flex;
  gap: 8px;
  justify-content: center;
}
.users-actions-stack .pa-row-action {
  min-width: 64px;
  text-align: center;
  font-size: 12px;
  font-weight: 600;
  padding: 6px 12px;
  border-radius: 4px;
  opacity: 1;
}
.users-actions-stack .pa-row-action.pa-row-edit {
  color: var(--accent);
  background: transparent;
  border: 1px solid var(--border-strong);
}
.users-actions-stack .pa-row-action.pa-row-edit:hover {
  background: var(--accent-bg);
  border-color: var(--accent);
}

/* ──────────────────────────────────────────────────────────
   Toasts — top of content stack
   ──────────────────────────────────────────────────────── */
.toasts { display: flex; flex-direction: column; gap: 10px; margin-bottom: 18px; }
.toast {
  padding: 10px 14px;
  border-radius: var(--radius);
  font-size: 13px;
  font-weight: 500;
  border: 1px solid var(--border);
  background: var(--bg-elev);
  color: var(--text);
  box-shadow: 0 1px 0 rgba(0,0,0,0.02);
}
.toast-success {
  background: rgba(79, 122, 74, 0.08);
  border-color: rgba(79, 122, 74, 0.32);
  color: var(--green);
}
.toast-error {
  background: rgba(168, 92, 58, 0.08);
  border-color: rgba(168, 92, 58, 0.32);
  color: var(--accent);
}

/* ──────────────────────────────────────────────────────────
   Row-action variants on the Pending Approval queue
   ──────────────────────────────────────────────────────── */
.pa-actions-stack { display: inline-flex; flex-direction: column; align-items: stretch; gap: 4px; }
.pa-inline-form { margin: 0; }
.pa-row-action.pa-row-approve,
.pa-row-action.pa-row-reject,
.pa-row-action.pa-row-dispatch {
  font-weight: 600;
  border: 1px solid transparent;
  cursor: pointer;
  font-family: inherit;
  background: transparent;
  text-align: center;
  width: 100%;
  opacity: 1;
}
.pa-row-action.pa-row-approve {
  color: var(--green);
  border-color: rgba(79, 122, 74, 0.32);
  background: rgba(79, 122, 74, 0.06);
}
.pa-row-action.pa-row-approve:hover { background: rgba(79, 122, 74, 0.14); color: var(--green); }
.pa-row-action.pa-row-reject {
  color: var(--accent);
  border-color: rgba(168, 92, 58, 0.32);
  background: transparent;
}
.pa-row-action.pa-row-reject:hover { background: var(--accent-bg); color: var(--accent); }
.pa-row-action.pa-row-dispatch {
  color: var(--bg-elev);
  background: var(--accent);
  border-color: var(--accent);
}
.pa-row-action.pa-row-dispatch:hover { background: var(--accent-soft); border-color: var(--accent-soft); color: var(--bg-elev); }
.pa-row-action.pa-row-action-ghost { opacity: 0.7; }
.pa-row:hover .pa-row-action.pa-row-action-ghost { opacity: 1; }

/* ──────────────────────────────────────────────────────────
   Modal — shared across new-batch, reject, confirm-dispatch
   ──────────────────────────────────────────────────────── */
body.pa-modal-open { overflow: hidden; }
.pa-modal[hidden] { display: none; }
.pa-modal {
  position: fixed; inset: 0;
  z-index: 1000;
  display: flex; align-items: flex-start; justify-content: center;
  padding: 48px 24px;
  overflow-y: auto;
  overscroll-behavior: contain;
}
.pa-modal-scrim {
  position: fixed; inset: 0;
  background: rgba(31, 31, 31, 0.45);
  backdrop-filter: blur(2px);
}
.pa-modal-panel {
  position: relative;
  width: 100%; max-width: 480px;
  margin: auto 0;
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: 0 24px 60px rgba(31, 31, 31, 0.18);
  padding: 28px 30px 24px;
  font-family: var(--font-sans);
}
.pa-modal-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 16px; margin-bottom: 18px;
}
.pa-modal-title {
  margin: 0;
  font-family: var(--font-serif);
  font-size: 26px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--text);
}
.pa-modal-title em { color: var(--accent); font-style: italic; font-weight: 600; }
.pa-modal-close {
  background: transparent;
  border: none;
  font-size: 22px;
  line-height: 1;
  color: var(--text-dim);
  cursor: pointer;
  padding: 4px 8px;
  border-radius: 4px;
}
.pa-modal-close:hover { color: var(--text); background: var(--bg-elev-2); }
.pa-modal-form { display: flex; flex-direction: column; gap: 16px; }
.pa-modal-lede { margin: 0; color: var(--text-dim); font-size: 13px; }
.pa-modal-field { display: flex; flex-direction: column; gap: 6px; font-size: 13px; color: var(--text-dim); min-width: 0; }
.pa-modal-field > span { font-weight: 600; color: var(--text-dim); font-size: 11.5px; text-transform: uppercase; letter-spacing: 0.08em; }
.pa-modal-field > input,
.pa-modal-field > select,
.pa-modal-field > textarea {
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 9px 12px;
  font-size: 14px;
  font-family: var(--font-sans);
  color: var(--text);
  /* Honor the parent grid/flex cell width — without these the input's
     intrinsic ~20-char width pushes grid rows past the modal edge and
     trips horizontal-scroll on tight layouts like the blend create
     modal's miner-batch rows. */
  width: 100%;
  min-width: 0;
  box-sizing: border-box;
}
.pa-modal-field > textarea { font-family: var(--font-sans); resize: vertical; min-height: 72px; }
.pa-modal-field > input:focus,
.pa-modal-field > select:focus,
.pa-modal-field > textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-bg);
}
.pa-modal-help { font-size: 11.5px; color: var(--text-muted); line-height: 1.35; margin-top: 2px; }

/* M1 — per-lot Enter Sampling / Make Offer modals share a stacked
   read-only block that summarises the lot's context (lot id, warehouse,
   weighbridge tonnage) above the editable inputs. Uses the same warm
   neutral surface as .pa-modal-summary but stacks rows vertically. */
.cpm-modal-readonly {
  display: flex; flex-direction: column; gap: 4px;
  padding: 10px 14px; margin: 10px 0 14px;
  border: 1px dashed var(--border-strong);
  border-radius: 8px;
  background: var(--bg-elev-2);
}
.cpm-modal-readonly-row { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; font-size: 13px; }
.cpm-modal-readonly-label { color: var(--text-dim); font-weight: 600; font-size: 12px; text-transform: uppercase; letter-spacing: 0.05em; }
.cpm-modal-readonly-value { color: var(--text); font-variant-numeric: tabular-nums; }

/* V2 — Populate KYC 1 modal needs more horizontal room than the narrow
   M1 modals (sampling / make-offer) because it renders a per-MB tile
   row that's 17 × 36px = 612px wide for MINER/REINFO. .pa-modal--wide
   widens the panel; the tile row + readonly block scroll horizontally
   only when the viewport actually can't fit. */
.pa-modal.pa-modal--wide .pa-modal-panel {
  max-width: 900px;
  width: 92vw;
}
.cpm-kyc1-mb-grid {
  display: flex; flex-direction: column; gap: 12px;
  margin: 14px 0 6px;
  max-height: 50vh; overflow-y: auto;
}
.cpm-kyc1-mb-row {
  display: flex; flex-direction: column; gap: 4px;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg-elev);
}
.cpm-kyc1-mb-head {
  display: flex; align-items: baseline; gap: 8px;
  font-size: 12.5px; font-weight: 600;
}
.cpm-kyc1-mb-code { color: var(--text); }
.cpm-kyc1-mb-miner { color: var(--text-dim); font-weight: 500; }
.cpm-kyc1-tile-row {
  display: flex; flex-wrap: wrap; gap: 4px;
}
.cpm-kyc1-tile {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; min-width: 36px; height: 28px;
  border-radius: 5px;
  border: 1px solid transparent;
  cursor: pointer;
  padding: 0;
  background: #EBC9C0;        /* dusty rose pending, matches V1 dashboard tone */
  transition: background-color 100ms ease, border-color 100ms ease;
}
.cpm-kyc1-tile .cpm-kyc1-tile-code {
  font-size: 11px; font-weight: 600; letter-spacing: 0.04em;
  color: #6B3F36;
}
.cpm-kyc1-tile.is-received {
  background: color-mix(in srgb, var(--green, #4F7A4A) 18%, transparent);
}
.cpm-kyc1-tile.is-received .cpm-kyc1-tile-code {
  color: var(--green, #4F7A4A);
}
.cpm-kyc1-tile:hover {
  border-color: color-mix(in srgb, var(--accent) 50%, transparent);
}
.cpm-kyc1-tile:disabled {
  opacity: 0.5; cursor: progress;
}
.pa-modal-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.pa-modal-summary {
  display: flex; justify-content: space-between; align-items: baseline;
  padding: 12px 14px;
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius);
  background: var(--bg-elev-2);
}
.pa-modal-summary-label {
  color: var(--text-dim); font-size: 11px;
  text-transform: uppercase; letter-spacing: 0.10em; font-weight: 600;
}
.pa-modal-summary-value {
  color: var(--accent);
  font-family: var(--font-serif);
  font-size: 24px;
  font-weight: 600;
  letter-spacing: -0.01em;
}
.pa-modal-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 4px; }
.pa-btn.pa-btn-danger {
  background: var(--accent);
  border: 1px solid var(--accent);
  color: var(--bg-elev);
}
.pa-btn.pa-btn-danger:hover { background: var(--accent-soft); border-color: var(--accent-soft); }
.pa-btn.pa-btn-danger:disabled { opacity: 0.45; cursor: not-allowed; }
@media (max-width: 540px) {
  .pa-modal-panel { padding: 22px 18px 18px; }
  .pa-modal-row { grid-template-columns: 1fr; }
}

/* ──────────────────────────────────────────────────────────
   Libertad4 — simplified two-section layout for Pending Approval
   ──────────────────────────────────────────────────────── */

.lib4-section { margin-bottom: 36px; }
.lib4-section + .lib4-section { margin-top: 32px; }

.lib4-section-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 16px;
}
.lib4-section-title {
  margin: 6px 0 4px;
  font-family: var(--font-serif);
  font-size: 30px;
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--text);
  line-height: 1.1;
}
.lib4-section-title em { color: var(--accent); font-style: italic; font-weight: 600; }
.lib4-section-sub { margin: 0; color: var(--text-dim); font-size: 13px; }

.lib4-table-card { padding: 0; overflow: hidden; }
.lib4-table { font-size: 13.5px; table-layout: fixed; }
.lib4-table thead th {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-dim);
  padding: 14px 16px;
}
.lib4-table tbody td { padding: 14px 16px; vertical-align: middle; }
.lib4-num { text-align: left; font-variant-numeric: tabular-nums; }
.lib4-kyc-th, .lib4-action-th { width: 1%; white-space: nowrap; }
/* All columns left-aligned per global alignment rule — including
   status pills, KYC dots, action buttons. */
.lib4-table .lib4-status-th, .lib4-table .lib4-status-cell { text-align: left; }
.lib4-table .lib4-kyc-th,    .lib4-table .lib4-kyc-cell    { text-align: left; }
.lib4-tracker-table .lib4-status-th, .lib4-tracker-table .lib4-status-cell { text-align: left; }
.lib4-row[data-href] { cursor: pointer; }
.lib4-row:hover td { background: var(--bg-elev-2); }
.lib4-lot-link { color: var(--accent); font-weight: 600; text-decoration: none; }
.lib4-lot-link:hover { text-decoration: underline; }
.lib4-batch-meta {
  font-size: 11px;
  color: var(--text-muted);
  margin-top: 2px;
}
.lib4-status-pending {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--accent);
  background: var(--accent-bg);
  border: 1px solid rgba(168, 92, 58, 0.28);
}
.lib4-action-cell { text-align: left; }
.lib4-dispatch-btn { padding: 8px 16px; font-size: 12.5px; }

/* "Negotiation — generate invoice." section: ACTION header sits over a
   single centered Generate Invoice button per row. Centering both the
   <th> text and the <td> contents keeps the vertical alignment exact
   (header text axis == button axis). */
.lib4-gen-action-th { text-align: left; }
.lib4-gen-action-cell { text-align: left; }

/* KYC three-state pill (received-only, no breakdown — that lives on detail). */
.lib4-kyc-dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  vertical-align: middle;
  border: 1px solid transparent;
  margin-right: 6px;
}
.lib4-kyc-dot.is-full    { background: #4F7A4A; border-color: rgba(79, 122, 74, 0.55); }
.lib4-kyc-dot.is-partial { background: #B0822B; border-color: rgba(176, 130, 43, 0.55); }
.lib4-kyc-dot.is-none    { background: transparent; border-color: var(--border-strong); }
.lib4-kyc-meta { font-size: 11px; font-variant-numeric: tabular-nums; }

.lib4-empty td { padding: 0; }
.lib4-empty-inner {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 48px 20px; color: var(--text-dim);
}
.lib4-empty-inner h3 {
  margin: 0;
  font-family: var(--font-serif);
  font-weight: 600;
  color: var(--text);
  font-size: 18px;
}
.lib4-empty-inner p { margin: 0; color: var(--text-muted); font-size: 13px; }

@media (max-width: 720px) {
  .lib4-section-head { flex-direction: column; align-items: stretch; }
}

/* ──────────────────────────────────────────────────────────
   CPM lot detail — batch header + 4 accordion sections
   ──────────────────────────────────────────────────────── */
.cpm-detail { max-width: 1100px; }
.cpm-detail-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 16px; margin: 6px 0 16px;
}
.cpm-detail-id { display: flex; align-items: center; gap: 12px; }
.cpm-detail-id .lot-code-primary { font-size: 22px; }
.cpm-detail-id .lot-code-secondary { font-size: 12px; }

.cpm-detail-card { padding: 22px 26px; margin-bottom: 22px; }
.cpm-detail-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px 28px;
  margin: 0;
}
.cpm-detail-grid > div { display: flex; flex-direction: column; gap: 4px; }
.cpm-detail-grid dt {
  font-size: 10.5px;
  color: var(--text-dim);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.10em;
  margin: 0;
}
.cpm-detail-grid dd {
  margin: 0;
  font-family: var(--font-serif);
  font-size: 17px;
  font-weight: 500;
  color: var(--text);
  letter-spacing: -0.005em;
}
@media (max-width: 820px) {
  .cpm-detail-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cpm-detail-head { flex-direction: column; align-items: stretch; }
}

/* Accordion sections */
.cpm-section {
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  margin-bottom: 14px;
  overflow: hidden;
}
.cpm-section[open] { box-shadow: 0 1px 0 rgba(0,0,0,0.02); }
.cpm-section-head {
  display: flex; align-items: center; gap: 16px;
  padding: 16px 22px;
  cursor: pointer;
  list-style: none;
  user-select: none;
}
.cpm-section-head::-webkit-details-marker { display: none; }
.cpm-section-title {
  font-family: var(--font-serif);
  font-size: 18px;
  font-weight: 600;
  color: var(--text);
  letter-spacing: -0.01em;
  flex: 1;
}
.cpm-section-summary-meta {
  font-size: 12px;
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
  margin-right: 4px;
}
.cpm-section-status {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px;
  font-weight: 500;
  color: var(--text-dim);
}
.cpm-section-dot {
  display: inline-block;
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--border-strong);
}
.cpm-status-complete    { color: var(--green); }
.cpm-status-complete    .cpm-section-dot { background: var(--green); }
.cpm-status-in_progress { color: var(--orange); }
.cpm-status-in_progress .cpm-section-dot { background: var(--orange); }
.cpm-status-pending     { color: var(--text-muted); }
.cpm-status-pending     .cpm-section-dot { background: var(--border-strong); }
.cpm-status-skipped     { color: var(--text-muted); }
.cpm-status-skipped     .cpm-section-dot { background: var(--border-strong); }
.cpm-strike { text-decoration: line-through; }

.cpm-section-chev {
  font-size: 14px;
  color: var(--text-dim);
  transition: transform 160ms ease;
}
.cpm-section[open] .cpm-section-chev { transform: rotate(180deg); }
.cpm-section-body {
  padding: 4px 22px 22px;
  border-top: 1px solid var(--border);
}

/* Definition lists inside a section body */
.cpm-kv { display: grid; grid-template-columns: 180px 1fr; gap: 6px 16px; margin: 6px 0 14px; font-size: 14px; }
.cpm-kv dt { color: var(--text-dim); font-weight: 500; }
.cpm-kv dd { margin: 0; color: var(--text); }

.cpm-section-form { margin-top: 12px; }
.cpm-section-form .form-field { display: flex; flex-direction: column; gap: 4px; margin-bottom: 12px; }
.cpm-section-form .grid-2, .cpm-section-form .grid-3 { display: grid; gap: 14px; }
.cpm-section-form .grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.cpm-section-form .grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.cpm-section-form input,
.cpm-section-form select,
.cpm-section-form textarea {
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 8px 10px;
  font-size: 14px;
  font-family: var(--font-sans);
  color: var(--text);
}
.cpm-section-form input:focus,
.cpm-section-form select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-bg);
}
@media (max-width: 820px) {
  .cpm-section-form .grid-2,
  .cpm-section-form .grid-3 { grid-template-columns: 1fr; }
}

.cpm-reset-form { margin-top: 14px; }
.cpm-reset-btn { color: var(--accent); border-color: var(--accent); }
.cpm-reset-btn:hover { background: var(--accent-bg); color: var(--accent); border-color: var(--accent); }

/* KYC click-to-toggle grid */
.cpm-kyc-note { font-size: 12px; margin: 4px 0 14px; }
.cpm-kyc-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
  gap: 8px;
}
.cpm-kyc-toggle { margin: 0; }
/* Every tile is the same height regardless of label length — the
   longest label ("Consulta de REINFO IMPRESO fecha y hora") wraps to
   ~4 lines at the typical column width. Label flexes to fill the top,
   icon stays anchored at the bottom centre. */
.cpm-kyc-col {
  display: flex; flex-direction: column; align-items: center;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  min-height: 122px;
  padding: 10px 6px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-elev);
  cursor: pointer;
  font-family: inherit;
  text-align: center;
}
.cpm-kyc-col:hover { background: var(--bg-elev-2); border-color: var(--border-strong); }
.cpm-kyc-col .cpm-kyc-label {
  font-size: 10.5px;
  font-weight: 600;
  color: var(--text-dim);
  letter-spacing: 0.02em;
  line-height: 1.2;
  word-break: break-word;
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
}
.cpm-kyc-col .cpm-kyc-icon {
  width: 22px; height: 22px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%;
  font-size: 12px;
  font-weight: 700;
  flex: 0 0 auto;
}
.cpm-kyc-col.is-received .cpm-kyc-icon { color: #ffffff; background: var(--green); border: 1px solid var(--green); }
.cpm-kyc-col.is-pending  .cpm-kyc-icon { color: var(--text-muted); background: var(--bg-elev-2); border: 1px solid var(--border-strong); }
@media (max-width: 720px) {
  .cpm-kyc-row { grid-template-columns: repeat(auto-fit, minmax(86px, 1fr)); }
}

/* ──────────────────────────────────────────────────────────
   Libertad4 — Ore & KYC Tracker
   ──────────────────────────────────────────────────────── */
.lib4-tracker { max-width: 1280px; }
.lib4-tracker-head { margin-bottom: 22px; }
.lib4-tracker-title {
  margin: 6px 0 4px;
  font-family: var(--font-serif);
  font-size: 30px;
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--text);
  line-height: 1.1;
}
.lib4-tracker-title em { color: var(--accent); font-style: italic; font-weight: 600; }
.lib4-tracker-sub { margin: 0; color: var(--text-dim); font-size: 13.5px; }

/* Status filter tabs */
.lib4-tracker-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  border-bottom: 1px solid var(--border);
  margin: 12px 0 18px;
}
.lib4-tracker-tab {
  color: var(--text-dim);
  text-decoration: none;
  padding: 10px 14px 11px;
  border-bottom: 2px solid transparent;
  font-size: 13px;
  font-weight: 500;
  display: inline-flex; align-items: center; gap: 8px;
  white-space: nowrap;
  transition: color 120ms ease, background 120ms ease, border-color 120ms ease;
}
.lib4-tracker-tab:hover { color: var(--text); background: var(--bg-elev-2); text-decoration: none; }
.lib4-tracker-tab.is-on { color: var(--accent); border-bottom-color: var(--accent); font-weight: 600; }
.lib4-tracker-tab-count {
  display: inline-block;
  font-size: 11px;
  font-weight: 600;
  color: var(--text-muted);
  background: var(--bg-elev-2);
  border-radius: 999px;
  padding: 1px 8px;
  font-variant-numeric: tabular-nums;
}
.lib4-tracker-tab.is-on .lib4-tracker-tab-count { color: var(--accent); background: var(--accent-bg); }

/* Per-bucket tint when the tab is active — gives each stage its own colour. */
.lib4-tracker-tab.bucket-in_transit.is-on             { color: var(--stage-in_transit);                   border-bottom-color: var(--stage-in_transit); }
.lib4-tracker-tab.bucket-at_cpm.is-on                 { color: var(--stage-at_weighbridge_sampling);      border-bottom-color: var(--stage-at_weighbridge_sampling); }
.lib4-tracker-tab.bucket-offer.is-on                  { color: var(--stage-awaiting_supplier_acceptance); border-bottom-color: var(--stage-awaiting_supplier_acceptance); }
.lib4-tracker-tab.bucket-accepted.is-on               { color: var(--stage-invoiced_awaiting_tranche_1);  border-bottom-color: var(--stage-invoiced_awaiting_tranche_1); }
.lib4-tracker-tab.bucket-invoiced_pending_kyc.is-on   { color: var(--stage-invoiced_awaiting_tranche_1);  border-bottom-color: var(--stage-invoiced_awaiting_tranche_1); }
.lib4-tracker-tab.bucket-invoiced_pending_final.is-on { color: var(--stage-invoiced_awaiting_tranche_2);  border-bottom-color: var(--stage-invoiced_awaiting_tranche_2); }
.lib4-tracker-tab.bucket-invoiced_kyc_complete.is-on      { color: var(--stage-invoiced_kyc_complete);            border-bottom-color: var(--stage-invoiced_kyc_complete); }
.lib4-tracker-tab.bucket-in_transit.is-on             .lib4-tracker-tab-count { color: var(--stage-in_transit);                   background: color-mix(in srgb, var(--stage-in_transit) 12%, transparent); }
.lib4-tracker-tab.bucket-at_cpm.is-on                 .lib4-tracker-tab-count { color: var(--stage-at_weighbridge_sampling);      background: color-mix(in srgb, var(--stage-at_weighbridge_sampling) 12%, transparent); }
.lib4-tracker-tab.bucket-offer.is-on                  .lib4-tracker-tab-count { color: var(--stage-awaiting_supplier_acceptance); background: color-mix(in srgb, var(--stage-awaiting_supplier_acceptance) 12%, transparent); }
.lib4-tracker-tab.bucket-accepted.is-on               .lib4-tracker-tab-count { color: var(--stage-invoiced_awaiting_tranche_1);  background: color-mix(in srgb, var(--stage-invoiced_awaiting_tranche_1) 12%, transparent); }
.lib4-tracker-tab.bucket-invoiced_pending_kyc.is-on   .lib4-tracker-tab-count { color: var(--stage-invoiced_awaiting_tranche_1);  background: color-mix(in srgb, var(--stage-invoiced_awaiting_tranche_1) 12%, transparent); }
.lib4-tracker-tab.bucket-invoiced_pending_final.is-on .lib4-tracker-tab-count { color: var(--stage-invoiced_awaiting_tranche_2);  background: color-mix(in srgb, var(--stage-invoiced_awaiting_tranche_2) 12%, transparent); }
.lib4-tracker-tab.bucket-invoiced_kyc_complete.is-on      .lib4-tracker-tab-count { color: var(--stage-invoiced_kyc_complete);            background: color-mix(in srgb, var(--stage-invoiced_kyc_complete) 12%, transparent); }

/* Tracker table cells */
.lib4-tracker-card { padding: 0; overflow: hidden; }
.lib4-tracker-table { font-size: 13.5px; }
.lib4-tracker-table thead th {
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-dim);
  padding: 14px 16px;
}
.lib4-tracker-table tbody td { padding: 14px 16px; vertical-align: middle; }
.lib4-tracker-table .lib4-row { cursor: pointer; }
.lib4-tracker-table .lib4-row:hover td { background: var(--bg-elev-2); }

/* KYC dot (3-state) inside the tracker */
.lib4-tracker-dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  vertical-align: middle;
  margin-right: 8px;
}
.lib4-tracker-dot.is-red    { background: var(--red); }
.lib4-tracker-dot.is-amber  { background: var(--orange); }
.lib4-tracker-dot.is-green  { background: var(--green); }
.lib4-tracker-kyc-text { font-size: 12.5px; color: var(--text-dim); font-variant-numeric: tabular-nums; }

/* Status pill per bucket */
.lib4-tracker-pill {
  display: inline-block;
  padding: 4px 10px;
  border-radius: 4px;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  border: 1px solid;
  white-space: nowrap;
}
.lib4-tracker-pill.bucket-in_transit             { color: var(--stage-in_transit);                   background: color-mix(in srgb, var(--stage-in_transit) 10%, transparent);                   border-color: color-mix(in srgb, var(--stage-in_transit) 28%, transparent); }
.lib4-tracker-pill.bucket-at_cpm                 { color: var(--stage-at_weighbridge_sampling);      background: color-mix(in srgb, var(--stage-at_weighbridge_sampling) 10%, transparent);      border-color: color-mix(in srgb, var(--stage-at_weighbridge_sampling) 28%, transparent); }
.lib4-tracker-pill.bucket-offer                  { color: var(--stage-awaiting_supplier_acceptance); background: color-mix(in srgb, var(--stage-awaiting_supplier_acceptance) 10%, transparent); border-color: color-mix(in srgb, var(--stage-awaiting_supplier_acceptance) 28%, transparent); }
.lib4-tracker-pill.bucket-accepted               { color: var(--stage-invoiced_awaiting_tranche_1);  background: color-mix(in srgb, var(--stage-invoiced_awaiting_tranche_1) 10%, transparent);  border-color: color-mix(in srgb, var(--stage-invoiced_awaiting_tranche_1) 28%, transparent); }
.lib4-tracker-pill.bucket-invoiced_pending_kyc   { color: var(--stage-invoiced_awaiting_tranche_1);  background: color-mix(in srgb, var(--stage-invoiced_awaiting_tranche_1) 10%, transparent);  border-color: color-mix(in srgb, var(--stage-invoiced_awaiting_tranche_1) 28%, transparent); }
.lib4-tracker-pill.bucket-invoiced_pending_final { color: var(--stage-invoiced_awaiting_tranche_2);  background: color-mix(in srgb, var(--stage-invoiced_awaiting_tranche_2) 10%, transparent);  border-color: color-mix(in srgb, var(--stage-invoiced_awaiting_tranche_2) 28%, transparent); }
.lib4-tracker-pill.bucket-invoiced_kyc_complete      { color: var(--stage-invoiced_kyc_complete);            background: color-mix(in srgb, var(--stage-invoiced_kyc_complete) 10%, transparent);            border-color: color-mix(in srgb, var(--stage-invoiced_kyc_complete) 28%, transparent); }

.lib4-tracker-empty td { padding: 0; border-bottom: none; }
.lib4-tracker-empty-inner {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 56px 18px;
  color: var(--text-dim);
}
.lib4-tracker-empty-inner strong {
  font-family: var(--font-serif);
  font-weight: 600;
  font-size: 16px;
  color: var(--text);
}

/* Submit Invoice card on the libertad4 lot detail page */
.lib4-invoice-card { margin: 24px 0; }
.lib4-invoice-message { color: var(--text-dim); font-size: 13.5px; margin: 0 0 14px; }
.lib4-invoice-message strong { color: var(--accent); font-family: var(--font-serif); font-size: 16px; }
.lib4-invoice-form .form-field { max-width: 320px; }
.lib4-invoice-actions { margin-top: 14px; }

/* ──────────────────────────────────────────────────────────
   Libertad4 — ore lot detail (slim two-section layout)
   ──────────────────────────────────────────────────────── */

.lib4-detail { max-width: 1200px; }
.lib4-detail-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 16px; margin-bottom: 22px;
}
/* Matches .lib4-tracker-title exactly so the two page headings read as a
   single visual treatment across the warehouse portal. */
.lib4-detail-title {
  margin: 6px 0 4px;
  font-family: var(--font-serif);
  font-size: 30px;
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--text);
  line-height: 1.1;
}
.lib4-detail-title em { color: var(--accent); font-style: italic; font-weight: 600; }
.lib4-detail-supplier { font-size: 13.5px; }

.lib4-summary-card { margin-bottom: 24px; }
.lib4-summary-grid {
  display: grid;
  grid-template-columns: 180px 1fr;
  gap: 10px 24px;
  margin: 0;
  font-size: 14px;
}
.lib4-summary-grid dt { color: var(--text-dim); font-weight: 500; }
.lib4-summary-grid dd { margin: 0; color: var(--text); }
.lib4-summary-grid .mono { font-weight: 600; color: var(--accent); }
.lib4-status-chip {
  display: inline-block;
  padding: 4px 12px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.03em;
  color: var(--accent);
  background: var(--accent-bg);
  border: 1px solid rgba(168, 92, 58, 0.28);
}

.lib4-locked-notice {
  margin: -6px 0 18px;
  padding: 10px 14px;
  border-radius: var(--radius);
  background: var(--bg-elev-2);
  border: 1px solid var(--border);
  color: var(--text-dim);
  font-size: 13px;
}

.lib4-edit-form .lib4-summary-grid dd input,
.lib4-edit-form .lib4-summary-grid dd select,
.lib4-edit-form .lib4-summary-grid dd textarea {
  width: 100%;
  max-width: 320px;
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 7px 10px;
  font-size: 14px;
  font-family: var(--font-sans);
  color: var(--text);
}
.lib4-edit-form .lib4-summary-grid dd input:focus,
.lib4-edit-form .lib4-summary-grid dd select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-bg);
}
.lib4-inline-error {
  margin-top: 6px;
  font-size: 12px;
  color: var(--red);
  font-family: var(--font-sans);
}
/* Empty placeholder — the JS-driven uniqueness check renders an empty div
   on first paint. Without this rule the .form-error chrome (red bg/border)
   shows as a stray block under the field. */
.lib4-inline-error:empty { display: none; }
.lib4-edit-actions {
  display: flex; justify-content: flex-end; gap: 10px;
  margin-top: 18px;
}

.lib4-kyc-card { padding-bottom: 22px; }
.lib4-kyc-note {
  font-size: 12.5px;
  margin: -6px 0 18px;
  letter-spacing: 0.01em;
}
.lib4-kyc-row {
  display: grid;
  grid-template-columns: repeat(17, minmax(0, 1fr));
  gap: 10px;
  align-items: stretch;
}
.lib4-kyc-col {
  display: flex; flex-direction: column; align-items: center;
  gap: 8px;
  padding: 12px 6px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-elev);
  cursor: default;
  user-select: none;
  text-align: center;
  min-width: 0;
}
.lib4-kyc-label {
  font-size: 10.5px;
  font-weight: 600;
  color: var(--text-dim);
  letter-spacing: 0.02em;
  line-height: 1.15;
  word-break: break-word;
  min-height: 26px;
  display: flex; align-items: center;
}
.lib4-kyc-icon {
  width: 26px; height: 26px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%;
  font-weight: 700;
  font-size: 14px;
  line-height: 1;
}
.lib4-kyc-icon.is-received {
  color: #ffffff;
  background: var(--green);
  border: 1px solid var(--green);
}
.lib4-kyc-icon.is-pending {
  color: var(--text-muted);
  background: var(--bg-elev-2);
  border: 1px solid var(--border-strong);
}

/* ──────────────────────────────────────────────────────────
   V8 — Ore Lots header, filter row, status multi-select, view toggle,
   and Kanban board. Replaced the legacy single-tab strip (.ol-tabs).
   All tones stay inside the AlphaOro warm palette — terracotta accent,
   parchment surfaces, warm-grey muted ink. No bright primaries.
   ──────────────────────────────────────────────────────── */

/* Page header — title left, action buttons right (Export, + New Lot). */
.ol-pageheader {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 18px;
}
.ol-pageheader-actions { display: flex; align-items: center; gap: 8px; }

/* KPI strip — small extra bottom gap so the filter row has air. The
   strip itself rides on the shared .kpi-strip / .kpi rules. */
.ol-kpi-strip { margin-bottom: 18px; }

/* Filter row — multi-select dropdown, list/kanban toggle, lot count. */
.ol-filters {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg, 10px);
  margin-bottom: 18px;
}
.ol-filters-spacer { flex: 1; }
.ol-filters-count {
  color: var(--text-dim);
  font-size: 12.5px;
  font-weight: 500;
  padding: 4px 12px;
  background: var(--bg-elev-2);
  border-radius: 999px;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* Status multi-select — button that opens a dropdown panel of
   checkboxes. Auto-applies on tick. Sized to read like the
   screenshot's "All Statuses ▾" trigger but in AlphaOro tones. */
.ol-status-multi { position: relative; }
.ol-status-multi-button {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 12px;
  color: var(--text);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: border-color 120ms ease, background 120ms ease;
  min-width: 180px;
  justify-content: space-between;
}
.ol-status-multi-button:hover { background: var(--bg-elev-2); border-color: var(--border-strong, #d8d2bf); }
.ol-status-multi-button[aria-expanded="true"] {
  border-color: var(--accent);
  background: var(--accent-bg);
  color: var(--accent);
}
.ol-status-multi-caret { font-size: 10px; color: var(--text-dim); }
.ol-status-multi-button[aria-expanded="true"] .ol-status-multi-caret { color: var(--accent); }

.ol-status-multi-panel {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 50;
  min-width: 280px;
  max-height: 360px;
  overflow-y: auto;
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(40, 30, 18, 0.10);
  padding: 6px;
}
.ol-status-checkbox {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 13px;
  color: var(--text);
  user-select: none;
}
.ol-status-checkbox:hover { background: var(--bg-elev-2); }
.ol-status-checkbox input[type="checkbox"] {
  accent-color: var(--accent);
  width: 14px;
  height: 14px;
  margin: 0;
}
.ol-status-checkbox-label { flex: 1; }
.ol-status-checkbox-count {
  font-size: 11px;
  color: var(--text-dim);
  background: var(--bg-elev-2);
  border-radius: 999px;
  padding: 1px 8px;
  font-variant-numeric: tabular-nums;
}
.ol-status-multi-clear {
  display: block;
  padding: 8px 10px;
  margin-top: 4px;
  border-top: 1px solid var(--border);
  font-size: 12px;
  color: var(--text-dim);
  text-decoration: none;
}
.ol-status-multi-clear:hover { color: var(--accent); text-decoration: none; }

/* List/Kanban view toggle — segmented control. Active button picks up
   the terracotta accent; inactive sits flat with muted ink. */
.ol-view-toggle {
  display: inline-flex;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg-elev);
  overflow: hidden;
}
.ol-view-toggle-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 14px;
  color: var(--text-dim);
  font-size: 13px;
  font-weight: 500;
  text-decoration: none;
  border-right: 1px solid var(--border);
  transition: color 120ms ease, background 120ms ease;
}
.ol-view-toggle-btn:last-child { border-right: none; }
.ol-view-toggle-btn:hover { color: var(--text); background: var(--bg-elev-2); text-decoration: none; }
.ol-view-toggle-btn.is-on {
  color: var(--accent);
  background: var(--accent-bg);
  font-weight: 600;
}
.ol-view-toggle-icon { font-size: 14px; }

/* ──────────────────────────────────────────────────────────
   V8 Kanban — horizontal scroll, lane per status, cards inside.
   Per-stage colour stripe on each lane header reuses the existing
   --stage-* vars so the kanban reads the same as the badges
   elsewhere in the app.
   ──────────────────────────────────────────────────────── */
.ol-kanban {
  display: flex;
  gap: 12px;
  overflow-x: auto;
  padding: 4px 4px 12px;
  margin: 0 -4px;
}
.ol-kanban-lane {
  flex: 0 0 280px;
  background: var(--bg-elev-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  display: flex;
  flex-direction: column;
  max-height: 720px;
}
.ol-kanban-lane-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 14px 11px;
  border-bottom: 2px solid var(--text-dim);
  background: var(--bg-elev);
  border-top-left-radius: 10px;
  border-top-right-radius: 10px;
}
.ol-kanban-lane-label {
  font-size: 11.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text);
}
.ol-kanban-lane-count {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-dim);
  background: var(--bg-elev-2);
  border-radius: 999px;
  padding: 2px 10px;
  font-variant-numeric: tabular-nums;
}
/* Per-stage lane tint — stripe at top + count badge use the existing
   --stage-* colour vars so kanban + badges read coherently. */
.ol-kanban-lane.stage-at_weighbridge_sampling .ol-kanban-lane-head { border-bottom-color: var(--stage-at_weighbridge_sampling); }
.ol-kanban-lane.stage-in_negotiation .ol-kanban-lane-head { border-bottom-color: var(--stage-in_negotiation); }
.ol-kanban-lane.stage-awaiting_supplier_acceptance .ol-kanban-lane-head { border-bottom-color: var(--stage-awaiting_supplier_acceptance); }
.ol-kanban-lane.stage-accepted_awaiting_invoice .ol-kanban-lane-head { border-bottom-color: var(--stage-accepted_awaiting_invoice); }
.ol-kanban-lane.stage-invoiced_awaiting_tranche_1 .ol-kanban-lane-head { border-bottom-color: var(--stage-invoiced_awaiting_tranche_1); }
.ol-kanban-lane.stage-invoiced_awaiting_tranche_2 .ol-kanban-lane-head { border-bottom-color: var(--stage-invoiced_awaiting_tranche_2); }
.ol-kanban-lane.stage-invoiced_kyc_complete .ol-kanban-lane-head { border-bottom-color: var(--stage-invoiced_kyc_complete); }
.ol-kanban-lane.stage-at_weighbridge_sampling .ol-kanban-lane-count { color: var(--stage-at_weighbridge_sampling); background: color-mix(in srgb, var(--stage-at_weighbridge_sampling) 12%, transparent); }
.ol-kanban-lane.stage-in_negotiation .ol-kanban-lane-count { color: var(--stage-in_negotiation); background: color-mix(in srgb, var(--stage-in_negotiation) 12%, transparent); }
.ol-kanban-lane.stage-awaiting_supplier_acceptance .ol-kanban-lane-count { color: var(--stage-awaiting_supplier_acceptance); background: color-mix(in srgb, var(--stage-awaiting_supplier_acceptance) 12%, transparent); }
.ol-kanban-lane.stage-accepted_awaiting_invoice .ol-kanban-lane-count { color: var(--stage-accepted_awaiting_invoice); background: color-mix(in srgb, var(--stage-accepted_awaiting_invoice) 12%, transparent); }
.ol-kanban-lane.stage-invoiced_awaiting_tranche_1 .ol-kanban-lane-count { color: var(--stage-invoiced_awaiting_tranche_1); background: color-mix(in srgb, var(--stage-invoiced_awaiting_tranche_1) 12%, transparent); }
.ol-kanban-lane.stage-invoiced_awaiting_tranche_2 .ol-kanban-lane-count { color: var(--stage-invoiced_awaiting_tranche_2); background: color-mix(in srgb, var(--stage-invoiced_awaiting_tranche_2) 12%, transparent); }
.ol-kanban-lane.stage-invoiced_kyc_complete .ol-kanban-lane-count { color: var(--stage-invoiced_kyc_complete); background: color-mix(in srgb, var(--stage-invoiced_kyc_complete) 12%, transparent); }

.ol-kanban-lane-body {
  flex: 1;
  overflow-y: auto;
  padding: 10px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.ol-kanban-card {
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  box-shadow: 0 1px 2px rgba(40, 30, 18, 0.04);
  transition: box-shadow 120ms ease, border-color 120ms ease, transform 120ms ease;
}
.ol-kanban-card:hover {
  border-color: var(--accent);
  box-shadow: 0 4px 10px rgba(40, 30, 18, 0.08);
}
.ol-kanban-card-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.ol-kanban-card-code {
  font-weight: 600;
  font-size: 13px;
  color: var(--text);
  text-decoration: none;
}
.ol-kanban-card-code:hover { color: var(--accent); text-decoration: none; }
.ol-kanban-card-meta { font-size: 12px; color: var(--text-dim); }
.ol-kanban-card-supplier { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ol-kanban-card-figures {
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
  font-variant-numeric: tabular-nums;
}
.ol-kanban-card-figure { display: flex; flex-direction: column; gap: 2px; }
.ol-kanban-card-figure-label {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-dim);
  font-weight: 600;
}
.ol-kanban-card-figure-value { font-size: 13px; font-weight: 600; color: var(--text); }
.ol-kanban-card-date {
  font-size: 11.5px;
  color: var(--text-dim);
}
/* V27.2 — when multiple buttons stack inside the action area, give them
   breathing room. Single-button cards still render flush at margin-top:2. */
.ol-kanban-card-action {
  margin-top: 2px;
  display: flex; flex-direction: column; gap: 6px;
}
.ol-kanban-action-btn { width: 100%; justify-content: center; }
.ol-kanban-empty {
  font-size: 12px;
  color: var(--text-dim);
  font-style: italic;
  text-align: center;
  padding: 18px 6px;
}

/* Dashboard — Capital Exposure clickable rows */
.exposure-row { cursor: pointer; }
.exposure-row:hover td { background: var(--bg-elev-2); }

/* /ore-lots/ list table — honor colgroup widths and keep status badges
   single-line. STATUS column inherits the base left-alignment so the
   badge floats at the left edge of its cell rather than centering. */
.ol-list-table { table-layout: fixed; }
.ol-list-table tbody td { vertical-align: middle; }
.ol-list-table .badge { white-space: nowrap; }
/* Pre-weighbridge truck tables on /ore-lots/ (Pending Approval / Approved
   for Dispatch / In Transit). Defaults only — tuner owns runtime widths
   via ColumnWidthOverride. Visual styling inherits from .data-table /
   .data-table--terracotta (terracotta pill, rounded rows card, etc.). */
.ol-truck-table tbody td { vertical-align: middle; }
.ol-truck-table .ol-truck-action-cell { white-space: nowrap; }
.ol-awaiting-dispatch,
.action-muted { color: #6B6B66; font-size: 13px; }
.ol-action-cell { white-space: nowrap; }

/* Small inline chip — paired with CPM LOT # in invoiced rows. */
.row-invoice-chip {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 6px;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  color: #6B6B66;
  background: #F1EEE6;
  border-radius: 3px;
  white-space: nowrap;
  vertical-align: baseline;
}
/* Shared sizing for both header buttons on /ore-lots/ ("Export to
   Excel" + "+ New Lot"). The padding inherits from .btn-primary /
   .btn-secondary (both already 12px 24px); this class only pins width,
   alignment, and link decoration so the two buttons read as a balanced
   pair regardless of their distinct primary/secondary styling. */
.ol-header-btn {
  min-width: 160px;
  text-align: center;
  white-space: nowrap;
  text-decoration: none;
}

/* ====================================================================
   Upload Centre (admin-only portal). Three-card sequential layout —
   step 1 fully lit, steps 2+ visually muted to guide ordering, but
   none of the controls are hard-disabled (the wipe-and-replace logic
   does its own ordering checks server-side).
   ==================================================================== */

.upload-centre { max-width: 920px; }
.upload-centre-head { margin-bottom: 20px; }
.upload-centre-title {
  margin: 4px 0 8px;
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: 36px;
  line-height: 1.1;
  color: var(--text);
}
.upload-centre-title em {
  color: var(--accent);
  font-style: italic;
}
.upload-centre-sub {
  margin: 0 0 22px;
  color: var(--text-dim);
  font-size: 14px;
}

.upload-centre-warning {
  background: #FFF8E5;
  border-left: 4px solid #B0822B;
  border-radius: 6px;
  padding: 16px;
  margin-bottom: 28px;
  font-size: 13.5px;
  line-height: 1.5;
  color: #1F1F1F;
}

.upload-card {
  background: var(--bg-elev, #FFFFFF);
  border: 1px solid var(--border, #E1DBC9);
  border-radius: var(--radius-lg, 12px);
  padding: 24px 28px;
  margin-bottom: 24px;
}
.upload-card.is-muted { opacity: 0.78; }
.upload-card.is-muted .upload-card-actions { opacity: 0.7; }
.upload-card-head { margin-bottom: 14px; }
.upload-card-title {
  margin: 0 0 6px;
  font-family: var(--font-serif);
  font-weight: 600;
  font-size: 20px;
  color: var(--text, #1F1F1F);
}
.upload-card-step { color: var(--accent, #A85C3A); margin-right: 4px; }
.upload-card-status { margin: 0; color: var(--text-dim); font-size: 13px; }
/* V28.1 — from-status → to-status flow line on each upload card. */
.upload-card-flow {
  margin: 4px 0 6px;
  font-size: 12.5px;
  display: inline-flex; gap: 6px; align-items: center;
  color: var(--text);
}
.upload-card-flow strong { color: var(--accent); font-weight: 600; }
.upload-card-actions {
  display: flex;
  gap: 8px;
  margin: 14px 0 16px;
}
.upload-btn {
  min-width: 160px;
  text-align: center;
  white-space: nowrap;
  text-decoration: none;
}
.upload-card-note {
  margin: 12px 0 0;
  font-size: 12.5px;
  font-style: italic;
}

.upload-drop-form { margin: 0; }
.upload-drop {
  display: block;
  border: 2px dashed color-mix(in srgb, var(--accent, #A85C3A) 40%, transparent);
  border-radius: 12px;
  padding: 32px;
  text-align: center;
  cursor: pointer;
  background: transparent;
  transition: background 120ms ease, border-color 120ms ease;
}
.upload-drop:hover,
.upload-drop.is-dragover {
  background: color-mix(in srgb, var(--accent, #A85C3A) 6%, transparent);
  border-color: color-mix(in srgb, var(--accent, #A85C3A) 70%, transparent);
}
.upload-drop-text {
  color: var(--text-dim, #6B6B66);
  font-size: 13px;
  font-family: var(--font-sans);
}
.ol-list-table .ol-invoice-value {
  font-family: var(--font-serif);
  font-weight: 600;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}

/* Capital Exposure summary rows — TOTAL (bold, thick top border, taller
   padding) and INVOICED & COMPENSATED (muted/italic, informational only).
   Neither row carries a stage badge or click-through. */
.exposure-summary td { font-variant-numeric: tabular-nums; }
.exposure-summary-total td {
  border-top: 1px solid #1F1F1F;
  padding-top: 16px;
  padding-bottom: 16px;
  font-weight: 600;
}
.exposure-summary-total .exposure-summary-label {
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: 12px;
  color: #1F1F1F;
}
.exposure-summary-compensated td,
.exposure-summary-settled td {
  color: #6B6B66;
  font-style: italic;
}
.exposure-summary-compensated .exposure-summary-label,
.exposure-summary-settled .exposure-summary-label {
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: 12px;
  font-style: normal;
  color: #6B6B66;
}
.data-table th.num, .data-table td.num { text-align: left; font-variant-numeric: tabular-nums; }
/* Alignment helpers that win against `.data-table th, .data-table td` (which
   sets text-align: left at 0,0,1,1). Both `.lib4-num` and `.center` are 0,0,1,0
   on their own — qualifying on `.data-table` raises specificity to 0,0,2,1
   so they apply to both head and body cells consistently. */
.data-table th.lib4-num, .data-table td.lib4-num { text-align: left; font-variant-numeric: tabular-nums; }
/* `.center` is the explicit STATUS / ACTION column class — header and
   data cells both render centered. */
.data-table th.center,   .data-table td.center   { text-align: center; }

/* Capital Exposure by Stage table.
   7 columns: Stage (left, wide enough for "Awaiting Supplier Acceptance"
   on a single line) + 6 numeric (right). The numeric columns share the
   remainder evenly. */
.exposure-table {
  table-layout: fixed;
  width: 100%;
}
.exposure-table th:first-child,
.exposure-table td:first-child {
  /* Fits the longest pill ("Awaiting Supplier Acceptance" — 28 uppercase
     chars at 10.5px / 0.08em letter-spacing) plus pill + cell padding.
     text-align comes from the `.center` class applied in the template
     (Stage is a STATUS column, centered per the global rule). */
  width: 340px;
}
.exposure-table th:not(:first-child),
.exposure-table td:not(:first-child) {
  width: calc((100% - 340px) / 6);
}
.exposure-table td.num,
.exposure-table th.num {
  text-align: left;
  font-variant-numeric: tabular-nums;
}
/* Pills always render fully — never truncate. */
.exposure-table .badge {
  white-space: nowrap;
  overflow: visible;
  text-overflow: clip;
}

/* Capital Exposure table — Stage column LEFT-aligned (header + data),
   despite the app-wide STATUS-column centering rule. Scoped tightly to
   this table only via compound class specificity: the head selector is
   0,0,4,2 (beats the global terracotta th.center at 0,0,3,2) and the
   body selector is 0,0,3,2 (beats .data-table td.center at 0,0,2,1).
   Every other STATUS column app-wide stays centered. */
.data-table.data-table--terracotta.exposure-table thead th.center,
.data-table.exposure-table tbody td.center { text-align: left; }

/* ──────────────────────────────────────────────────────────
   Advances workspace — hero, warehouse cards, list
   ──────────────────────────────────────────────────────── */
.adv-page { max-width: 1280px; }
.adv-hero {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 18px; margin-bottom: 26px;
}
.adv-hero-sub { margin: 4px 0 0; font-size: 13px; }
.adv-hero-actions { display: flex; gap: 10px; flex-shrink: 0; }

.adv-section { margin-bottom: 36px; }
.adv-section-title {
  margin: 0 0 14px;
  font-family: var(--font-serif);
  font-size: 20px;
  font-weight: 600;
  color: var(--text);
  letter-spacing: -0.01em;
}

.adv-card-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
}
.adv-card {
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 22px 24px 20px;
  display: flex; flex-direction: column;
  gap: 14px;
}
.adv-card-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px;
}
.adv-card-name {
  background: transparent;
  border: none;
  padding: 0;
  font-family: var(--font-serif);
  font-size: 18px;
  font-weight: 600;
  color: var(--accent);
  cursor: pointer;
  text-align: left;
  letter-spacing: -0.01em;
}
.adv-card-name:hover { color: var(--accent-soft); text-decoration: underline; }
.adv-card-filter-link {
  font-size: 11.5px;
  color: var(--text-dim);
  text-decoration: none;
}
.adv-card-filter-link:hover { color: var(--accent); text-decoration: underline; }
.adv-card-stats { margin: 0; display: flex; flex-direction: column; gap: 10px; }
.adv-card-stats > div { display: flex; flex-direction: column; gap: 2px; }
.adv-card-stats dt {
  font-size: 10.5px;
  color: var(--text-dim);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.10em;
  margin: 0;
}
.adv-card-stats dd {
  margin: 0;
  font-family: var(--font-serif);
  font-size: 20px;
  font-weight: 600;
  color: var(--text);
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
}
.adv-card-stats dd.adv-card-exposure { color: var(--accent); }

.adv-list-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 16px; margin-bottom: 12px;
}
.adv-filter-form { margin: 0; }
.adv-filter-label {
  display: flex; flex-direction: column; gap: 4px;
  font-size: 11px;
  color: var(--text-dim);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.adv-filter-label select {
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 8px 10px;
  font-size: 13.5px;
  color: var(--text);
  font-family: var(--font-sans);
  min-width: 220px;
}
.adv-filter-label select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-bg);
}

.adv-warehouse-link {
  background: transparent; border: none; padding: 0;
  color: var(--accent); font-family: inherit; font-size: inherit;
  cursor: pointer;
}
.adv-warehouse-link:hover { color: var(--accent-soft); text-decoration: underline; }

.adv-table td .mono { font-family: var(--font-mono); font-size: 12px; }

@media (max-width: 1100px) {
  .adv-card-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 720px) {
  .adv-card-grid { grid-template-columns: 1fr; }
  .adv-hero { flex-direction: column; align-items: stretch; }
  .adv-hero-actions { flex-direction: column; }
  .adv-list-head { flex-direction: column; align-items: stretch; }
}

/* ──────────────────────────────────────────────────────────
   Lot identifier display — primary line + (optional) secondary.
   Used inside .cpm-pa-lot-link, .lib4-lot-link, list cells, and the
   ore_lots detail / edit headers. The actual code is supplied by the
   {% lot_code lot %} inclusion tag in core/templatetags/cpmorox_format.py
   ──────────────────────────────────────────────────────── */
.lot-code-primary {
  display: block;
  font-weight: 600;
  font-size: 13px;
  color: var(--accent);
  line-height: 1.2;
}
.lot-code-secondary {
  display: block;
  font-size: 11px;
  font-weight: 500;
  color: var(--text-muted);
  margin-top: 2px;
  letter-spacing: 0.02em;
}
.lot-code-await { font-style: italic; font-weight: 500; }

/* When the lot-code lives inside an existing styled link (e.g. the
   primary list-table lot link), let the link color cascade rather than
   forcing the accent twice. */
a .lot-code-primary { color: inherit; }

/* ──────────────────────────────────────────────────────────
   CPM Pending Approval — two-column workflow view
   ──────────────────────────────────────────────────────── */
.cpm-pa-page .page-title { margin-bottom: 18px; }

.cpm-pa-search {
  margin: 0 0 22px;
}
.cpm-pa-search .pa-search { width: 100%; }

/* Used by pages that reuse the two-column shell but don't have a search bar. */
.cpm-pa-hero-sub { margin: -8px 0 22px; font-size: 13.5px; }
.cpm-pa-col-sub { margin: -4px 0 10px; font-size: 12.5px; }

/* Negotiation table — accent the offer USD cell so it scans like money */
.neg-table .neg-offer-cell {
  font-family: var(--font-serif);
  font-weight: 600;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}

/* CPM negotiation list — two sections stacked vertically (replacing the
   former side-by-side layout). Each section is full-width; generous gap
   so they read as distinct workflow stages.
   Selectors chain .cpm-pa-table.neg-table so the negotiation overrides
   win the specificity tie with the generic .cpm-pa-table rules below. */
.neg-stack { display: flex; flex-direction: column; gap: 52px; margin-top: 8px; }
.neg-stack-section { min-width: 0; }

/* Column widths — proportional to content rather than evenly spread. */
.cpm-pa-table.neg-table { table-layout: auto; }
.cpm-pa-table.neg-table th:first-child,
.cpm-pa-table.neg-table td:first-child         { width: 180px; min-width: 180px; }
/* Column widths come from a <colgroup> on each negotiation table; we just
   need table-layout: fixed to honor those percentages. */
.cpm-pa-table.neg-table { table-layout: fixed; }

/* No wrapping anywhere on these tables — headers, cells, status badges,
   button labels. The Lot column uses internal <div>s which still stack
   vertically (block elements ignore nowrap). */
.cpm-pa-table.neg-table thead th,
.cpm-pa-table.neg-table tbody td { white-space: nowrap; }
.cpm-pa-table.neg-table .badge { white-space: nowrap; }

/* Status column (3rd column in both tables) — center the header and the
   pill so the badge sits directly below its label. */
.cpm-pa-table.neg-table thead th:nth-child(3),
.cpm-pa-table.neg-table tbody td:nth-child(3) { text-align: left; }

/* Action column — buttons sit side-by-side, centered under a centered
   header label. White-space: nowrap on the group prevents wrapping when
   the column tightens. */
.cpm-pa-table.neg-table .cpm-pa-actions-th {
  text-align: left;
}
.cpm-pa-table.neg-table .cpm-pa-actions-cell {
  text-align: left;
  vertical-align: middle;
  white-space: nowrap;
}
.cpm-pa-table.neg-table .cpm-pa-actions-cell .cpm-pa-actions-stack {
  display: inline-flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: 8px;
  white-space: nowrap;
  max-width: none;
  margin: 0;
}
.cpm-pa-table.neg-table .cpm-pa-actions-cell .pa-inline-form {
  display: inline-flex;
  margin: 0;
}
.cpm-pa-table.neg-table .cpm-pa-actions-stack .pa-row-action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: auto;
  min-width: 0;
  padding: 6px 14px;
  font-size: 12px;
  white-space: nowrap;
  box-sizing: border-box;
}

/* Vertical alignment within rows — the Lot cell has a small "MW-130"
   subtitle that makes its row taller; every other cell middle-aligns so
   text doesn't drift to the top. */
.cpm-pa-table.neg-table tbody td { vertical-align: middle; }

.cpm-pa-flow {
  display: grid;
  grid-template-columns: 1fr;
  gap: 32px;
  align-items: stretch;
}
.cpm-pa-col { min-width: 0; }
.cpm-pa-col-head {
  display: flex; align-items: baseline; gap: 10px;
  margin-bottom: 10px;
}
.cpm-pa-col-title {
  margin: 0;
  font-family: var(--font-serif);
  font-size: 19px;
  font-weight: 600;
  color: var(--text);
  letter-spacing: -0.01em;
}
.cpm-pa-col-count {
  display: inline-block;
  padding: 2px 9px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  color: var(--accent);
  background: var(--accent-bg);
  font-variant-numeric: tabular-nums;
  font-family: var(--font-sans);
}
.cpm-pa-col-pending .cpm-pa-col-count  { color: var(--stage-pending_approval); background: color-mix(in srgb, var(--stage-pending_approval) 12%, transparent); }
.cpm-pa-col-approved .cpm-pa-col-count { color: var(--stage-approved);         background: color-mix(in srgb, var(--stage-approved) 12%, transparent); }

.cpm-pa-col-card { padding: 0; overflow: hidden; }

/* Chevron retired — sections are stacked vertically so left→right cue is
   redundant. Keep the markup in place for the responsive media-query
   classes that still reference it, but never render. */
.cpm-pa-flow-arrow { display: none; }

.cpm-pa-table { font-size: 13px; }
.cpm-pa-table thead th {
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-dim);
  padding: 12px 14px;
}
.cpm-pa-table tbody td { padding: 12px 14px; vertical-align: middle; }
.cpm-pa-table .num { text-align: left; font-variant-numeric: tabular-nums; }
/* Lot Number column: matches the right-column layout — wide enough for
   "LOT-DEMO-XXXX" on a single line. */
.cpm-pa-table th:first-child,
.cpm-pa-table td:first-child { min-width: 160px; }
.cpm-pa-table .cpm-pa-actions-th { width: 120px; text-align: left; }
/* Keep the td as a normal table-cell (so its border-bottom forms a
   continuous row divider) — the vertical stacking happens on the inner
   .cpm-pa-actions-stack flex container, not on the td itself. */
.cpm-pa-table .cpm-pa-actions-cell {
  text-align: left;
  vertical-align: middle;
  white-space: normal;
}
.cpm-pa-actions-stack {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 6px;
  margin: 0 auto;
  max-width: 96px;
}
.cpm-pa-actions-stack .pa-inline-form { display: block; margin: 0; }
.cpm-pa-actions-stack .pa-row-action {
  display: block;
  width: 100%;
  margin: 0;
  text-align: center;
  padding: 6px 10px;
  font-size: 12px;
  font-weight: 600;
  border-radius: 4px;
  opacity: 1;
}
/* Open button as a proper tertiary — matches the visual weight of
   Approve/Reject (border, transparent background, hover tint). */
.cpm-pa-actions-stack .pa-row-action.pa-row-open {
  color: var(--accent);
  background: transparent;
  border: 1px solid var(--border-strong);
  text-decoration: none;
}
.cpm-pa-actions-stack .pa-row-action.pa-row-open:hover {
  background: var(--accent-bg);
  border-color: var(--accent);
}

.cpm-pa-lot-link {
  color: var(--accent);
  font-weight: 600;
  text-decoration: none;
  font-size: 13px;
  white-space: nowrap;
}
.cpm-pa-lot-link:hover { text-decoration: underline; }
.cpm-pa-row-meta {
  font-size: 11px;
  color: var(--text-muted);
  margin-top: 2px;
}

.cpm-pa-empty td { padding: 0; border-bottom: none; }
.cpm-pa-empty-inner {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 36px 18px;
  color: var(--text-dim);
  text-align: center;
}
.cpm-pa-empty-inner strong {
  font-family: var(--font-serif);
  font-weight: 600;
  font-size: 14.5px;
  color: var(--text);
}
.cpm-pa-empty-inner span { font-size: 12.5px; color: var(--text-muted); }

@media (max-width: 1100px) {
  .cpm-pa-table { font-size: 12.5px; }
  .cpm-pa-table thead th, .cpm-pa-table tbody td { padding: 10px 10px; }
}

/* Libertad4 dashboard — compact KYC ticks for the overdue table */
.lib4-kyc-row-compact {
  display: flex;
  flex-wrap: nowrap;
  gap: 3px;
  align-items: center;
}
.lib4-kyc-icon-mini {
  width: 18px;
  height: 18px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  font-size: 10px;
  font-weight: 700;
  line-height: 1;
  cursor: default;
  border: 1px solid transparent;
}

/* Dashboard KYC-overdue table: honor the colgroup widths and center the
   Tranche 2 indicator under its header. The 17-circle group inherits the
   default flex-start (left) alignment so the first circle sits directly
   under the "KYC 1" header. */
.lib4-overdue-table { table-layout: fixed; }
.lib4-overdue-t2-th { text-align: left; white-space: nowrap; }
.lib4-overdue-t2-cell { text-align: left; vertical-align: middle; }

/* Send Batches (libertad4 /pending-approval/) — fixed layout, single-line
   rows. The 5th column is centered on BOTH tables under a single shared
   rule so the STATUS badge and the ACTION button pivot around the exact
   same X axis when the two tables stack vertically. */
.lib4-sb-table { table-layout: fixed; }
.lib4-sb-table thead th { white-space: nowrap; }
.lib4-sb-table tbody td { white-space: nowrap; vertical-align: middle; }
.lib4-sb-table .lib4-sb-action-th,
.lib4-sb-table .lib4-sb-action-cell {
  text-align: left;
  vertical-align: middle;
  white-space: nowrap;
}
/* Strip any inherited horizontal margin so the centered child is
   pivoted exactly on the cell's X-center. Both the badge and the
   dispatch button are inline-level (inline-block / inline-flex); the
   shared text-align:center then gives identical placement. */
.lib4-sb-action-cell .lib4-status-pending,
.lib4-sb-action-cell .lib4-dispatch-btn {
  margin: 0;
  vertical-align: middle;
}

/* Vertical hairline between the 17 KYC circles and the Tranche 2 circle.
   Sits inside the same inline-flex container as the circles so spacing
   stays consistent regardless of cell padding. */
.lib4-kyc-divider {
  display: inline-block;
  flex: 0 0 1px;
  width: 1px;
  height: 18px;
  background: #E1DBC9;
  margin: 0 12px;
}

/* Tracker KYC column — single combined column carrying both circle groups.
   The header reuses an identical inline-flex layout so the two labels
   ('KYC DOCUMENTS' / 'TRANCHE 2') sit directly above their circle groups. */
/* Tracker table — shared base used by both libertad4 /kyc/ (20 cols) and
   CPM /kyc-tracker/ (21 cols, adds a STATUS column). Two-tier header
   groups the 17 doc columns under "KYC 1" and the T2 column under
   "KYC 2". Doc-column headers are rotated 90° (read bottom-to-top) so
   the labels fit in narrow ~3.4-3.6% columns. */
.lib4-tracker-table {
  table-layout: fixed;
  min-width: 1100px;
}
/* CPM variant currently shares the libertad4 20-column layout (no extra
   STATUS column). The class is kept as a hook for future CPM-only
   overrides without forcing rules onto the shared base. */
.cpm-tracker-table { min-width: 1100px; }

/* CPM tracker's 17 KYC circles are clickable AJAX toggle buttons (the
   T2 circle stays a read-only span). Reset the user-agent <button>
   chrome so the .lib4-kyc-icon-mini bg / border / font styling shows
   through, and flip the cursor to pointer to advertise the interaction.
   Disabled state during in-flight fetch dims the tile. */
.cpm-tracker-kyc-btn {
  font: inherit;
  padding: 0;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
}
.cpm-tracker-kyc-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.cpm-tracker-kyc-btn:disabled { cursor: default; opacity: 0.6; }

/* CPM tracker T2 circle is clickable only when the lot is at
   invoiced_awaiting_tranche_2 — the .is-clickable button reuses the
   same chrome reset as the KYC 1 toggle. The read-only span variant
   for every other stage falls through to the default cursor. */
.cpm-kyc2-form { display: inline-flex; margin: 0; padding: 0; }
button.cpm-kyc2-btn {
  font: inherit;
  padding: 0;
  appearance: none;
  -webkit-appearance: none;
  cursor: pointer;
}
button.cpm-kyc2-btn:hover { background: color-mix(in srgb, var(--accent) 12%, transparent); }
button.cpm-kyc2-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
button.cpm-kyc2-btn:disabled { cursor: default; opacity: 0.6; }
button.cpm-kyc2-btn:disabled:hover { background: transparent; }
span.cpm-kyc2-btn { cursor: default; }

/* Allow the table to overflow into a horizontal scroll inside its card
   when the viewport is narrower than the table's min-width. */
.lib4-tracker-scroll { overflow-x: auto; }

/* Supra-header row 1: group labels (KYC Commercial / KYC Compliance). */
.lib4-tracker-group-th {
  text-align: left;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-size: 11px;
  font-weight: 500;
  color: #6B6B66;
  padding: 14px 8px;
  border-bottom: 1px solid #E1DBC9;
  white-space: nowrap;
}

/* Row 2: individual rotated doc/T2 headers. writing-mode + rotate(180)
   produces clean bottom-to-top text that Chrome/Safari/Firefox all
   render identically. */
.lib4-tracker-doc-row th {
  padding: 6px 0;
  border-bottom: 1px solid #E1DBC9;
  vertical-align: bottom;
  height: 110px;
}
.lib4-tracker-doc-th-label {
  display: inline-block;
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  white-space: nowrap;
  font-family: var(--font-sans, "Inter", system-ui, sans-serif);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: #6B6B66;
  line-height: 1;
}

/* Lot Number / Warehouse headers stay horizontal, vertically centered
   against the rotated header row to their right. */
.lib4-tracker-id-th,
.lib4-tracker-wh-th {
  vertical-align: middle;
  text-align: left;
}

/* Per-doc circle cells: minimal padding, single circle.
   Left-aligned per global alignment rule. */
.lib4-tracker-doc-cell {
  padding: 6px 2px;
  text-align: left;
  vertical-align: middle;
}

/* T2 column visual separation — left border + breathing-room padding
   so KYC Commercial and KYC Compliance are clearly distinct groups
   and the T2 circle isn't pressed against the divider line. */
.lib4-tracker-doc-row .lib4-tracker-t2-th,
.lib4-tracker-t2-cell {
  border-left: 1px solid #E1DBC9;
  padding-left: 16px;
  padding-right: 12px;
}
.lib4-tracker-t2-cell {
  text-align: left;
  vertical-align: middle;
}
.lib4-tracker-group-compliance {
  border-left: 1px solid #E1DBC9;
  padding-left: 16px;
}
.lib4-days-overdue {
  font-family: var(--font-serif);
  font-size: 17px;
  font-weight: 600;
  color: var(--accent);
}

/* Libertad4 negotiation table — reference implementation for the new
   app-wide list/table conventions. Scoped to .lib4-neg-table so the
   rules don't leak into other libertad4 tables yet. */
.lib4-neg-table { table-layout: fixed; }
.lib4-neg-table thead th,
.lib4-neg-table tbody td { padding: 12px 16px; }
.lib4-neg-table tbody td { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Lot number column uses tabular-nums so codes like CPM-RJ-006 line up. */
.lib4-neg-lot { font-variant-numeric: tabular-nums; }
.lib4-neg-table .lib4-offer-cell {
  font-family: var(--font-serif);
  font-weight: 600;
  font-size: 15px;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}
/* Action buttons side-by-side with an 8px gap. inline-flex preserves the
   parent td's text-align:right so the group hugs the right edge. */
.lib4-neg-actions {
  display: inline-flex;
  gap: 8px;
  white-space: nowrap;
  align-items: center;
}
.lib4-neg-actions .pa-inline-form { margin: 0; display: inline-flex; }
.lib4-accept-btn { padding: 8px 14px; font-size: 12.5px; }
.lib4-reject-btn { padding: 8px 14px; font-size: 12.5px; color: var(--text-dim); }
.lib4-reject-btn:hover { color: var(--accent); border-color: var(--border-strong); }

@media (max-width: 1100px) {
  .lib4-kyc-row { grid-template-columns: repeat(9, minmax(0, 1fr)); }
}
@media (max-width: 720px) {
  .lib4-kyc-row { grid-template-columns: repeat(5, minmax(0, 1fr)); }
  .lib4-summary-grid { grid-template-columns: 1fr; gap: 4px 0; }
  .lib4-summary-grid dt { margin-top: 8px; }
}

/* ====================================================================
   Reconciliation page (CPM-only)
   ==================================================================== */

.recon-page { padding: 0; }
.recon-head { display:flex; align-items:flex-end; justify-content:space-between; gap:24px; margin-bottom:18px; }
.recon-head-actions { display: inline-flex; align-items: center; gap: 8px; flex-shrink: 0; }
.recon-sub { margin-top:6px; max-width:720px; }

.recon-banner {
  border: 1px solid var(--border);
  border-left-width: 3px;
  background: var(--bg-elev);
  border-radius: 6px;
  padding: 12px 16px;
  margin-bottom: 18px;
  font-size: 13.5px;
  line-height: 1.5;
}
.recon-banner-warn {
  border-color: color-mix(in srgb, var(--accent) 35%, var(--border));
  border-left-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 6%, var(--bg-elev));
}
.recon-banner strong { color: var(--accent); }

.recon-section { margin-bottom: 28px; }
.recon-section-title {
  font-family: var(--serif, "Source Serif 4", Georgia, serif);
  font-size: 17px;
  font-weight: 600;
  letter-spacing: 0.01em;
  margin: 0 0 10px;
  color: var(--text);
}

/* ── Warehouse summary cards ───────────────────────────────────────── */
.recon-card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 12px;
}
.recon-card {
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 14px 16px 12px;
  transition: border-color 120ms ease, background 120ms ease, transform 120ms ease, box-shadow 120ms ease;
  position: relative;
}
.recon-card[data-href] { cursor: pointer; }
.recon-card[data-href]:hover {
  border-color: color-mix(in srgb, var(--accent) 30%, var(--border));
  background: color-mix(in srgb, var(--accent) 2%, var(--bg-elev));
  transform: translateY(-1px);
  box-shadow: 0 2px 6px color-mix(in srgb, var(--text) 6%, transparent);
}
.recon-card[data-href]:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.recon-card.is-net-owing {
  border: 1.5px solid var(--accent);
  background: color-mix(in srgb, var(--accent) 4%, var(--bg-elev));
}
.recon-card.is-active {
  border: 1.5px solid var(--accent);
  background: color-mix(in srgb, var(--accent) 8%, var(--bg-elev));
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 25%, transparent);
}
.recon-card.is-active.is-net-owing {
  background: color-mix(in srgb, var(--accent) 10%, var(--bg-elev));
}
.recon-card-head {
  /* V27.3 — name takes all available width; flag + ⋮ tuck together on
     the right. Previously this used justify-content:space-between which
     fanned three items apart (Name | Flag-in-middle | ⋮) — Flag should
     sit next to the ⋮, not float in the middle. */
  display: flex; align-items: center;
  gap: 8px; margin-bottom: 10px;
}
.recon-card-name {
  font-family: var(--serif, "Source Serif 4", Georgia, serif);
  font-size: 16px; font-weight: 600; color: var(--text);
  text-align: left;
  flex: 1; min-width: 0;
}
.recon-card-flag {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent);
  padding: 2px 8px; border-radius: 99px; white-space: nowrap; font-weight: 600;
}
.recon-card-flag-active {
  color: var(--bg-elev);
  background: var(--accent);
}
/* V16 — ellipsis edit menu used on warehouse cards, queue rows, and advance summaries. */
.recon-row-menu {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; padding: 0; margin-left: 6px;
  border: 1px solid transparent;
  background: transparent;
  color: var(--text-dim);
  border-radius: 6px; cursor: pointer;
  font-size: 16px; line-height: 1; font-weight: 700;
}
.recon-row-menu:hover, .recon-row-menu:focus-visible {
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  border-color: color-mix(in srgb, var(--accent) 24%, transparent);
  outline: none;
}
.recon-row-menu-inline { margin-left: 4px; vertical-align: middle; }

/* V18 — +New Invoice modal: repeating (invoice number, amount) rows
   with an inline remove (×) button on each row, plus a "+ Add another
   invoice" button below the list. The row is a 3-col grid so the
   remove button aligns vertically with the input rows. */
.inv-rows {
  display: flex; flex-direction: column; gap: 14px;
  margin-bottom: 12px;
}
.inv-row {
  display: grid;
  grid-template-columns: 1fr 1fr 32px;
  gap: 14px;
  align-items: end;
}
.inv-row-remove {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 38px;
  padding: 0;
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-dim);
  border-radius: 6px; cursor: pointer;
  font-size: 18px; line-height: 1; font-weight: 700;
}
.inv-row-remove:hover, .inv-row-remove:focus-visible {
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  border-color: color-mix(in srgb, var(--accent) 24%, transparent);
  outline: none;
}
.inv-row-remove:disabled { opacity: 0; pointer-events: none; }
.inv-row-add {
  margin-bottom: 12px;
  align-self: flex-start;
  font-size: 13px;
}

/* V20 — CPM Generate Invoice modal: vertical list of blend rows with
   per-row checkboxes. Used by the kanban "Generate Invoice" button. */
.cpm-gen-inv-blends {
  display: flex; flex-direction: column; gap: 6px;
  max-height: 220px; overflow-y: auto;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 8px 10px;
  margin-top: 6px;
}
.cpm-gen-inv-blend-row {
  display: flex; align-items: center; gap: 8px;
  font-size: 13px;
}
.cpm-gen-inv-blend-row input[type="checkbox"] { margin: 0; }
.recon-card-stats {
  display: grid; gap: 6px 0; margin: 0;
}
.recon-card-stats > div { display:flex; align-items:baseline; justify-content:space-between; gap: 8px; }
.recon-card-stats dt {
  font-size: 11.5px; letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--text-dim); margin: 0;
}
.recon-card-stats dd {
  margin: 0;
  font-variant-numeric: tabular-nums;
  font-size: 14px;
  color: var(--text);
}
.recon-card-exposure { font-weight: 600; }
.recon-card-exposure.is-negative { color: var(--accent); }

/* ── Advances section header + group heading ───────────────────────── */
.recon-list-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 16px; margin-bottom: 10px;
}
.recon-list-head .recon-section-title { margin-bottom: 0; }
.recon-list-filter {
  font-family: var(--serif, "Source Serif 4", Georgia, serif);
  font-weight: 500;
  color: var(--accent);
  font-size: 17px;
  margin-left: 4px;
}
.recon-show-all {
  font-size: 12.5px;
  color: var(--accent);
  text-decoration: none;
  padding: 4px 10px;
  border: 1px solid color-mix(in srgb, var(--accent) 35%, var(--border));
  border-radius: 99px;
  background: color-mix(in srgb, var(--accent) 6%, transparent);
  transition: background 120ms ease, border-color 120ms ease;
  white-space: nowrap;
}
.recon-show-all:hover {
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  border-color: var(--accent);
}

/* Subsequent warehouse groups get 16px of breathing room above their
   heading — the first group sits immediately under the column header
   band and doesn't need it. */
.recon-adv-group + .recon-adv-group { margin-top: 16px; }
.recon-group-heading {
  font-family: var(--font-sans);
  font-size: 14px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-dim, #6B6B66);
  margin: 0 0 8px;
  /* 20px top / 12px bottom — gives the warehouse name room to breathe
     so the eye reads it as a section break, not just another row. */
  padding: 20px 0 12px;
  /* Terracotta "shelf line" — visually says "rows below this belong
     to this warehouse." Heavier than the regular hairline so it reads
     as a group divider, not a row separator. */
  border-bottom: 2px solid rgba(168, 92, 58, 0.30);
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
}

/* ── Advance rows (collapsible) ────────────────────────────────────── */
.recon-adv-list { list-style: none; padding: 0; margin: 0; }
.recon-adv-item + .recon-adv-item { margin-top: 6px; }

.recon-adv {
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg-elev);
  transition: border-color 120ms ease, box-shadow 120ms ease;
}
.recon-adv[open] {
  border-color: color-mix(in srgb, var(--accent) 30%, var(--border));
  box-shadow: 0 1px 0 color-mix(in srgb, var(--accent) 12%, transparent);
}
.recon-adv-summary,
.recon-adv-header {
  display: grid;
  /* fr units, NOT percentages. Percentage tracks consume 100% of the
     container content box BEFORE gaps, so `100% tracks + 12px gap × 6`
     overflows the card to the right by 72px and the FULLY APPLIED
     badge in the last column spills past the visible edge. fr units
     distribute the post-gap leftover space, so the grid always fits.
     Ratios match the previous-spec fallback (3/14/22/14/14/15/18),
     plus a V16 4fr trailing track for the per-row edit ellipsis. */
  grid-template-columns: 3fr 14fr 22fr 14fr 14fr 15fr 15fr 4fr;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  font-size: 13px;
}
.recon-adv-summary {
  cursor: pointer;
  list-style: none;
}
.recon-adv-summary::-webkit-details-marker { display: none; }
.recon-adv-summary::marker { display: none; }

/* Single header row at the top of the Advances section. Sticks above
   every warehouse group below it — not repeated per warehouse. Solid
   terracotta band with white text is the strongest anchor on the page
   short of a real <thead>; reads instantly as "these are the columns
   for everything below." Rounded top corners match the card containers
   in the section below. The .recon-adv-num-head and
   .recon-adv-status-head modifiers carry the right text-align so
   headers line up over their corresponding cells in .recon-adv-summary. */
/* Matches shared terracotta header pill — keep in sync. */
.recon-adv-header {
  background: #A85C3A;
  color: #FFFFFF;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: 600;
  padding: 16px;
  white-space: nowrap;
  border-radius: 12px;
  margin-bottom: 8px;
}
.recon-adv-num-head { text-align: left; }
.recon-adv-status-head { text-align: center; }

.recon-adv-chev {
  font-size: 11px; color: var(--text-dim);
  transition: transform 150ms ease;
}
.recon-adv[open] .recon-adv-chev { transform: rotate(90deg); color: var(--accent); }

.recon-adv-ref { font-weight: 600; color: var(--text); }
.recon-adv-wh { color: var(--text); }
.recon-adv-date { color: var(--text-dim); }
.recon-adv-amount, .recon-adv-balance {
  font-variant-numeric: tabular-nums;
  text-align: left;
}
.recon-adv-amount { font-weight: 600; }
.recon-adv-balance { color: var(--text); }
.recon-adv-summary .recon-pill { justify-self: center; }
/* V16 — pin the per-row ⋮ to the far right of its trailing grid cell. */
.recon-adv-summary .recon-row-menu { justify-self: end; margin-left: 0; }

/* K7: per-warehouse heading on the Advances list — warm-grey pill,
   same shape as .recon-pill, tone borrowed from .lib4-unit-single.
   Lives inside the existing .recon-group-heading <h3> so the wrapper's
   spacing rules still drive vertical rhythm; the pill itself just
   shrink-wraps the warehouse name. */
.recon-warehouse-pill {
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 11.5px; text-transform: uppercase; letter-spacing: 0.05em;
  font-weight: 600;
  padding: 3px 11px; border-radius: 99px; white-space: nowrap;
  color: var(--text-dim);
  background: color-mix(in srgb, var(--text-dim) 14%, transparent);
}
.recon-group-heading:has(> .recon-warehouse-pill) {
  /* The heading becomes a transparent host for the pill — strip the
     default h3 font weight/size so the pill stands on its own. */
  font-weight: 400;
  font-size: inherit;
}

.recon-pill {
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.04em;
  font-weight: 600;
  padding: 3px 9px; border-radius: 99px; white-space: nowrap;
}
.recon-pill-open {
  color: var(--green, #4F7A4A);
  background: color-mix(in srgb, var(--green, #4F7A4A) 14%, transparent);
}
.recon-pill-fully_applied {
  color: var(--text-dim);
  background: color-mix(in srgb, var(--text-dim) 14%, transparent);
}
.recon-pill-overdrawn {
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 14%, transparent);
}

/* T5b — invoice-reconciliation pill colours. Reuses the same tinted-pill
   shape as .recon-pill-open / -overdrawn; only the colour scope differs. */
.recon-pill-unallocated {
  color: var(--text-dim);
  background: color-mix(in srgb, var(--text-dim) 14%, transparent);
}
.recon-pill-partial {
  color: #8a6510;
  background: rgba(200, 147, 43, 0.14);
}
.recon-pill-allocated {
  color: var(--green, #4F7A4A);
  background: color-mix(in srgb, var(--green, #4F7A4A) 14%, transparent);
}
.recon-pill-paid_out {
  color: var(--green, #4F7A4A);
  background: color-mix(in srgb, var(--green, #4F7A4A) 14%, transparent);
}

/* T5b — gated invoice rows (sibling lots still pre-KYC-complete). The row
   reads at ~60% opacity so the queue still shows the row as upcoming work
   while making it visually clear it's not yet actionable. Hover state is
   unchanged so the user can still scan the values cleanly. */
.recon-invoice-row.is-gated > td { opacity: 0.6; }
.recon-invoice-row.is-gated:hover > td { opacity: 1; }

.recon-action-btn + .recon-action-btn { margin-left: 6px; }

/* V5: keep Allocate + Pay Out side-by-side regardless of column width.
   Without the flex wrapper, the inline-block buttons wrap to two rows
   when the ACTION column gets narrow. */
.recon-action-row {
  display: flex;
  flex-wrap: nowrap;
  gap: 6px;
  justify-content: center;
  align-items: center;
}
.recon-action-row .recon-action-btn + .recon-action-btn { margin-left: 0; }

.recon-adv-body {
  padding: 4px 14px 14px;
  border-top: 1px solid var(--border);
}
.recon-applied-table {
  width: 100%;
  font-size: 12.5px;
  margin-top: 10px;
}
.recon-applied-table th {
  font-size: 11px; letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--text-dim);
}
/* Match the head's horizontal padding to the body's so column tracks
   align under the terracotta band. */
.recon-applied-table thead th { padding-left: 8px; padding-right: 8px; }
.recon-applied-table td { padding: 6px 8px; }
.recon-applied-table td.num { font-variant-numeric: tabular-nums; }
.recon-batch-link { color: var(--text); font-weight: 600; }
.recon-batch-link:hover { color: var(--accent); }
.recon-split-note {
  font-size: 11.5px; color: var(--text-dim); margin-top: 2px;
  font-style: italic;
}
.recon-adv-foot {
  display: flex; justify-content: space-between; align-items: center;
  gap: 16px;
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px dashed var(--border);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}
.recon-adv-hint {
  margin: 10px 0 0;
  font-size: 12px;
  color: var(--text-dim);
  font-style: italic;
}
.recon-adv-empty { padding: 12px 0; }

/* ── Invoices Without Advance section ──────────────────────────────── */
.recon-iwa-section { margin-top: 32px; }
.recon-iwa-section.has-rows {
  background: color-mix(in srgb, var(--accent) 3%, transparent);
  border-left: 3px solid var(--accent);
  border-radius: 4px;
  padding: 14px 16px 16px;
}
.recon-iwa-empty {
  color: var(--text-dim);
  font-size: 13px;
  font-style: italic;
  margin: 0;
}
.recon-iwa-table { width: 100%; font-size: 13px; }
.recon-iwa-table thead th { padding-left: 8px; padding-right: 8px; }
.recon-iwa-table td { padding: 8px; }
.recon-iwa-table td.num { font-variant-numeric: tabular-nums; }

@media (max-width: 1100px) {
  .recon-adv-summary,
  .recon-adv-header {
    grid-template-columns: 4% 1fr 1fr 100px;
    row-gap: 4px;
  }
  .recon-adv-date, .recon-adv-balance { grid-column: span 2; }
}

/* ====================================================================
   AJAX toasts (currently only fired from the CPM lot detail page).
   ==================================================================== */
.cpm-toast-region {
  position: fixed;
  right: 24px;
  bottom: 24px;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 8px;
  z-index: 9999;
  pointer-events: none;
}
.cpm-toast {
  background: #FFFFFF;
  border: 1px solid #E1DBC9;
  color: #1F1F1F;
  font-family: var(--font-sans, "Inter", system-ui, sans-serif);
  font-size: 14px;
  line-height: 1.4;
  padding: 12px 16px;
  border-radius: 12px;
  box-shadow: 0 6px 18px rgba(31, 31, 31, 0.08), 0 1px 2px rgba(31, 31, 31, 0.04);
  max-width: 360px;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 200ms ease, transform 200ms ease;
  pointer-events: auto;
}
.cpm-toast.is-shown { opacity: 1; transform: translateY(0); }
.cpm-toast.is-hiding { opacity: 0; transform: translateY(6px); }
.cpm-toast.is-error {
  border-color: rgba(168, 92, 58, 0.45);
  color: #1F1F1F;
}
.cpm-toast.is-error::before {
  content: "⚠ ";
  color: var(--accent, #A85C3A);
  font-weight: 600;
}

/* ====================================================================
   CPM /pending-approval/ — scoped table tightening + horizontal action
   groups. Lives under .cpm-pa-col-pending / .cpm-pa-col-approved so it
   only affects this page; the /negotiation/ tables (.cpm-pa-table.neg-table)
   keep their own bespoke widths.
   ==================================================================== */

.cpm-pa-col-pending .cpm-pa-table,
.cpm-pa-col-approved .cpm-pa-table { table-layout: fixed; }

.cpm-pa-col-pending .cpm-pa-table thead th,
.cpm-pa-col-pending .cpm-pa-table tbody td,
.cpm-pa-col-approved .cpm-pa-table thead th,
.cpm-pa-col-approved .cpm-pa-table tbody td {
  padding: 12px 16px;
  vertical-align: middle;
}

.cpm-pa-col-pending .cpm-pa-table .cpm-pa-row-meta,
.cpm-pa-col-approved .cpm-pa-table .cpm-pa-row-meta { line-height: 1.4; }

/* Left-align the Action column per global alignment rule. */
.cpm-pa-col-pending .cpm-pa-table .cpm-pa-actions-th {
  text-align: left;
  width: auto;
}
.cpm-pa-col-pending .cpm-pa-table .cpm-pa-actions-cell {
  text-align: left;
  white-space: nowrap;
}
/* Approve / Reject / Open side-by-side, gap 6px, centered as a group.
   Wins over the base flex-direction:column rule by higher specificity. */
.cpm-pa-col-pending .cpm-pa-actions-cell .cpm-pa-actions-stack {
  display: inline-flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: 6px;
  white-space: nowrap;
  margin: 0;
}
.cpm-pa-col-pending .cpm-pa-actions-cell .pa-inline-form {
  display: inline-flex;
  margin: 0;
}
.cpm-pa-col-pending .cpm-pa-actions-stack .pa-row-action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: auto;
  min-width: 64px;
  padding: 6px 12px;
  font-size: 12px;
  white-space: nowrap;
  box-sizing: border-box;
}

/* APPROVED — single Open button, left-aligned per global rule. */
.cpm-pa-col-approved .cpm-pa-table .cpm-pa-actions-th {
  text-align: left;
  width: auto;
}
.cpm-pa-col-approved .cpm-pa-table .cpm-pa-actions-cell {
  text-align: left;
  white-space: nowrap;
}
.cpm-pa-col-approved .cpm-pa-actions-cell .cpm-pa-actions-stack {
  display: inline-flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: 6px;
  white-space: nowrap;
  margin: 0;
}
.cpm-pa-col-approved .cpm-pa-actions-stack .pa-row-action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: auto;
  min-width: 80px;
  padding: 6px 16px;
  font-size: 12px;
  white-space: nowrap;
  box-sizing: border-box;
}

/* ---------------------------------------------------------------------------
   Libertad4 blend page (Phase 12, /pending-approval/ for libertad4 role)
   --------------------------------------------------------------------------- */

.lib4-blend-page { padding-bottom: 40px; }

.lib4-blend-pageheader {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  margin-bottom: 20px;
}

.lib4-blend-kpis { margin: 0 0 32px; }

.lib4-blend-list { display: flex; flex-direction: column; gap: 12px; }
/* V25 — flex gap is the only spacer between header band and the cards
   inside it. Without these resets the global `.card { margin-bottom:20px }`
   piles onto every row and the `.lib4-list-header-band { margin-bottom:8px }`
   piles onto the header — both stack ON TOP of the flex gap and make the
   header-to-first-card gap visually different from inter-card gaps. */
.lib4-blend-list > .lib4-list-header-band { margin-bottom: 0; }
.lib4-blend-list > .lib4-blend-row.card { margin-bottom: 0; }
/* V1 — libertad-4 KYC tracker tightens the vertical spacing between blend
   cards so more fit per viewport. Scoped to the libertad-4 KYC tracker
   wrapper specifically (the CPM-side wrapper carries the .cpm-blend-tracker
   modifier; everything else is libertad-4-facing). */
.lib4-blend-tracker:not(.cpm-blend-tracker) .lib4-blend-list { gap: 6px; }
/* V2 — CPM /kyc/ tracker gets the same tightened spacing as the libertad-4
   tracker. Negotiation list, send-batches, etc. (other surfaces using
   .lib4-blend-list outside the KYC tracker wrappers) keep the default
   12px gap because they don't carry .cpm-blend-tracker. */
.cpm-blend-tracker .lib4-blend-list { gap: 6px; }
/* V3 — /send-batches/ + /invoicing/ truck/lot row spacing matches the gap
   between the terracotta header band and the first row card. The page
   wrapper .lib4-blend-page is shared by both libertad-4 surfaces; the
   tightened spacing reads as one consistent visual rhythm. */
.lib4-blend-page .lib4-blend-list { gap: 6px; }

/* Shared column-track plumbing for blend-list pages.

   Header band and each row's .lib4-blend-summary both read their
   grid-template-columns from the same custom property --lib4-grid-cols,
   which is set ONCE on the enclosing .lib4-section[data-grid=...]. That
   guarantees every row in a section uses the identical track layout as
   the section's header band — labels can't drift out of their columns.

   Critical for pixel alignment: the row article carries a 1px .card
   border, while the header band has no border. Without compensation the
   header content edge sits 1px LEFT of the row content edge. Fix: give
   the header band a 1px transparent border + box-sizing: border-box so
   the two boxes have identical outer geometry. Same gap, same padding,
   same border → identical column tracks. */
.lib4-list-header-band {
  /* visual props (background, color, font, padding) come from the
     shared .terracotta-header rule near the top of this file. Here we
     only carry the card-list grid plumbing + box-sizing alignment. */
  display: grid;
  grid-template-columns: var(--lib4-grid-cols, 2fr 1.4fr 1fr 1fr 1.6fr 1fr 36px);
  gap: 14px;
  align-items: center;
  border: 1px solid transparent;
  box-sizing: border-box;
  white-space: nowrap;
  border-radius: 12px;
  margin-bottom: 8px;
}
/* Default for header band cells is left (inherited from the band).
   `.lib4-list-header-center` is the explicit center for STATUS / ACTION
   column header labels. `.lib4-list-header-num` and `-right` no longer
   right-align (global rule is left); they're left as aliases for the
   default in case any older markup still references them. */
.lib4-list-header-num,
.lib4-list-header-right  { text-align: left; }
.lib4-list-header-center { text-align: center; }

.lib4-blend-row {
  padding: 0;
  overflow: hidden;
  transition: box-shadow 120ms ease;
}
.lib4-blend-row:hover { box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04); }

.lib4-blend-summary {
  display: grid;
  grid-template-columns: var(--lib4-grid-cols, 2fr 1.4fr 1fr 1fr 1.6fr 1fr 36px);
  gap: 14px;
  align-items: center;
  padding: 14px 18px;
  box-sizing: border-box;
}

/* Per-section column templates. data-grid on any ancestor of the
   header band + rows sets --lib4-grid-cols once; both inherit the
   same template via CSS custom-property cascade. */
/* Sizing convention (content-aware):
   - numeric tracks (tonnage, grade) are FIXED widths sized to typical
     values so "99.0 t" / "99.00" sit snug to their neighbours instead
     of floating far right of an over-wide column.
   - date track is FIXED ~130px (fits "May 27, 2026").
   - action track is FIXED, sized to the widest button(s) in that section.
   - flex tracks (code+badge, warehouse, details) use minmax(min, Nfr)
     so they absorb remaining width and don't shrink below a readable
     minimum at narrower viewports. */
/* Slack now lives on the rightmost flex text column (MINER BATCHES /
   DETAILS) instead of WAREHOUSE. Result: TONNAGE and GRADE pull LEFT
   to sit snug to WAREHOUSE; empty whitespace falls past grade where
   it's absorbed by the wider details column. */
[data-grid="sb-pending"]      { --lib4-grid-cols: minmax(150px,1.2fr) minmax(140px,1.3fr) 80px 70px minmax(180px,2fr) 120px 48px; }
[data-grid="sb-dispatch"]     { --lib4-grid-cols: minmax(150px,1.2fr) minmax(140px,1.3fr) 80px 70px minmax(180px,2fr) 180px 48px; }
[data-grid="neg-pending"]     { --lib4-grid-cols: minmax(150px,1.2fr) minmax(140px,1.3fr) 80px 70px minmax(180px,2fr) 150px; }
[data-grid="neg-awaiting"]    { --lib4-grid-cols: minmax(150px,1.2fr) minmax(140px,1.3fr) 80px 70px minmax(180px,2fr) 130px; }
[data-grid="cpm-pa-pending"]  { --lib4-grid-cols: minmax(150px,1.2fr) minmax(140px,1.3fr) 80px 70px minmax(180px,2fr) 200px 48px; }
[data-grid="cpm-pa-approved"] { --lib4-grid-cols: minmax(150px,1.2fr) minmax(140px,1.3fr) 80px 70px minmax(180px,2fr) 130px 48px; }
[data-grid="kyc-tracker"]     { --lib4-grid-cols: minmax(150px,1.2fr) minmax(140px,1.3fr) 80px 70px minmax(200px,2.2fr) 48px; }
[data-grid="neg-lib4-offers"]   { --lib4-grid-cols: minmax(150px,1.2fr) minmax(140px,1.3fr) 80px 70px minmax(180px,2fr) 220px; }
[data-grid="neg-lib4-accepted"] { --lib4-grid-cols: minmax(150px,1.2fr) minmax(140px,1.3fr) 80px 70px minmax(180px,2fr) 180px; }
[data-grid="cpm-kyc-tracker"]   { --lib4-grid-cols: minmax(160px,1.2fr) minmax(120px,1fr) minmax(260px,2.8fr) 60px 36px; }
/* T3a libertad 4 Invoicing portal — Available to Invoice table.
   T3b prepends a fixed 48px checkbox column at the front. The 6 data
   columns that follow stay tuner-owned. The 48px lead column is OUT
   of tuner scope — fixed width.
   Defaults only — tuner owns runtime widths.
   Columns: [checkbox] | CPM LOT CODE | LOT TYPE | TONNAGE (t) | GRADE | OFFER (USD) | ACCEPTED ON */
[data-grid="lib4-invoicing-available"] { --lib4-grid-cols: 48px minmax(160px,1.5fr) 100px 110px 110px minmax(140px,1.2fr) 130px; }

/* T3c — Past Invoices history table. Single table (NOT per-warehouse).
   Lead 40px column is the chevron and is OUT of tuner scope.
   Defaults only — tuner owns runtime widths.
   Columns: [chevron] | INVOICE NUMBER | WAREHOUSE | CPM LOTS | TOTAL OFFER (USD) | GENERATED ON */
[data-grid="lib4-invoicing-past"] { --lib4-grid-cols: 40px minmax(140px,1.4fr) minmax(140px,1.4fr) 90px minmax(140px,1.2fr) 130px; }

/* T3c — drill-down detail sub-table for Past Invoices.
   Drill-down detail — not tuner-managed. */
.lib4-invoicing-past-detail-table { width: 100%; border-collapse: collapse; font-size: 13px; margin: 4px 0 2px; }
.lib4-invoicing-past-detail-table thead th {
  color: var(--text-dim);
  text-transform: uppercase;
  font-size: 10.5px;
  letter-spacing: 0.05em;
  font-weight: 600;
  padding: 8px 10px;
  text-align: left;
  border-bottom: 1px solid var(--border);
  background: transparent;
}
.lib4-invoicing-past-detail-table thead th.num { text-align: left; }
.lib4-invoicing-past-detail-table tbody td { padding: 8px 10px; vertical-align: middle; border-bottom: 1px solid var(--border); }
.lib4-invoicing-past-detail-table tbody td.num { font-variant-numeric: tabular-nums; }
.lib4-invoicing-past-detail-table tbody tr:last-child td { border-bottom: 0; }
.lib4-invoicing-past-detail-table tbody td .badge { white-space: nowrap; }

/* T3a — warehouse sub-section header above each per-warehouse table on
   the libertad 4 /invoicing/ page. */
.lib4-invoicing-warehouse-head { margin: 18px 0 8px; }
.lib4-invoicing-warehouse-name { font-size: 16px; color: var(--text-dim); font-weight: 600; margin: 0; }
.lib4-invoicing-warehouse-count { color: var(--text-mute); font-weight: 500; margin-left: 6px; }
.lib4-invoicing-section { margin-bottom: 6px; }

/* T3b — checkbox cell + selection summary + create-invoice modal. */
.lib4-invoicing-check-cell { display: flex; align-items: center; justify-content: center; }
.lib4-invoicing-check-cell input[type="checkbox"] { width: 18px; height: 18px; cursor: pointer; }
.lib4-invoicing-selection-summary { margin-top: 8px; min-height: 1.2em; }
.lib4-invoicing-selection-summary[data-state="ok"] { color: var(--text); }
.lib4-invoicing-selection-summary[data-state="mixed"] { color: var(--accent); }
.lib4-invoicing-selection-summary[data-state="empty"] { color: var(--text-dim); }
.lib4-invoicing-modal-recap { background: var(--bg-elev-2); border: 1px solid var(--border); border-radius: 8px; padding: 12px 14px; margin-bottom: 14px; }
.lib4-invoicing-modal-recap-row { display: flex; justify-content: space-between; gap: 12px; padding: 4px 0; font-size: 13px; }
.lib4-invoicing-modal-label { color: var(--text-dim); text-transform: uppercase; font-size: 11px; letter-spacing: 0.05em; font-weight: 600; }
.lib4-invoicing-modal-value { color: var(--text); font-weight: 500; }
.lib4-invoicing-modal-table { width: 100%; border-collapse: collapse; margin-top: 10px; font-size: 13px; }
.lib4-invoicing-modal-table thead th { color: var(--text-dim); text-transform: uppercase; font-size: 10.5px; letter-spacing: 0.05em; font-weight: 600; padding: 6px 4px; text-align: left; border-bottom: 1px solid var(--border); }
.lib4-invoicing-modal-table thead th.num { text-align: right; }
.lib4-invoicing-modal-table tbody td { padding: 6px 4px; }
.lib4-invoicing-modal-table tbody td.num { text-align: right; font-variant-numeric: tabular-nums; }
.lib4-invoicing-modal-error { color: var(--accent); font-size: 13px; margin: 0 0 8px; min-height: 1em; }

/* ---------------------------------------------------------------------------
   Admin/DEBUG-only column tuner — visible only when the body has the
   `ctnr-on` class (toggled by static/js/column_tuner.js). All UI here
   is invisible in production / for non-admin users because the
   tuner script is only ever loaded under the
   {% if column_tuner_enabled %} guard in base.html.
   --------------------------------------------------------------------------- */
.ctnr-toolbar {
  position: fixed; right: 18px; bottom: 18px; z-index: 9999;
  display: flex; flex-direction: column; gap: 8px; align-items: flex-end;
  font-family: -apple-system, BlinkMacSystemFont, "Inter", sans-serif;
}
.ctnr-toolbar .ctnr-toggle {
  background: #1F1F1F; color: #FFFFFF; border: none; border-radius: 999px;
  padding: 10px 16px; font-size: 12px; font-weight: 600; cursor: pointer;
  box-shadow: 0 4px 12px rgba(0,0,0,0.25); letter-spacing: 0.03em;
}
.ctnr-toolbar .ctnr-toggle:hover { background: #2F2F2F; }
.ctnr-toolbar .ctnr-reset-all {
  background: #FFFFFF; color: #A85C3A; border: 1px solid #A85C3A;
  border-radius: 999px; padding: 6px 12px; font-size: 11px; font-weight: 600;
  cursor: pointer; box-shadow: 0 2px 6px rgba(0,0,0,0.10);
}
.ctnr-toolbar .ctnr-reset-all:hover { background: #FBEEEA; }
html.ctnr-on .ctnr-toolbar .ctnr-toggle { background: #A85C3A; }

/* Drag handles — only visible when tuner is ON. Anchored to the
   right edge of each header cell (grid cells via position: relative,
   <th> elements are already a relative box). */
.ctnr-handle {
  position: absolute; top: 0; right: -3px; width: 6px; height: 100%;
  background: transparent; cursor: col-resize; z-index: 5;
  display: none; touch-action: none;
}
html.ctnr-on .ctnr-handle { display: block; }
html.ctnr-on .ctnr-handle:hover,
html.ctnr-on .ctnr-handle:active {
  background: color-mix(in srgb, #FFFFFF 70%, transparent);
  outline: 1px solid #FFFFFF;
}
/* Header cells need position: relative so the absolute-positioned
   handle anchors to the cell, not the page. */
html.ctnr-on .lib4-list-header-band > * { position: relative; }
html.ctnr-on .data-table--terracotta thead th { position: relative; }

.ctnr-tip {
  position: fixed; z-index: 10000; pointer-events: none;
  background: #1F1F1F; color: #FFFFFF; font-size: 11px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  padding: 6px 10px; border-radius: 6px; max-width: 60vw;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  box-shadow: 0 4px 12px rgba(0,0,0,0.3);
}
.ctnr-tip[hidden] { display: none; }

/* Loud error toast for tuner save failures — surfaces silent 403s
   instead of letting them disappear into a swallowed promise. */
.ctnr-error-flash {
  position: fixed; left: 18px; bottom: 18px; z-index: 10001;
  background: #b23c3c; color: #FFFFFF; font-size: 12px; font-weight: 600;
  padding: 10px 14px; border-radius: 8px; max-width: 60vw;
  box-shadow: 0 4px 12px rgba(0,0,0,0.30);
}
.ctnr-error-flash[hidden] { display: none; }

/* Manual allocation modal — simplified 3-choice flow. */
.ma-modal-body { padding: 18px; }
.ma-modal-summary { margin: 0 0 18px; font-size: 14px; color: var(--text); }
.ma-modal-summary strong { color: var(--text); }
.ma-choice-stack { display: flex; flex-direction: column; gap: 10px; }
.ma-choice-stack .ma-choice-btn { width: 100%; padding: 14px 16px; font-size: 14px; font-weight: 600; }
.ma-modal-actions { display: flex; gap: 10px; justify-content: flex-end; margin-top: 18px; }
.ma-advance-select { width: 100%; padding: 10px 12px; border: 1px solid var(--border); border-radius: 6px; font-size: 13.5px; margin-top: 6px; }
.ma-warn { color: #8a6510; background: rgba(200,147,43,0.10); padding: 10px 12px; border-radius: 6px; margin-top: 0; }

.lib4-blend-code { font-weight: 600; font-size: 14px; color: var(--text); }
.lib4-unit-badge {
  display: inline-block;
  margin-left: 8px;
  padding: 1px 7px;
  border-radius: 8px;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  vertical-align: middle;
}
.lib4-unit-badge.lib4-unit-blend {
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  color: var(--accent);
}
.lib4-unit-badge.lib4-unit-single {
  background: color-mix(in srgb, var(--text-dim) 14%, transparent);
  color: var(--text-dim);
}
.lib4-blend-name { font-size: 12.5px; color: var(--text-dim); margin-top: 2px; }
.lib4-blend-warehouse { font-size: 13px; color: var(--text); }
.lib4-blend-num { font-size: 13.5px; color: var(--text); font-variant-numeric: tabular-nums; text-align: left; }
/* Stack of info/status pills. align-items: flex-start makes each pill
   shrink to its text content (hug-text shading) instead of stretching
   to fill the column. Pills sit at the left edge of the cell, stacked
   top-down with a 4px gap. In a centered STATUS column, the cell's own
   text-align:center is overridden by the flex layout — apply
   `align-items: center` via a parent rule there if needed (currently
   no STATUS column uses .lib4-blend-badges in a centered cell, so the
   default flex-start is correct for every site). */
.lib4-blend-badges { display: flex; flex-direction: column; gap: 4px; align-items: flex-start; }
.lib4-blend-badge {
  display: inline-block;
  font-size: 11.5px;
  padding: 2px 8px;
  border-radius: 10px;
  background: var(--bg-elev-2);
  color: var(--text-dim);
  white-space: nowrap;
}
.lib4-blend-date { font-size: 12.5px; }

.lib4-blend-expand {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-dim);
  width: 32px;
  height: 32px;
  border-radius: 6px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: transform 160ms ease, background 120ms ease, color 120ms ease;
}
.lib4-blend-expand:hover { background: var(--bg-elev-2); color: var(--text); }
.lib4-blend-row.is-open .lib4-blend-expand { transform: rotate(180deg); color: var(--accent); border-color: var(--accent); }

.lib4-blend-detail {
  max-height: 0;
  overflow: hidden;
  transition: max-height 260ms ease;
  border-top: 0 solid var(--border);
}
.lib4-blend-row.is-open .lib4-blend-detail {
  max-height: 600px;
  border-top: 1px solid var(--border);
}
.lib4-blend-detail .lib4-mb-subtable {
  width: 100%;
  border-collapse: collapse;
}
.lib4-blend-detail .lib4-mb-subtable th,
.lib4-blend-detail .lib4-mb-subtable td {
  padding: 10px 18px;
  font-size: 12.5px;
}
.lib4-blend-detail .lib4-mb-subtable thead th {
  /* V3 — pre-V3 used var(--bg-elev-2) (#F5F0E2), nearly identical to
     the page parchment (#EDE7D9), making the inner sub-table header
     read as a beige-on-beige strip with no visible separation. The new
     warm light grey lands a clear shade darker than the parchment
     background, so the header band visually separates from the row
     card without losing the palette warmth. */
  background: #E0D9C5;
  color: #5C5142;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: 11px;
}

/* ---------- New Blend modal ---------- */

.lib4-blend-modal .lib4-blend-panel {
  max-width: 760px;
  width: 92vw;
  max-height: 90vh;
  display: flex;
  flex-direction: column;
}

.lib4-blend-form {
  overflow-y: auto;
  overflow-x: hidden;
  padding-right: 4px;
}

.lib4-blend-form-band {
  margin: 0 0 14px;
  padding: 8px 12px;
  border-radius: 6px;
  background: rgba(178, 60, 60, 0.08);
  color: #b23c3c;
  font-size: 13px;
  display: none;
}
.lib4-blend-form-band.is-on { display: block; }

.lib4-blend-section { margin-bottom: 18px; }
.lib4-blend-section-title {
  font-size: 12.5px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-dim);
  margin: 0 0 10px;
  font-weight: 600;
}

.lib4-mb-rows { display: flex; flex-direction: column; gap: 8px; margin-bottom: 8px; }

.lib4-mb-row {
  background: var(--bg-elev-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 12px;
  transition: opacity 200ms ease, transform 200ms ease, max-height 200ms ease;
}
.lib4-mb-row.is-removing { opacity: 0; transform: translateX(-12px); max-height: 0; padding-top: 0; padding-bottom: 0; margin-top: 0; margin-bottom: 0; overflow: hidden; }

.lib4-mb-row-grid {
  display: grid;
  grid-template-columns: 1.2fr 1.6fr 1fr 1fr 28px;
  gap: 10px;
  align-items: end;
}
/* Batch-vs-Blend redesign: 3 inputs (code + tonnage + grade) + remove
   button, miner_name dropped per the new flow. */
.lib4-mb-row-grid-3 {
  grid-template-columns: 1.4fr 1fr 1fr 28px;
}
.lib4-mb-row-grid .pa-modal-field { margin: 0; }

/* Batch-vs-Blend choice modal */
.lib4-choice-modal .lib4-choice-panel {
  max-width: 480px;
  width: 92vw;
}
.lib4-choice-body {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  padding: 8px 0 16px;
}
.lib4-choice-tile {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 18px 14px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--bg-elev-2);
  cursor: pointer;
  text-align: left;
  transition: border-color 120ms ease, background 120ms ease, box-shadow 160ms ease;
}
.lib4-choice-tile:hover {
  border-color: var(--accent);
  background: var(--bg-elev);
  box-shadow: 0 1px 6px rgba(168, 92, 58, 0.08);
}
.lib4-choice-tile-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--text);
}
.lib4-choice-tile-sub {
  font-size: 12px;
  color: var(--text-dim);
  line-height: 1.4;
}

/* Single-batch modal */
.lib4-batch-modal .lib4-batch-panel {
  max-width: 520px;
  width: 92vw;
  max-height: 90vh;
  display: flex;
  flex-direction: column;
}
.lib4-batch-form { overflow-y: auto; padding-right: 4px; }

/* ---------------------------------------------------------------------------
   CPM /pending-approval/ page (Phase 12, blend-centric)
   --------------------------------------------------------------------------- */

.cpm-pending-approval .cpm-pa-search {
  margin: 0 0 18px;
}
.cpm-pending-approval .cpm-pa-search input[type="search"] {
  width: 100%;
  padding: 10px 14px;
  font-size: 13.5px;
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-sizing: border-box;
}
.cpm-pending-approval .cpm-pa-search input[type="search"]:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-bg);
}
.cpm-pending-approval .cpm-section-count {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text-dim);
  background: var(--bg-elev-2);
  border-radius: 10px;
  padding: 2px 10px;
  margin-left: 8px;
}
/* Approval rows: the grid template now comes from --lib4-grid-cols on
   the parent [data-grid="cpm-pa-pending|cpm-pa-approved"] so header
   band and rows share ONE template. This class no longer sets the
   grid; the per-section column widths live with the other [data-grid]
   blocks near the top of the file. */
.cpm-pa-actions {
  display: inline-flex;
  gap: 8px;
  justify-content: center;
  align-items: center;
}
.cpm-pa-approve-btn { padding: 8px 14px; font-size: 12.5px; }
.cpm-pa-reject-btn {
  padding: 8px 14px;
  font-size: 12.5px;
  color: var(--text-dim);
}
.cpm-pa-reject-btn:hover { color: #b23c3c; border-color: #b23c3c; }

/* K2 — KYC tracker tile column headers use 3-4 letter abbreviated codes
   (FAC, GRR, etc.) with the full Spanish name in a native title= tooltip.
   The K2 wrapper class disables the legacy fixed-percent colgroup so the
   doc cells settle at a fixed 36px width — that way a 17-tile MINER/REINFO
   row fits on a standard laptop viewport, and a 7-tile TRADER row hugs
   its content rather than stretching tiles to absurd widths. */
.lib4-tracker-mb-scroll-k2 .lib4-tracker-mb-table { width: auto; }
.lib4-tracker-mb-scroll-k2 .lib4-tracker-doc-cell { width: 36px; min-width: 36px; }
.lib4-tracker-doc-th-abbrev {
  height: 28px;
  padding: 2px 0;
  text-align: center;
  vertical-align: middle;
}
.lib4-tracker-doc-th-abbrev .lib4-tracker-doc-th-code {
  display: inline-block;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.05em;
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}
.lib4-tracker-mb-scroll-k2 .lib4-tracker-mb-table th.lib4-tracker-doc-th-abbrev {
  height: 28px;
}

/* L1 — libertad-4 dashboard KYC outstanding table.
   Warehouse filter dropdown above the table + inline read-only tile row
   inside the KYC 1 PROGRESS column. Tiles reuse the K2 abbrev text
   styling (.lib4-tracker-doc-th-code) and add a received/pending tone
   driven by .is-received. Cells are <span>, never <button> — libertad-4
   has no edit rights on KYC ticks. */
.lib4-dashboard-filter {
  display: flex; align-items: center; gap: 10px; margin: 0 0 12px;
}
.lib4-dashboard-filter-label {
  font-size: 12px; color: var(--text-dim); text-transform: uppercase;
  letter-spacing: 0.05em; font-weight: 600;
}
.lib4-dashboard-filter select {
  padding: 6px 10px; border-radius: 6px; border: 1px solid var(--border);
  background: var(--bg-elev); color: var(--text); font-size: 13px;
}
.lib4-dashboard-tile-row {
  display: flex; flex-wrap: wrap; gap: 4px;
}
/* V1 — pending KYC tiles change from warm-grey to a soft pinkish-red
   (dusty rose adjacent to the project's terracotta) so a libertad-4
   user can spot still-outstanding docs at a glance without confusion
   with disabled / muted UI elements. Received tiles stay green. */
.lib4-dashboard-doc-tile {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; min-width: 36px; height: 26px;
  border-radius: 5px;
  background: #EBC9C0;   /* dusty rose pending — palette-friendly */
  cursor: default;
}
.lib4-dashboard-doc-tile .lib4-tracker-doc-th-code {
  color: #6B3F36;        /* darker warm tone on rose, readable */
}
.lib4-dashboard-doc-tile.is-received {
  background: color-mix(in srgb, var(--green, #4F7A4A) 18%, transparent);
}
.lib4-dashboard-doc-tile.is-received .lib4-tracker-doc-th-code {
  color: var(--green, #4F7A4A);
}

/* L2 — clickable KPI cards (Pago Au / Detracción). Anchor wrapper keeps
   the .kpi/.kpi-stack base look; .lib4-kpi-card adds hover + active
   states so the card visibly behaves as a filter toggle. */
.lib4-kpi-card {
  display: block;
  cursor: pointer;
  text-decoration: none;
  color: inherit;
  border: 2px solid transparent;
  transition: border-color 120ms ease, background-color 120ms ease, transform 120ms ease;
}
.lib4-kpi-card:hover {
  border-color: color-mix(in srgb, var(--accent) 40%, transparent);
}
.lib4-kpi-card:focus-visible {
  outline: none;
  border-color: var(--accent);
}
.lib4-kpi-card.is-active {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 8%, transparent);
}

/* L2 — clear-filter chip rendered above the KYC outstanding table when
   a doc filter is active. Terracotta tone matches the cards' active
   state so the relationship is visually obvious. */
.lib4-filter-chip-row {
  margin: 0 0 12px;
}
.lib4-filter-chip {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 4px 4px 4px 12px;
  border-radius: 99px;
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--accent);
  font-size: 12.5px; font-weight: 600;
}
.lib4-filter-chip-clear {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; border-radius: 50%;
  background: color-mix(in srgb, var(--accent) 20%, transparent);
  color: var(--accent);
  text-decoration: none;
  font-size: 16px; line-height: 1;
  transition: background-color 120ms ease;
}
.lib4-filter-chip-clear:hover {
  background: var(--accent);
  color: var(--bg-elev);
}

/* G1 — CPM Approve Truck modal. One card per unit with a required
   confidential grade input. Layout mirrors the receive-at-weighbridge
   modal's per-unit row stack. */
.cpm-approve-panel { max-width: 560px; }
.cpm-approve-intro { margin-top: 0; font-size: 13px; }
.cpm-approve-units {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 14px 0 4px;
}
.cpm-approve-unit-card { padding: 12px 14px; }
.cpm-approve-unit-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
  font-size: 13px;
}
.cpm-approve-unit-code { font-weight: 600; }
.cpm-approve-unit-row { margin: 0; }
.cpm-approve-helper {
  margin: 6px 0 0;
  font-size: 11.5px;
  color: var(--text-dim);
}

.cpm-pa-reject-modal .cpm-pa-reject-panel {
  max-width: 480px;
  width: 92vw;
}

/* ---------------------------------------------------------------------------
   /ore-lots/ Receive-at-Weighbridge action column + modal
   --------------------------------------------------------------------------- */

.ol-list-table .ol-receive-th,
.ol-list-table .ol-receive-cell {
  text-align: left;
  white-space: nowrap;
  vertical-align: middle;
}
.ol-receive-btn {
  padding: 6px 12px;
  font-size: 12px;
  white-space: nowrap;
}
/* Pre-arrival rows show the truck plate in the Lot ID column. The
   subtle italic differentiates it from a real CPM lot number without
   stealing focus. */
.ol-row-pending-arrival .ol-truck-plate {
  font-style: italic;
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}

.ol-receive-modal .ol-receive-panel {
  max-width: 520px;
  width: 92vw;
  max-height: 90vh;
  display: flex;
  flex-direction: column;
}
.ol-receive-form { overflow-y: auto; padding-right: 4px; }
.ol-receive-recap {
  background: var(--bg-elev-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 12px 14px;
  margin-bottom: 14px;
}
.ol-receive-recap dl {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px 16px;
  margin: 0;
}
.ol-receive-recap dl > div { display: flex; flex-direction: column; gap: 2px; }
.ol-receive-recap dt {
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-dim);
  margin: 0;
}
.ol-receive-recap dd {
  font-size: 13px;
  color: var(--text);
  margin: 0;
  font-variant-numeric: tabular-nums;
}

/* D3 — shared-truck receive: one row per sibling single batch. */
.ol-receive-multi-banner {
  font-size: 12px;
  font-style: italic;
}
.ol-receive-entry-row {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 12px;
  margin-bottom: 8px;
  background: var(--bg-elev-2);
}
.ol-receive-entry-head {
  font-size: 11.5px;
  margin-bottom: 6px;
  display: flex;
  gap: 8px;
  align-items: baseline;
}
.ol-receive-entry-head .mono {
  font-family: var(--font-mono, "JetBrains Mono", monospace);
  font-weight: 600;
}
.ol-receive-tonnage-block-multi {
  /* When the multi-row block is showing, the legacy single-tonnage
     half of this row is hidden — only the date input remains. */
  grid-template-columns: 1fr;
}
.ol-receive-tonnage-block-multi label[for*="weighbridge_tonnage"],
.ol-receive-tonnage-block-multi .pa-modal-field:first-child {
  display: none;
}

/* Offline-negotiation flow — offer badge stands out in the row chip
   strip; reuses the accent terracotta so it reads as "this is the
   commercially meaningful number." */
.neg-offer-badge {
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--accent);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.neg-offer-modal .neg-offer-panel,
.neg-invoice-modal .neg-offer-panel {
  max-width: 480px;
  width: 92vw;
}

.lib4-mb-remove {
  width: 28px;
  height: 28px;
  border: 1px solid var(--border);
  background: transparent;
  border-radius: 6px;
  color: var(--text-dim);
  font-size: 16px;
  cursor: pointer;
  line-height: 1;
}
.lib4-mb-remove:hover:not(:disabled) { background: var(--bg-elev); color: var(--text); }
.lib4-mb-remove:disabled { opacity: 0.35; cursor: not-allowed; }

.lib4-mb-add {
  padding: 8px 14px;
  font-size: 12.5px;
}

.lib4-mb-error {
  display: none;
  margin-top: 4px;
  font-size: 11.5px;
  color: #b23c3c;
}
.lib4-mb-error.is-on { display: block; }
input.has-error,
select.has-error { border-color: #b23c3c !important; }

.lib4-blend-totals {
  display: flex;
  gap: 18px;
  padding: 12px 14px;
  background: var(--bg-elev-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  margin: 10px 0 16px;
}
.lib4-blend-total { display: flex; flex-direction: column; gap: 2px; }
.lib4-blend-total-label {
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-dim);
}
.lib4-blend-total-value {
  font-size: 14px;
  font-variant-numeric: tabular-nums;
  color: var(--text);
  font-weight: 600;
}

/* ---------- Dispatch flow (Prompt 3) ---------- */

/* (Per-section grid now comes from --lib4-grid-cols on the parent
   .lib4-section[data-grid=...]; the legacy .lib4-blend-row-dispatch
   selector no longer needs to set its own grid.) */
/* Action column buttons sit centered under the centered ACTION
   header label (global STATUS/ACTION-center rule). */
.lib4-blend-action {
  display: flex;
  align-items: center;
  justify-content: center;
  /* V27.2 — when the action cell holds more than one button (e.g.
     Enter Offer + Send to 3rd Party Lab on /negotiation/ rows), keep
     them visibly separated. */
  gap: 8px;
  flex-wrap: wrap;
}
.lib4-blend-dispatch-btn {
  padding: 8px 14px;
  font-size: 12.5px;
  white-space: nowrap;
}
.lib4-blend-fully-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: 10px;
  background: rgba(79, 122, 74, 0.12);  /* green tint, matches --green */
  color: var(--green, #4F7A4A);
  font-size: 11.5px;
  font-weight: 600;
  white-space: nowrap;
}

/* T2 — + Add New Truck dialog. Reuses the .pa-modal / .pa-modal-panel
   shell from the existing modals (used for blend / batch creation,
   dispatch, etc.) and adds the truck-specific contents builder UI. */
.lib4-truck-panel { max-width: 720px; width: 92vw; max-height: 92vh; display: flex; flex-direction: column; }
.lib4-truck-form  { overflow-y: auto; padding: 0 4px; }
.lib4-truck-field-plate { max-width: 240px; }
.lib4-truck-contents { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--border); }
.lib4-truck-contents-head { display: flex; align-items: baseline; gap: 12px; justify-content: space-between; margin-bottom: 10px; }
.lib4-truck-summary { font-size: 12.5px; color: var(--text-dim); }
.lib4-truck-units { display: flex; flex-direction: column; gap: 14px; }
.lib4-truck-unit-block { background: var(--bg-elev-2); border-radius: 8px; padding: 14px 16px; }
.lib4-truck-unit-block .pa-modal-row + .pa-modal-row { margin-top: 18px; }
.lib4-truck-unit-block.is-saved { padding-top: 12px; padding-bottom: 12px; }
.lib4-truck-unit-head  { display: flex; align-items: center; gap: 10px; justify-content: space-between; margin-bottom: 10px; }
.lib4-truck-unit-save-row { display: flex; justify-content: flex-end; margin-top: 14px; }
.lib4-truck-save-tick {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px;
  background: var(--accent); color: #fff;
  border: none; border-radius: 4px;
  cursor: pointer;
}
.lib4-truck-save-tick:disabled { opacity: 0.5; cursor: not-allowed; }
.lib4-truck-save-tick:hover:not(:disabled) { filter: brightness(0.92); }
.lib4-truck-unit-collapsed { display: flex; align-items: center; gap: 10px; }
/* Author display:flex above beats UA [hidden]{display:none}; restore it so
   the collapsed view stays hidden in the expanded state and the pill + ×
   from this block don't render alongside the expanded header's pill + ×. */
.lib4-truck-unit-collapsed[hidden] { display: none; }
.lib4-truck-collapsed-summary { color: var(--text); flex: 1; font-size: 13.5px; }
.lib4-truck-collapsed-actions { display: flex; gap: 6px; margin-left: auto; align-items: center; }
.lib4-truck-unit-edit {
  background: transparent; border: 1px solid var(--border);
  width: 28px; height: 28px; border-radius: 6px;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--text-dim); cursor: pointer; padding: 0;
}
.lib4-truck-unit-edit:hover { color: var(--accent); border-color: var(--accent); }
.lib4-truck-stats {
  display: grid; grid-template-columns: 1fr 1fr; gap: 16px;
  margin-top: 14px;
  padding: 14px 16px;
  background: var(--bg-elev-2);
  border-radius: 8px;
}
.lib4-truck-stats[hidden] { display: none; }
.lib4-truck-stat-label { font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-dim); font-weight: 600; }
.lib4-truck-stat-value { font-family: var(--font-serif); font-size: 28px; font-weight: 600; color: var(--text); margin-top: 4px; line-height: 1.1; }
.lib4-truck-unit-code  { font-weight: 600; }
.lib4-truck-unit-remove {
  background: transparent; border: 1px solid var(--border); color: var(--text-dim);
  width: 26px; height: 26px; border-radius: 6px; cursor: pointer; font-size: 14px; line-height: 1;
}
.lib4-truck-unit-remove:disabled { opacity: 0.35; cursor: not-allowed; }
.lib4-truck-batches { margin-top: 8px; }
.lib4-block-title { font-size: 12px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-dim); margin: 4px 0 6px; }
.lib4-truck-batch-rows { display: flex; flex-direction: column; gap: 6px; }
.lib4-truck-batch-row  { display: grid; grid-template-columns: 1.2fr 1.2fr 26px; gap: 8px; align-items: center; }
.lib4-truck-batch-row input { padding: 8px 10px; border: 1px solid var(--border); border-radius: 6px; font-size: 13px; }
.lib4-truck-add-row { display: flex; gap: 10px; align-items: center; margin-top: 14px; }
.lib4-truck-add-choice { display: inline-flex; gap: 8px; }
.lib4-truck-add-choice[hidden] { display: none; }
.lib4-truck-unit { background: var(--bg-elev-2); border-radius: 8px; padding: 12px 14px; margin-bottom: 8px; }
.lib4-truck-unit-head .lib4-truck-unit-code { font-weight: 600; font-size: 13.5px; }

/* T4 — Optional miner_code. When MinerBatch.miner_code is blank the
   slot still renders (so list rows align row-to-row) but is greyed
   with the same secondary-text colour used for muted labels. One
   class, applied across both libertad4 and CPM surfaces. */
.miner-code-empty { color: #B5B0A6; font-style: italic; }

/* Dispatch modal — narrower than the New Blend modal. */
.lib4-dispatch-modal .lib4-dispatch-panel {
  max-width: 520px;
  width: 92vw;
  max-height: 90vh;
  display: flex;
  flex-direction: column;
}
.lib4-dispatch-form {
  overflow-y: auto;
  padding-right: 4px;
}
.lib4-dispatch-recap {
  background: var(--bg-elev-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 12px 14px;
  margin-bottom: 14px;
}
.lib4-dispatch-recap dl {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px 16px;
  margin: 0;
}
.lib4-dispatch-recap dl > div { display: flex; flex-direction: column; gap: 2px; }
.lib4-dispatch-recap dt {
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-dim);
  margin: 0;
}
.lib4-dispatch-recap dd {
  font-size: 13px;
  color: var(--text);
  margin: 0;
  font-variant-numeric: tabular-nums;
}

/* Dispatched-lots sub-table sits below the miner-batches sub-table in
   the expanded panel — visually separated with a thin divider. */
.lib4-dispatched-subtable { margin-top: 12px; border-top: 1px solid var(--border); }
.lib4-dispatched-action-th,
.lib4-dispatched-action-cell {
  width: 80px;
  text-align: left;
}
.lib4-cancel-link {
  background: transparent;
  border: 0;
  color: #b23c3c;
  font-size: 12px;
  cursor: pointer;
  padding: 2px 6px;
  border-radius: 4px;
}
.lib4-cancel-link:hover { background: rgba(178, 60, 60, 0.08); text-decoration: none; }

/* ---------------------------------------------------------------------------
   Libertad4 KYC tracker — blend rows with expandable MinerBatch sub-tables
   --------------------------------------------------------------------------- */

/* libertad4 KYC tracker — grid now comes from --lib4-grid-cols on the
   parent .lib4-section[data-grid="kyc-tracker"]. The .lib4-blend-tracker
   class only carries cosmetic context for the page; the row's
   .lib4-blend-summary picks up the shared variable directly. */

/* Roll-up KYC badge — colour reflects overall doc state. */
.lib4-tracker-rollup.is-complete {
  background: color-mix(in srgb, var(--green, #4F7A4A) 14%, transparent);
  color: var(--green, #4F7A4A);
  font-weight: 600;
}
.lib4-tracker-rollup.is-partial {
  background: color-mix(in srgb, #C8932B 14%, transparent);
  color: #8a6510;
  font-weight: 600;
}
.lib4-tracker-rollup.is-empty {
  background: var(--bg-elev-2);
  color: var(--text-dim);
}

/* Expanded panel's sub-table — 17 rotated headers + miner-batch rows.
   Reuses the .lib4-tracker-doc-th and .lib4-kyc-icon-mini chrome so the
   visual treatment matches the (untouched) legacy tracker styling. */
.lib4-tracker-mb-scroll { overflow-x: auto; padding: 4px 12px 12px; }
.lib4-tracker-mb-table {
  table-layout: fixed;
  min-width: 1100px;
  margin: 0;
}
.lib4-tracker-mb-table .lib4-tracker-mb-doc-row th {
  vertical-align: bottom;
  padding-top: 12px;
  padding-bottom: 6px;
  border-bottom: 1px solid #E1DBC9;
}
.lib4-tracker-mb-id-th,
.lib4-tracker-mb-name-th,
.lib4-tracker-mb-num-th,
.lib4-tracker-mb-total-th {
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-size: 11px;
  font-weight: 500;
  color: var(--text-dim);
  white-space: nowrap;
}
.lib4-tracker-mb-num-th,
.lib4-tracker-mb-total-th { text-align: left; }
.lib4-tracker-mb-table .lib4-tracker-doc-th {
  height: 110px;
  padding: 6px 0;
  vertical-align: bottom;
  border-bottom: 1px solid #E1DBC9;
}
.lib4-tracker-mb-table tbody td {
  padding: 8px 6px;
  vertical-align: middle;
  font-size: 13px;
}
.lib4-tracker-mb-table tbody td.mono {
  font-family: var(--font-mono, "JetBrains Mono", monospace);
  font-weight: 600;
}
.lib4-tracker-mb-table .lib4-tracker-doc-cell {
  padding: 6px 2px;
  text-align: left;
}
.lib4-tracker-mb-counter {
  font-variant-numeric: tabular-nums;
  color: var(--text-dim);
  font-weight: 600;
}
.lib4-tracker-mb-counter.is-complete {
  color: var(--green, #4F7A4A);
}

/* Read-only enforcement — libertad4 cannot click the doc circles. The
   default cursor + transparent-to-click <span> is enough; this rule
   makes the intent explicit and adds a subtle no-hover stance. */
.lib4-kyc-readonly { cursor: default; pointer-events: none; }

/* CPM blend tracker — grid now comes from --lib4-grid-cols on the
   parent [data-grid="cpm-kyc-tracker"]; the rows inherit via .lib4-blend-summary.
   Order: code | warehouse | badges (incl roll-up + stage) |
   KYC 2 cell | expand caret. */
.cpm-tracker-kyc2-cell {
  display: flex;
  align-items: center;
  justify-content: center;
}
.cpm-tracker-kyc2-cell .cpm-kyc2-btn {
  width: 28px;
  height: 28px;
  font-size: 13px;
}

/* Commercial-stage pill colours — paints the row's stage badge so
   T1 / T2 / FC are visually distinguishable at a glance. */
.cpm-stage-badge {
  font-weight: 600;
  text-transform: none;
  letter-spacing: 0;
  font-size: 11.5px;
}
.cpm-stage-badge.cpm-stage-invoiced_awaiting_tranche_1 {
  background: color-mix(in srgb, #C8932B 14%, transparent);
  color: #8a6510;
}
.cpm-stage-badge.cpm-stage-invoiced_awaiting_tranche_2 {
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--accent);
}
.cpm-stage-badge.cpm-stage-invoiced_kyc_complete {
  background: color-mix(in srgb, var(--green, #4F7A4A) 14%, transparent);
  color: var(--green, #4F7A4A);
}

/* ──────────────────────────────────────────────────────────
   V9 Phase 1 — Role Permissions surface.
   Read-only role-card grid (/permissions/) + matrix detail page
   (/permissions/<role>/). Cards take their accent colour from
   --perm-accent set inline per row (each role has its own warm
   AlphaOro-palette accent set in core.constants.ROLE_ACCENT_COLOR).
   ──────────────────────────────────────────────────────── */

.perm-page { display: flex; flex-direction: column; gap: 18px; }
.perm-page-band {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  padding: 18px 22px;
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-left: 4px solid var(--accent);
  border-radius: 10px;
}
.perm-page-band-text { display: flex; flex-direction: column; gap: 4px; }
.perm-page-title {
  margin: 0;
  font-family: var(--font-serif);
  font-size: 22px;
  font-weight: 600;
  color: var(--text);
  letter-spacing: -0.01em;
}
.perm-page-sub {
  margin: 0;
  color: var(--text-dim);
  font-size: 13px;
}
.perm-phase-pill {
  display: inline-flex;
  align-items: center;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--accent);
  background: var(--accent-bg);
  padding: 5px 12px;
  border-radius: 999px;
  white-space: nowrap;
}

.perm-roles-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 16px;
}
.perm-role-card {
  --perm-accent: var(--accent);
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-top: 3px solid var(--perm-accent);
  border-radius: 10px;
  padding: 18px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  transition: box-shadow 120ms ease, transform 120ms ease;
}
.perm-role-card:hover {
  box-shadow: 0 6px 18px rgba(40, 30, 18, 0.08);
}
.perm-role-card-head {
  display: flex;
  align-items: center;
  gap: 8px;
}
.perm-role-card-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--perm-accent);
}
.perm-role-card-name {
  margin: 0;
  font-family: var(--font-serif);
  font-size: 17px;
  font-weight: 600;
  color: var(--text);
}
.perm-role-card-description {
  margin: 0;
  color: var(--text-dim);
  font-size: 12.5px;
  line-height: 1.45;
  min-height: 36px;
}
.perm-role-card-meta {
  margin: 0;
  font-size: 12px;
  color: var(--text-dim);
}
.perm-role-card-meta strong {
  color: var(--text);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.perm-role-card-actions {
  margin-top: 6px;
  display: flex;
}
.perm-role-card-btn {
  background: var(--perm-accent);
  border-color: var(--perm-accent);
  flex: 1;
  text-align: center;
}
.perm-role-card-btn:hover {
  background: color-mix(in srgb, var(--perm-accent) 88%, #000);
  border-color: color-mix(in srgb, var(--perm-accent) 88%, #000);
  text-decoration: none;
}

/* Detail page — crumb + role band + module panels. */
.perm-detail-page { display: flex; flex-direction: column; gap: 16px; }

.perm-crumbs {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12.5px;
  color: var(--text-dim);
}
.perm-crumb-link { color: var(--text-dim); text-decoration: none; }
.perm-crumb-link:hover { color: var(--accent); text-decoration: none; }
.perm-crumb-sep { color: var(--text-dim); font-size: 11px; }
.perm-crumb-current { color: var(--text); font-weight: 600; }

.perm-detail-band {
  --perm-accent: var(--accent);
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  padding: 18px 22px;
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-left: 4px solid var(--perm-accent);
  border-radius: 10px;
}
.perm-detail-band-text { display: flex; flex-direction: column; gap: 6px; }
.perm-detail-role {
  display: flex;
  align-items: center;
  gap: 10px;
}
.perm-detail-dot {
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--perm-accent);
}
.perm-detail-title {
  margin: 0;
  font-family: var(--font-serif);
  font-size: 22px;
  font-weight: 600;
  color: var(--text);
}
.perm-detail-description { margin: 0; color: var(--text-dim); font-size: 13px; }
.perm-detail-meta { margin: 0; font-size: 12.5px; color: var(--text-dim); }
.perm-detail-meta strong { color: var(--text); font-variant-numeric: tabular-nums; }

.perm-page-help {
  margin: 0;
  color: var(--text-dim);
  font-size: 12.5px;
  padding: 0 4px;
}

/* V15 — scope-grouping section heading on the detail page. */
.perm-scope-heading {
  margin: 14px 4px 6px;
  font-family: var(--font-serif);
  font-size: 13px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-dim);
  padding-bottom: 6px;
  border-bottom: 1px solid var(--border);
}
.perm-scope-heading-cpm { color: var(--accent); border-bottom-color: var(--accent); }
.perm-scope-heading-libertad4 { color: #5C6FA8; border-bottom-color: #5C6FA8; }

/* Module panel — stacked container of action pills. */
.perm-detail-module {
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 16px 18px 18px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.perm-detail-module-head {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.perm-detail-module-name {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
  letter-spacing: 0.01em;
}
.perm-detail-module-sub {
  font-size: 12px;
  color: var(--text-dim);
}
.perm-detail-module-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.perm-detail-module-empty {
  font-size: 12px;
  color: var(--text-dim);
  font-style: italic;
}

/* Action pill — checkbox-pill design from the reference screenshot.
   Phase 2: live edit, pointer cursor, accent hover. The is-on state
   keeps the terracotta fill from Phase 1. */
.perm-action-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 14px;
  border: 1.5px solid var(--border);
  border-radius: 999px;
  background: var(--bg-elev);
  color: var(--text-dim);
  font-size: 12.5px;
  font-weight: 500;
  cursor: pointer;
  user-select: none;
  transition: border-color 120ms ease, background 120ms ease, color 120ms ease;
}
.perm-action-pill:hover {
  border-color: var(--accent);
  color: var(--accent);
}
.perm-action-pill input[type="checkbox"] {
  margin: 0;
  width: 13px;
  height: 13px;
  accent-color: var(--accent);
}
.perm-action-pill-label { white-space: nowrap; }
.perm-action-pill.is-on {
  border-color: var(--accent);
  background: var(--accent-bg);
  color: var(--accent);
  font-weight: 600;
}
/* V28.5 — a pill that's been toggled but not yet saved. Dashed
   ring so it's obvious which cells the user has staged for save. */
.perm-action-pill-pending {
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 35%, transparent);
  outline: 1px dashed var(--accent);
  outline-offset: 2px;
}

/* V28.5 — sticky save bar at the bottom of the permissions detail page. */
.perm-save-bar {
  position: sticky; bottom: 0;
  margin-top: 32px;
  padding: 14px 18px;
  background: var(--bg-elev);
  border-top: 1px solid var(--border);
  border-radius: 12px;
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px;
  z-index: 5;
  box-shadow: 0 -2px 14px rgba(0, 0, 0, 0.05);
}
.perm-save-bar-text { color: var(--text-dim); font-size: 13.5px; }
.perm-save-bar-actions { display: flex; gap: 8px; }
.perm-detail-page.perm-has-pending .perm-save-bar {
  background: color-mix(in srgb, var(--accent) 6%, var(--bg-elev));
  border-color: color-mix(in srgb, var(--accent) 30%, var(--border));
}
.perm-detail-page.perm-has-pending .perm-save-bar-text {
  color: var(--text);
  font-weight: 600;
}

/* V9 Phase 2 — Quick-select bar (Grant all / Clear all). Sits inline
   above the module panels; matches the reference screenshot's tone. */
.perm-quick-select {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 12.5px;
}
.perm-quick-label {
  color: var(--text);
  font-weight: 600;
}
.perm-quick-link {
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  font: inherit;
  color: var(--accent);
  cursor: pointer;
  text-decoration: underline;
}
.perm-quick-link:hover { color: var(--accent-soft); }
.perm-quick-sep { color: var(--text-dim); }

/* Toast — success / error feedback after a save. Auto-hides after a
   couple of seconds via the inline JS. */
.perm-toast {
  position: fixed;
  bottom: 24px;
  right: 24px;
  z-index: 9999;
  padding: 10px 16px;
  background: var(--accent);
  color: #ffffff;
  border-radius: 8px;
  font-size: 13px;
  font-weight: 500;
  box-shadow: 0 6px 18px rgba(40, 30, 18, 0.18);
  max-width: 360px;
}
.perm-toast.perm-toast-error {
  background: #B23E2A;
}

/* ──────────────────────────────────────────────────────────
   V11 — libertad-4 /pending-approval/ kanban + dashboard
   warehouse multi-select. Reuses the .ol-kanban / .ol-kanban-lane
   / .ol-kanban-card classes from V8; only adds the per-stage lane
   stripe rules for the 4 truck statuses and a thin alias of the
   .ol-status-multi dropdown for the dashboard warehouse filter.
   ──────────────────────────────────────────────────────── */

/* Truck-status lane stripes for the libertad-4 /pending-approval/ kanban. */
.ol-kanban-lane.stage-pending_approval  .ol-kanban-lane-head { border-bottom-color: var(--stage-pending_approval); }
.ol-kanban-lane.stage-approved          .ol-kanban-lane-head { border-bottom-color: var(--stage-approved); }
.ol-kanban-lane.stage-in_transit        .ol-kanban-lane-head { border-bottom-color: var(--stage-in_transit); }
.ol-kanban-lane.stage-arrived           .ol-kanban-lane-head { border-bottom-color: var(--stage-arrived); }

.ol-kanban-lane.stage-pending_approval  .ol-kanban-lane-count { color: var(--stage-pending_approval); background: color-mix(in srgb, var(--stage-pending_approval) 12%, transparent); }
.ol-kanban-lane.stage-approved          .ol-kanban-lane-count { color: var(--stage-approved);         background: color-mix(in srgb, var(--stage-approved) 12%, transparent); }
.ol-kanban-lane.stage-in_transit        .ol-kanban-lane-count { color: var(--stage-in_transit);       background: color-mix(in srgb, var(--stage-in_transit) 12%, transparent); }
.ol-kanban-lane.stage-arrived           .ol-kanban-lane-count { color: var(--stage-arrived);          background: color-mix(in srgb, var(--stage-arrived) 12%, transparent); }

/* Dashboard warehouse multi-select — visually identical to the
   .ol-status-multi dropdown (V8); only the data-* hook names differ. */
.wh-multi {
  display: inline-flex;
  align-items: center;
  gap: 10px;
}
.wh-multi-wrap { position: relative; }
.wh-multi-button {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 12px;
  color: var(--text);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: border-color 120ms ease, background 120ms ease;
  min-width: 200px;
  justify-content: space-between;
}
.wh-multi-button:hover { background: var(--bg-elev-2); }
.wh-multi-button[aria-expanded="true"] {
  border-color: var(--accent);
  background: var(--accent-bg);
  color: var(--accent);
}
.wh-multi-caret { font-size: 10px; color: var(--text-dim); }
.wh-multi-button[aria-expanded="true"] .wh-multi-caret { color: var(--accent); }

.wh-multi-panel {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 50;
  min-width: 280px;
  max-height: 360px;
  overflow-y: auto;
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(40, 30, 18, 0.10);
  padding: 6px;
}
.wh-multi-checkbox {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 13px;
  color: var(--text);
  user-select: none;
}
.wh-multi-checkbox:hover { background: var(--bg-elev-2); }
.wh-multi-checkbox input[type="checkbox"] {
  accent-color: var(--accent);
  width: 14px;
  height: 14px;
  margin: 0;
}
.wh-multi-checkbox-label { flex: 1; }
.wh-multi-empty {
  display: block;
  padding: 8px 10px;
  font-size: 12px;
  color: var(--text-dim);
  font-style: italic;
}
.wh-multi-clear {
  display: block;
  padding: 8px 10px;
  margin-top: 4px;
  border-top: 1px solid var(--border);
  font-size: 12px;
  color: var(--text-dim);
  text-decoration: none;
}
.wh-multi-clear:hover { color: var(--accent); text-decoration: none; }

