/* main.css -- v3's chrome. TRANSCRIBED FROM mis-anka, NOT APPROXIMATED.

   Sanjiv, 2026-08-15: "I want the app and the UI for MIS duplicated for v3. Not only the
   number of tabs, but the look and feel of each tab should be the same."

   SOURCE: C:/Dev/mis-anka/web/static/css/main.css, sha256:43d7b6d7de9a, copied BYTE FOR BYTE
   below this header. Not "inspired by", not re-derived from screenshots -- the same file.
   mis-anka's own header says it transcribed anka-mis's :root and dashboard.html the same
   way, and for the same reason: two apps that approximate one another's surface diverge
   on the first change nobody notices, and then the two screens disagree about what the
   business looks like while both claim to be MIS.

   WHY COPYING IS SAFE HERE AND WOULD NOT BE FOR A RULE. This file carries NO NUMBERS AND
   NO LOGIC -- mis-anka's own header states that, and it is verifiable: 212 selectors, no
   arithmetic, no data. A duplicated RULE is the defect this repository has found six times
   (the income BU map, the Auction pool, the supervisory weights, and three more). A
   duplicated STYLESHEET cannot move a figure. The whole point of the "no figure computed
   twice" rule is that the second copy can DISAGREE; a border radius cannot.

   TO RE-SYNC: re-run the copy, do not hand-edit. Any v3-only rule belongs in the ADDITIONS
   block at the foot of this file, so the transcribed region stays a pure copy and the diff
   against mis-anka stays readable.
*/

/* main.css — palette and chrome, read from anka-mis @3596138 this session:
   static/css/main.css :root (16 tokens + the --dash-* additive set) and
   templates/dashboard.html <style> (lines 5-239). Values are transcribed, not
   approximated, so the two apps render the same surface.

   THIS FILE CARRIES NO NUMBERS AND NO LOGIC. Design decision 7 — the engine computes
   once and stores; the view reads. Styling cannot move a figure. */

:root {
  --bg: #eef0f5;
  --bg-elev: #ffffff;
  --bg-card: #ffffff;
  --border: #d0d7de;
  --text: #24292f;
  --text-dim: #57606a;
  --text-bright: #1f2328;
  --accent: #0969da;
  --accent-dim: #0550ae;
  --green: #1a7f37;
  --red: #cf222e;
  --amber: #9a6700;

  --dash-pos: #10b981;
  --dash-accent: #3b82f6;
  --dash-row-hover: #f0f4ff;
  --dash-row-rule: #f0f0f0;
  --dash-card-radius: 12px;
  --dash-card-shadow: 0 2px 8px rgba(0, 0, 0, 0.07);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  font-size: 14px;
}

.container { max-width: 1800px; margin: 0 auto; padding: 16px 24px; }

/* ── Nav bar — white with shadow, no flat border ─────────────────────────── */
.topbar {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  background: #ffffff;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
  border: none;
  border-radius: 12px; padding: 12px 18px; margin-bottom: 20px;
}
.topbar .wordmark { font-weight: 700; font-size: 18px; color: var(--text-bright); margin-right: 8px; }
.topbar .pill {
  padding: 4px 10px; background: var(--bg); border: 1px solid var(--border);
  border-radius: 999px; color: var(--text-dim); font-size: 12px; font-family: monospace;
}
.topbar .spacer { flex: 1; }
.topbar a { color: var(--text-dim); text-decoration: none; font-size: 13px; }
.topbar a:hover { color: var(--accent); }

/* ── KPI strip ──────────────────────────────────────────────────────────── */
.kpi-strip { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; margin-bottom: 20px; }
.kpi {
  background: #ffffff;
  box-shadow: 0 1px 0 rgba(0,0,0,0.05), 0 4px 16px rgba(0,0,0,0.10), 0 8px 24px rgba(0,0,0,0.06);
  border: none;
  border-bottom: 3px solid rgba(0, 0, 0, 0.10);
  border-radius: 12px;
  padding: 16px 18px;
  border-top: 3px solid transparent;
  transition: transform 0.2s, box-shadow 0.2s;
  cursor: default;
}
.kpi:hover { transform: translateY(-4px); box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15); }
.kpi.kpi-revenue   { border-top-color: #3b82f6; }
.kpi.kpi-opprofit  { border-top-color: #10b981; }
.kpi.kpi-netprofit { border-top-color: #6366f1; }
.kpi.kpi-hc        { border-top-color: #64748b; }
.kpi-label {
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.6px;
  color: var(--text-dim); margin-bottom: 6px;
}
.kpi-value { font-size: 22px; font-weight: 700; color: var(--text-bright); margin-bottom: 6px; }
.kpi-value.pos { color: #10b981; }
.kpi-value.neg { color: var(--red); }
.kpi-sub { font-size: 13px; margin-left: 6px; color: var(--text-dim); font-weight: 400; }
.kpi-delta { font-size: 11px; line-height: 1.5; }
.kpi-delta-row { display: block; }
.delta-pos { color: #10b981; }
.delta-neg { color: var(--red); }
.muted { color: var(--text-dim); }

/* ── Main view tabs — pill switcher ─────────────────────────────────────── */
.main-tabs {
  display: inline-flex; background: #f1f5f9; border-radius: 10px;
  padding: 4px; margin-bottom: 20px; gap: 0; border: none;
}
.main-tab {
  padding: 8px 24px; border: none; background: transparent;
  color: #6b7280; cursor: pointer; font-size: 14px; font-weight: 500;
  border-radius: 8px; transition: all 0.15s;
}
.main-tab.active {
  background: #ffffff; color: #1d4ed8; font-weight: 600;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.12);
}
.main-tab:hover:not(.active) { color: var(--text-bright); }

/* ADMIN LINKS IN THE TAB STRIP. Deliberately NOT .main-tab: that class is bound by
   querySelectorAll('.main-tab') to the pane switcher, so a Users button carrying it would
   try to reveal a pane that does not exist. These LEAVE the page, so they are anchors and
   are separated by a rule to say so. */
.main-tab-sep {
  width: 1px; align-self: stretch; margin: 4px 6px; background: #d7dee8;
}
.main-tab-link {
  padding: 8px 18px; color: #6b7280; text-decoration: none; font-size: 14px;
  font-weight: 500; border-radius: 8px; transition: all 0.15s; display: inline-flex;
  align-items: center;
}
.main-tab-link:hover { color: #1d4ed8; background: #ffffff; }

/* BACK TO THE DASHBOARD, on every admin page. Was a small "statement" link inside a line
   of page metadata — the same size and colour as the username beside it, so it read as a
   label rather than the way out. These pages are dead ends without it: they carry no tab
   strip of their own. A button-shaped control, first thing on the page, identical on all
   three. */
.admin-bar {
  display: flex; align-items: center; gap: .75rem; flex-wrap: wrap;
  margin: 0 0 1.25rem;
}
.btn-home {
  display: inline-flex; align-items: center; gap: .4rem; padding: .45rem .9rem;
  background: #1d4ed8; color: #fff; text-decoration: none; border-radius: 6px;
  font-size: .85rem; font-weight: 600; transition: background .15s;
}
.btn-home:hover { background: #1740b0; color: #fff; }
.admin-who { font-size: .82rem; color: #666; }
.admin-who a { color: #1d4ed8; }

/* ── Full P&L statement ─────────────────────────────────────────────────── */
.pnl-statement {
  background: var(--bg-card);
  box-shadow: var(--dash-card-shadow);
  border: none;
  border-radius: var(--dash-card-radius);
  padding: 28px 32px;
}
.pnl-statement h2 {
  margin: 0 0 4px 0; font-size: 12px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.5px; color: var(--text-dim);
}
.pnl-statement h2 .ttl-accent { color: var(--dash-accent); }
.pnl-statement .pnl-sub { font-size: 12px; color: var(--text-dim); margin-bottom: 24px; }

table.pnl-full { width: 100%; border-collapse: collapse; font-size: 13px; }
table.pnl-full th {
  padding: 10px 14px; text-align: left; border-bottom: 2px solid var(--border);
  font-size: 11px; color: var(--text-dim); text-transform: uppercase;
  letter-spacing: 0.5px; font-weight: 600; background: #f8fafc;
}
table.pnl-full th.num { text-align: right; }
table.pnl-full td { padding: 9px 14px; border-bottom: 1px solid #e8ecf0; }
table.pnl-full td.num { text-align: right; font-family: monospace; }
table.pnl-full td.ytd { text-align: right; font-family: monospace; color: var(--text-dim); }

/* Alternating rows: odd white, even #f7f9fc */
table.pnl-full tbody tr:nth-child(odd):not(.pnl-hl):not(.pnl-sub):not(.pnl-blank):not(.pnl-pos-hl):not(.pnl-neg-hl) td { background: #ffffff; }
table.pnl-full tbody tr:nth-child(even):not(.pnl-hl):not(.pnl-sub):not(.pnl-blank):not(.pnl-pos-hl):not(.pnl-neg-hl) td { background: #f7f9fc; }
table.pnl-full tr.pnl-blank td { border-bottom: none; height: 12px; background: transparent !important; }

/* Section total rows — highlighted, left coloured bar */
table.pnl-full tr.pnl-hl td {
  background: #e8f0fe; font-weight: 600; color: var(--text-bright);
  border-top: 2px solid #cbd5e1; padding-left: 16px;
}
table.pnl-full tr.pnl-hl td:first-child { border-left: 4px solid #3b82f6; padding-left: 14px; }
table.pnl-full tr.pnl-hl td.ytd { color: #5c7db5; }

/* Result bands — positive */
table.pnl-full tr.pnl-pos-hl td {
  background: #dcfce7 !important; color: #14532d;
  font-weight: 700; font-size: 15px; border-top: 2px solid #86efac;
}
table.pnl-full tr.pnl-pos-hl td:first-child { border-left: 4px solid #10b981; padding-left: 14px; }
/* Result bands — negative */
table.pnl-full tr.pnl-neg-hl td {
  background: #fee2e2 !important; color: #7f1d1d;
  font-weight: 700; font-size: 15px; border-top: 2px solid #fca5a5;
}
table.pnl-full tr.pnl-neg-hl td:first-child { border-left: 4px solid #ef4444; padding-left: 14px; }

/* Subtotals */
table.pnl-full tr.pnl-sub td { font-weight: 600; background: #e8f0fe; border-top: 2px solid #cbd5e1; }
table.pnl-full tr.pnl-sub td:first-child { border-left: 4px solid #3b82f6; padding-left: 14px; }

/* Indented sub-items */
table.pnl-full tr.pnl-indent td:first-child { padding-left: 32px; color: #4b5563; font-size: 13px; }
table.pnl-full tr:hover:not(.pnl-blank):not(.pnl-hl):not(.pnl-sub):not(.pnl-pos-hl):not(.pnl-neg-hl) td { background: #f0f4ff !important; }

table.pnl-full tr.expand-row td { background: #fafbfc !important; }
table.pnl-full tr.clickable { cursor: pointer; }
.caret { display: inline-block; width: 14px; color: var(--text-dim); }

/* ── P&L toolbar: comparison month + collapse all / expand all ──────────────
   The comparison selector is a GET form so the choice lives in the URL. The fold
   buttons are not: which lines are folded is a view preference and nothing here
   persists one. */
.pnl-toolbar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin: 0 0 12px 0; font-size: 12px;
}
.pnl-toolbar .tb-spacer { flex: 1 1 auto; }
.cmp-form { display: flex; align-items: center; gap: 7px; }
.cmp-form label { color: var(--text-dim); }
.cmp-form select {
  font-size: 12px; padding: 5px 8px; border: 1px solid #cbd5e1;
  border-radius: 6px; background: #fff; color: var(--text); font-family: inherit;
}
.fold-btn {
  font-size: 12px; padding: 5px 11px; border: 1px solid #cbd5e1; border-radius: 6px;
  background: #fff; color: var(--text); cursor: pointer; font-family: inherit;
}
.fold-btn:hover { border-color: var(--accent); color: var(--accent); }
.fold-btn:focus-visible,
.cmp-form select:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* THE FOLD CONTROL IS A REAL BUTTON, not a styled span: a <details>/<summary> cannot
   wrap <tr> siblings, so keyboard operability and the announced expanded/collapsed
   state have to come from the control itself. It is stripped back to look like the
   caret it replaces. */
.fold-tog {
  background: none; border: 0; padding: 0; margin: 0; cursor: pointer;
  font: inherit; color: inherit; line-height: inherit;
}
.fold-tog:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.fold-tog:hover .caret { color: var(--accent); }

/* ── OWNERSHIP IS VISIBLE, WHETHER OR NOT THE OWNER CAN FOLD ────────────────
   Collapsing Total Support Staff (D) LOOKED broken because the rows that followed —
   the not-in-(E) block, then E's own components — carried no sign of belonging to
   anything, so they read as D's leftovers. The walk was right; the page said nothing.
   Every owned row now carries a left rule and a deeper indent, so a headline's
   components are visibly its own even in a month where it cannot fold. */
/* THE BRACKET. It OPENS at the group header, runs down every owned row, and visibly
   CLOSES at the subtotal, so a reader scanning downward is told whose rows these are at
   the first one rather than the last. The indent alone was not enough: it says "these
   belong to something", not "these belong to (E)". */
table.pnl-full tr.grp-owned td:first-child,
table.pnl-full tr.grp-open td:first-child,
table.pnl-full tr.grp-end td:first-child {
  box-shadow: inset 3px 0 0 -1px #9db4cd;
}
table.pnl-full tr.grp-owned td:first-child { padding-left: 38px; }
table.pnl-full tr.grp-owned:hover td:first-child { box-shadow: inset 3px 0 0 -1px var(--accent); }
/* The subtotal keeps its own 4px accent border, so the bracket closes against it
   rather than doubling it. */
table.pnl-full tr.grp-end td:first-child { box-shadow: none; }

/* The group header — opens the bracket, names the group, carries the fold control. */
table.pnl-full tr.grp-head td {
  padding: 9px 14px 6px 14px; background: #eef3f9 !important;
  border-top: 2px solid #cbd5e1; border-bottom: 1px solid #dbe3ec;
  font-size: 12px; font-weight: 600; color: #33475e; letter-spacing: .01em;
}
table.pnl-full tr.grp-head .grp-count {
  float: right; font-weight: 400; font-size: 11px; color: var(--text-dim);
  letter-spacing: .02em;
}
@media (max-width: 900px) {
  table.pnl-full tr.grp-head .grp-count { float: none; display: block; }
}

/* The "Deducted at EBITDA, not part of (E)" subheading. Deliberately quiet and
   deliberately unmissable: it is the only thing standing between a reader and the
   assumption that these three lines are inside the subtotal beneath them. */
table.pnl-full tr.grp-sub td {
  padding: 5px 14px 5px 38px; font-size: 11px; letter-spacing: .04em;
  text-transform: uppercase; color: var(--text-dim); background: #f4f7fb !important;
  border-bottom: 1px solid #e8ecf0;
}
/* The block summary — what the three lines become when the host folds. */
table.pnl-full tr.grp-blocksum td { background: #f4f7fb !important; color: #4b5563; }
table.pnl-full tr.grp-blocksum td:first-child { padding-left: 38px; font-style: italic; }

/* ── SLICES ─────────────────────────────────────────────────────────────────
   The warning is sized like content, not like a footnote. A cost breakdown that
   reads as a P&L and is missing overhead is worse than not shipping it, so what
   these are NOT sits above the numbers at the same weight. */
.slice-warn {
  font-size: 13px; line-height: 1.65; color: #7c2d12;
  background: #fff7ed; border: 1px solid #fed7aa; border-left: 4px solid #ea580c;
  padding: 12px 14px; border-radius: 0 8px 8px 0; margin: 4px 0 18px 0;
}
.slice-h { font-size: 15px; margin: 26px 0 6px 0; color: var(--text); }
.slice-note {
  font-size: 12px; color: var(--text-dim); line-height: 1.6;
  background: #f7f9fc; border-left: 3px solid #cbd5e1;
  padding: 8px 12px; border-radius: 0 6px 6px 0; margin-bottom: 10px;
}

.why-link {
  cursor: pointer; color: var(--accent); text-decoration: underline;
  text-underline-offset: 2px; margin-left: 4px;
}
.pnl-note-tight { padding: 7px 12px; line-height: 1.5; }

/* Explanatory note above the statement — the fold default and the n/m rule are both
   stated on screen rather than left to be inferred from behaviour. */
.pnl-note {
  font-size: 12px; color: var(--text-dim); line-height: 1.65;
  background: #f7f9fc; border-left: 3px solid #cbd5e1;
  padding: 9px 12px; border-radius: 0 6px 6px 0; margin-bottom: 12px;
}
.pnl-note code {
  font-family: monospace; font-size: 11px; background: #eef2f7;
  padding: 1px 4px; border-radius: 3px;
}

/* Comparison columns. Colour is GOOD/BAD, never up/down — a cost that rose is red. */
table.pnl-full td.cmp-col { text-align: right; font-family: monospace; color: var(--text-dim); }
table.pnl-full td.chg-good { color: #047857; }
table.pnl-full td.chg-bad  { color: #b91c1c; }
table.pnl-full tr.pnl-hl td.chg-good,
table.pnl-full tr.pnl-sub td.chg-good { color: #065f46; font-weight: 600; }
table.pnl-full tr.pnl-hl td.chg-bad,
table.pnl-full tr.pnl-sub td.chg-bad  { color: #991b1b; font-weight: 600; }
table.pnl-full.has-cmp { font-size: 12.5px; }
table.pnl-full.has-cmp td, table.pnl-full.has-cmp th { padding: 8px 9px; }

/* ── Quiet data-quality one-liner ───────────────────────────────────────── */
.dq-line {
  font-size: 12px; color: var(--text-dim); margin-bottom: 14px;
  padding: 8px 12px; background: #ffffff; border-radius: 8px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
}
.dq-line a { color: var(--accent); text-decoration: none; cursor: pointer; }
.dq-line a:hover { text-decoration: underline; }
.dq-detail { margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--border); }
.dq-detail ul { margin: 0; padding-left: 18px; }
.dq-detail li { margin: 3px 0; }

.empty { text-align: center; padding: 60px 20px; color: var(--text-dim); }
.empty h2 { color: var(--text-bright); }

/* ── Client View: anka's two-panel ClientPanel + DetailPanel ──────────────────── */
/* THE PAGE SCROLLS, NOT THE PANEL — anka's .grid2, which carries no height rule at all.
   The left column was 400px fixed with `max-height: 78vh; overflow-y: auto`, so the
   roster scrolled inside its own box and the page could never be taller than the detail
   panel. That is what stopped the view reaching the bottom. `align-items: start` is gone
   too: without it the two columns stretch to a common height, as anka's default grid
   alignment does. 38% fluid, not a fixed pixel width. */
.client-grid { display: grid; grid-template-columns: 38% 1fr; gap: 14px; }

/* ── BU summary, at the foot of the client roster ─────────────────────────────── */
.bu-summary { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--border); }
.bu-summary table { width: 100%; font-size: 11px; border-collapse: collapse; }
.bu-summary th { color: var(--text-dim); font-weight: 500; font-size: 10px;
                 text-transform: uppercase; letter-spacing: 0.4px; padding: 4px 6px;
                 text-align: left; }
.bu-summary td { padding: 4px 6px; }
.bu-summary th.num, .bu-summary td.num { text-align: right; }
.bu-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%;
          margin-right: 6px; vertical-align: middle; }
.bu-total td { border-top: 1px solid var(--border); font-weight: 600;
               color: var(--text-bright); padding-top: 6px; }
/* The em-dash is a statement that the figure is ABSENT, not zero. Dimmed so it reads as
   "nothing here" rather than as a value. */
.no-rev { color: var(--text-dim); cursor: help; }

/* ── 12-month trend, full width below the grid ────────────────────────────────── */
.trend-wrap { margin-top: 14px; }
.trend-svg { width: 100%; height: 240px; display: block; }
.trend-grid { stroke: var(--border); stroke-width: 1; }
.trend-tick { fill: var(--text-dim); font-size: 10px; }
.trend-line { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.trend-dot { cursor: pointer; }
.trend-dot:hover { r: 5; }
.chart-legend { display: flex; gap: 14px; font-size: 11px; color: var(--text-dim);
                margin: 6px 0 4px 0; }
.chart-legend-line { display: inline-block; width: 14px; height: 2px;
                     margin-right: 5px; vertical-align: middle; }
.client-search {
  width: 100%; box-sizing: border-box; padding: 8px 10px; margin-bottom: 10px;
  border: 1px solid var(--border); border-radius: 6px; font-size: 13px;
  background: var(--bg-elev); color: var(--text);
}
.client-search:focus { outline: none; border-color: var(--dash-accent); }
.client-row {
  display: grid; grid-template-columns: 1fr auto; gap: 2px 10px;
  padding: 9px 10px; border-bottom: 1px solid var(--dash-row-rule);
  cursor: pointer; border-left: 3px solid transparent; font-size: 13px;
}
.client-row:hover { background: var(--dash-row-hover); }
.client-row.active { background: #e8f0fe; border-left-color: var(--dash-accent); }
.client-row .client-code { font-weight: 600; color: var(--text-bright); }
.client-row .client-meta { font-size: 11px; color: var(--text-dim); line-height: 1.6; }
.client-row .num { text-align: right; font-family: monospace; font-size: 12px; }
.tag-noassoc { color: var(--amber); }
.margin-bar-wrap {
  display: block; width: 100%; height: 4px; margin-top: 3px;
  background: #e6e9ef; border-radius: 2px; overflow: hidden;
}
.margin-bar { display: block; height: 100%; border-radius: 2px; }
.margin-bar.mb-pos { background: var(--dash-pos); }
.margin-bar.mb-neg { background: var(--red); }
.client-none { padding: 20px; text-align: center; color: var(--text-dim); font-size: 13px; }
.client-header {
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: 16px; margin-bottom: 18px;
}
.client-np { font-size: 22px; font-weight: 700; font-family: monospace; }
.client-np.pos { color: var(--dash-pos); }
.client-np.neg { color: var(--red); }
.badge {
  display: inline-block; margin-left: 6px; padding: 1px 6px; border-radius: 10px;
  background: #eef1f6; border: 1px solid var(--border);
  font-size: 10px; color: var(--text-dim); font-weight: 400; vertical-align: middle;
}
/* A named absence, styled to read as a note rather than as a measured nil. */
table.pnl-full tr.pnl-belowline td { color: var(--text-dim); font-style: italic; }

@media (max-width: 1400px) {
  .client-grid { grid-template-columns: 1fr; }
  /* .client-list-panel's max-height override is gone with the rule it overrode. */
}
@media (max-width: 1100px) {
  .kpi-strip { grid-template-columns: repeat(2, 1fr); }
}

/* ── currency toggle ──────────────────────────────────────────────────────────
   Both stored currencies are rendered into the page; this decides which is shown.
   Purely a visibility switch — nothing is converted in the browser. */
.ccy-toggle { margin-left: auto; display: inline-flex; gap: 2px; align-self: center; }
.ccy-btn {
  font: inherit; font-size: 12px; letter-spacing: .04em; cursor: pointer;
  padding: 5px 12px; border: 1px solid var(--line, #2a3550);
  background: transparent; color: var(--muted, #8b97b4); border-radius: 4px;
}
.ccy-btn.active { background: var(--accent, #4a7cff); color: #fff; border-color: transparent; }
.m-usd { display: none; }
body.show-usd .m-inr { display: none; }
body.show-usd .m-usd { display: inline; }

/* ── roster sort tabs and the derived BU label ────────────────────────────────
   Presentation only. sortBy() reorders rows already rendered from stored values. */
.sort-tabs { display: flex; gap: 2px; margin: 6px 0 8px; flex-wrap: wrap; }
.sort-btn {
  font: inherit; font-size: 11px; cursor: pointer; padding: 3px 9px;
  border: 1px solid var(--line, #2a3550); background: transparent;
  color: var(--muted, #8b97b4); border-radius: 3px;
}
.sort-btn.active { background: var(--accent, #4a7cff); color: #fff; border-color: transparent; }
.client-bu { font-size: 11px; font-weight: 400; color: var(--muted, #8b97b4); }

/* ── AX Client economics ──────────────────────────────────────────────────────
   Wide table: it scrolls inside its own container so the page never scrolls
   sideways, and the Client column stays pinned while the metrics scroll. */
.ax-scroller { overflow-x: auto; }
table.ax th, table.ax td { white-space: nowrap; }
table.ax th.ax-stick, table.ax td.ax-stick {
  position: sticky; left: 0; z-index: 2; background: var(--panel, #131a2b);
}
table.ax th.ax-sortable { cursor: pointer; user-select: none; }
table.ax th.ax-sortable .ax-srt { opacity: .25; margin-left: 3px; font-size: 10px; }
table.ax th.ax-sorted { color: var(--text-bright, #e8edf7); }
table.ax th.ax-sorted .ax-srt { opacity: 1; }
table.ax .ax-grpstart { border-left: 2px solid var(--line, #2a3550); }
table.ax tr.ax-mgroup th { text-align: center; }

/* ── Clients master ───────────────────────────────────────────────────────────
   The two write affordances render disabled until auth exists (step 7). */
.cl-active { color: var(--pos, #3ecf8e); }
.cl-btn {
  font: inherit; font-size: 11px; padding: 2px 8px; border-radius: 3px;
  border: 1px solid var(--line, #2a3550); background: transparent;
  color: var(--muted, #8b97b4);
}
.cl-btn[disabled] { opacity: .4; cursor: not-allowed; }

/* ── LAYOUT: nothing scrolls the page sideways, no number breaks in half ───────
   Two defects visible at ~590px: the tab strip was `inline-flex` with no wrap, so
   seven tabs pushed the page wider than the viewport and the last label was cut
   mid-word; and amount cells had no white-space rule, so "₹4.91 Cr" broke across
   two lines. A currency figure split over a line break is misread at a glance,
   which on a financial statement is worse than being narrow. */

/* 1. Amounts never break. Applies to every table and to the roster rows. */
table.pnl-full td.num,
table.pnl-full td.ytd,
table.pnl-full th.num,
.client-row .num,
.client-np,
.kpi-value { white-space: nowrap; }

/* 2. The tab strip wraps inside its own box instead of widening the page. */
.main-tabs { flex-wrap: wrap; max-width: 100%; }
.ccy-toggle { margin-left: auto; }

/* 3. Wide tables scroll INSIDE their own container; the body never does.
   .ax-scroller already does this for AX; this generalises it. */
.pnl-statement { overflow-x: auto; }
html, body { overflow-x: hidden; }

@media (max-width: 700px) {
  /* At phone width the toggle belongs on its own line, not squeezed against a tab. */
  .ccy-toggle { margin-left: 0; width: 100%; justify-content: flex-end; }
  .main-tab { padding: 8px 14px; font-size: 13px; }
  .container { padding: 12px 12px; }
  table.pnl-full { font-size: 12px; }
  table.pnl-full td, table.pnl-full th { padding: 7px 8px; }
}

/* ── cost composition bar + the four client headline numbers ──────────────────
   anka dashboard.html:115-125, transcribed. Segment widths come from the server
   as percentages of Σ|v|; nothing is computed in the browser. */
.mini-kpis { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin: 14px 0 10px; }
.mini-kpi { background: #f7f9fc; border: 1px solid #e8ecf0; border-radius: 8px; padding: 8px 12px; }
.mini-kpi-v { font-size: 17px; font-weight: 600; white-space: nowrap; margin-top: 2px; }
.mini-kpi-v.pos { color: #10b981; }
.mini-kpi-v.neg { color: #ef4444; }
.cost-bar { display: flex; height: 12px; border-radius: 6px; overflow: hidden; background: #eef2f7; }
.cost-bar-seg { height: 100%; min-width: 1px; cursor: help; }
.cost-bar-seg.direct  { background: #3b82f6; }
.cost-bar-seg.support { background: #f59e0b; }
.cost-bar-seg.other   { background: #8b5cf6; }
.cost-bar-seg.profit  { background: #10b981; }
.cost-bar-seg.loss    { background: #ef4444; }
.cost-legend { display: flex; gap: 12px; flex-wrap: wrap; font-size: 11px; color: var(--text-dim, #6b7280); margin: 8px 0 4px; }
.cost-legend-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 4px; }
.dot-direct { background: #3b82f6; } .dot-support { background: #f59e0b; }
.dot-other { background: #8b5cf6; } .dot-profit { background: #10b981; }
.dot-loss { background: #ef4444; }
@media (max-width: 700px) { .mini-kpis { grid-template-columns: repeat(2, 1fr); } }

/* name prominent, code secondary; net profit beside the composition bar */
.code-slot { font-size: 11px; color: var(--text-dim, #6b7280); margin-top: 2px; }
.code-slot code { font-size: 11px; }
.bar-row { display: flex; justify-content: flex-end; margin-top: 6px; }
.bar-np { display: flex; align-items: baseline; gap: 8px; }
.bar-np-v { font-size: 15px; font-weight: 600; white-space: nowrap; }
.bar-np.pos .bar-np-v { color: #10b981; }
.bar-np.neg .bar-np-v { color: #ef4444; }

/* ── control strip ────────────────────────────────────────────────────────────
   The disabled pickers are styled to read as WAITING, not broken: same shape as
   the live controls, dimmed, cursor not-allowed, with the reason in the title and
   spelled out beside them. A control that just looks greyed out invites a click
   and explains nothing. */
.ctrl { display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
        margin: 0 0 18px; padding: 10px 14px; background: var(--bg-card);
        border: 1px solid var(--border); border-radius: 8px; }
.ctrl .spacer { flex: 1 1 auto; }
.ctrl-grp { display: flex; align-items: center; gap: 6px; }
.ctrl-lab { font-size: 10px; font-weight: 700; text-transform: uppercase;
            letter-spacing: 0.5px; color: var(--text-dim); }
.ctrl-sel { padding: 4px 8px; font-size: 12px; border: 1px solid var(--border);
            border-radius: 5px; background: var(--bg); color: var(--text-bright); }
.ctrl-sel.wide { min-width: 190px; }
.ctrl-sel:disabled { opacity: 0.5; cursor: not-allowed; }
.ctrl-why { font-size: 11px; color: var(--text-dim); font-style: italic; }
.ctrl-why code { font-style: normal; }
.ctrl-sep { width: 1px; align-self: stretch; background: var(--border); }
.ctrl-fx { font-size: 12px; font-weight: 600; color: var(--text-bright);
           font-variant-numeric: tabular-nums; }
.ctrl-dl { font-size: 12px; font-weight: 600; padding: 5px 12px; border-radius: 5px;
           border: 1px solid var(--border); color: var(--text-bright);
           text-decoration: none; white-space: nowrap; }
.ctrl-dl:hover { border-color: var(--dash-accent); color: var(--dash-accent); }

/* ── upload health ────────────────────────────────────────────────────────────
   Findings carry colour; clean checks are deliberately grey and collapsed. The
   "could not run" block is styled as neither — it is not a finding and it is not
   reassurance, and giving it either colour would say something untrue. */
.uh-banner { background: rgba(61,108,223,0.10); border: 1px solid rgba(61,108,223,0.45);
             border-radius: 6px; padding: 8px 12px; font-size: 12px; margin: 10px 0 14px; }
table.uh td { vertical-align: top; font-size: 12px; }
.uh-sev { display: inline-block; font-size: 10px; font-weight: 700; letter-spacing: 0.4px;
          padding: 1px 7px; border-radius: 9px; color: #fff; }
.uh-FAIL { background: var(--red); }
.uh-WARN { background: #b8860b; }
.uh-INFO { background: #6c757d; }
.uh-key { font-size: 10px; color: var(--text-dim); }
.uh-sample { margin-top: 4px; font-size: 11px; color: var(--text-dim);
             word-break: break-word; }
.uh-none { background: rgba(46,158,79,0.10); border: 1px solid rgba(46,158,79,0.45);
           border-radius: 6px; padding: 10px 12px; font-size: 13px; font-weight: 600; }
.uh-clean { margin-top: 14px; }
.uh-clean summary { cursor: pointer; font-size: 12px; color: var(--text-dim);
                    padding: 6px 0; }
.uh-clean table.uh td { color: var(--text-dim); }
.uh-cannot { margin-top: 14px; padding: 10px 12px; font-size: 12px;
             border: 1px dashed var(--border); border-radius: 6px; color: var(--text-dim); }
.uh-cannot ul { margin: 6px 0 0; padding-left: 20px; }
.uh-cannot li { margin: 4px 0; }

/* Audit — section headings inside one panel. */
.aud-h { margin: 22px 0 4px; font-size: 12px; font-weight: 600; text-transform: uppercase;
         letter-spacing: 0.5px; color: var(--text-dim); }

/* ── "Can this month be published?" — the two promotion gates ──────────────────
   Deliberately the strongest visual element above the statement: it answers the
   question a reader has before they trust any figure on the page. Critical and
   advisory are separated by weight and colour, not only by a label. */
.pub-panel { border-radius: 10px; padding: 14px 16px; margin: 0 0 14px 0;
             border: 1px solid var(--border); background: var(--bg-elev); }
.pub-panel.pub-blocked { border-left: 4px solid #ef4444; }
.pub-panel.pub-ok      { border-left: 4px solid #10b981; }
.pub-head { font-size: 14px; color: var(--text-bright); margin-bottom: 10px; }
.pub-sub { font-size: 12px; color: var(--text-dim); margin-left: 8px; font-weight: 400; }
.pub-gate { border-top: 1px solid var(--border); padding: 10px 0 6px 0; }
.pub-gate p { margin: 4px 0; font-size: 12px; line-height: 1.6; }
.pub-gate-h { font-size: 11px; text-transform: uppercase; letter-spacing: 0.5px;
              color: var(--text-dim); font-weight: 600; margin-bottom: 4px; }
.pub-pill { display: inline-block; margin-left: 8px; padding: 1px 7px; border-radius: 9px;
            font-size: 10px; letter-spacing: 0.3px; background: var(--bg); border: 1px solid var(--border); }
.g-blocked .pub-pill { background: #fee2e2; border-color: #fca5a5; color: #991b1b; }
.g-clear   .pub-pill { background: #dcfce7; border-color: #86efac; color: #166534; }
/* Collapsed publication panel. <details>/<summary>, so no script and no stored state. */
.pub-details > summary {
  cursor: pointer;
  list-style: none;                 /* Firefox / spec */
  display: block;                   /* NOT flex: a flex summary loses its marker box */
}
.pub-details > summary::-webkit-details-marker { display: none; }   /* Safari / old Blink */
/* OWN CHEVRON, DRAWN AS A LITERAL CHARACTER.
   It was written as the CSS escape '\25b8' through a Python string, where \25 is an
   OCTAL escape -- the file ended up holding control char 0x15 followed by the text "b8",
   which is what rendered as a stack of glyphs beside the verdict line. A literal character
   in a UTF-8 file cannot be mangled by whatever writes it. */
.pub-details > summary::before {
  content: '▸';
  display: inline-block;
  width: 12px;
  margin-right: 2px;
  color: var(--text-dim);
  transform-origin: 45% 50%;
  transition: transform .12s ease;
}
.pub-details[open] > summary::before { transform: rotate(90deg); }
.pub-details > summary:hover::before { color: var(--accent); }
.pub-details > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.pub-badges { display: inline-flex; flex-wrap: wrap; gap: 5px; margin-left: 8px;
              vertical-align: middle; }
.pub-badges .pub-pill { margin-left: 0; }
.p-ok  { background: #dcfce7; border-color: #86efac; color: #166534; }
.p-bad { background: #fee2e2; border-color: #fca5a5; color: #991b1b; }

/* Detectors that exist but did not run against this run — named, never just counted. */
.pub-gap { margin: 4px 0 6px 0; padding-left: 18px; font-size: 12px; line-height: 1.7; }
.pub-gap li { margin: 1px 0; }
.pub-gap code { font-size: 11px; }
.pub-flag { padding: 8px 10px; border-radius: 6px; margin: 6px 0; background: var(--bg); }
.pf-crit { border-left: 3px solid #ef4444; }
.pf-adv  { border-left: 3px solid #d1d5db; font-size: 12px; }
.pf-title { font-weight: 600; color: var(--text-bright); font-size: 13px; }
.pf-adv .pf-title { font-weight: 500; font-size: 12px; }
.pf-how { font-size: 12px; color: var(--text); margin-top: 3px; }
.pf-meta { font-size: 11px; color: var(--text-dim); margin-top: 4px; }
.pf-meta span { margin-right: 10px; }
.pf-meta a, .pub-flag a { cursor: pointer; text-decoration: underline; color: var(--dash-accent); }
.pf-detail { margin-top: 6px; font-size: 11px; color: var(--text-dim);
             border-top: 1px dashed var(--border); padding-top: 6px; }
.pf-detail p { margin: 4px 0 0 0; }
/* The exact rule, not a paraphrase — a paraphrase of a promotion rule is how people
   learn the screen cannot be trusted. */
.pub-rule { margin-top: 10px; padding: 9px 11px; border-radius: 6px; background: var(--bg);
            font-size: 11px; color: var(--text-dim); line-height: 1.7; }
.pub-adv { border-top: 1px solid var(--border); padding-top: 10px; margin-top: 4px; }


/* ══ V3 ADDITIONS ═══════════════════════════════════════════════════════════════════════
   Everything above this line is mis-anka's file, unmodified. Everything below is v3-only,
   kept here so the transcribed region stays byte-identical and re-syncable.

   THESE ADD SURFACE, THEY DO NOT RESTYLE IT. Each one exists because v3 has something
   mis-anka does not -- a parity table, a promotion freeze that names who froze it, a
   manifest that records a read decision per column -- and none of them changes a colour,
   a spacing or a font that mis-anka already sets. */

/* The promotion state, in the topbar. mis-anka shows the run id; v3 also knows whether the
   month is FROZEN and who froze it, which is the first thing a reader of a reported month
   needs and the thing mis-anka's run pill cannot say. */
.pill.frozen { background: #dcfce7; border-color: #86efac; color: #166534; }
.pill.thawed { background: #fef3c7; border-color: #fcd34d; color: #92400e; }
.pill.stale  { background: #fee2e2; border-color: #fca5a5; color: #991b1b; }

/* PARITY. v3 stores its differences against mis-anka on v3.pnl_parity, row by row, with a
   classification and the rule that adjudicated it. mis-anka has no equivalent because it
   is the thing being reconciled AGAINST -- so this is v3's own surface, not a copy. */
.par-ok    { color: var(--green); }
.par-ruled { color: var(--amber); }
.par-open  { color: var(--red); font-weight: 600; }
.par-note  { font-size: 11px; color: var(--text-dim); }

/* A pane v3 cannot fill. Styled as a STATEMENT, deliberately not as an error and
   deliberately not as an empty table: "v3 does not store this" and "this month had none"
   are different facts, and a grey empty state would render them identically. */
.absent {
  font-size: 13px; line-height: 1.7; color: #1e3a5f;
  background: #eff6ff; border: 1px solid #bfdbfe; border-left: 4px solid #3b82f6;
  padding: 14px 16px; border-radius: 0 8px 8px 0; margin: 4px 0 18px 0;
}
.absent b { color: #0c2d54; }
.absent code { font-family: monospace; font-size: 11px; background: #dbeafe;
               padding: 1px 4px; border-radius: 3px; }
