/* ─── NETRA ERP — Kering-inspired luxury theme ───────────────────────────────
   Warm ivory ground · near-black ink · white cards w/ hairline borders ·
   restrained champagne accent · refined serif display (maison wordmark feel). */

:root {
  --sidebar-bg:   #16130E;   /* deep warm black */
  --sidebar-w:    236px;
  --accent:       #A8895F;   /* muted champagne gold */
  --accent-hover: #C7A879;
  --text-main:    #EDE7DA;   /* cream (on dark sidebar) */
  --text-muted:   #9C9384;   /* warm grey */
  --surface:      #1E1A13;
  --border:       #E7E1D4;   /* hairline warm grey (light surfaces) */
  --paper:        #F4F1EA;   /* warm ivory page ground */
  --card:         #FFFFFF;
  --ink:          #1A1714;   /* warm near-black text */
  --ink-soft:     #7C766B;   /* warm muted text on light */
  --danger:       #9E3B36;
  --success:      #3F6B4E;
  --warning:      #9A6B1E;
  --info:         #3A5A78;

  --serif: 'Cormorant Garamond', 'Hoefler Text', Didot, 'Times New Roman', serif;
  --sans:  'Inter', 'Helvetica Neue', system-ui, -apple-system, 'Segoe UI', sans-serif;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: var(--sans);
  background: var(--paper);
  color: var(--ink);
  font-size: 14px;
  -webkit-font-smoothing: antialiased;
}

/* ─── Shell layout ───────────────────────────────────────────────────────── */

.netra-shell { min-height: 100vh; }

/* ─── Sidebar ────────────────────────────────────────────────────────────── */

#sidebar {
  width: var(--sidebar-w);
  min-height: 100vh;
  background: var(--sidebar-bg);
  color: var(--text-main);
  display: flex;
  flex-direction: column;
  flex-shrink: 0;
  padding: 0;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
}

.sidebar-brand {
  padding: 20px 18px 14px;
  border-bottom: 1px solid rgba(168,137,95,0.28);
}

.sidebar-brand .brand-name {
  display: block;
  font-family: var(--serif);
  font-size: 1.7rem;
  font-weight: 600;
  letter-spacing: 5px;
  color: #fff;
  line-height: 1;
}

.sidebar-brand .brand-sub {
  display: block;
  font-size: 0.62rem;
  color: var(--accent);
  letter-spacing: 2.5px;
  text-transform: uppercase;
  margin-top: 6px;
}

#sidebar hr { border-color: var(--border); margin: 0; }

#sidebar .nav { padding: 8px 0; flex: 1; }

#sidebar .nav-section {
  padding: 14px 18px 5px;
  font-size: 0.6rem;
  letter-spacing: 2.5px;
  color: var(--accent);
  text-transform: uppercase;
  list-style: none;
  opacity: 0.85;
}

#sidebar .nav-link {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 18px;
  color: var(--text-main);
  font-size: 0.85rem;
  border-radius: 0;
  text-decoration: none;
  transition: background 0.15s, color 0.15s;
}

#sidebar .nav-link:hover {
  background: rgba(168,137,95,0.12);
  color: var(--accent-hover);
}

#sidebar .nav-link.active {
  background: rgba(168,137,95,0.16);
  color: #fff;
  border-left: 2px solid var(--accent);
  padding-left: 14px;
}

.sidebar-footer {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 16px;
  border-top: 1px solid rgba(168,137,95,0.28);
  font-size: 0.78rem;
  color: var(--text-muted);
}

.sidebar-footer .sidebar-user strong {
  display: block;
  color: var(--text-main);
  font-size: 0.82rem;
}

.sidebar-footer a { color: var(--text-muted); text-decoration: none; font-size: 1rem; }
.sidebar-footer a:hover { color: var(--accent); }

/* ─── Main content ───────────────────────────────────────────────────────── */

.netra-main {
  flex: 1;
  padding: 30px 36px;
  min-height: 100vh;
  overflow-x: hidden;
  min-width: 0;          /* a flex item's default min-width:auto refuses to shrink below its content, which
                            is what makes a wide table push the sidebar instead of scrolling itself */
}

/* ─── The collapsing sidebar ──────────────────────────────────────────────────
   Owner, 2026-09-21: "make the left panel dissolvable and pull up when needed like the panel can open when
   we click a small arrow button so we get more space in the center."

   The state is ONE attribute on <html> — data-nav="off" — set before first paint by an inline script in the
   head, so a remembered choice never flashes open and snap shut. Everything below is that attribute's
   consequences, which keeps the whole behaviour readable in one place.

   Collapsed means width 0 AND visibility hidden: width alone leaves the links focusable, so a keyboard
   reader would tab into a menu that is not on the screen. visibility is delayed until the width transition
   has finished, and removed immediately on the way back, so the panel is never half-drawn. */

#sidebar {
  transition: width .18s ease, visibility 0s;
}

:root[data-nav="off"] #sidebar {
  width: 0;
  min-width: 0;
  overflow: hidden;
  visibility: hidden;
  transition: width .18s ease, visibility 0s .18s;
}

/* THE ONE CONTROL. It sits just clear of the sidebar when open and at the screen edge when closed, so the
   same button always does both jobs — there is never a second control that could disagree about the state. */
.nav-toggle {
  position: fixed;
  top: 10px;
  left: calc(var(--sidebar-w) + 6px);
  z-index: 1040;                      /* over the page, under the trace drawer's backdrop at 1049 */
  width: 26px;
  height: 26px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  font-size: .72rem;
  color: var(--ink-soft);
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 3px;
  cursor: pointer;
  transition: left .18s ease, color .12s, border-color .12s;
}

.nav-toggle:hover { color: var(--ink); border-color: var(--accent); }
.nav-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

:root[data-nav="off"] .nav-toggle { left: 6px; }

/* A moving panel is decoration, not information: honour the request to stop moving things. */
@media (prefers-reduced-motion: reduce) {
  #sidebar, .nav-toggle { transition: none; }
  :root[data-nav="off"] #sidebar { transition: none; }
}

/* A printed sheet has no menu and no button to open one. The existing print block already hides #sidebar
   and widens .netra-main; this only has to take the control with it. */
@media print { .nav-toggle { display: none !important; } }

/* ─── Page header ────────────────────────────────────────────────────────── */

.page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 26px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--border);
}

.page-header h1 {
  font-family: var(--serif);
  font-size: 2rem;
  font-weight: 600;
  letter-spacing: 0.5px;
  margin: 0;
  color: var(--ink);
}

.page-header .page-meta {
  font-size: 0.82rem;
  color: var(--ink-soft);
  margin-top: 2px;
  letter-spacing: 0.3px;
}

/* ─── KPI cards ──────────────────────────────────────────────────────────── */

.kpi-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 16px;
  margin-bottom: 26px;
}

.kpi-card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 2px;
  padding: 18px;
  position: relative;
}

.kpi-card .kpi-label {
  font-size: 0.66rem;
  color: var(--ink-soft);
  text-transform: uppercase;
  letter-spacing: 1.4px;
  margin-bottom: 6px;
}

.kpi-card .kpi-value {
  font-family: var(--serif);
  font-size: 1.9rem;
  font-weight: 600;
  color: var(--ink);
  line-height: 1.1;
}

.kpi-card .kpi-sub { font-size: 0.72rem; color: var(--ink-soft); margin-top: 3px; }

.kpi-card.accent  { border-top: 2px solid var(--accent); }
.kpi-card.success { border-top: 2px solid var(--success); }
.kpi-card.info    { border-top: 2px solid var(--info); }
.kpi-card.warning { border-top: 2px solid var(--warning); }

/* ─── Tables ─────────────────────────────────────────────────────────────── */

.netra-table-wrap {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 2px;
  overflow: hidden;
}

.netra-table-wrap .table-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 13px 18px;
  border-bottom: 1px solid var(--border);
  background: #FBFAF6;
}

.netra-table-wrap .table-toolbar h5 {
  margin: 0;
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: 0.3px;
}

.table { margin: 0; font-size: 0.84rem; }

.table thead th {
  background: #F7F4EC;
  font-size: 0.66rem;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--ink-soft);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
  font-weight: 600;
}

.table td { vertical-align: middle; }

/* Status badges — muted luxe */
.badge-posted    { background: #E7EFE8; color: #2F5A3E; }
.badge-draft     { background: #F5EEDD; color: #7A5A18; }
.badge-open      { background: #E6ECF2; color: #2C4866; }
.badge-formal    { background: #E8EFF0; color: #2A4D52; }
.badge-voided    { background: #F2E2E1; color: #7A2D29; }
.badge-validated { background: #E7EFE8; color: #2F5A3E; }
.badge-pending   { background: #F5EEDD; color: #7A5A18; }
.badge-confirmed { background: #E6ECF2; color: #2C4866; }
.badge-secondary { background: #ECE8DF; color: #6B6457; }

/* ─── Cards ──────────────────────────────────────────────────────────────── */

.netra-card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 2px;
  padding: 22px;
  margin-bottom: 16px;
}

.netra-card h5 {
  font-size: 0.95rem;
  font-weight: 600;
  margin-bottom: 16px;
  color: var(--ink);
  border-bottom: 1px solid var(--border);
  padding-bottom: 10px;
  letter-spacing: 0.3px;
}

/* ─── Forms ──────────────────────────────────────────────────────────────── */

.netra-form .form-label {
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--ink-soft);
  margin-bottom: 4px;
  text-transform: uppercase;
  letter-spacing: 0.6px;
}

.netra-form .form-control,
.netra-form .form-select {
  font-size: 0.85rem;
  border-radius: 2px;
  border: 1px solid #D8D1C2;
}

.netra-form .form-control:focus,
.netra-form .form-select:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 0.18rem rgba(168,137,95,0.18);
}

/* ─── Buttons ────────────────────────────────────────────────────────────── */

.btn-netra {
  background: var(--ink);
  color: #fff;
  font-weight: 500;
  font-size: 0.8rem;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  border: none;
  padding: 9px 22px;
  border-radius: 2px;
  transition: background 0.15s;
}

.btn-netra:hover { background: var(--accent); color: #fff; }

/* ─── Hero (landing banner — reserves space for a video/banner) ──────────── */

.netra-hero {
  position: relative;
  margin: -30px -36px 30px;     /* full-bleed within .netra-main padding */
  min-height: 56vh;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  background:
    radial-gradient(120% 120% at 50% 0%, rgba(168,137,95,0.18) 0%, transparent 55%),
    linear-gradient(180deg, #1B1813 0%, #16130E 60%, #110E0A 100%);
  color: #fff;
  overflow: hidden;
}

/* The video/banner goes here later — an empty stage now, behind the text. */
.netra-hero .hero-media {
  position: absolute;
  inset: 0;
  z-index: 0;
  background: transparent;   /* drop a <video> or <img> here later */
}
.netra-hero .hero-media video,
.netra-hero .hero-media img { width: 100%; height: 100%; object-fit: cover; opacity: 0.55; }

.netra-hero .hero-text { position: relative; z-index: 1; padding: 40px 20px; }

.netra-hero .hero-lead {
  font-family: var(--serif);
  font-size: clamp(4rem, 12vw, 9rem);
  font-weight: 600;
  letter-spacing: 8px;
  line-height: 0.95;
  margin: 0;
  color: #fff;
  text-shadow: 0 2px 30px rgba(0,0,0,0.35);
}

.netra-hero .hero-netra {
  font-family: var(--serif);
  font-size: clamp(1.6rem, 4vw, 3rem);
  font-weight: 500;
  letter-spacing: 14px;
  text-transform: lowercase;
  color: var(--accent-hover);
  margin: 10px 0 0;
}

.netra-hero .hero-tag {
  font-size: clamp(0.7rem, 1.6vw, 0.95rem);
  letter-spacing: 6px;
  text-transform: uppercase;
  color: rgba(237,231,218,0.8);
  margin-top: 18px;
}

.netra-hero .hero-rule {
  width: 60px; height: 1px; background: var(--accent);
  margin: 22px auto 0;
}

/* ─── Departments grid (Kering "houses" style) ───────────────────────────── */

.dept-section-title {
  font-family: var(--serif);
  font-size: 1.4rem;
  font-weight: 600;
  letter-spacing: 1px;
  color: var(--ink);
  margin: 6px 0 4px;
}
.dept-section-sub {
  font-size: 0.74rem; text-transform: uppercase; letter-spacing: 2px;
  color: var(--ink-soft); margin-bottom: 20px;
}

.dept-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 1px;
  background: var(--border);             /* hairline gutters between tiles */
  border: 1px solid var(--border);
  border-radius: 2px;
  overflow: hidden;
}

.dept-tile {
  background: var(--card);
  padding: 30px 24px 26px;
  text-decoration: none;
  color: var(--ink);
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 150px;
  transition: background 0.25s, color 0.25s;
  position: relative;
}

.dept-tile .dept-icon { font-size: 1.4rem; color: var(--accent); transition: color 0.25s; }
.dept-tile .dept-name {
  font-family: var(--serif);
  font-size: 1.5rem;
  font-weight: 600;
  letter-spacing: 0.5px;
  margin-top: auto;
}
.dept-tile .dept-desc { font-size: 0.74rem; color: var(--ink-soft); letter-spacing: 0.3px; transition: color 0.25s; }

.dept-tile:hover { background: var(--ink); color: #fff; }
.dept-tile:hover .dept-icon { color: var(--accent-hover); }
.dept-tile:hover .dept-desc { color: rgba(255,255,255,0.7); }

/* ─── Login page ─────────────────────────────────────────────────────────── */

.login-wrapper {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background:
    radial-gradient(120% 100% at 50% 0%, rgba(168,137,95,0.15) 0%, transparent 55%),
    linear-gradient(180deg, #1B1813 0%, #110E0A 100%);
}

.login-box {
  background: var(--surface);
  border: 1px solid rgba(168,137,95,0.3);
  border-radius: 3px;
  padding: 44px 40px;
  width: 370px;
}

.login-box .login-brand { text-align: center; margin-bottom: 30px; }

.login-box .login-brand .brand {
  font-family: var(--serif);
  font-size: 2.6rem;
  font-weight: 600;
  letter-spacing: 8px;
  color: #fff;
  line-height: 1;
}

.login-box .login-brand small {
  display: block;
  font-size: 0.66rem;
  color: var(--accent);
  letter-spacing: 3px;
  text-transform: uppercase;
  margin-top: 8px;
}

.login-box .form-label { color: var(--text-muted); font-size: 0.78rem; letter-spacing: 0.5px; }

.login-box .form-control {
  background: #15110B;
  border: 1px solid rgba(168,137,95,0.28);
  color: var(--text-main);
  font-size: 0.9rem;
  border-radius: 2px;
}

.login-box .form-control:focus {
  background: #15110B;
  border-color: var(--accent);
  color: var(--text-main);
  box-shadow: 0 0 0 0.18rem rgba(168,137,95,0.22);
}

.login-box .btn-login {
  width: 100%;
  background: var(--accent);
  color: #15110B;
  font-weight: 600;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  border: none;
  padding: 11px;
  border-radius: 2px;
  font-size: 0.82rem;
  margin-top: 10px;
  transition: background 0.15s;
}

.login-box .btn-login:hover { background: var(--accent-hover); }

.login-box .text-danger { color: #d98a84 !important; font-size: 0.82rem; }

/* ─── Decorations ────────────────────────────────────────────────────────── */

.diamond-icon {
  display: inline-block;
  width: 7px; height: 7px;
  background: var(--accent);
  transform: rotate(45deg);
  margin-right: 9px;
  vertical-align: middle;
}

.rough-code {
  font-family: 'SFMono-Regular', 'Courier New', monospace;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--ink);
  background: #F1EDE3;
  padding: 1px 6px;
  border-radius: 2px;
}

.kapan-code { font-family: 'SFMono-Regular', 'Courier New', monospace; font-size: 0.78rem; color: var(--ink-soft); }

/* ─── Amount display ─────────────────────────────────────────────────────── */

.amt-usd { color: #3F6B4E; font-weight: 600; }   /* USD — Western grouping (1,000,000) */
.amt-inr { color: #8A6A1E; }                       /* INR — Indian grouping (1,00,000) */
.amt-cts { color: #2C4866; font-weight: 600; }

/* ─── Print / PDF — financial statements (management "Download PDF") ──────── */
/* A print-only letterhead; hidden on screen, shown only when printing / saving to PDF. */
.print-letterhead { display: none; }
@media print {
    @page { size: A4; margin: 14mm 12mm; }
    /* Strip the app chrome so the PDF is just the statement. */
    #sidebar, .sidebar-footer, .no-print, .page-header form, .page-header a.btn { display: none !important; }
    .netra-main { margin: 0 !important; padding: 0 !important; width: 100% !important; max-width: 100% !important; }
    body { background: #fff !important; -webkit-print-color-adjust: exact !important; print-color-adjust: exact !important; }
    .page-header { border: none !important; margin: 0 0 6px !important; }
    .page-header h1, .page-header .page-meta { display: none !important; }   /* the letterhead replaces these */
    .print-letterhead { display: block !important; text-align: center; margin: 0 0 12px; padding-bottom: 8px; border-bottom: 2px solid #1f2a44; }
    .print-letterhead .co  { font-family: Georgia, 'Times New Roman', serif; letter-spacing: .22em; font-size: 22px; font-weight: 600; color: #1f2a44; }
    .print-letterhead .doc { font-size: 14px; font-weight: 600; margin-top: 4px; }
    .print-letterhead .meta{ font-size: 10.5px; color: #555; margin-top: 3px; }
    .netra-table-wrap { box-shadow: none !important; border: 1px solid #bbb; margin-bottom: 10px !important; }
    table { font-size: 10.5px !important; }
    thead { display: table-header-group; }         /* repeat column headers on each printed page */
    tr, .netra-card { page-break-inside: avoid; }
    .amt-usd, .amt-inr, .amt-cts { color: #000 !important; }   /* crisp black money on paper */
    a[href]::after { content: ""; }                /* don't append raw URLs */
}


/* ── Percentage-first assortment rollup (_ShapeRoll) ─────────────────────────────
   The owner's rule: parcels of different roughs compare only on SHARES. So the share
   bar leads every row, value is normalized ($/ct + value share), and absolute carats /
   est-$ are muted context. Same visual language as the parcel-compare butterfly. */
.sr-tbl { font-size: .7rem; }
.sr-tbl th { background: #f4f7fc; color: #56637a; font-weight: 600; font-size: .62rem;
             letter-spacing: .04em; text-transform: uppercase; padding: .18rem .4rem; white-space: nowrap; border-bottom: 1px solid #dce3ee; }
.sr-tbl td { padding: .12rem .4rem; line-height: 1.35; vertical-align: middle; font-variant-numeric: tabular-nums; }
.sr-tbl tbody tr:hover td { background: #fafcff; }
.sr-tbl .sr-lbl { font-weight: 600; color: #1f2a44; white-space: nowrap; }
.sr-tbl .sr-ctx { color: #97a0b0; }                       /* absolutes = context, never the comparison */
.sr-tbl .sr-rate { color: #1f2a44; }
.sr-tbl .sr-real { color: #1e7f3c; font-weight: 600; }
.sr-share { display: flex; align-items: center; gap: .35rem; justify-content: flex-end; }
.sr-bar { position: relative; height: 13px; flex: 1; min-width: 34px; background: #f1f4f9; border-radius: 3px; overflow: hidden; }
.sr-fill { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 3px;
           background: linear-gradient(90deg, #7fb3ec, #2a78d6); }
.sr-pct { min-width: 42px; text-align: right; font-weight: 700; color: #1f2a44; }
.sr-tot td { font-weight: 700; background: #f4f7fc !important; border-top: 1.5px solid #1f3a6e; }

/* ── The assortment GRID (_AssortmentPivot) and the AG–AM summary card ───────────────
   One layout, mounted by every screen that shows an assortment: the Assortment Matrix,
   Final Stock, Polish History and the A1 sample report. It lived inside the matrix page
   until 2026-09-18, so the other three drew the identical markup unstyled and "the same
   grid" read as a different report on each of them. Size blocks flow side by side; each
   table shrinks to its own content. */
.mx-blocks { display: flex; flex-wrap: wrap; gap: .45rem .7rem; align-items: flex-start; }
.mx-block { margin-bottom: 0; }
.mx-size { font-weight: 700; color: #1f3a6e; background: #eef3fb; padding: .1rem .45rem; font-size: .66rem; border: 1px solid #cdd9ef; border-bottom: none; border-radius: 4px 4px 0 0; white-space: nowrap; }
.mx-grid { font-size: .6rem; width: auto; }
.mx-grid th { background: #1f3a6e; color: #fff; font-weight: 600; white-space: nowrap; }
.mx-grid td, .mx-grid th { padding: .02rem .28rem; line-height: 1.15; }
.mx-cl { font-weight: 600; background: #f7f9fc; white-space: nowrap; }
.mx-rowtot { font-weight: 700; background: #f7f9fc; }
.mx-zero { color: #c7ccd4; }
.mx-band { background: #16306b !important; border-left: 2px solid #fff; }
.mx-faint { color: #cfd6e0; background: #fbfcfe; }
.mx-tot td { font-weight: 700; background: #fff7e6; border-top: 2px solid #1f3a6e; }
.mx-gtot td { font-weight: 700; color: #1f3a6e; background: #eef3fb; }
.matrix-head { background: #fffdf3; border: 1px solid #1f3a6e; border-radius: 6px; padding: .6rem .9rem; }
.matrix-head .mh-code { font-size: 1.15rem; font-weight: 700; color: #1f3a6e; letter-spacing: .5px; }
.matrix-head .mh-pill { display: inline-block; margin-right: 1.1rem; }
.matrix-head .mh-pill b { color: #1f3a6e; }
/* AG–AM summary cards (shown first on the matrix, and on the sample report). */
.sm-card { border: 1px solid #cdd9ef; border-radius: 6px; overflow: hidden; height: 100%; }
.sm-title { font-weight: 700; font-size: .72rem; color: #fff; background: #1f3a6e; padding: .15rem .55rem; letter-spacing: .3px; }
.sm-grid { font-size: .66rem; }
.sm-grid th { background: #eef3fb; color: #1f3a6e; font-weight: 600; padding: .1rem .3rem; white-space: nowrap; }
.sm-grid td { padding: .04rem .3rem; line-height: 1.2; }
.sm-grid .sm-lbl { font-weight: 600; white-space: nowrap; }
.sm-grid .sm-tot td { font-weight: 700; background: #fff7e6; border-top: 1.5px solid #1f3a6e; }
@media print {
    .mx-block, .mx-grid, .sm-card, .matrix-head { page-break-inside: avoid; }
    .mx-grid { font-size: .58rem !important; }
}

/* ── Profitability · indicative per-size purchase price (reporting only) ─────────────────────────
   A supplier prices several sizes as one parcel; this block shows what each size was really worth,
   solved from the outcome. Ochre because it is an ANALYTICAL overlay, never a booked number. */
.fr-card { border-left: 4px solid #8a5a00; }
.fr-tbl  { font-size: .78rem; }
.fr-tbl th { background: #fbf3e4; color: #7a5000; font-weight: 600; font-size: .62rem; letter-spacing: .04em;
             text-transform: uppercase; padding: .3rem .45rem; white-space: nowrap; }
.fr-tbl td { padding: .25rem .45rem; font-variant-numeric: tabular-nums; }
.fr-band { font-family: ui-monospace, Menlo, monospace; font-size: .7rem; background: #eef3fb; color: #1f3a6e;
           padding: .05em .4em; font-weight: 700; }
.fr-code { font-family: ui-monospace, Menlo, monospace; font-size: .74rem; font-weight: 600; }
.fr-new  { font-weight: 700; color: #1f2a44; }
.fr-up   { color: #1a6144; font-weight: 700; }
.fr-dn   { color: #a8201a; font-weight: 700; }
.fr-ctx  { color: #97a0b0; }
.fr-sum  { background: #fbf7ef; font-weight: 600; border-top: 1px dashed #d6bb84; }
.fr-wait > td { background: #f7f8fa; color: #6b7688; }
.fr-conf { color: #a8201a; font-size: .62rem; font-weight: 700; cursor: help; margin-left: .3rem; }
.fr-res  { color: #8a5a00; font-size: .62rem; font-weight: 700; cursor: help; margin-left: .25rem; }
/* The booked rate is kept as its own solid column — it is the purchase and it never changes. */
.fr-book { color: #1f2a44; font-weight: 600; background: #f4f6fa; }
.fr-tbl th.fr-book { background: #eef1f7; color: #46506a; }
.fr-sub  { font-weight: 400; text-transform: none; letter-spacing: 0; opacity: .75; }

/* ══ Rough book · Profitability ═══════════════════════════════════════════════════════════════════
   The old flat list made the owner hunt for a lot. This is a FINDER: folded type → size band, with
   filter chips, a search box, and a visible badge wherever lots were bought clubbed under one rate. */
.rb-bar { display: flex; flex-wrap: wrap; gap: .6rem; align-items: center; justify-content: space-between; }
.rb-tools { display: flex; gap: .4rem; align-items: center; }
.rb-find { width: 17rem; max-width: 46vw; }

.rb-filters { display: flex; flex-wrap: wrap; gap: .3rem; align-items: center;
              padding: .5rem .9rem; border-bottom: 1px solid var(--border, #e2e6ee); background: #fafbfd; }
.rb-flabel { font-size: .64rem; letter-spacing: .08em; text-transform: uppercase; color: #8a93a4;
             font-weight: 700; margin-right: .15rem; }
.rb-sep { width: 1px; height: 1.1rem; background: #d8dde7; margin: 0 .45rem; }
.rb-chip { border: 1px solid #d3dae6; background: #fff; color: #46506a; font-size: .73rem; font-weight: 600;
           padding: .16rem .6rem; border-radius: 999px; cursor: pointer; line-height: 1.5; }
.rb-chip:hover { border-color: #9db1d4; }
.rb-chip.on { background: #1f3a6e; border-color: #1f3a6e; color: #fff; }
.rb-chip.rb-club.on { background: #8a5a00; border-color: #8a5a00; }

.rb-type { border-top: 2px solid #1f3a6e; }
.rb-thead { display: flex; flex-wrap: wrap; gap: .5rem; align-items: baseline; cursor: pointer;
            padding: .45rem .9rem; background: #eef3fb; }
.rb-thead:hover { background: #e5edf9; }
.rb-caret { color: #6c7a94; width: .8rem; display: inline-block; transition: transform .12s; }
.rb-thead.shut .rb-caret { transform: rotate(-90deg); }
.rb-tname { font-weight: 700; color: #1f2a44; letter-spacing: -.01em; }
.rb-tmeta { font-size: .72rem; color: #6c7a94; font-variant-numeric: tabular-nums; }

.rb-band.folded { display: none; }
.rb-code { font-family: ui-monospace, Menlo, monospace; font-size: .76rem; font-weight: 700; color: #1f2a44; }
.rb-wait { color: #8a5a00; font-size: .68rem; font-weight: 700; cursor: help; }
.rb-conf { color: #a8201a; font-size: .62rem; font-weight: 700; cursor: help; margin-left: .3rem; }

/* clubbed purchases get a stable colour so a bought-together set is spottable at a glance */
.rb-clip { font-size: .61rem; font-weight: 700; padding: .08em .42em; border-radius: 3px;
           margin-left: .35rem; cursor: help; white-space: nowrap; }
.rb-clip.c0 { background: #e6eefb; color: #1f3a6e; }
.rb-clip.c1 { background: #fbf0e2; color: #8a5a00; }
.rb-clip.c2 { background: #e7f3ec; color: #1a6144; }
.rb-clip.c3 { background: #f5e9f3; color: #6d2461; }
.rb-clip.c4 { background: #fdeceb; color: #a8201a; }
.rb-clip.c5 { background: #eaeaf6; color: #3b3a7a; }

.rb-empty { padding: 1.6rem; text-align: center; color: #8a93a4; font-size: .85rem; }

/* Rough book · second view — a whole PURCHASE as one block, so a clubbed set is not scattered
   across three size bands just because it contained three sizes. */
.rb-seg { display: inline-flex; border: 1px solid #d3dae6; border-radius: 999px; overflow: hidden; }
.rb-seg button { border: 0; background: #fff; color: #46506a; font-size: .73rem; font-weight: 600;
                 padding: .18rem .8rem; cursor: pointer; line-height: 1.5; }
.rb-seg button + button { border-left: 1px solid #e4e9f1; }
.rb-seg button.on { background: #1f3a6e; color: #fff; }
.rb-buy { border-top: 2px solid #d3dae6; }
.rb-buy.clubbed { border-top-width: 3px; }
.rb-buy.clubbed.c0 { border-top-color: #1f3a6e; }
.rb-buy.clubbed.c1 { border-top-color: #8a5a00; }
.rb-buy.clubbed.c2 { border-top-color: #1a6144; }
.rb-buy.clubbed.c3 { border-top-color: #6d2461; }
.rb-buy.clubbed.c4 { border-top-color: #a8201a; }
.rb-buy.clubbed.c5 { border-top-color: #3b3a7a; }
.rb-buy.kflow { padding-top: .55rem; }
.rb-fold.folded { display: none; }

/* Rough book · the reconciliation strip. The book is keyed on rough purchases, so revenue sold under any
   other kind of code falls outside it. Showing a total without showing the residue would repeat the very
   fault this page exists to fix, so every posted dollar is named here. */
.rb-recon { border-top: 2px solid #1f2a44; background: #fafbfd; padding: .7rem .9rem .8rem; }
.rb-rtitle { font-size: .64rem; letter-spacing: .09em; text-transform: uppercase; color: #6c7a94;
             font-weight: 700; margin-bottom: .35rem; }
.rb-rtbl { width: 100%; font-size: .79rem; border-collapse: collapse; }
.rb-rtbl td { padding: .22rem .3rem; vertical-align: baseline; }
.rb-rtbl td.n { text-align: right; font-family: ui-monospace, Menlo, monospace; font-weight: 600;
                font-variant-numeric: tabular-nums; white-space: nowrap; width: 8rem; }
.rb-rtbl td.w { color: #97a0b0; font-size: .72rem; white-space: nowrap; width: 7rem; text-align: right; }
.rb-rtbl tr.hot td { color: #8a5a00; }
.rb-rtbl tr.bad td { color: #a8201a; font-weight: 600; }
.rb-rtbl tr.tot td { border-top: 1px solid #cdd5e2; font-weight: 700; color: #1f2a44; padding-top: .32rem; }

/* Combined tallies · two roughs mixed and sold as one, split back to source.
   Slate rather than the ochre of the reprice panel: this is not an estimate, it is recorded fact being
   re-read — only the blended revenue is allocated, and by physical evidence rather than a ratio. */
.ct-note { padding: .55rem .9rem; font-size: .8rem; color: #56637a; background: #f7f9fc;
           border-bottom: 1px solid #e4e9f1; }
.ct-block { border-top: 2px solid #2f4858; }
.ct-head { display: flex; flex-wrap: wrap; gap: .6rem; align-items: baseline; padding: .45rem .9rem;
           background: #eef2f5; }
.ct-code { font-family: ui-monospace, Menlo, monospace; font-size: .8rem; font-weight: 700; color: #22333f;
           overflow-wrap: anywhere; }
.ct-meta { font-size: .73rem; color: #667788; font-variant-numeric: tabular-nums; }
.ct-ok { margin-left: auto; font-size: .7rem; font-weight: 700; color: #1a6144; }
.ct-ok.bad { color: #a8201a; }
.ct-basis { padding: .25rem .9rem .3rem; font-size: .73rem; color: #7a8896; font-style: italic; }
.ct-tbl { font-size: .78rem; }
.ct-tbl th { background: #fff; color: #7a8896; font-weight: 600; font-size: .6rem; letter-spacing: .04em;
             text-transform: uppercase; padding: .28rem .55rem; white-space: nowrap; border-bottom: 1px solid #eceff5; }
.ct-tbl td { padding: .28rem .55rem; font-variant-numeric: tabular-nums; }
.ct-src { font-family: ui-monospace, Menlo, monospace; font-size: .76rem; font-weight: 700; color: #22333f; }
.ct-kap { font-family: ui-monospace, Menlo, monospace; font-size: .71rem; color: #7a8896; }
.ct-ctx { color: #a2aab8; }
.ct-up  { color: #1a6144; font-weight: 700; }
.ct-dn  { color: #a8201a; font-weight: 700; }
.ct-pro { color: #8a5a00; font-size: .62rem; font-weight: 700; margin-left: .3rem; cursor: help; }
.ct-tot { background: #f4f7f9; font-weight: 700; border-top: 1px solid #d4dde3; }

/* ══ kflow · the rough → children tree ═════════════════════════════════════════════════════════════
   Owner's preferred shape, first built for Kapan WIP in the Inventory cockpit and now the house style
   for any one-to-many list: a boxed parent on the left, its children branching off a stem, a dashed
   subtotal closing each group. Lifted here from the Inventory page's inline <style> so every module
   draws the same tree and they cannot drift apart. */
.kflow { display:flex; align-items:center; margin:0 0 .65rem 0; }
.kflow .rbox { border:2px solid #1f2a44; border-radius:.6rem; background:#fff; padding:.45rem .7rem; min-width:185px; }
.kflow .rbox .r-code { font-weight:800; color:#1f2a44; font-size:.85rem; font-family:ui-monospace,Menlo,monospace; }
.kflow .rbox .r-cts  { font-size:.78rem; color:#5b6b87; }
.kflow .stem { width:22px; border-top:1.5px solid #b6c2d4; align-self:center; }
.kflow .branches { display:flex; flex-direction:column; justify-content:center; flex:1 1 auto; min-width:0; }
.kflow .branch { position:relative; padding:.14rem 0 .14rem 20px; font-size:.79rem; }
.kflow .branch::before { content:''; position:absolute; left:0; top:0; bottom:0; border-left:1.5px solid #b6c2d4; }
.kflow .branch:first-child::before { top:50%; }
.kflow .branch:last-child::before  { bottom:50%; }
.kflow .branch:only-child::before  { top:50%; bottom:50%; }
.kflow .branch::after  { content:''; position:absolute; left:0; top:50%; width:14px; border-top:1.5px solid #b6c2d4; }
.kflow .branch .k-code { font-family:ui-monospace,Menlo,monospace; color:#1f2a44; }
.kflow .branch .k-cts  { font-weight:600; }
.kflow .subtotal { padding:.18rem 0 0 20px; font-size:.78rem; font-weight:700; color:#1f2a44;
                   border-top:1px dashed #d7dee9; margin-top:.15rem; }

/* ── extensions for money-bearing trees (Profitability, assortment) ──
   The parent box is a FIXED width and the numeric cells are fixed widths too, so every branch in every
   group starts at the same x and the columns line up down the whole page — one header per section then
   labels them all. */
.kflow .rbox.fixed { flex:0 0 200px; width:200px; }
.kflow .rbox.flat  { border-color:#8a5a00; background:#fdf9f1; }   /* one flat rate over several sizes */
.kflow .rbox .r-tag { display:inline-block; font-size:.63rem; font-weight:800; letter-spacing:.04em;
                      color:#8a5a00; background:#f6e7c8; border-radius:3px; padding:.02em .3em; margin-top:.15rem; }
.kflow .rbox .r-note { font-size:.7rem; color:#8a5a00; }
.kflow-hdr { padding:.1rem 0 .2rem calc(200px + 22px + 20px); font-size:.66rem; font-weight:700;
             letter-spacing:.04em; text-transform:uppercase; color:#939db0; }
.kflow .branch.wide, .kflow-hdr .wide { display:flex; align-items:baseline; gap:.4rem; }
.kflow-hdr .wide { display:flex; align-items:baseline; gap:.4rem; }
/* the merged flow-as-table (Polish History pipeline): the lot's numbers ride the closing subtotal line,
   and a full-width grand-total row aligns with them because every numeric cell is fixed-width from the right */
.kflow .subtotal.wide { display:flex; align-items:baseline; gap:.4rem; }
.kflow-subrow { display:flex; align-items:baseline; gap:.4rem; font-size:.78rem; font-weight:700; color:#1f2a44; }
.kb-lbl  { flex:1 1 auto; min-width:8rem; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* The wrappers SCROLL rather than clip. .netra-table-wrap hides its overflow, which once cut the last
   money column clean off the page with no scrollbar to hint it was there — a number you cannot see is
   worse than one you have to scroll to. */
/* The book scrolls INSIDE a viewport-height box, so both its scrollbars are always on screen. The previous
   arrangement — a page-tall scroll container — put the horizontal bar at the foot of a four-thousand-pixel
   table, which is to say nowhere. The column header sticks to the top of the box while you scroll. */
.rb { max-height: 78vh; overflow: auto; }
.rsel { overflow-x: auto; }
.rb .kflow-hdr { position: sticky; top: 0; z-index: 4; background: #fff;
                 border-bottom: 1px solid #e7ecf4; padding-top: .35rem; }
.rb .rb-thead { position: sticky; top: 0; z-index: 5; background: #f5f8fc; }
.kb-num  { flex:0 0 auto; font-family:ui-monospace,Menlo,monospace; font-variant-numeric:tabular-nums;
           text-align:right; white-space:nowrap; }
.kw-cts  { width:4.8rem; } .kw-rate { width:5rem; } .kw-d { width:3.4rem; }
.kw-sale { width:5.8rem; } .kw-mar  { width:3.8rem; }
/* the assortment trees (pickers + progress) */
.kw-w { width:5.6rem; } .kw-dl { width:4.4rem; } .kw-st { width:4rem; text-align:right; }
.kflow .sub { padding-left:22px; }                       /* a mix's member kapans, one level in */
.rsel .kflow { margin-bottom:.5rem; }
.rsel-grp + .rsel-grp, .ap-grp + .ap-grp { border-top:1px solid #eef1f6; padding-top:.5rem; }
.rsel-all { font-size:.68rem; color:#5b6b87; cursor:pointer; user-select:none; margin-top:.2rem; }
.rsel-all input { vertical-align:-1px; margin-right:.2rem; }
.kflow .b-book { color:#5b6b87; }
.kflow .b-ind  { font-weight:800; color:#1f2a44; }
.b-up   { color:#1a6144; font-weight:700; }
.b-dn   { color:#a8201a; font-weight:700; }
.b-mute { color:#a2aab8; }
.k-size { font-family:ui-monospace,Menlo,monospace; font-size:.66rem; background:#1f3a6e; color:#fff;
          padding:.04em .38em; border-radius:3px; vertical-align:.05em; }
.kflow .subtotal .money { font-weight:600; }
@media (max-width:900px) {
  .kflow { flex-direction:column; align-items:stretch; }
  .kflow .stem { display:none; }
  .kflow .rbox.fixed { flex:1 1 auto; width:auto; }
  .kflow-hdr { display:none; }
  .kw-sale, .kw-mar, .kw-d, .kw-dl { display:none; }
}

/* ── Origin evidence · the KP-or-domestic choice on a purchase line ─────────────────────────────── */
.kp-basis { display:flex; flex-wrap:wrap; gap:1.1rem; align-items:center; padding:.45rem .7rem;
            background:#f7f9fc; border:1px solid #e3e9f2; border-radius:.4rem; }
.kp-basis .kp-lab { font-size:.72rem; font-weight:700; text-transform:uppercase; letter-spacing:.04em;
                    color:#6c7a94; }
.kp-basis label { font-size:.82rem; color:#1f2a44; cursor:pointer; margin:0; }
.kp-basis input { margin-right:.3rem; vertical-align:-1px; }

/* Rough book · the hand-entered market rate, distinct from the derived one beside it */
.kflow .b-mkt { font-weight:800; color:#6d2461; }

/* Market price entry — the buyer's own split of a flat-rate purchase */
.mkt-tbl { font-size:.82rem; }
.mkt-tbl td, .mkt-tbl th { padding:.3rem .5rem; vertical-align:middle; }
.mkt-tbl .mkt-rate { font-family:ui-monospace,Menlo,monospace; }
.mkt-take { border:0; background:#f4f1f7; color:#6d2461; font-family:ui-monospace,Menlo,monospace;
            font-size:.78rem; padding:.1rem .4rem; border-radius:3px; cursor:pointer; }
.mkt-take:hover { background:#e9e0f0; }
.mkt-foot td { border-top:2px solid #1f2a44; font-weight:700; font-family:ui-monospace,Menlo,monospace; }
.mkt-ok  { color:#1a6144; font-weight:700; }
.mkt-bad { color:#a8201a; font-weight:700; }
.mkt-btn { display:inline-block; font-size:.66rem; font-weight:700; padding:.12em .5em; border-radius:3px;
           background:#f4f1f7; color:#6d2461; text-decoration:none; border:1px solid #e2d6ea; }
.mkt-btn:hover { background:#e9e0f0; color:#6d2461; }
.mkt-btn.on { background:#6d2461; color:#fff; border-color:#6d2461; }

/* Profitability · the book leads, the working folds away beneath it */
.prof-detail { border-top:2px solid #e7ecf4; padding-top:.8rem; }
.pf-lead { font-size:.76rem; color:#8a93a4; margin-bottom:.5rem; }
.prof-fold { border:1px solid #e3e9f2; border-radius:.4rem; margin-bottom:.5rem; background:#fbfcfe; }
.prof-fold > summary { cursor:pointer; padding:.5rem .8rem; list-style:none; display:flex; flex-wrap:wrap;
                       gap:.6rem; align-items:baseline; }
.prof-fold > summary::-webkit-details-marker { display:none; }
.prof-fold > summary::before { content:'▸'; color:#6c7a94; font-size:.8rem; }
.prof-fold[open] > summary::before { content:'▾'; }
.prof-fold .pf-t { font-weight:700; font-size:.84rem; color:#1f2a44; }
.prof-fold .pf-h { font-size:.72rem; color:#8a93a4; }
.prof-fold .pf-body { padding:0 .5rem .5rem; }
.prof-fold[open] > summary { border-bottom:1px solid #e7ecf4; background:#f5f8fc; }

/* the market rate cell doubles as the way in */
.mkt-cell { color:#6d2461; font-weight:800; text-decoration:none; border-bottom:1px dashed #c9a8d4; }
.mkt-cell:hover { color:#6d2461; background:#f4f1f7; }

/* Rough book · the value of everything the rough recovered, and the part of it no rate can price */
.kflow .b-val { font-weight:700; color:#1f2a44; }
.rb-unpriced { font-size:.62rem; font-weight:700; color:#8a5a00; white-space:nowrap; }
.rb-note { padding:.5rem .9rem; background:#f7f9fc; border-bottom:1px solid #e8edf5; font-size:.74rem;
           line-height:1.5; color:#46506a; }
.rb-load { font-size:.61rem; font-weight:600; color:#8a5a00; white-space:nowrap; }
.kflow .b-net { font-weight:800; color:#1a6144; }
.rb-exp { display:inline-flex; align-items:center; gap:.3rem; font-size:.72rem; color:#46506a; }
.rb-exp input { width:4.5rem; font-size:.75rem; padding:.1rem .3rem; border:1px solid #d3dae6; border-radius:3px;
                text-align:right; font-family:ui-monospace,Menlo,monospace; }

/* "Why this figure" — the derivation as a hover card, deliberately NOT embedded in the row */
.rb-why { cursor: help; border-bottom: 1px dotted #9aa5b8; }
.why-card { position:absolute; z-index:1080; min-width:19rem; max-width:24rem; background:#fff;
            border:1px solid #cdd6e4; border-radius:.45rem; box-shadow:0 8px 26px rgba(20,30,50,.16);
            padding:.55rem .7rem; font-size:.74rem; color:#1f2a44; }
.why-card .wh { font-family:ui-monospace,Menlo,monospace; font-weight:800; font-size:.72rem; color:#1f2a44;
                border-bottom:1px solid #e7ecf4; padding-bottom:.3rem; margin-bottom:.35rem; }
.why-card .wr { display:flex; gap:.5rem; align-items:baseline; padding:.12rem 0; }
.why-card .wl { flex:0 0 7.2rem; color:#46506a; font-weight:600; }
.why-card .wd { flex:1 1 auto; color:#8a93a4; font-size:.68rem; }
.why-card .wv { font-family:ui-monospace,Menlo,monospace; font-variant-numeric:tabular-nums; font-weight:700; }
.why-card .muted .wv, .why-card .muted .wl { color:#a2aab8; font-weight:600; }
.why-card .tot { border-top:1px dashed #d7dee9; margin-top:.2rem; padding-top:.25rem; }
.why-card .tot .wv { color:#1f3a6e; }
/* An estimate is never allowed to look like a settled figure */
.kflow .b-est { color:#8a5a00; font-weight:800; font-style:italic; }
.rb-estlbl { font-size:.6rem; font-weight:700; color:#8a5a00; letter-spacing:.03em; }
.r-stage { font-size:.66rem; line-height:1.4; color:#8a5a00; margin-top:.15rem; }
.r-stage.ok { color:#1a6144; font-weight:600; }
.r-stage .rs-code { font-family:ui-monospace,Menlo,monospace; font-weight:700; }

/* The group box stays put while the numbers scroll. Making the wrapper scroll horizontally (so the last
   money column could never be silently clipped) had a cost: scroll right and the box naming the group
   slid off the left edge, so you lost track of which size or purchase you were reading. It sticks now. */
.rb, .rsel { position: relative; }
.rb .kflow > .rbox, .rsel .kflow > .rbox {
  position: sticky; left: 0; z-index: 3;
  box-shadow: 6px 0 8px -6px rgba(20,30,50,.13);
}
.rb .kflow > .stem, .rsel .kflow > .stem { position: sticky; left: 200px; z-index: 2; background: #fff; }

/* The cost side of the rough book: six SHORT columns — rate · exp · net after exp · profit/ct · profit $ ·
   margin — each holding the three rates as lines (b booked · i indicative · m market), so a plain lot is one
   line tall and a clubbed one three. This replaced a five-line stack per rate (owner, 2026-10-10: "the column
   is getting too long"), which had itself replaced six wide columns. The expense is shown on its own and
   taken off the polish side, never loaded onto the rate: the cost is what was paid. Widths are set per column
   to the longest string it can carry in monospace — measured by rendering, not estimated — and the label
   column, the flexible one, absorbs the total. */
.kw-rc { display: inline-flex; flex-direction: column; align-items: flex-end; line-height: 1.3; font-size: .72rem; }
.kw-rc .rl { white-space: nowrap; }
.kw-rc .rt { font-style: normal; font-size: .52rem; font-weight: 800; letter-spacing: .04em; opacity: .55;
             margin-right: .22rem; text-transform: uppercase; vertical-align: .08em; }
.rc-rate { width: 4.6rem; } .rc-exp { width: 3.6rem; } .rc-net { width: 4.2rem; }
.rc-pct { width: 4.2rem; } .rc-usd { width: 4.8rem; } .rc-m { width: 4.4rem; }
.kw-rc .st-e { color: #8a5a00; font-weight: 600; }
.kw-rc .rl.b-net { font-weight: 800; }
.kflow-hdr .kw-rc { line-height: 1.15; }
/* Header labels WRAP inside their own cell. Fixed-width cells with nowrap text meant a long label ran
   straight over its neighbour, which is what made the header unreadable. */
.kflow-hdr .kb-num, .kflow-hdr .kb-lbl { white-space: normal; line-height: 1.15; overflow: visible;
                                          word-break: break-word; }
.kflow-hdr .wide { align-items: flex-end; }

/* A reachable horizontal scrollbar for the rough book. The table's own scroller is thousands of pixels
   tall, so its bar lives at the bottom of the table, not the bottom of the screen — invisible precisely
   when the table is too wide. This proxy is pinned to the viewport and kept in step with it. */
.hscroll-proxy { display: none !important; }   /* superseded: the book's own bar is now on screen */
.hscroll-proxy .hscroll-inner { height: 1px; }
.hscroll-proxy::-webkit-scrollbar { height: 14px; }
.hscroll-proxy::-webkit-scrollbar-thumb { background: #9aa5b8; border-radius: 7px; }
.hscroll-proxy::-webkit-scrollbar-track { background: #eef1f6; }
.rb-inproc { color:#8a5a00; font-weight:600; }

/* The books' trading account, on the Profitability page so the report can be tied to the ledger by eye */
.books-strip { border:1px solid #e3e9f2; border-radius:.4rem; background:#fbfcfe; padding:.6rem .8rem; }
.books-strip .bs-head { font-weight:700; font-size:.86rem; color:#1f2a44; margin-bottom:.4rem; }
.books-strip .bs-sub { font-weight:400; font-size:.72rem; color:#8a93a4; margin-left:.4rem; }
.bs-tbl { width:100%; max-width:44rem; font-size:.78rem; border-collapse:collapse; }
.bs-tbl th { font-size:.66rem; text-transform:uppercase; letter-spacing:.04em; color:#8a93a4; font-weight:600;
             padding:.15rem .5rem; border-bottom:1px solid #e7ecf4; }
.bs-tbl td { padding:.13rem .5rem; font-variant-numeric:tabular-nums; }
.bs-tbl td:not(:first-child) { font-family:ui-monospace,Menlo,monospace; }
.bs-gp td, .bs-np td { border-top:1px solid #d7dee9; font-weight:700; color:#1f2a44; }
.bs-np td { border-top:2px solid #1f2a44; }
.bs-pct { font-family:inherit; font-size:.72rem; color:#1a6144; margin-left:.4rem; }
.bs-note { font-size:.7rem; color:#6c7a94; margin-top:.4rem; max-width:52rem; line-height:1.5; }

/* Gross and net yield — two narrow columns on every rough-book line, so the owner never has to ask lot by lot.
   Same width as the carat column; the estimate colour carries through from .b-est on the cell. */
.kflow-hdr .kw-yld, .branch .kw-yld { width: 62px; min-width: 62px; text-align: right; }
.rb-partial { font-size: .62rem; line-height: 1.1; color: #b58105; white-space: nowrap; }

/* Rough still outside the final tally, on the carat column of the rough book. Amber rather than red: the lot is
   not wrong, it is incomplete, and the figures to its right cover only the tallied part. The second line names
   WHERE the balance is — "not issued" and "awaiting tally" are the same carats and opposite problems. */
.rb-pend { font-size: .62rem; line-height: 1.1; color: #b58105; font-weight: 700; white-space: nowrap; }
.rb-pend-w { display: block; font-weight: 500; opacity: .8; }

/* The rough pipeline panel — shared by the three factory entry forms (Memo, Polish Receipt, Final Stock) so the
   same four stages are read the same way wherever a carat balance matters. Neutral by default; .fp-warn when
   something is outstanding, because incomplete is not an error and must not be dressed as one. */
.fp-pipe { margin-top: .4rem; border: 1px solid var(--bs-border-color, #dee2e6); border-radius: .4rem;
           padding: .4rem .55rem; font-size: .74rem; background: rgba(0,0,0,.015); }
.fp-pipe.fp-warn { border-color: #f0d9a0; background: #fffaf0; }
.fp-pipe .fp-h { font-weight: 600; margin-bottom: .25rem; line-height: 1.25; }
.fp-pipe.fp-warn .fp-h { color: #8a5a00; }
.fp-pipe .fp-row { display: flex; gap: .5rem; align-items: baseline; line-height: 1.5; }
.fp-pipe .fp-l { flex: 0 0 8.5rem; opacity: .75; }
.fp-pipe .fp-v { flex: 0 0 5rem; text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; }
.fp-pipe .fp-n { flex: 1 1 auto; font-size: .68rem; color: #b58105; }
.fp-pipe .fp-bad { color: #b02a37; font-weight: 700; }
@media (prefers-color-scheme: dark) {
  .fp-pipe { border-color: #3a3a3a; background: rgba(255,255,255,.03); }
  .fp-pipe.fp-warn { border-color: #6b5520; background: #2a2416; }
  .fp-pipe.fp-warn .fp-h { color: #f2d489; }
}

/* The same fact at the top of the page, before anyone starts comparing lots down a column. */
.rb-pendbar { border: 1px solid #f0d9a0; background: #fffaf0; border-radius: .4rem; padding: .5rem .7rem;
              font-size: .78rem; color: #6b4e00; margin-bottom: .75rem; }
.rb-pendbar b { color: #8a5a00; }
.rb-pendbar .rb-pl { display: inline-block; margin: .15rem .5rem .15rem 0; white-space: nowrap; }
@media (prefers-color-scheme: dark) {
  .rb-pendbar { border-color: #6b5520; background: #2a2416; color: #e8cf94; }
  .rb-pendbar b { color: #f2d489; }
}

/* A clubbed chip is a control: one flat rate covers several lots, so clicking it pins the group together. */
.rb-clip-go { cursor: pointer; user-select: none; }
.rb-clip-go:hover { filter: brightness(.94); }
.rb-clip-on { outline: 2px solid currentColor; outline-offset: 1px; }

/* ─── the clubbed chip ────────────────────────────────────────────────────────
   Rough bought together on one invoice at one rate. Shown wherever rough is listed, because a lot the supplier
   never priced on its own must not be read as though he had. Champagne = there is more than one size in the
   parcel, so restating it means something; grey = same size throughout, clubbed but nothing to reallocate. */
.club-chip {
  display: inline-block; text-decoration: none; white-space: nowrap;
  font-size: .68rem; font-weight: 600; letter-spacing: .3px;
  padding: .1rem .42rem; border-radius: 999px;
  background: #F0EADD; color: #7A5E32; border: 1px solid #DCCFB4;
}
.club-chip:hover { background: #E6DCC7; color: #5E4726; }
.club-chip-flat { background: #EFEDE8; color: #7C766B; border-color: var(--border); }
.club-chip-flat:hover { background: #E6E3DC; color: #5A554C; }
@media (prefers-color-scheme: dark) {
  .club-chip { background: #2C2519; color: #D8BE8C; border-color: #4A3D26; }
  .club-chip:hover { background: #3A3021; color: #EBD5A8; }
  .club-chip-flat { background: #262421; color: #A39C8F; border-color: #3A3733; }
}

/* ── Excel-like column sorting (netra-grid.js) ─────────────────────────────────────────────────────────
   Click a header to sort A→Z, again for Z→A, again for the page's own order. The caret is the only chrome;
   the Excel button downloads the rows in whatever order is showing. */
.ng-bar { display: flex; justify-content: flex-end; padding: .3rem .1rem .35rem; }
.ng-xl { border: 1px solid var(--border, #dee2e6); background: transparent; border-radius: .3rem;
         padding: .1rem .5rem; font-size: .72rem; line-height: 1.5; color: inherit; cursor: pointer; }
.ng-xl:hover { background: rgba(0,0,0,.05); }
.ng-xl:disabled { opacity: .5; cursor: progress; }

th.ng-th { cursor: pointer; user-select: none; white-space: nowrap; }
th.ng-th:hover { text-decoration: underline dotted; }
th.ng-th .ng-arrow { font-size: .6rem; margin-left: .25rem; opacity: .22; vertical-align: middle; }
th.ng-th .ng-arrow.on { opacity: 1; }

@media (prefers-color-scheme: dark) {
  .ng-xl:hover { background: rgba(255,255,255,.08); }
}
/* ══ Stone Accounting (from DIP) · DIP's OWN STYLESHEET, LIFTED ══════════════════════════════════
   The owner's ruling (9-Sep-26): "just copy paste the structure inside DIP ... and then map the
   data". What follows is a VERBATIM COPY of DIP's stylesheet, character for character, not a port
   and not a retune. NETRA supplies the numbers; DIP decides how the two screens look, so they
   cannot drift on appearance.

   Source: /Users/apple/Documents/DIP/frontend/src/index.css
     · lines 524-566  the flow map (.fm-*, .fr-*, .fk-*, .fl-*, .fo-*) — the range runs to 566,
                      not 560: the @media (max-width: 900px) that opens at 560 closes there.
     · lines 715-800  the road (.road*, .rn*, .rb-*) — the section comment through
                      ".rb-col.never .rb-name". DIP's drawer (802+) is not copied: NETRA has no
                      drawer, nothing on this road opens.
     · lines 88, 103-109, 391-394  the handful of DIP utilities its own markup for those two
                      views leans on (.panel, .badge and its tones, .small, .mono, .muted, .neg,
                      .pos). Without them the copied DOM has no card, no pill and no grey.

   TO UPDATE: re-lift those ranges. NEVER edit them here — an edit is a drift, and the drift is
   the thing this replaces. The copied lines are left unindented so a diff against DIP is exact.

   SCOPING: the copy is nested inside .dip-mirror, which carries DIP's variables (index.css lines
   1-17; every var(--x) inside the copied ranges is one of these twelve). Nothing reaches the rest
   of NETRA — .badge and .small alone would otherwise fight Bootstrap on every page. This needs a
   browser with CSS Nesting; the copied road already needs :has(), which is the same generation. */

.dip-mirror {
  --panel: #fffdf7;
  --panel2: #efe9d8;
  --text: #1f3324;
  --muted: #6b7a66;
  --line: #e2dcc8;
  --accent: #d97c14;
  --accent2: #e8931f;
  --blue: #1d5f95;
  --green: #2e6b3e;
  --amber: #c96a08;
  --red: #b3402a;
  --shadow: 0 14px 36px rgba(46, 38, 12, 0.10);
  color: var(--text);
}

/* The one line of the copy that cannot live inside .dip-mirror: a @keyframes nested in a style
   rule is dropped by every browser. Hoisted verbatim from index.css line 541; the nested original
   is left in place below, untouched, so the copied range stays byte-for-byte DIP's. */
@keyframes fm-found { 50% { box-shadow: 0 0 0 7px color-mix(in srgb, var(--accent) 18%, transparent); } }

.dip-mirror {

/* ── BEGIN VERBATIM COPY · DIP frontend/src/index.css 524-566 ─────────────────────────────────── */
/* --- Trace: the FLOW MAP (RO -> kapans tree, owner ask 15-Aug-26) ------- */
.fm-card { padding: 12px 14px; }
.fm-grid { display: flex; gap: 0; align-items: stretch; }
.fm-ro { flex: 0 0 190px; align-self: flex-start; position: sticky; top: 70px; display: flex; flex-direction: column; gap: 3px; border: 1.5px solid var(--accent); border-radius: 14px; padding: 10px 12px; background: color-mix(in srgb, var(--accent) 8%, var(--panel)); cursor: pointer; }
.fm-ro:hover { box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent); }
.fm-ro > b { font-size: 13px; }
.fm-ro .fr-line { font-size: 11px; color: var(--text); }
.fm-ro .fr-line.small { color: var(--muted); }
/* the trunk out of the RO node */
.fm-tree { flex: 1; margin-left: 34px; padding-left: 26px; border-left: 2px solid color-mix(in srgb, var(--muted) 45%, transparent); display: flex; flex-direction: column; gap: 6px; padding-top: 4px; padding-bottom: 4px; min-width: 0; }
.fm-branch { position: relative; }
/* the elbow from the trunk into each kapan */
.fm-branch::before { content: ''; position: absolute; left: -26px; top: 50%; width: 22px; border-top: 2px solid color-mix(in srgb, var(--muted) 45%, transparent); }
.fm-kapan { display: inline-flex; gap: 10px; align-items: baseline; border: 1px solid var(--line); border-radius: 10px; padding: 5px 11px; background: var(--panel2); cursor: pointer; max-width: 100%; }
.fm-kapan:hover { border-color: var(--accent2); }
.fm-kapan.live { border-color: color-mix(in srgb, var(--green) 55%, var(--line)); background: color-mix(in srgb, var(--green) 9%, var(--panel)); }
.fm-kapan.hl { border-color: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 30%, transparent); animation: fm-found 1.2s ease-in-out 2; }
@keyframes fm-found { 50% { box-shadow: 0 0 0 7px color-mix(in srgb, var(--accent) 18%, transparent); } }
@media (prefers-reduced-motion: reduce) { .fm-kapan.hl { animation: none; } }
.fm-kapan > b { font-size: 12px; }
.fm-kapan .fk-in { font-size: 11px; color: var(--muted); white-space: nowrap; }
.fk-state { font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fk-state.on { color: var(--green); font-weight: 600; }
.fk-state.done { color: var(--blue); }
.fk-state.dead { color: var(--red); }
.fk-state.idle { color: var(--muted); }
/* RO-level ledger node: dashed - it is a note on the RO, not a production step */
.fm-ledger { display: inline-flex; flex-direction: column; gap: 2px; border: 1.5px dashed color-mix(in srgb, var(--red) 45%, var(--line)); border-radius: 10px; padding: 6px 11px; background: color-mix(in srgb, var(--red) 5%, var(--panel)); cursor: help; max-width: 100%; }
.fm-ledger .fl-t { font-size: 9.5px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); font-weight: 700; }
.fm-ledger .fl-v { display: flex; gap: 14px; flex-wrap: wrap; font-size: 11.5px; }
.fm-out { flex: 0 0 128px; align-self: center; margin-left: 22px; position: relative; display: flex; flex-direction: column; gap: 2px; border: 1.5px solid color-mix(in srgb, var(--green) 55%, var(--line)); border-radius: 14px; padding: 9px 12px; background: color-mix(in srgb, var(--green) 10%, var(--panel)); }
.fm-out::before { content: ''; position: absolute; left: -22px; top: 50%; width: 18px; border-top: 2px solid color-mix(in srgb, var(--muted) 45%, transparent); }
.fm-out .fo-t { font-size: 9.5px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); font-weight: 700; }
.fm-out .fo-v { font-size: 14px; font-weight: 700; font-variant-numeric: tabular-nums; }
.fm-out .fo-s { font-size: 10.5px; color: var(--muted); }
.fm-out .fo-n { font-size: 10px; color: var(--muted); margin-top: 3px; border-top: 1px dashed var(--line); padding-top: 3px; }
@media (max-width: 900px) {
  .fm-grid { flex-direction: column; gap: 10px; }
  .fm-ro { position: static; flex-basis: auto; }
  .fm-tree { margin-left: 12px; }
  .fm-out { margin-left: 12px; flex-basis: auto; }
  .fm-out::before { display: none; }
}
/* ── END VERBATIM COPY · 524-566 ──────────────────────────────────────────────────────────────── */

/* ── BEGIN VERBATIM COPY · DIP frontend/src/index.css 715-800 ─────────────────────────────────── */
/* ===== THE ROAD (6-Sep-26) — Stone Accounting as the steps the stones took ===== */
.road-screen { display: flex; flex-direction: column; gap: 10px; }
.road-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; padding: 4px 2px; flex-wrap: wrap; }
.road-code { font-size: 28px; font-weight: 800; color: var(--blue); letter-spacing: .2px; }
.road-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.road-verdict { border: 0; cursor: pointer; font-family: inherit; }
.road { position: relative; background: var(--panel); border: 1px solid var(--line); border-radius: 18px; box-shadow: var(--shadow); padding: 34px 64px 14px; overflow-x: auto; }
.road-row { position: relative; display: flex; justify-content: space-between; align-items: flex-start; gap: 18px; min-width: 1100px; }
.road-row::before { content: ''; position: absolute; left: 24px; right: 24px; top: 22px; height: 3px; background: var(--text); border-radius: 2px; z-index: 0; }
.road-row.rev { flex-direction: row-reverse; }
.road-row.tail { justify-content: flex-start; gap: 80px; min-width: 0; flex: 0 0 auto; }
.road-row.tail::before { right: auto; width: calc(100% - 48px); }
.road-turn { position: relative; height: 52px; min-width: 1100px; }
.road-turn::before { content: ''; position: absolute; top: -30px; bottom: -30px; width: 3px; background: var(--text); }
.road-turn.r::before { right: 22.5px; }
.road-turn.l::before { left: 22.5px; }
.road-end { display: flex; align-items: flex-start; gap: 40px; min-width: 1100px; }
.road-tiles { display: flex; gap: 10px; flex: 1; justify-content: flex-end; padding-top: 2px; }
.road-tiles .tk { display: flex; flex-direction: column; gap: 2px; border: 1px solid var(--panel2); border-radius: 12px; padding: 10px 14px; min-width: 200px; cursor: pointer; background: var(--panel); }
.road-tiles .tk:hover { border-color: var(--line); background: color-mix(in srgb, var(--panel2) 40%, var(--panel)); }
.road-tiles .tk-k { font-size: 9.5px; text-transform: uppercase; letter-spacing: .03em; color: var(--muted); }
.road-tiles .tk b { font-size: 17px; font-variant-numeric: tabular-nums; }
.road-tiles .tk-s { font-size: 10px; color: var(--muted); }
.road-legend { display: flex; gap: 20px; align-items: center; flex-wrap: wrap; margin-top: 28px; padding-top: 10px; border-top: 1px solid var(--line); font-size: 10.5px; color: var(--muted); min-width: 1100px; }
.road-legend .lg { display: inline-block; width: 12px; height: 12px; border-radius: 999px; vertical-align: -2px; margin-right: 5px; background: var(--panel); border: 2px solid var(--text); }
.road-legend .lg.never { border: 2px dashed var(--line); }
.road-legend .lg.ok { border: 1.5px solid var(--green); background: color-mix(in srgb, var(--green) 17%, var(--panel)); }
.road-legend .lg.bad { border: 1.5px solid var(--red); background: color-mix(in srgb, var(--red) 15%, var(--panel)); }
.road-legend .lg.live { border: 1.5px solid var(--amber); background: color-mix(in srgb, var(--amber) 17%, var(--panel)); }

/* a step */
.rn { position: relative; display: flex; flex-direction: column; align-items: center; width: 48px; flex: 0 0 auto; cursor: pointer; z-index: 1; --rn-lw: 120px; }
.rn-c { width: 48px; height: 48px; border-radius: 999px; background: var(--panel); border: 2px solid var(--text); color: var(--text); display: flex; align-items: center; justify-content: center; box-sizing: border-box; transition: box-shadow .12s; }
.rn:hover { z-index: 40; }
.rn:hover > .rn-c { box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 35%, transparent); }
.rn-c.end { background: var(--blue); border-color: var(--blue); color: #fff8eb; }
.rn-c.never { border: 2px dashed var(--line); color: var(--muted); }
.rn-n { position: absolute; left: -6px; top: -8px; width: 20px; height: 20px; border-radius: 999px; background: var(--text); color: var(--panel); font-size: 9.5px; font-weight: 800; display: flex; align-items: center; justify-content: center; }
.rn-chip { position: absolute; left: 34px; top: 32px; min-width: 18px; height: 18px; padding: 0 5px; border-radius: 999px; font-size: 10px; font-weight: 800; display: flex; align-items: center; justify-content: center; font-variant-numeric: tabular-nums; box-sizing: border-box; white-space: nowrap; }
.rn-chip.ok { background: color-mix(in srgb, var(--green) 17%, var(--panel)); color: var(--green); border: 1.5px solid var(--green); }
.rn-chip.bad { background: color-mix(in srgb, var(--red) 15%, var(--panel)); color: var(--red); border: 1.5px solid var(--red); }
.rn-chip.live { background: color-mix(in srgb, var(--amber) 17%, var(--panel)); color: var(--amber); border: 1.5px solid var(--amber); }
.rn-l { width: var(--rn-lw); margin-top: 8px; text-align: center; font-size: 11px; line-height: 1.25; font-weight: 600; color: var(--text); }
.rn-c.never + .rn-n + .rn-l, .rn-c.never + .rn-l { color: var(--muted); font-weight: 400; }
.rn-sub { width: 170px; text-align: center; font-size: 10px; color: var(--muted); margin-top: 2px; }
.rn-small { width: 30px; }
.rn-small .rn-c { width: 30px; height: 30px; }
.rn-small .rn-chip { left: 20px; top: 18px; height: 16px; min-width: 16px; font-size: 9.5px; }
.rn-small .rn-l { --rn-lw: 70px; font-size: 10px; margin-top: 4px; }
.rn-sat { display: flex; flex-direction: column; align-items: center; margin-top: 6px; }
.rn-sat-line { width: 0; height: 26px; border-left: 1.5px dashed var(--muted); }
.rn-sat .rn-small { width: 36px; }
.rn-sat .rn-small .rn-c { width: 36px; height: 36px; }
.rn-sat .rn-small .rn-l { --rn-lw: 150px; }

/* the hover card */
.rn-card { display: none; pointer-events: none; position: absolute; top: 56px; left: 50%; transform: translateX(-50%); width: 220px; z-index: 30; flex-direction: column; gap: 5px; background: var(--panel); border: 1px solid var(--line); border-radius: 14px; padding: 11px 13px; box-shadow: var(--shadow); font-size: 11px; text-align: left; cursor: default; }
.rn:hover > .rn-card { display: flex; }
.rn:has(.rn:hover) > .rn-card { display: none; }   /* hovering a branch shows its own card, not its parent's */
.rn-small .rn-card { top: 36px; }
.road-row > .rn:last-child .rn-card, .road-row.rev > .rn:first-child .rn-card { left: auto; right: -8px; transform: none; }
.road-row:not(.rev) > .rn:first-child .rn-card { left: -8px; transform: none; }
.road-drawer td.mono { white-space: nowrap; }
.rn-card-h { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
.rn-card-h b { font-size: 12px; }
.rn-card-r { display: flex; justify-content: space-between; gap: 10px; }
.rn-card-r span { color: var(--muted); }
.rn-card-r b { font-variant-numeric: tabular-nums; font-weight: 600; }
.rn-card-v { border-top: 1px solid var(--line); padding-top: 5px; font-weight: 700; }
.rn-card-v.ok, .rn-card-v.clear { color: var(--green); }
.rn-card-v.bad { color: var(--red); }
.rn-card-v.live { color: var(--amber); }
.rn-card-go { color: var(--blue); font-weight: 700; font-size: 10.5px; }

/* the polishing lines band */
.road-band { position: relative; flex: 1; min-width: 560px; border: 1.5px dashed var(--line); border-radius: 14px; margin-top: -14px; padding: 8px 12px 10px; background: var(--panel); }
.road-band::before { content: ''; position: absolute; left: 22.5px; right: 0; top: 36px; height: 3px; background: var(--text); z-index: 0; }
.road-band::after { content: ''; position: absolute; left: 22.5px; top: 36px; bottom: -32px; width: 3px; background: var(--text); z-index: 0; }
.road-band.never { opacity: .7; }
.rb-head { font-size: 9.5px; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); font-weight: 700; position: relative; z-index: 1; background: var(--panel); display: inline-block; padding-right: 8px; }
.rb-cols { display: flex; justify-content: space-between; gap: 8px; margin-top: 10px; position: relative; z-index: 1; }
.rb-col { position: relative; display: flex; flex-direction: column; align-items: center; gap: 10px; min-width: 60px; }
.rb-col::before { content: ''; position: absolute; left: 50%; top: 24px; bottom: 30px; width: 1.5px; background: var(--text); z-index: 0; }
.rb-col.never::before { background: var(--line); }
.rb-name { position: relative; z-index: 1; font-size: 10.5px; font-weight: 800; background: var(--panel); padding: 2px 6px; border-radius: 6px; }
.rb-col.never .rb-name { color: var(--muted); font-weight: 600; }
/* ── END VERBATIM COPY · 715-800 ──────────────────────────────────────────────────────────────── */

/* ── BEGIN VERBATIM COPY · DIP frontend/src/index.css 88-91, 103-109, 391-394 ─────────────────── */
.panel { background: var(--panel); border: 1px solid var(--line); border-radius: 18px; box-shadow: var(--shadow); overflow: hidden; margin-bottom: 16px; }
.panel-head { padding: 14px 16px; border-bottom: 1px solid var(--line); display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.panel-head h3 { margin: 0; font-size: 13px; display: flex; gap: 6px; align-items: center; }
.panel-body { padding: 14px; }
.badge { display: inline-flex; padding: 4px 8px; border-radius: 999px; font-size: 11px; font-weight: 800; white-space: nowrap; }
.badge.green { background: color-mix(in srgb, var(--green) 17%, var(--panel)); color: var(--green); }
.badge.blue { background: color-mix(in srgb, var(--blue) 15%, var(--panel)); color: var(--blue); }
.badge.amber { background: color-mix(in srgb, var(--amber) 17%, var(--panel)); color: var(--amber); }
.badge.red { background: color-mix(in srgb, var(--red) 15%, var(--panel)); color: var(--red); }
.badge.gray { background: var(--panel2); color: var(--muted); }
.small { font-size: 11px; color: var(--muted); }
.mono { font-family: ui-monospace, Menlo, monospace; }
.muted { color: var(--muted); }
.neg { color: var(--red); }
.pos { color: var(--green); }
/* ── END VERBATIM COPY · 88-91, 103-109, 391-394 ──────────────────────────────────────────────── */

/* The sweep screen (14-Sep-26): DIP's KPI strip and its spreadsheet table, lifted as they stand.
   The frozen-corner rules at the end of the second block were found in Chromium at 400 rows, not
   by reading the CSS - which is exactly why they are copied rather than rewritten. */
/* ── VERBATIM COPY · DIP frontend/src/index.css 489-494 ──────────────────────────────────── */
.trace-kpis { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 9px; }
.trace-kpis .tk { display: flex; flex-direction: column; border: 1px solid var(--panel2);
  border-radius: 8px; padding: 5px 12px; background: var(--panel); min-width: 108px; }
.trace-kpis .tk-k { font-size: 9.5px; text-transform: uppercase; letter-spacing: .03em; color: var(--muted); }
.trace-kpis .tk b { font-size: 14.5px; font-variant-numeric: tabular-nums; }
.trace-kpis .tk-s { font-size: 10px; color: var(--muted); }
/* ── END VERBATIM COPY · 489-494 ──────────────────────────────────────────────────────────── */

/* ── VERBATIM COPY · DIP frontend/src/index.css 674-701 ──────────────────────────────────── */
.xl { font-variant-numeric: tabular-nums; font-size: 11.5px; border-collapse: separate; border-spacing: 0; }
.xl th, .xl td { border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); padding: 3px 7px; white-space: nowrap; }
.xl th { position: sticky; top: 0; z-index: 3; background: var(--panel2); cursor: pointer; user-select: none; font-size: 10.5px; border-bottom: 1px solid var(--line-firm, var(--line)); }
.xl th:hover { color: var(--accent); }
.xl th.sorted { color: var(--accent); }
.xl th .dir { font-size: 9px; opacity: .8; }
.xl tbody tr:nth-child(even) td { background: color-mix(in srgb, var(--panel2) 26%, transparent); }
.xl tbody tr:hover td { background: color-mix(in srgb, var(--accent) 9%, var(--panel)); }
.xl td.rowh { position: sticky; left: 0; z-index: 2; background: var(--panel); font-weight: 700; }
.xl tbody tr:nth-child(even) td.rowh { background: color-mix(in srgb, var(--panel2) 55%, var(--panel)); }
.xl tbody tr:hover td.rowh { background: color-mix(in srgb, var(--accent) 12%, var(--panel)); }
.xl td.bad { background: color-mix(in srgb, var(--red) 17%, var(--panel)) !important; color: var(--red); font-weight: 700; }
.xl td.warnc { background: color-mix(in srgb, var(--amber) 18%, var(--panel)) !important; color: var(--amber); font-weight: 700; }
.xl tfoot td { position: sticky; bottom: 0; z-index: 3; background: var(--panel2); border-top: 2px solid var(--accent); font-weight: 700; }
.xl .cf { font-size: 9.5px; color: var(--muted); font-weight: 400; display: block; }
.xl-wrap { overflow: auto; max-height: calc(100vh - 300px); }
/* THE TWO FROZEN CORNERS. Found in Chromium at 400 rows, not by reading the CSS:
   `.xl td.rowh` scores 0-2-1 and `.xl tfoot td` only 0-1-2, so without the second
   rule below the totals row's TOTAL cell keeps the BODY's panel background and the
   BODY's z-index - it renders a different colour from the rest of its own row and
   sits one layer underneath it. And the header's first cell was sticky top only, so
   scrolling right slid "Packet" out from over its own frozen column. Layering is
   deliberate: body first column 2, frozen header and footer rows 3, the two corners
   where they cross 4. */
.xl thead th:first-child { left: 0; z-index: 4; }
.xl tfoot td.rowh { background: var(--panel2); z-index: 4; }
.xl-daughters td { background: color-mix(in srgb, var(--accent) 6%, var(--panel)) !important; padding: 8px 10px 10px 26px; }

/* ── END VERBATIM COPY · 674-701 ──────────────────────────────────────────────────────────── */
}

/* ── THE ASSORTMENT STAGE STRIP (Pages/Assortment/Index.cshtml) ───────────────────────────────────────
   The assortment flow drawn as what it is: a sequence with a fork in it. It lived in the sidebar as a
   flat list of thirteen names, twice — once filed by where the code lives, once filed by screen name —
   and a flat list cannot show a sequence, which is why both attempts read as sprawl (owner, 2026-09-20:
   "remove from the side bar. One word of assortment desk and then all these links inside").

   Each tile is a LINK, so everything here styles an <a>: the strip is navigation, and the only thing that
   draws a link on that page is the gated _DeskLink partial. The rules stay in this file rather than on the
   page for the same reason the grid's do — one assortment look, in one place.

   The strip SCROLLS sideways below about 900px rather than wrapping. A wrapped strip puts "Final tally"
   under "A1 received" with an arrow pointing into the gap, which says the opposite of the truth about the
   order of the stages. A scroll bar is honest; a wrapped sequence is not. */

.stage-strip {
  display: flex;
  align-items: stretch;
  gap: 0;
  overflow-x: auto;
  padding: 2px;
}

.stage-tile {
  /* A COLUMN, so the count and the carats can be pinned to the BOTTOM. The strip stretches every tile to
     one height, so bottom-aligning the figures makes them line up across the row no matter how many lines
     a name takes — and names do take different numbers of lines as the strip narrows ("Raw Assortment 2"
     wraps where "Final tally" does not). An earlier version reserved a fixed two lines for the name
     instead; that held at 1500px and broke at 1024, where a name needed three, and the counts sat at
     three different heights. Reserving space guesses how much; pinning to the bottom does not have to. */
  display: flex;
  flex-direction: column;
  flex: 1 1 0;
  min-width: 8.6rem;
  padding: 10px 12px 12px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 2px;
  text-align: center;
  text-decoration: none;
  color: var(--ink);
  transition: border-color .12s, box-shadow .12s, background .12s;
}

.stage-tile:hover  { border-color: var(--accent); box-shadow: 0 1px 4px rgba(26,23,20,.08); color: var(--ink); }
.stage-tile:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* THE SELECTED TILE IS MARKED TWICE — a heavier border AND a thick left rule — because a border colour
   alone is the one distinction a reader with a colour deficiency may not see, and the whole page below
   answers to whichever tile is selected. */
.stage-tile.is-on {
  border-color: var(--ink);
  border-left: 3px solid var(--accent);
  background: #FCFAF5;
  box-shadow: inset 0 -2px 0 var(--accent);
}

/* The three parts a tile is built from are the _DeskLink partial's own hooks (dl-text / dl-big / dl-sub).
   An earlier version of these rules named .st-name and .st-cts, which that partial never emits — so they
   were dead and the tiles were quietly falling back to Bootstrap's utilities. A styling hook that does not
   exist is worse than none: it reads as applied.

   THE NAMES RESERVE TWO LINES whether they need them or not. "Raw Assortment 2" wraps and the others do
   not, so the counts sat at different heights across the strip and the row stopped reading as one
   sequence. Caught by rendering the page; no suite can see it. */
.stage-tile .dl-text { font-size: .74rem; font-weight: 600; letter-spacing: .02em; margin-top: 3px;
                       min-height: 2.5em; flex: 1 1 auto;
                       display: flex; align-items: center; justify-content: center;
                       gap: .3em; flex-wrap: wrap; line-height: 1.18; }
.stage-tile .dl-text .bi { color: var(--ink-soft); font-weight: 400; }
.stage-tile .dl-big  { font-family: var(--serif); font-size: 1.5rem; line-height: 1.1; }
.stage-tile .dl-sub  { font-size: .68rem; color: var(--ink-soft); font-variant-numeric: tabular-nums; }

.stage-arrow {
  display: flex;
  align-items: center;
  color: var(--ink-soft);
  padding: 0 5px;
  font-size: .8rem;
  flex: 0 0 auto;
}

/* The queue and the fork note — the two things a cumulative funnel cannot say. "Awaiting A2" is the
   EXCLUSIVE count (received and not sorted at all), which is the figure an assorter arriving at work
   needs and the one the strip's "has reached" tiles deliberately do not show. */
.stage-aside {
  flex: 0 0 auto;
  min-width: 9.5rem;
  padding: 10px 12px;
  margin-left: 10px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--warning);
  border-radius: 2px;
  background: #FCFAF5;
}

.stage-aside .k { font-size: .66rem; text-transform: uppercase; letter-spacing: .05em; color: var(--ink-soft); }
.stage-aside .v { font-family: var(--serif); font-size: 1.35rem; line-height: 1.15; }
.stage-aside .s { font-size: .68rem; color: var(--ink-soft); }

.stage-fork {
  font-size: .7rem;
  color: var(--ink-soft);
  text-align: center;
  border-top: 1px dashed var(--border);
  margin-top: 10px;
  padding-top: 7px;
}

/* The bar that says which stage is selected and carries that stage's two screens. */
.stage-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 22px;
  background: var(--card);
  border: 1px solid var(--border);
  border-left: 3px solid var(--ink);
  border-radius: 2px;
  padding: 12px 16px;
}

.stage-bar h2 { font-family: var(--serif); font-size: 1.3rem; margin: 0; }
.stage-bar .fig .k { font-size: .64rem; text-transform: uppercase; letter-spacing: .05em; color: var(--ink-soft); }
.stage-bar .fig .v { font-size: 1.05rem; font-weight: 600; font-variant-numeric: tabular-nums; }

@media print {
  .stage-strip { overflow-x: visible; }
  .stage-tile:not(.is-on) { opacity: .55; }
}

/* ── THE DESK'S TABS (Pages/Assortment/Index.cshtml) ──────────────────────────────────────────────────
   One word each, sitting in the table toolbar between the heading and the search box. They are <button>
   elements, not links: the Desk writes no anchor of its own, every link on it goes through the gated
   _DeskLink partial, and a tab is not a destination anyway.

   Bootstrap's own .nav-tabs draws a bottom border and a raised active tab, which fights the toolbar's own
   border — so the border is dropped and the active tab is marked by weight and a rule UNDER it, inside the
   toolbar's own line. */

.desk-tabs.nav-tabs { border-bottom: 0; gap: 2px; flex-wrap: wrap; margin: 0 auto 0 26px; }

.desk-tabs .nav-link {
  border: 0;
  border-bottom: 2px solid transparent;
  border-radius: 0;
  padding: 3px 11px;
  font-size: .8rem;
  color: var(--ink-soft);
  background: none;
}

.desk-tabs .nav-link:hover { color: var(--ink); border-bottom-color: var(--border); }

.desk-tabs .nav-link.active {
  color: var(--ink);
  font-weight: 600;
  background: none;
  border-bottom-color: var(--accent);
}

/* A tab is a screen control, not part of the document — a printed sheet shows the pane that was open. */
@media print { .desk-tabs { display: none; } }

/* The zone heading above the stage strip. It exists because a carat figure standing on a stage tile reads as
   inventory held at that stage, and none of these stages holds anything: A2 and A3 are descriptive re-sorts
   and the goods sit in UNSORTED_POLISH until the final tally moves them to READY_POLISH. Naming the zone
   once, above every figure in it, is cheaper than qualifying each tile. */
.wip-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: .5rem; padding: 2px 4px 9px; }
.wip-head .k { font-size: .66rem; text-transform: uppercase; letter-spacing: .07em; font-weight: 600;
               color: var(--ink); }
.wip-head .s { font-size: .7rem; color: var(--ink-soft); }

/* ─── Labour bill review window (Labour Bills) ──────────────────────────────────────────────────────────
   The invoice beside every figure the bill carries, so the checker reads the two against each other
   (owner, 2026-09-26: "the uploaded file i cant see while validating"). A figure the Read put over an entered
   one is marked, with what it replaced shown under it — a correction is made knowingly, never silently. */
.lb-doc { border: 1px solid var(--border); background: #FBFAF6; border-radius: 2px; height: 70vh; min-height: 360px;
          display: flex; align-items: center; justify-content: center; overflow: hidden; }
.lb-doc-frame { width: 100%; height: 100%; border: 0; background: #fff; }
.lb-doc-img { max-width: 100%; max-height: 100%; object-fit: contain; }
.lb-doc-none { color: var(--ink-soft); font-size: .85rem; padding: 1rem; text-align: center; }
.lb-changed { background: #fff6dd !important; border-color: #d9a441 !important; }
.lb-was { font-size: .72rem; color: var(--warning); margin-top: 2px; }
.lb-facts { font-size: .8rem; border-top: 1px solid var(--border); padding: .5rem 0 0 1rem; }
.lb-facts li { margin-bottom: 2px; }
.lb-facts .lb-warn, .lb-read-warn .lb-warn { color: var(--warning); }
.lb-read-warn { color: var(--warning); }
.lb-history summary { font-size: .8rem; color: var(--ink-soft); cursor: pointer; }
/* A carat problem on a table row: a few words in the cell, the whole sentence on hover. */
.lb-flag { display: inline-block; max-width: 8em; font-size: .72rem; line-height: 1.25; color: #8a5a00; background: #fff6dd;
           border: 1px solid #f0d9a0; border-radius: 3px; padding: 1px 5px; cursor: help; white-space: normal; text-align: left; }
/* Below 1200px the window goes full-screen and stacks the invoice ABOVE the form: side by side at 1,024 the
   form's column squeezed the amount boxes until "10,19,592" printed as "10195" (found by rendering). */
@media (max-width: 1199.98px) { .lb-doc { height: 58vh; } }
