/* ==========================================================================
   DSR Reconciliation — operator console.

   COLOUR CARRIES ONE MEANING HERE AND ONLY ONE: what kind of decision an item
   needs. Not which lane it came from, not which rule fired, not how big it is.
   An operator scanning this page should be able to answer "is that money gone
   or is it just filed wrong?" from across the room, and that is a four-way
   distinction (src/backoffice/presentation.py DISPOSITIONS), not a six-way
   one. The engine's six categories are still on every row, in words.

   RED IS RESERVED FOR MONEY THAT LEFT CUSTODY AND DID NOT ARRIVE. An excess
   is not red: the money is in the bank, and colouring it like a loss teaches
   people that half the red on the page is noise.

   Figures are set in a tabular-numeral mono face throughout. Money in a
   proportional font does not line up at the decimal, and a column of
   shortfalls that does not line up is a column nobody scans.
   ========================================================================== */

:root {
  --paper:        #eceee8;
  --surface:      #ffffff;
  --surface-2:    #f6f7f3;
  --rail:         #16242c;
  --rail-2:       #1d3038;

  --text:         #17262f;
  --text-2:       #2a4756;
  --muted:        #55656e;
  --muted-2:      #6d7c85;

  --rule:         #d7dbd2;
  --rule-soft:    #e5e8e0;

  --accent:       #0e7c6b;
  --accent-2:     #0a6357;
  --accent-soft:  #0e7c6b17;
  --accent-line:  #0e7c6b47;

  /* Dispositions. One hue per kind of decision. */
  --loss:         #c0442a;
  --loss-bg:      #f9e8e3;
  --loss-text:    #8f2f1a;
  --recover:      #15805a;
  --recover-bg:   #e2f0e9;
  --recover-text: #106044;
  --correct:      #b07d18;
  --correct-bg:   #f7eeda;
  --correct-text: #85590c;
  --flight:       #5e7a8c;
  --flight-bg:    #e6ecef;
  --flight-text:  #435d6d;

  --pos:          #15805a;
  --neg:          #c0442a;

  --r:            10px;
  --r-sm:         6px;
  --r-xs:         3px;
  --rail-w:       246px;
  --pad:          28px;

  --sh-1: 0 1px 2px #14232c0d, 0 1px 1px #14232c08;
  --sh-2: 0 2px 6px #14232c12, 0 1px 2px #14232c0d;
  --sh-3: 0 12px 32px #14232c1f, 0 2px 8px #14232c0f;

  --sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
          "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, "SF Mono", "Cascadia Mono", "Segoe UI Mono", Menlo,
          Consolas, "Liberation Mono", monospace;
}

:root[data-theme="dark"] {
  --paper:        #12181b;
  --surface:      #182025;
  --surface-2:    #1d262b;
  --rail:         #0d1417;
  --rail-2:       #162027;

  --text:         #e4eae7;
  --text-2:       #cdd6d2;
  --muted:        #97a5a9;
  --muted-2:      #7f8d92;

  --rule:         #27343a;
  --rule-soft:    #1f2a2f;

  --accent:       #2ba58e;
  --accent-2:     #37bda3;
  --accent-soft:  #2ba58e1f;
  --accent-line:  #2ba58e55;

  --loss:         #e2694c;
  --loss-bg:      #3a1f18;
  --loss-text:    #f0a691;
  --recover:      #34b083;
  --recover-bg:   #17342a;
  --recover-text: #7fd9b6;
  --correct:      #d5a03c;
  --correct-bg:   #382c15;
  --correct-text: #eccb8a;
  --flight:       #7f9aab;
  --flight-bg:    #212d34;
  --flight-text:  #a8bdc9;

  --pos:          #34b083;
  --neg:          #e2694c;

  --sh-1: 0 1px 2px #0006;
  --sh-2: 0 2px 6px #0007;
  --sh-3: 0 12px 32px #0009;
}

* { box-sizing: border-box; }

/* An author `display` rule beats the user-agent's `[hidden] { display: none }`
   whatever the specificity, so any element given a display value here would
   ignore its own `hidden` attribute. That is how the "Nothing reconciled yet"
   banner came to sit permanently above a queue of 158 live exceptions.
   Global, and deliberately !important: `hidden` means hidden. */
[hidden] { display: none !important; }


html, body { margin: 0; padding: 0; }

body {
  background: var(--paper);
  color: var(--text);
  font-family: var(--sans);
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { margin: 0; font-weight: 650; letter-spacing: -0.015em; }

.mono, .num, .figure {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

.neg { color: var(--neg); }
.pos { color: var(--pos); }

/* ============================================================ shell */
.shell { min-height: 100vh; }
.content { padding-left: var(--rail-w); }

@media (max-width: 900px) {
  .content { padding-left: 0; }
}

/* ============================================================ rail */
.rail {
  position: fixed;
  inset: 0 auto 0 0;
  width: var(--rail-w);
  background: var(--rail);
  color: #fff;
  display: flex;
  flex-direction: column;
  z-index: 40;
  overflow-y: auto;
}

.rail-brand { padding: 20px 22px 16px; }
.rail-name {
  display: block;
  font-size: 19px;
  font-weight: 700;
  letter-spacing: -0.03em;
}
.rail-sub {
  display: block;
  margin-top: 2px;
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #ffffff73;
}

.rail-period {
  margin: 0 14px 6px;
  padding: 10px 12px;
  border-radius: var(--r-sm);
  background: #ffffff0d;
  border: 1px solid #ffffff14;
}
.rp-label {
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #ffffff66;
}
.rp-value {
  display: block;
  margin-top: 2px;
  font-family: var(--mono);
  font-size: 11.5px;
  color: #ffffffdb;
}
.rp-asof { display: block; margin-top: 5px; font-size: 11px; color: #ffffff85; }

.rail-nav { flex: 1; padding: 6px 12px 12px; }
.nav-group {
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: #ffffff59;
  padding: 0 10px;
  margin: 16px 0 5px;
}
.nav-item {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  padding: 7px 10px;
  margin-bottom: 1px;
  border: 0;
  border-radius: var(--r-sm);
  background: transparent;
  color: #ffffffb8;
  font: inherit;
  font-size: 13px;
  text-align: left;
  cursor: pointer;
}
.nav-item:hover { background: #ffffff0f; color: #fff; }
.nav-item.active { background: var(--accent); color: #fff; font-weight: 600; }
.nav-num {
  font-family: var(--mono);
  font-size: 9.5px;
  color: #ffffff4d;
  width: 13px;
}
.nav-item.active .nav-num { color: #ffffff8c; }
.nav-label { flex: 1; }
.nav-count {
  font-family: var(--mono);
  font-size: 10.5px;
  padding: 1px 6px;
  border-radius: 20px;
  background: #ffffff17;
  color: #ffffffa6;
}
.nav-item.active .nav-count { background: #ffffff2b; color: #fff; }
.nav-count.bad  { background: var(--loss); color: #fff; }
.nav-count.warn { background: var(--correct); color: #16242c; }
.nav-count.ok   { background: #ffffff1f; }

/* The disclosure for the operational views. It carries its own count badge so
   a collapsed section can never be the reason someone missed a number that
   changed — the badge is the same one the entries inside it carry, summed. */
.nav-disclosure {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  padding: 7px 10px;
  margin: 16px 0 2px;
  border: 0;
  border-radius: var(--r-sm);
  background: transparent;
  color: #ffffff8a;
  font: inherit;
  font-size: 11.5px;
  letter-spacing: 0.04em;
  text-align: left;
  cursor: pointer;
}
.nav-disclosure:hover { background: #ffffff0f; color: #fff; }
.nav-caret {
  font-size: 9px;
  width: 13px;
  transition: transform 0.12s ease;
}
.nav-disclosure[aria-expanded="true"] .nav-caret { transform: rotate(90deg); }
.nav-admin { padding-left: 6px; }

.rail-foot { border-top: 1px solid #ffffff14; padding: 14px 22px 18px; }
.actor-label {
  display: block;
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #ffffff66;
  margin-bottom: 5px;
}
.actor-input {
  width: 100%;
  padding: 6px 9px;
  border-radius: var(--r-sm);
  border: 1px solid #ffffff21;
  background: #ffffff0d;
  color: #fff;
  font: inherit;
  font-size: 12.5px;
}
.actor-input::placeholder { color: #ffffff54; }
.rail-actions { display: flex; gap: 8px; margin-top: 10px; }
.rail-btn {
  flex: 1;
  padding: 5px 8px;
  border-radius: var(--r-sm);
  border: 1px solid #ffffff21;
  background: transparent;
  color: #ffffffad;
  font: inherit;
  font-size: 11.5px;
  cursor: pointer;
}
.rail-btn:hover { background: #ffffff14; color: #fff; }
.rail-note {
  margin: 12px 0 0;
  font-size: 11px;
  line-height: 1.5;
  color: #ffffff70;
}

.rail-toggle {
  display: none;
  position: fixed;
  top: 12px;
  left: 12px;
  z-index: 50;
  width: 34px;
  height: 34px;
  border-radius: var(--r-sm);
  border: 1px solid var(--rule);
  background: var(--surface);
  color: var(--text);
  font-size: 15px;
  cursor: pointer;
}
@media (max-width: 900px) {
  .rail { transform: translateX(-100%); transition: transform .18s ease; }
  body.nav-open .rail { transform: translateX(0); }
  .rail-toggle { display: block; }
}

/* ============================================================ page */
.page { max-width: 1280px; padding: 0 var(--pad); margin: 0 auto; }

.viewbar {
  position: sticky;
  top: 0;
  z-index: 20;
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--rule);
}
.viewbar-inner { padding: 18px 0 14px; }
.eyebrow {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted-2);
}
.viewbar h1 { font-size: 25px; margin-top: 3px; }
.viewbar p {
  margin: 5px 0 0;
  max-width: 74ch;
  font-size: 13px;
  color: var(--muted);
}

main { padding: 22px 0 72px; }

.section-head {
  display: flex;
  align-items: baseline;
  gap: 12px;
  flex-wrap: wrap;
  font-size: 15px;
  margin: 32px 0 12px;
}
.section-sub { font-size: 12.5px; font-weight: 400; color: var(--muted); }

.footnote {
  margin: 12px 0 0;
  max-width: 84ch;
  font-size: 12px;
  line-height: 1.6;
  color: var(--muted);
}

.banner {
  display: flex;
  gap: 12px;
  margin: 16px 0;
  padding: 12px 14px;
  border-radius: var(--r);
  border: 1px solid var(--loss);
  background: var(--loss-bg);
  color: var(--loss-text);
  font-size: 13px;
}
.banner code {
  font-family: var(--mono);
  font-size: 12px;
  background: #0000000f;
  padding: 1px 4px;
  border-radius: var(--r-xs);
}

/* ============================================================ headline */
.headline {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 1px;
  background: var(--rule);
  border: 1px solid var(--rule);
  border-radius: var(--r);
  overflow: hidden;
}
.hl {
  background: var(--surface);
  padding: 16px 18px;
}
.hl-value {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  font-size: 26px;
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.15;
}
.hl-label { margin-top: 3px; font-size: 12.5px; font-weight: 600; }
.hl-note { margin-top: 2px; font-size: 11.5px; color: var(--muted); }
.hl-money {
  margin-top: 8px;
  font-family: var(--mono);
  font-size: 14px;
  color: var(--text-2);
}

/* ============================================================ chips */
.chiprow { display: flex; flex-wrap: wrap; gap: 8px; margin: 14px 0 4px; }
.dchip {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 7px 12px;
  border-radius: 20px;
  border: 1px solid var(--rule);
  background: var(--surface);
  font: inherit;
  font-size: 12.5px;
  cursor: pointer;
  color: var(--text);
}
.dchip:hover { border-color: var(--accent-line); }
.dchip.on { border-color: currentColor; box-shadow: inset 0 0 0 1px currentColor; }
.dchip-n { font-family: var(--mono); font-weight: 600; }
.dchip-money { font-family: var(--mono); font-size: 11.5px; color: var(--muted); }

[data-disp="cash_loss"]   { color: var(--loss-text); }
[data-disp="recoverable"] { color: var(--recover-text); }
[data-disp="to_correct"]  { color: var(--correct-text); }
[data-disp="in_flight"]   { color: var(--flight-text); }

.pill {
  display: inline-block;
  padding: 1.5px 7px;
  border-radius: 20px;
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.02em;
  white-space: nowrap;
}
.pill[data-disp="cash_loss"]   { background: var(--loss-bg);    color: var(--loss-text); }
.pill[data-disp="recoverable"] { background: var(--recover-bg); color: var(--recover-text); }
.pill[data-disp="to_correct"]  { background: var(--correct-bg); color: var(--correct-text); }
.pill[data-disp="in_flight"]   { background: var(--flight-bg);  color: var(--flight-text); }

.tag {
  display: inline-block;
  margin: 0 4px 2px 0;
  padding: 1px 6px;
  border-radius: var(--r-xs);
  border: 1px solid var(--rule);
  font-family: var(--mono);
  font-size: 10px;
  color: var(--muted);
  white-space: nowrap;
}
.tag-hypothesis { border-color: var(--correct); color: var(--correct-text); background: var(--correct-bg); }

.deadline { font-family: var(--mono); font-size: 11.5px; color: var(--muted); }
.deadline.over { color: var(--loss); font-weight: 600; }
.deadline.soon { color: var(--correct-text); }

/* ============================================================ jobs */
.jobs { display: grid; gap: 10px; }
.job {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 16px;
  width: 100%;
  padding: 14px 16px;
  border: 1px solid var(--rule);
  border-left: 3px solid currentColor;
  border-radius: var(--r);
  background: var(--surface);
  box-shadow: var(--sh-1);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.job:hover { box-shadow: var(--sh-2); border-color: var(--accent-line); }
.job-title { font-size: 15px; font-weight: 600; color: var(--text); }
.job-meta { margin-top: 3px; font-size: 12px; color: var(--muted); }
.job-right { text-align: right; }
.job-amt {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  font-size: 18px;
  font-weight: 600;
}
.job-open {
  margin-top: 3px;
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
}

/* ============================================================ day chart */
.daychart {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: 6px;
  padding: 16px 16px 12px;
  border: 1px solid var(--rule);
  border-radius: var(--r);
  background: var(--surface);
}
.daycol { display: flex; flex-direction: column; align-items: center; }
.day-over, .day-short { width: 100%; display: flex; }
.day-over { align-items: flex-end; justify-content: center; }
.day-short { align-items: flex-start; justify-content: center; }
.bar { width: 60%; max-width: 52px; border-radius: 2px 2px 0 0; min-height: 1px; }
.bar-over  { background: var(--correct); opacity: .75; }
.bar-short { background: var(--loss); border-radius: 0 0 2px 2px; }
.day-axis { width: 100%; height: 1px; background: var(--rule); margin: 0; }
.day-label { margin-top: 7px; font-size: 11.5px; font-weight: 600; }
.day-sub { font-family: var(--mono); font-size: 10.5px; color: var(--muted); }
.chart-key {
  display: flex;
  gap: 16px;
  margin-top: 10px;
  font-size: 11.5px;
  color: var(--muted);
}
.key-swatch {
  display: inline-block;
  width: 9px;
  height: 9px;
  border-radius: 2px;
  margin-right: 5px;
  vertical-align: baseline;
}

/* ============================================================ cards */
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 12px;
  margin-top: 12px;
}
.card {
  padding: 15px 16px;
  border: 1px solid var(--rule);
  border-radius: var(--r);
  background: var(--surface);
  box-shadow: var(--sh-1);
}
.card h3 { font-size: 13.5px; margin-bottom: 6px; }
.card-value {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  font-size: 22px;
  font-weight: 600;
  letter-spacing: -0.02em;
}
.hint { margin: 6px 0 0; font-size: 12px; line-height: 1.55; color: var(--muted); }

.lane-list { list-style: none; margin: 10px 0 0; padding: 0; }
.lane-list li {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 4px 0;
  border-top: 1px solid var(--rule-soft);
  font-size: 12px;
}
.lane-name { color: var(--muted); }
.lane-value { font-family: var(--mono); font-variant-numeric: tabular-nums; }

/* ============================================================ filters */
.filterbar {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 10px;
  padding: 12px 14px;
  border: 1px solid var(--rule);
  border-radius: var(--r);
  background: var(--surface);
  margin-bottom: 12px;
}
.fgroup { display: flex; flex-direction: column; gap: 3px; }
.flabel {
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted-2);
}
.finput {
  padding: 5px 8px;
  min-width: 130px;
  border-radius: var(--r-sm);
  border: 1px solid var(--rule);
  background: var(--surface-2);
  color: var(--text);
  font: inherit;
  font-size: 12.5px;
}
.finput:focus { outline: 2px solid var(--accent-line); outline-offset: -1px; }
.switch { display: flex; align-items: center; gap: 6px; font-size: 12.5px; }
.btn-reset {
  padding: 5px 10px;
  border-radius: var(--r-sm);
  border: 1px solid var(--rule);
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}
.btn-reset:hover { color: var(--text); border-color: var(--accent-line); }
.filter-summary {
  margin-left: auto;
  font-family: var(--mono);
  font-size: 11.5px;
  color: var(--muted);
}

/* ============================================================ datestrip */
.datestrip {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  padding: 10px 0 0;
}
.datestrip-label {
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted-2);
}
.dschip {
  padding: 4px 9px;
  border-radius: var(--r-sm);
  border: 1px solid var(--rule);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}
.dschip:hover { border-color: var(--accent-line); }
.dschip.on { background: var(--accent); border-color: var(--accent); color: #fff; }
.dschip-zero { color: var(--muted-2); }
.dschip-count {
  margin-left: 6px;
  font-family: var(--mono);
  font-size: 10.5px;
  opacity: .75;
}
.datestrip-all {
  border: 0;
  background: transparent;
  color: var(--accent);
  font: inherit;
  font-size: 12px;
  cursor: pointer;
  text-decoration: underline;
}

/* ============================================================ tables */
.tablewrap {
  border: 1px solid var(--rule);
  border-radius: var(--r);
  background: var(--surface);
  overflow: hidden;
}
.tablewrap.scroll-x { overflow-x: auto; }

table.grid { width: 100%; border-collapse: collapse; font-size: 13px; }
table.grid thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  padding: 8px 12px;
  text-align: left;
  font-family: var(--mono);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted-2);
  background: var(--surface-2);
  border-bottom: 1px solid var(--rule);
  white-space: nowrap;
}
table.grid td {
  padding: 8px 12px;
  border-bottom: 1px solid var(--rule-soft);
  vertical-align: top;
}
table.grid tbody tr:last-child td { border-bottom: 0; }
table.grid tbody tr.clickable { cursor: pointer; }
table.grid tbody tr.clickable:hover { background: var(--accent-soft); }
table.grid tbody tr.sel { background: var(--accent-soft); box-shadow: inset 3px 0 0 var(--accent); }
table.grid .num { text-align: right; font-family: var(--mono); font-variant-numeric: tabular-nums; white-space: nowrap; }
table.grid.compact td, table.grid.compact thead th { padding: 5px 9px; font-size: 12px; }

.row-flagged { box-shadow: inset 3px 0 0 var(--correct); }

.store-code { font-family: var(--mono); font-size: 12px; font-weight: 600; }
.store-name { display: block; font-size: 11.5px; color: var(--muted); }
.sub { display: block; font-size: 11px; color: var(--muted); }

.state-pill {
  display: inline-block;
  padding: 1.5px 7px;
  border-radius: 20px;
  border: 1px solid var(--rule);
  font-size: 11px;
  white-space: nowrap;
}
.state-pill[data-state="Closed"] { background: var(--recover-bg); border-color: transparent; color: var(--recover-text); }
.state-pill[data-state="Awaiting Vendor"] { background: var(--correct-bg); border-color: transparent; color: var(--correct-text); }
.state-pill[data-state="In Progress"] { background: var(--accent-soft); border-color: transparent; color: var(--accent-2); }
.state-pill[data-daystate="Exception"] { background: var(--loss-bg); border-color: transparent; color: var(--loss-text); }
.state-pill[data-daystate="Tied"] { background: var(--recover-bg); border-color: transparent; color: var(--recover-text); }

.result-pill {
  display: inline-block;
  padding: 1.5px 8px;
  border-radius: 20px;
  font-family: var(--mono);
  font-size: 10.5px;
}
.result-pill[data-result="PASS"] { background: var(--recover-bg); color: var(--recover-text); }
.result-pill[data-result="WARN"] { background: var(--correct-bg); color: var(--correct-text); }
.result-pill[data-result="FAIL"] { background: var(--loss-bg); color: var(--loss-text); }

.assignee-none { color: var(--muted-2); font-style: italic; font-size: 12px; }
.empty { padding: 24px; text-align: center; color: var(--muted); font-size: 13px; }
.check-id { font-family: var(--mono); font-size: 11px; color: var(--muted); }
.check-detail { margin-top: 2px; font-size: 11.5px; color: var(--muted); }
.waterfall-total td { font-weight: 700; background: var(--surface-2); }
.family-head { margin: 24px 0 8px; font-size: 13.5px; }

/* ============================================================ findings */
.finding {
  padding: 15px 16px;
  margin-bottom: 10px;
  border: 1px solid var(--rule);
  border-left: 3px solid var(--correct);
  border-radius: var(--r);
  background: var(--surface);
  box-shadow: var(--sh-1);
}
.finding[data-severity="CRITICAL"] { border-left-color: var(--loss); }
.finding[data-severity="HIGH"] { border-left-color: var(--correct); }
.finding-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.finding-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: 10px;
  margin: 12px 0 0;
}
.dstat { }
.dstat b {
  display: block;
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  font-size: 16px;
}
.dstat span { font-size: 11.5px; color: var(--muted); }

/* ============================================================ drawer */
.drawer { position: fixed; inset: 0; z-index: 60; }
.drawer-backdrop { position: absolute; inset: 0; background: #0a1216a3; }
.drawer-panel {
  position: absolute;
  inset: 0 0 0 auto;
  width: min(560px, 100%);
  background: var(--paper);
  box-shadow: var(--sh-3);
  display: flex;
  flex-direction: column;
}
.drawer-head {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 16px 20px 12px;
  border-bottom: 1px solid var(--rule);
  background: var(--surface);
}
.drawer-head h2 { font-size: 16px; }
.drawer-key { font-family: var(--mono); font-size: 11px; color: var(--muted); }
.drawer-close {
  margin-left: auto;
  border: 0;
  background: transparent;
  color: var(--muted);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
}
.drawer-body { flex: 1; overflow-y: auto; padding: 16px 20px 40px; }
.drawer-body > * + * { margin-top: 12px; }

.dlead { font-size: 14px; line-height: 1.6; }
.dlead .headline-amt {
  display: block;
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  font-size: 27px;
  font-weight: 650;
  letter-spacing: -0.03em;
  margin-bottom: 4px;
}
.dgrid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 1px;
  background: var(--rule);
  border: 1px solid var(--rule);
  border-radius: var(--r);
  overflow: hidden;
}
.dgrid .dstat { background: var(--surface); padding: 10px 12px; }

.note {
  padding: 10px 12px;
  border-radius: var(--r-sm);
  border: 1px solid var(--rule);
  background: var(--surface-2);
  font-size: 12px;
  line-height: 1.55;
  color: var(--muted);
}
.note b { color: var(--text-2); }
.note-warn { border-color: var(--loss); background: var(--loss-bg); color: var(--loss-text); }
.note-warn b { color: var(--loss-text); }

.field { margin-bottom: 9px; }
.field label {
  display: block;
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted-2);
  margin-bottom: 3px;
}
.field input, .field select, .field textarea {
  width: 100%;
  padding: 6px 9px;
  border-radius: var(--r-sm);
  border: 1px solid var(--rule);
  background: var(--surface-2);
  color: var(--text);
  font: inherit;
  font-size: 13px;
}
.field textarea { min-height: 62px; resize: vertical; }
.field-hint { font-family: var(--mono); font-size: 10.5px; color: var(--muted); }
.field-hint.bad { color: var(--loss); }

.btn-row { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.btn {
  padding: 6px 12px;
  border-radius: var(--r-sm);
  border: 1px solid var(--rule);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: 12.5px;
  cursor: pointer;
}
.btn:hover:not(:disabled) { border-color: var(--accent-line); }
.btn:disabled { opacity: .5; cursor: default; }
.btn-primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn-primary:hover:not(:disabled) { background: var(--accent-2); border-color: var(--accent-2); }

.adj-table { width: 100%; border-collapse: collapse; font-size: 11.5px; margin-top: 8px; }
.adj-table th {
  text-align: left;
  font-family: var(--mono);
  font-size: 9.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted-2);
  padding: 4px 6px;
}
.adj-table td { padding: 4px 6px; border-top: 1px solid var(--rule-soft); vertical-align: top; }

.activity-list { list-style: none; margin: 0; padding: 0; }
.activity-item { padding: 7px 0; border-top: 1px solid var(--rule-soft); font-size: 12.5px; }
.activity-item:first-child { border-top: 0; }
.a-kind {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent);
}
.a-meta { margin-top: 2px; font-size: 11px; color: var(--muted); }
.activity-empty { font-size: 12px; color: var(--muted); margin: 4px 0 0; }

/* ============================================================ toast */
.toast {
  position: fixed;
  left: 50%;
  bottom: 26px;
  transform: translateX(-50%);
  z-index: 80;
  padding: 9px 16px;
  border-radius: var(--r-sm);
  background: var(--rail);
  color: #fff;
  font-size: 13px;
  box-shadow: var(--sh-3);
}
.toast-error { background: var(--loss); }

.kbd {
  font-family: var(--mono);
  font-size: 10.5px;
  padding: 1px 5px;
  border-radius: var(--r-xs);
  border: 1px solid var(--rule);
  background: var(--surface-2);
  color: var(--muted);
}

@media print {
  .rail, .rail-toggle, .filterbar, .datestrip, .drawer, .toast { display: none !important; }
  .content { padding-left: 0; }
  .viewbar { position: static; }
  body { background: #fff; }
}

/* ==========================================================================
   Stage 1 — intake.

   The dropzone is deliberately large and deliberately the only thing on the
   page until something is dropped on it. This is the first screen a new
   operator sees and the only action worth taking on it.
   ========================================================================== */
.dropzone {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 44px 24px;
  border: 2px dashed var(--rule);
  border-radius: var(--r);
  background: var(--surface);
  cursor: pointer;
  text-align: center;
  transition: border-color .15s ease, background .15s ease;
}
.dropzone:hover, .dropzone:focus-visible, .dropzone.over {
  border-color: var(--accent);
  background: var(--accent-soft);
  outline: none;
}
.dz-icon { font-size: 26px; color: var(--accent); line-height: 1; }
.dz-main { font-size: 15px; font-weight: 600; }
.dz-sub { font-size: 12px; color: var(--muted); max-width: 60ch; }

.filelist { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.filechip {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 5px 6px 5px 11px;
  border: 1px solid var(--rule);
  border-radius: 20px;
  background: var(--surface);
  font-size: 12.5px;
}
.fc-name { font-weight: 500; }
.fc-size { font-size: 11px; color: var(--muted); }
.fc-x {
  border: 0;
  background: transparent;
  color: var(--muted);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  padding: 0 4px;
}
.fc-x:hover { color: var(--loss); }

.runbar {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 12px;
  margin-top: 16px;
  padding: 14px 16px;
  border: 1px solid var(--rule);
  border-radius: var(--r);
  background: var(--surface);
}
.btn-lg { padding: 9px 20px; font-size: 14px; font-weight: 600; }

/* The stage bar tracks the pipeline's OWN stage names, so it cannot drift out
   of step with what is actually running. */
.stagebar { display: flex; flex-wrap: wrap; gap: 4px; }
.stage {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px 4px 6px;
  border-radius: 20px;
  font-size: 11.5px;
  color: var(--muted-2);
  background: var(--surface-2);
}
.stage-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--rule);
  flex: none;
}
.stage.done { color: var(--recover-text); background: var(--recover-bg); }
.stage.done .stage-dot { background: var(--recover); }
.stage.active { color: #fff; background: var(--accent); font-weight: 600; }
.stage.active .stage-dot { background: #fff; animation: pulse 1.1s ease-in-out infinite; }
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }
@media (prefers-reduced-motion: reduce) { .stage.active .stage-dot { animation: none; } }

/* ==========================================================================
   Stage 5 — chases. A list beside the thread it opens, because reading a
   chase means reading what was asked and what came back, together.
   ========================================================================== */
.split { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 14px; }
@media (max-width: 1100px) { .split { grid-template-columns: 1fr; } }
.split-list { min-width: 0; }
.split-detail {
  min-width: 0;
  align-self: start;
  position: sticky;
  top: 92px;
  max-height: calc(100vh - 110px);
  overflow-y: auto;
}
.split-detail > * + * { margin-top: 10px; }

.mailbody {
  margin: 8px 0 0;
  padding: 10px 12px;
  border-radius: var(--r-sm);
  background: var(--surface-2);
  border: 1px solid var(--rule-soft);
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1.55;
  white-space: pre-wrap;
  word-break: break-word;
}
/* An inbound message is visually distinct from an outbound one: reading a
   thread and mistaking our own words for theirs is how a chase gets closed on
   evidence nobody sent. */
.msg-in { border-left: 3px solid var(--recover); }
.msg-out { border-left: 3px solid var(--flight); }

.linkish {
  border: 0;
  background: transparent;
  padding: 0;
  font: inherit;
  color: inherit;
  text-decoration: underline;
  cursor: pointer;
}


/* ==========================================================================
   Sign in. Covers the application rather than replacing it, so an expired
   session returns the operator to the view they were on rather than to a
   landing page.
   ========================================================================== */
.gate {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: var(--paper);
}
.gate-panel {
  width: min(380px, 100%);
  padding: 28px;
  border: 1px solid var(--rule);
  border-radius: var(--r);
  background: var(--surface);
  box-shadow: var(--sh-3);
}
.gate-brand { margin-bottom: 18px; }
.gate-brand .rail-name { color: var(--text); font-size: 18px; }
.gate-brand .rail-sub { color: var(--muted); }
.gate-lead { margin: 0 0 18px; font-size: 13px; color: var(--muted); }
.gate .btn-row { margin-top: 16px; }
.gate .btn-lg { width: 100%; justify-content: center; }
#gate-error:empty { display: none; }


/* ==========================================================================
   Readiness. Two severities and they are not the same thing:

   `blocking` means a decision made here will be lost or is unattributable —
   it stays until it is fixed, and cannot be dismissed.
   `note` means a capability is off and the app behaves correctly without it.
   ========================================================================== */
.ready-strip { display: grid; gap: 8px; margin: 16px 0 0; }
.ready {
  display: flex;
  gap: 11px;
  padding: 11px 14px;
  border-radius: var(--r);
  border: 1px solid var(--rule);
  background: var(--surface);
  font-size: 13px;
  line-height: 1.5;
}
.ready-blocking { border-color: var(--loss); background: var(--loss-bg); color: var(--loss-text); }
.ready-blocking b { color: var(--loss-text); }
.ready-note { border-color: var(--rule); background: var(--surface-2); color: var(--muted); }
.ready-mark { flex: none; font-family: var(--mono); font-weight: 700; }
.ready-fix {
  display: block;
  margin-top: 4px;
  font-family: var(--mono);
  font-size: 11.5px;
  opacity: .85;
}

/* ============================================================== cases

   A restaurant-level case outranks every daily row on the page, and its
   styling says so: a heavier left edge coloured by severity, the money set
   large, and the note kept visible rather than folded away. The whole point of
   the rollup is that the reader meets the $21,854 pattern before the $3,916
   day that is part of it — a case that looks like just another row would
   undo that in the one place it matters. */
.cases { display: grid; gap: 10px; margin-bottom: 6px; }
.case {
  display: block;
  width: 100%;
  padding: 14px 16px;
  border: 1px solid var(--rule);
  border-left: 4px solid var(--muted);
  border-radius: var(--r);
  background: var(--surface);
  box-shadow: var(--sh-1);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.case:hover { box-shadow: var(--sh-2); border-color: var(--accent-line); }
.case[data-severity="CRITICAL"] { border-left-color: var(--loss); }
.case[data-severity="HIGH"]     { border-left-color: var(--correct); }
.case[data-severity="MEDIUM"]   { border-left-color: var(--accent-line); }
.case-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.case-title { font-size: 15px; font-weight: 600; color: var(--text); }
.case-body {
  display: flex;
  align-items: baseline;
  gap: 12px;
  flex-wrap: wrap;
  margin-top: 8px;
}
.case-amt {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  font-size: 20px;
  font-weight: 600;
}
.case-meta { font-size: 12px; color: var(--muted); }
.case-note {
  margin: 8px 0 0;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--muted);
}

/* Severity reads at a glance or it does not do its job. CRITICAL is the only
   one drawn in the loss colour — if three levels all shout, none of them
   does. */
.tag-sev[data-severity="CRITICAL"] {
  border-color: var(--loss);
  color: var(--loss-text);
  background: var(--loss-bg);
}
.tag-sev[data-severity="HIGH"] {
  border-color: var(--correct);
  color: var(--correct-text);
  background: var(--correct-bg);
}

/* The reason a variance was not raised, on the row that was not raised. Set
   quietly — it is context for a row nobody has to act on, not a warning. */
.tracked-why {
  display: block;
  margin-top: 4px;
  max-width: 52ch;
  line-height: 1.45;
  font-style: italic;
  opacity: 0.85;
}

/* ========================================================================== ASK

   Analyst Q&A. Built from the same tokens as everything else, so it reads as a
   view of the period rather than a chat widget bolted onto one.

   THE VISUAL HIERARCHY IS DELIBERATE AND IT IS NOT THE CHAT'S. In a messaging
   app the message is the content. Here the message is a claim about money and
   the RECORDS are the content, so the grounding panel gets a real border, a
   real surface and full-width tables, while the prose stays measured text. An
   answer that looks more authoritative than its evidence is the exact failure
   this app is built to prevent.
   ========================================================================== */

.ask-log {
  display: flex;
  flex-direction: column;
  gap: 18px;
  margin: 18px 0;
}

.ask-turn { display: flex; flex-direction: column; gap: 6px; }

.ask-who {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--muted-2);
}

.ask-said {
  max-width: 74ch;
  font-size: 14px;
  line-height: 1.6;
  color: var(--text);
  white-space: pre-wrap;
}

/* The analyst's own question, set back rather than forward. It is the least
   uncertain thing on the page and needs the least emphasis. */
.ask-turn-you .ask-said {
  padding: 10px 14px;
  border-left: 2px solid var(--accent-line);
  background: var(--surface-2);
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  color: var(--text-2);
}

.ask-pending { color: var(--muted); font-style: italic; }
.ask-error { color: var(--loss-text); }
/* Context under a failed answer — why it failed, what is unaffected, and how
   long until it is worth asking again. Quiet: it explains a setback, it is not
   a second one. */
.ask-note {
  margin-top: 6px;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--muted);
}

.ask-declined {
  max-width: 74ch;
  margin-top: 2px;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--muted);
}

/* How the question was READ, sitting with the answer rather than inside the
   collapsed grounding panel. Marked but not alarming: a re-scoped question is
   not an error, it is a fact about which answer you are looking at. */
.ask-scope {
  max-width: 74ch;
  margin-top: 6px;
  padding-left: 9px;
  border-left: 2px solid var(--rule);
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--muted);
}

/* Labels on an answer that is not what it appears to be. Both are the kind of
   thing a reader must not be able to miss while skimming. */
.ask-tag {
  align-self: flex-start;
  padding: 3px 9px;
  border: 1px solid;
  border-radius: var(--r-xs);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
}
.ask-tag-warn { border-color: var(--correct); color: var(--correct-text); background: var(--correct-bg); }
.ask-tag-bad  { border-color: var(--loss);    color: var(--loss-text);    background: var(--loss-bg); }

/* ------------------------------------------------------- grounding panel */
.ask-grounding {
  max-width: 100%;
  margin-top: 4px;
  border: 1px solid var(--rule);
  border-radius: var(--r-sm);
  background: var(--surface);
  box-shadow: var(--sh-1);
}

.ask-grounding > summary {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 13px;
  cursor: pointer;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text-2);
  list-style: none;
}
.ask-grounding > summary::-webkit-details-marker { display: none; }
.ask-grounding > summary::before {
  content: "▸";
  font-size: 10px;
  color: var(--muted-2);
  transition: transform .12s ease;
}
.ask-grounding[open] > summary::before { transform: rotate(90deg); }
.ask-grounding[open] > summary { border-bottom: 1px solid var(--rule-soft); }

/* A restaurant-level case in scope is the one thing worth pulling someone into
   the panel for, so it is advertised on the closed summary. */
.ask-grounding-flag {
  margin-left: auto;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--correct-bg);
  color: var(--correct-text);
  font-size: 11px;
  font-weight: 700;
}

.ask-filters {
  margin: 0;
  padding: 10px 13px 0;
  font-size: 12px;
  line-height: 1.5;
  color: var(--muted);
}

.ask-grounding .tablewrap { margin: 10px 0 0; border: 0; }
.ask-grounding .footnote { padding: 0 13px 10px; }
.ask-grounding .empty { padding: 16px 13px; }

/* CASES ABOVE DAILY ROWS, in the markup and here. A store short by the same
   percentage every day is one problem, not seven. */
.ask-findings { padding: 10px 13px 2px; display: flex; flex-direction: column; gap: 10px; }

.ask-finding {
  padding: 10px 12px;
  border: 1px solid var(--correct);
  border-left-width: 3px;
  border-radius: var(--r-sm);
  background: var(--correct-bg);
}
.ask-finding-head { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
.ask-finding-store { font-weight: 700; font-size: 13px; color: var(--text); }
.ask-finding-sev {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .04em;
  color: var(--correct-text);
}
.ask-finding-note {
  margin-top: 5px;
  max-width: 70ch;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--text-2);
}
.ask-finding-meta { margin-top: 5px; font-size: 11.5px; color: var(--muted); }

/* ------------------------------------------------------- period context */
/* The two counts that are never published apart. Rendered on every answer, not
   once at the top, so a figure can never be read against a period the reader
   has scrolled away from. */
.ask-context {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px 22px;
  margin-top: 8px;
  padding: 9px 13px;
  border: 1px solid var(--rule-soft);
  border-radius: var(--r-sm);
  background: var(--surface-2);
}
.ask-context-period {
  font-family: var(--mono);
  font-size: 11.5px;
  color: var(--muted-2);
}
.ask-context-cells { display: flex; flex-wrap: wrap; gap: 8px 22px; }
.ask-ctx { display: flex; align-items: baseline; gap: 6px; }
.ask-ctx-value {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  font-size: 14px;
  font-weight: 700;
  color: var(--text);
}
.ask-ctx-label { font-size: 12px; color: var(--text-2); }
.ask-ctx-note { font-size: 11px; color: var(--muted-2); }

/* ------------------------------------------------------------ suggestions */
.ask-suggest { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 14px 0; }
.ask-suggest-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--muted-2);
}
.ask-chip {
  padding: 6px 12px;
  border: 1px solid var(--rule);
  border-radius: 999px;
  background: var(--surface);
  color: var(--text-2);
  font: inherit;
  font-size: 12.5px;
  cursor: pointer;
  text-align: left;
}
.ask-chip:hover { border-color: var(--accent-line); color: var(--text); background: var(--accent-soft); }

/* --------------------------------------------------------------- opening */
.ask-opening {
  padding: 16px 18px;
  border: 1px dashed var(--rule);
  border-radius: var(--r-sm);
  background: var(--surface-2);
}
.ask-opening-lead { max-width: 78ch; margin: 0; font-size: 13px; line-height: 1.6; color: var(--text-2); }
.ask-opening-head {
  margin: 14px 0 6px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--muted-2);
}
.ask-opening-list { margin: 0; padding-left: 18px; max-width: 78ch; }
.ask-opening-list li { font-size: 12.5px; line-height: 1.6; color: var(--muted); }

/* -------------------------------------------------------------- composer */
.ask-composer {
  position: sticky;
  bottom: 0;
  padding: 14px 0 10px;
  background: var(--paper);
  border-top: 1px solid var(--rule);
}
.ask-label {
  display: block;
  margin-bottom: 6px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--muted-2);
}
.ask-input {
  width: 100%;
  padding: 11px 13px;
  border: 1px solid var(--rule);
  border-radius: var(--r-sm);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: 14px;
  line-height: 1.5;
  resize: vertical;
}
.ask-input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.ask-composer-foot {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 12px;
  margin-top: 8px;
}
.ask-count { font-family: var(--mono); font-size: 11.5px; color: var(--muted-2); }

.ask-foot {
  max-width: 78ch;
  margin: 12px 0 0;
  font-size: 12px;
  line-height: 1.6;
  color: var(--muted);
}

@media print {
  /* The composer is an input; the transcript is the record. */
  .ask-composer, .ask-suggest { display: none; }
  .ask-grounding[open] > summary::before { content: ""; }
}

/* A case about another money path is context, not the answer. Set back from a
   case that IS the answer, because cash and credit are never netted anywhere
   else in this system and must not read as interchangeable here either. */
.ask-finding-aside {
  border-color: var(--rule);
  border-left-color: var(--flight);
  background: var(--surface-2);
}
.ask-finding-aside .ask-finding-sev { color: var(--muted); }
.ask-finding-lane {
  margin-top: 5px;
  font-size: 11.5px;
  font-weight: 600;
  line-height: 1.5;
  color: var(--flight-text);
}
