/* UBL Solar Sites Tracker — one design system for the internal app and the bank
   portal, so the two can never drift apart.

   Status colours are the validated status palette (good / warning / critical +
   a deliberate neutral for "no state yet"): CVD separation ΔE 11.3, normal
   vision 22.1, both modes. Amber sits under 3:1 on a white surface by design —
   the mitigation is that a status NEVER appears as colour alone: every pill
   carries a dot and a word, every bar row carries its count, and the legend
   names each colour. */
:root {
  color-scheme: light;
  --page: #f1f3f5;
  --panel: #ffffff;
  --panel-2: #f6f8f9;
  --panel-3: #eef1f4;
  --border: #e2e6ea;
  --border-strong: #d3d9df;
  --text: #14181c;
  --dim: #5b6672;
  --faint: #8b95a3;
  --accent: #14512f;
  --accent-2: #1c7346;
  --accent-soft: rgba(20, 81, 47, 0.09);
  --on-accent: #ffffff;
  --input-bg: #ffffff;
  --input-border: #d3d9df;
  --row-hover: #f6f9f8;
  --thead: #f6f8f9;
  --shadow-sm: 0 1px 2px rgba(15, 23, 32, 0.05);
  --shadow: 0 1px 2px rgba(15, 23, 32, 0.05), 0 4px 12px rgba(15, 23, 32, 0.04);
  --shadow-lg: 0 12px 40px rgba(15, 23, 32, 0.16);
  --brand: #e11d2a;

  /* status — mark colours (bars, dots) */
  --st-done: #0ca30c;
  --st-prog: #fab219;
  --st-hold: #d03b3b;
  --st-none: #8a94a3;
  --st-na: #b9c0c8;
  /* status — text steps, for a label sitting on the tint */
  --st-done-ink: #0a7c2f;
  --st-prog-ink: #8a5a00;
  --st-hold-ink: #a52c2c;
  --st-none-ink: #5b6672;
  --st-na-ink: #6c7681;
  --info: #2a6fd0;
  --tint: 15%;
}
html.dark {
  color-scheme: dark;
  --page: #0e1116;
  --panel: #171b20;
  --panel-2: #1d222a;
  --panel-3: #232933;
  --border: rgba(255, 255, 255, 0.08);
  --border-strong: rgba(255, 255, 255, 0.16);
  --text: #e9edf2;
  --dim: #9aa5b3;
  --faint: #6f7a88;
  --accent: #6fe3ac;
  --accent-2: #4dd396;
  --accent-soft: rgba(111, 227, 172, 0.14);
  --on-accent: #04241a;
  --input-bg: #12161b;
  --input-border: rgba(255, 255, 255, 0.14);
  --row-hover: #1c222a;
  --thead: #1b2028;
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 6px 18px rgba(0, 0, 0, 0.3);
  --shadow-lg: 0 18px 50px rgba(0, 0, 0, 0.6);

  --st-done-ink: #58d98c;
  --st-prog-ink: #f2c15c;
  --st-hold-ink: #f08a8a;
  --st-none-ink: #a3adba;
  --st-na-ink: #8b95a3;
  --info: #6ea8f7;
  --tint: 22%;
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--page);
  color: var(--text);
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  font-feature-settings: 'cv02', 'cv03', 'cv04';
}
h1, h2, h3, h4 { margin: 0; font-weight: 700; letter-spacing: -0.015em; line-height: 1.25; }
a { color: inherit; }
button { font: inherit; cursor: pointer; }
::selection { background: var(--accent-soft); }
.hidden { display: none !important; }
.mono { font-family: ui-monospace, 'SF Mono', Menlo, monospace; font-size: 0.94em; }
.num, .kpi .value, table.data td.num { font-variant-numeric: tabular-nums; }
.muted { color: var(--dim); }
.tiny { font-size: 11.5px; }
.spacer { flex: 1; }

/* ---- shell -------------------------------------------------------------- */
.topbar {
  position: sticky; top: 0; z-index: 40;
  display: flex; align-items: center; gap: 14px;
  padding: 11px 22px;
  background: color-mix(in srgb, var(--panel) 88%, transparent);
  backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--border);
}
.brand { display: flex; align-items: center; gap: 11px; font-weight: 800; letter-spacing: -0.02em; font-size: 15px; }
.brand .bolt {
  display: grid; place-items: center; width: 30px; height: 30px; flex: none;
  border-radius: 9px; background: var(--accent); color: var(--on-accent); font-size: 15px;
}
.brand small { display: block; font-size: 9.5px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--faint); margin-top: 1px; }
.nav { display: flex; gap: 2px; margin-left: 10px; }
.nav button {
  border: 0; background: transparent; color: var(--dim);
  padding: 7px 13px; border-radius: 9px; font-weight: 600; font-size: 13px;
  transition: background .15s, color .15s;
}
.nav button:hover { background: var(--panel-2); color: var(--text); }
.nav button.active { background: var(--accent); color: var(--on-accent); }
.who { text-align: right; line-height: 1.2; }
.who b { display: block; font-size: 13px; font-weight: 700; }
.who span { font-size: 10px; color: var(--faint); text-transform: uppercase; letter-spacing: 0.07em; font-weight: 700; }
.wrap { max-width: 1560px; margin: 0 auto; padding: 22px; }
@media (max-width: 720px) {
  .topbar { padding: 10px 14px; gap: 10px; flex-wrap: wrap; }
  .who { display: none; }
  .wrap { padding: 14px; }
}

/* ---- surfaces ----------------------------------------------------------- */
.panel { background: var(--panel); border: 1px solid var(--border); border-radius: 16px; box-shadow: var(--shadow-sm); }
.pad { padding: 18px 20px; }
.grid { display: grid; gap: 14px; }
.cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 1000px) { .cols-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } .cols-2 { grid-template-columns: 1fr; } }
@media (max-width: 520px) { .cols-4 { grid-template-columns: 1fr; } }
.section-h {
  font-size: 10.5px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.09em;
  color: var(--faint); margin-bottom: 14px;
}
.hero { display: flex; justify-content: space-between; gap: 22px; flex-wrap: wrap; align-items: center; }
.hero h3 { font-size: 19px; }
.hero p { margin: 6px 0 0; max-width: 74ch; color: var(--dim); font-size: 12.5px; line-height: 1.6; }

/* Programme meter — a headline number with one thin track underneath. */
.meter { min-width: 190px; }
.meter .big { font-size: 34px; font-weight: 800; letter-spacing: -0.035em; line-height: 1; font-variant-numeric: tabular-nums; }
.meter .big small { font-size: 15px; font-weight: 600; color: var(--faint); letter-spacing: 0; }
.meter .track { height: 6px; border-radius: 999px; background: var(--panel-3); overflow: hidden; margin-top: 9px; }
.meter .track > div { height: 100%; border-radius: 999px; background: linear-gradient(90deg, var(--accent-2), var(--accent)); }

/* KPI card — a coloured rule ties the number to its status meaning. */
.kpi { position: relative; overflow: hidden; padding: 16px 18px; }
.kpi::before { content: ''; position: absolute; inset: 0 auto 0 0; width: 3px; background: var(--kpi, var(--border-strong)); }
.kpi .label { font-size: 10px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.09em; color: var(--faint); }
.kpi .value { font-size: 30px; font-weight: 800; letter-spacing: -0.035em; margin-top: 5px; line-height: 1.05; }
.kpi .sub { font-size: 11.5px; color: var(--dim); margin-top: 3px; }

/* ---- controls ----------------------------------------------------------- */
.btn, .btn-primary, .btn-danger {
  border-radius: 10px; border: 1px solid var(--input-border);
  background: var(--panel); color: var(--text);
  padding: 8px 14px; font-size: 13px; font-weight: 600;
  display: inline-flex; align-items: center; gap: 7px; white-space: nowrap;
  transition: background .15s, border-color .15s, transform .08s, box-shadow .15s;
}
.btn:hover { background: var(--panel-2); border-color: var(--border-strong); }
.btn:active, .btn-primary:active, .btn-danger:active { transform: translateY(1px); }
.btn-primary { background: var(--accent); color: var(--on-accent); border-color: transparent; font-weight: 700; box-shadow: var(--shadow-sm); }
.btn-primary:hover { background: var(--accent-2); }
.btn-danger { background: transparent; color: var(--st-hold-ink); border-color: color-mix(in srgb, var(--st-hold) 40%, transparent); font-weight: 700; }
.btn-danger:hover { background: color-mix(in srgb, var(--st-hold) 12%, transparent); }
.btn:disabled, .btn-primary:disabled { opacity: 0.5; cursor: not-allowed; }
.btn-icon { padding: 8px 10px; }
label.f { display: block; font-size: 10px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.07em; color: var(--faint); margin-bottom: 6px; }
input.i, select.i, textarea.i {
  width: 100%; padding: 9px 11px; font: inherit; font-size: 13px;
  color: var(--text); background: var(--input-bg);
  border: 1px solid var(--input-border); border-radius: 10px;
  transition: border-color .15s, box-shadow .15s;
}
select.i { appearance: none; padding-right: 30px;
  background-image: linear-gradient(45deg, transparent 50%, var(--dim) 50%), linear-gradient(135deg, var(--dim) 50%, transparent 50%);
  background-position: calc(100% - 16px) 51%, calc(100% - 11px) 51%;
  background-size: 5px 5px, 5px 5px; background-repeat: no-repeat; }
input.i:focus, select.i:focus, textarea.i:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
input.i:disabled, select.i:disabled, textarea.i:disabled { background: var(--panel-2); color: var(--dim); cursor: not-allowed; }
input.i::placeholder { color: var(--faint); }
.toolbar { display: flex; gap: 9px; flex-wrap: wrap; align-items: center; }
.search { position: relative; }
.search input { padding-left: 32px; }
.search::before {
  content: ''; position: absolute; left: 11px; top: 50%; width: 14px; height: 14px; margin-top: -7px;
  pointer-events: none; opacity: .55;
  background: currentColor; color: var(--dim);
  -webkit-mask: var(--mag) center / contain no-repeat; mask: var(--mag) center / contain no-repeat;
}
:root { --mag: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M20 20l-4.2-4.2'/%3E%3C/svg%3E"); }
.seg { display: inline-flex; gap: 2px; padding: 3px; background: var(--panel-2); border: 1px solid var(--border); border-radius: 12px; }
.seg button {
  border: 0; background: transparent; color: var(--dim);
  padding: 7px 15px; border-radius: 9px; font-size: 13px; font-weight: 600;
  transition: background .15s, color .15s;
}
.seg button:hover { color: var(--text); }
.seg button.active { background: var(--panel); color: var(--text); box-shadow: var(--shadow-sm); }

/* ---- table -------------------------------------------------------------- */
.table-scroll { overflow-x: auto; overscroll-behavior-x: contain; }
table.data { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 12.5px; }
table.data th {
  position: sticky; top: 0; z-index: 2;
  text-align: left; white-space: nowrap; padding: 10px 14px;
  background: var(--thead); color: var(--faint);
  font-size: 9.5px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.08em;
  border-bottom: 1px solid var(--border);
}
table.data td { padding: 10px 14px; white-space: nowrap; border-bottom: 1px solid var(--border); }
table.data tbody tr:last-child td { border-bottom: 0; }
table.data tbody tr { transition: background .12s; }
table.data tbody tr:hover td { background: var(--row-hover); }
table.data tbody tr.clickable { cursor: pointer; }
table.data td.num { text-align: right; }
table.data td.name { font-weight: 650; }
/* The site name stays put while the wide accounts view scrolls sideways. */
table.data th:first-child, table.data td:first-child {
  position: sticky; left: 0; z-index: 1;
  background: var(--panel);
  box-shadow: 1px 0 0 var(--border);
}
table.data th:first-child { z-index: 3; background: var(--thead); }
table.data tbody tr:hover td:first-child { background: var(--row-hover); }
.empty { padding: 46px 24px; text-align: center; color: var(--dim); }
.empty b { display: block; color: var(--text); margin-bottom: 5px; font-size: 14px; }

/* ---- status: never colour alone ---------------------------------------- */
.pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 10px 3px 8px; border-radius: 999px;
  font-size: 11px; font-weight: 700; white-space: nowrap; letter-spacing: 0.005em;
  background: color-mix(in srgb, var(--c) var(--tint), transparent); color: var(--ink);
}
.pill::before { content: ''; width: 6px; height: 6px; border-radius: 999px; background: var(--c); flex: none; }
.pill.s-done { --c: var(--st-done); --ink: var(--st-done-ink); }
.pill.s-prog { --c: var(--st-prog); --ink: var(--st-prog-ink); }
.pill.s-hold { --c: var(--st-hold); --ink: var(--st-hold-ink); }
.pill.s-none { --c: var(--st-none); --ink: var(--st-none-ink); }
.pill.s-na   { --c: var(--st-na);   --ink: var(--st-na-ink); }

/* Stacked meter. Segments are separated by a 2px gap in the surface colour —
   never a stroke — and the whole bar carries 4px rounded ends. */
.bar { height: 10px; border-radius: 5px; background: var(--panel-3); overflow: hidden; display: flex; gap: 2px; }
.bar > span { height: 100%; display: block; transition: width .3s ease; }
.bar > span:first-child { border-radius: 5px 0 0 5px; }
.bar > span:last-child { border-radius: 0 5px 5px 0; }
.bar > span:only-child { border-radius: 5px; }
.bar-thin { height: 6px; border-radius: 3px; }
.bar-thin > span:first-child { border-radius: 3px 0 0 3px; }
.bar-thin > span:last-child { border-radius: 0 3px 3px 0; }
.bar-row { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; font-size: 12.5px; margin-bottom: 6px; }
.bar-row b { font-weight: 650; }
.bar-row span { color: var(--dim); font-variant-numeric: tabular-nums; font-size: 11.5px; }
.legend { display: flex; gap: 14px; flex-wrap: wrap; font-size: 11px; color: var(--dim); }
.legend span { display: inline-flex; align-items: center; gap: 6px; }
.legend i { width: 9px; height: 9px; border-radius: 3px; }

/* Hover readout for a stacked segment. */
#tip {
  position: fixed; z-index: 95; pointer-events: none;
  background: var(--text); color: var(--panel);
  padding: 5px 9px; border-radius: 7px; font-size: 11.5px; font-weight: 650;
  box-shadow: var(--shadow-lg); white-space: nowrap;
}

/* ---- drawer ------------------------------------------------------------- */
.backdrop {
  position: fixed; inset: 0; z-index: 60; display: flex; justify-content: flex-end;
  background: rgba(9, 13, 18, 0.5); backdrop-filter: blur(3px);
  animation: fade .16s ease;
}
.drawer {
  width: 760px; max-width: 96vw; height: 100%; overflow-y: auto;
  background: var(--page); padding: 20px 22px 32px;
  box-shadow: var(--shadow-lg); animation: slide .22s cubic-bezier(.22,.61,.36,1);
}
@keyframes fade { from { opacity: 0; } }
@keyframes slide { from { transform: translateX(28px); opacity: .4; } }
.drawer-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin-bottom: 18px; }
.drawer-head h3 { font-size: 19px; }
.x { border: 0; background: var(--panel); color: var(--dim); font-size: 20px; line-height: 1; padding: 5px 11px; border-radius: 9px; border: 1px solid var(--border); }
.x:hover { background: var(--panel-2); color: var(--text); }
fieldset.grp { border: 1px solid var(--border); border-radius: 14px; padding: 6px 18px 18px; margin: 0 0 14px; background: var(--panel); }
fieldset.grp legend { font-size: 10px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.09em; color: var(--accent); padding: 0 7px; }
.f-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 13px; }
.f-wide { grid-column: 1 / -1; }
@media (max-width: 640px) { .f-grid { grid-template-columns: 1fr; } .drawer { padding: 14px; } }
.err { color: var(--st-hold-ink); font-size: 13px; font-weight: 650; margin: 0 0 12px; }
.timeline { display: grid; gap: 9px; }
.tl-row { display: flex; align-items: center; gap: 11px; font-size: 12.5px; }
/* The LABEL takes the free space; the pill hugs its text. (Targeting the second
   child stretched the pill across the row instead.) */
.tl-row > span:first-child { flex: 1; font-weight: 600; }
.tl-row > .pill { flex: none; }
.kv { display: flex; justify-content: space-between; gap: 16px; font-size: 12.5px; padding: 7px 0; border-bottom: 1px solid var(--border); }
.kv:last-child { border-bottom: 0; }
.kv b { font-weight: 650; font-variant-numeric: tabular-nums; }
.hist { display: grid; gap: 11px; }
.hist > div { border-left: 2px solid var(--border); padding-left: 13px; }
.hist b { font-weight: 650; font-size: 12.5px; }
.file-row { display: flex; align-items: center; gap: 10px; padding: 9px 12px; border: 1px solid var(--border); border-radius: 11px; background: var(--panel-2); font-size: 12.5px; }
.file-row a { font-weight: 650; text-decoration: none; }
.file-row a:hover { text-decoration: underline; }

/* ---- toast -------------------------------------------------------------- */
#toast {
  position: fixed; left: 50%; bottom: 28px; transform: translateX(-50%);
  display: flex; align-items: center; gap: 8px;
  padding: 11px 18px; border-radius: 12px; font-size: 13px; font-weight: 700; z-index: 90;
  background: var(--text); color: var(--panel); box-shadow: var(--shadow-lg);
  animation: rise .2s cubic-bezier(.22,.61,.36,1);
}
#toast::before { content: ''; width: 7px; height: 7px; border-radius: 999px; background: var(--st-done); }
#toast.bad::before { background: var(--st-hold); }
@keyframes rise { from { transform: translate(-50%, 10px); opacity: 0; } }

/* ---- login -------------------------------------------------------------- */
.login-shell { min-height: 100vh; display: grid; grid-template-columns: 1.05fr 1fr; }
@media (max-width: 900px) { .login-shell { grid-template-columns: 1fr; } .login-art { display: none; } }
.login-art {
  position: relative; overflow: hidden; color: #e9f5ee; padding: 52px;
  display: flex; flex-direction: column; justify-content: space-between;
  background: linear-gradient(158deg, #0d2f1d 0%, #14512f 52%, #1c7346 100%);
}
.login-art::after {
  content: ''; position: absolute; inset: auto -20% -35% -10%; height: 60%;
  background: radial-gradient(closest-side, rgba(111,227,172,.28), transparent 70%);
}
.login-art h1 { font-size: 34px; line-height: 1.14; max-width: 15ch; }
.login-art p { max-width: 44ch; margin-top: 15px; line-height: 1.65; opacity: .85; font-size: 13.5px; }
.login-form { display: flex; align-items: center; justify-content: center; padding: 34px; }
.login-card { width: 100%; max-width: 372px; }

/* ==========================================================================
   APP SHELL — sidebar + soft canvas + right rail.
   The dashboard reads as cards floating on a tinted canvas: navigation is a
   fixed white panel on the left, content sits in the middle, and a rail on the
   right carries quick actions, the activity feed and the status breakdown.
   ========================================================================== */
:root {
  --canvas: #f4f4f8;
  --canvas-tint: radial-gradient(1100px 620px at 88% -8%, #ece7fb 0%, transparent 60%),
                 radial-gradient(900px 560px at 4% 102%, #e5f1fb 0%, transparent 62%);
  --side-w: 232px;
  --rail-w: 330px;
  /* Pastel stat-card surfaces. Decorative surfaces, not data encodings —
     magnitude is carried by the number, state by the validated status hues. */
  --card-pink: #fbd5e8;   --card-pink-ink: #7a2450;
  --card-amber: #fde8a6;  --card-amber-ink: #6f4b06;
  --card-blue: #d9e7fb;   --card-blue-ink: #1b3f70;
  --card-mint: #cdeedd;   --card-mint-ink: #10503a;
  --card-lilac: #e5dcfb;  --card-lilac-ink: #402a78;
}
html.dark {
  --canvas: #0e1116;
  --canvas-tint: radial-gradient(1100px 620px at 88% -8%, rgba(120, 96, 200, .16) 0%, transparent 60%),
                 radial-gradient(900px 560px at 4% 102%, rgba(56, 120, 180, .14) 0%, transparent 62%);
  --card-pink: #43263a;   --card-pink-ink: #f6cfe4;
  --card-amber: #3f3418;  --card-amber-ink: #f5d68a;
  --card-blue: #1c3350; --card-blue-ink: #cfe0f7;
  --card-mint: #163a2e;   --card-mint-ink: #a9e8c9;
  --card-lilac: #2c2550;  --card-lilac-ink: #d8cdf7;
}

body.app { background: var(--canvas); background-image: var(--canvas-tint); background-attachment: fixed; }
/* Full-bleed: the dashboard uses the whole window rather than sitting in a
   centred column with dead space down both sides. */
.shell { display: grid; grid-template-columns: var(--side-w) minmax(0, 1fr); gap: 14px; padding: 14px;
         min-height: 100vh; align-items: start; width: 100%; }

/* ---- sidebar ---- */
.side {
  position: sticky; top: 16px; height: calc(100vh - 32px);
  display: flex; flex-direction: column; gap: 4px;
  background: var(--panel); border: 1px solid var(--border); border-radius: 18px; padding: 16px 12px;
  box-shadow: var(--shadow-sm);
}
.side .brand { padding: 4px 8px 16px; }
.side-nav { display: flex; flex-direction: column; gap: 3px; }
.side-nav button {
  display: flex; align-items: center; gap: 11px; width: 100%;
  border: 0; background: transparent; color: var(--dim);
  padding: 10px 12px; border-radius: 11px; font-size: 13.5px; font-weight: 600; text-align: left;
  transition: background .15s, color .15s;
}
.side-nav button:hover { background: var(--panel-2); color: var(--text); }
.side-nav button.active { background: var(--accent-soft); color: var(--accent); font-weight: 700; }
.side-nav .ico { width: 18px; height: 18px; flex: none; opacity: .9; }
.side-foot { margin-top: auto; display: flex; flex-direction: column; gap: 3px; padding-top: 10px; border-top: 1px solid var(--border); }
.promo {
  margin: 14px 2px 10px; padding: 14px 15px; border-radius: 15px;
  background: linear-gradient(160deg, var(--card-amber), color-mix(in srgb, var(--card-amber) 70%, var(--panel)));
  color: var(--card-amber-ink);
}
.promo b { display: block; font-size: 13px; margin-bottom: 5px; }
.promo p { margin: 0 0 11px; font-size: 11.5px; line-height: 1.55; opacity: .85; }

/* ---- main column ---- */
.main { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.head { display: flex; align-items: center; gap: 14px; padding: 2px 4px; }
.head h2 { font-size: 22px; letter-spacing: -0.025em; }
.pagegrid { display: grid; grid-template-columns: minmax(0, 1fr) var(--rail-w); gap: 16px; align-items: start; }
/* With the rail hidden (the finance board owns the full width) the reserved
   rail column has to go too, or the content stops short of the page edge. */
.pagegrid.solo { grid-template-columns: minmax(0, 1fr); }
/* Not sticky: with four panels the rail is taller than the viewport, and a
   sticky element taller than the screen pins its top — everything below the
   fold becomes unreachable. It scrolls with the page instead. */
.rail { display: flex; flex-direction: column; gap: 16px; }
@media (max-width: 1240px) { .pagegrid { grid-template-columns: minmax(0, 1fr); } .rail { position: static; } }
@media (max-width: 900px) {
  .shell { grid-template-columns: 1fr; padding: 10px; gap: 10px; }
  .side { position: static; height: auto; flex-direction: row; align-items: center; overflow-x: auto; padding: 10px; }
  /* On the phone strip the brand is the mark plus one line — the stacked
     name + subtitle wrapped to four lines and ate the nav. */
  .side .brand { padding: 0 8px 0 2px; font-size: 13px; white-space: nowrap; }
  .side .brand small { display: none; }
  .side-nav { flex-direction: row; }
  .side-nav button { white-space: nowrap; padding: 9px 11px; }
  .side-foot { margin: 0 0 0 auto; flex-direction: row; border: 0; padding-top: 0; }
  .promo { display: none; }
}

/* ---- pastel stat cards ---- */
.stats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; }
@media (max-width: 1100px) { .stats { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .stats { grid-template-columns: 1fr; } }
.stat {
  position: relative; border-radius: 18px; padding: 16px 17px 14px;
  background: var(--bg); color: var(--ink); border: 1px solid color-mix(in srgb, var(--ink) 10%, transparent);
  min-height: 132px; display: flex; flex-direction: column; justify-content: space-between;
  transition: transform .16s ease, box-shadow .16s ease;
}
.stat:hover { transform: translateY(-2px); box-shadow: 0 10px 26px color-mix(in srgb, var(--ink) 16%, transparent); }
.stat .cap { font-size: 12px; font-weight: 700; opacity: .78; }
.stat .big { font-size: 33px; font-weight: 800; letter-spacing: -0.035em; line-height: 1.05; margin-top: 8px; font-variant-numeric: tabular-nums; }
.stat .foot { display: flex; align-items: center; gap: 8px; margin-top: 12px; font-size: 11px; font-weight: 650; }
.stat .chip { background: color-mix(in srgb, var(--ink) 12%, transparent); padding: 3px 8px; border-radius: 999px; }
.stat.s-pink { --bg: var(--card-pink); --ink: var(--card-pink-ink); }
.stat.s-amber { --bg: var(--card-amber); --ink: var(--card-amber-ink); }
.stat.s-blue { --bg: var(--card-blue); --ink: var(--card-blue-ink); }
.stat.s-mint { --bg: var(--card-mint); --ink: var(--card-mint-ink); }
.stat.s-lilac { --bg: var(--card-lilac); --ink: var(--card-lilac-ink); }

/* ---- rail pieces ---- */
.rail-actions { display: grid; gap: 9px; }
.rail-actions button { justify-content: space-between; width: 100%; padding: 12px 15px; border-radius: 13px; font-size: 13.5px; }
.feed { display: grid; gap: 2px; max-height: 330px; overflow-y: auto; margin: -6px -6px -6px 0; padding-right: 6px; }
.feed-row { display: flex; gap: 11px; align-items: flex-start; padding: 9px 6px; border-radius: 11px; }
.feed-row:hover { background: var(--panel-2); }
.avatar {
  width: 30px; height: 30px; border-radius: 999px; flex: none;
  display: grid; place-items: center; font-size: 11px; font-weight: 800; color: #fff; letter-spacing: -0.02em;
}
.feed-row p { margin: 0; font-size: 12.5px; line-height: 1.45; }
.feed-row .when { font-size: 11px; color: var(--faint); margin-top: 2px; }

/* ---- donut ---- */
.donut-wrap { display: grid; place-items: center; padding: 6px 0 14px; }
.donut { position: relative; width: 190px; height: 190px; }
.donut svg { transform: rotate(-90deg); }
.donut .center { position: absolute; inset: 0; display: grid; place-content: center; text-align: center; }
.donut .center b { display: block; font-size: 30px; font-weight: 800; letter-spacing: -0.035em; font-variant-numeric: tabular-nums; }
.donut .center span { font-size: 11px; color: var(--dim); }
.brk { display: grid; gap: 4px; }
.brk-row { display: grid; grid-template-columns: auto 1fr auto auto; align-items: center; gap: 10px; font-size: 12.5px; padding: 5px 2px; }
.brk-row i { width: 10px; height: 10px; border-radius: 3px; }
.brk-row b { font-variant-numeric: tabular-nums; font-weight: 650; }
.brk-row em { font-style: normal; color: var(--dim); font-variant-numeric: tabular-nums; min-width: 34px; text-align: right; }

/* ---- table extras ---- */
.row-actions { display: inline-flex; gap: 4px; }
.icon-btn {
  border: 0; background: transparent; color: var(--faint); border-radius: 8px;
  width: 26px; height: 26px; display: grid; place-items: center; padding: 0;
}
.icon-btn:hover { background: var(--panel-3); color: var(--text); }
.tag { display: inline-block; padding: 2px 9px; border-radius: 7px; font-size: 11px; font-weight: 650; background: var(--panel-3); color: var(--dim); }

/* ---- fitted table: everything on screen, nothing scrolled sideways ------- */
table.data.fit { table-layout: fixed; width: 100%; }
table.data.fit th, table.data.fit td { white-space: normal; vertical-align: top; padding: 11px 14px; }
table.data.fit th.ta-r, table.data.fit td.ta-r { text-align: right; }
table.data.fit td .ln { font-size: 12.5px; line-height: 1.35; overflow-wrap: anywhere; }
table.data.fit td .ln + .ln { margin-top: 2px; }
table.data.fit td .ln-strong { font-weight: 650; }
table.data.fit td .ln-sub { font-size: 11px; color: var(--dim); }
table.data.fit td .ln-money { font-weight: 700; font-variant-numeric: tabular-nums; }
table.data.fit td .pre { color: var(--faint); }
/* A long status ("Awaiting Payment") wraps inside its fixed-width cell rather
   than forcing the one thing this table promises never to do: sideways scroll. */
table.data.fit td .pill { margin-bottom: 3px; white-space: normal; }
.strip { display: flex; align-items: center; gap: 4px; }
.strip i { width: 11px; height: 11px; border-radius: 4px; display: block; }
.strip b { margin-left: 5px; font-size: 11.5px; font-weight: 700; color: var(--dim); font-variant-numeric: tabular-nums; }
/* The sticky first column is only needed when a table scrolls; fitted ones don't. */
table.data.fit th:first-child, table.data.fit td:first-child { position: static; box-shadow: none; background: transparent; }
table.data.fit tbody tr:hover td { background: var(--row-hover); }

/* ---- dropdown (enhanced <select>) --------------------------------------- */
.dd { position: relative; display: inline-block; min-width: 0; }
.dd-native {
  /* Kept in the DOM as the value, hidden from view and from the a11y tree —
     the button in front of it carries the semantics. */
  position: absolute; opacity: 0; pointer-events: none; width: 0; height: 0; margin: 0; padding: 0; border: 0;
}
.dd-btn {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 9px 11px; font: inherit; font-size: 13px; text-align: left;
  color: var(--text); background: var(--input-bg);
  border: 1px solid var(--input-border); border-radius: 10px;
  transition: border-color .15s, box-shadow .15s, background .15s;
}
.dd-btn:hover:not(:disabled) { border-color: var(--border-strong); }
.dd-btn:focus-visible { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.dd.is-open .dd-btn { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.dd-btn:disabled { background: var(--panel-2); color: var(--dim); cursor: not-allowed; }
.dd-label { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dd-label.is-placeholder { color: var(--dim); }
.dd-caret {
  flex: none; width: 8px; height: 8px; margin-left: 2px;
  border-right: 1.6px solid var(--dim); border-bottom: 1.6px solid var(--dim);
  transform: translateY(-2px) rotate(45deg); transition: transform .18s ease;
}
.dd.is-open .dd-caret { transform: translateY(1px) rotate(-135deg); }
.dd-dot { width: 8px; height: 8px; border-radius: 999px; flex: none; }

.dd-list {
  position: fixed; z-index: 120; max-width: 340px;
  background: var(--panel); border: 1px solid var(--border); border-radius: 13px;
  box-shadow: var(--shadow-lg); overflow: hidden;
  animation: ddIn .13s ease;
}
.dd-list.is-flipped { transform-origin: bottom; }
@keyframes ddIn { from { opacity: 0; transform: translateY(-4px); } }
.dd-search { padding: 9px 9px 5px; border-bottom: 1px solid var(--border); }
.dd-search input {
  width: 100%; padding: 7px 10px; font: inherit; font-size: 12.5px;
  color: var(--text); background: var(--input-bg);
  border: 1px solid var(--input-border); border-radius: 8px;
}
.dd-search input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); }
.dd-opts { max-height: 288px; overflow-y: auto; padding: 6px; }
.dd-opt {
  display: flex; align-items: center; gap: 9px;
  padding: 8px 10px; border-radius: 9px; font-size: 13px; cursor: pointer;
  color: var(--text); white-space: nowrap;
}
.dd-opt > span:first-of-type { flex: 1; overflow: hidden; text-overflow: ellipsis; }
.dd-opt.is-active { background: var(--panel-2); }
.dd-opt.is-selected { font-weight: 650; }
.dd-check { opacity: 0; color: var(--accent); font-weight: 800; }
.dd-opt.is-selected .dd-check { opacity: 1; }
.dd-none { padding: 14px 12px; font-size: 12.5px; color: var(--dim); text-align: center; }

/* ==========================================================================
   PHONE — below 820px a wide record stops being a table.
   A fixed-layout table on a 375px screen crushes every column into its
   neighbour, which is exactly the overlap this rules out: each row becomes a
   stacked card, and each cell prints its own column label. Nothing is hidden
   and nothing scrolls sideways.
   ========================================================================== */
@media (max-width: 1080px) {
  table.data.fit, table.data.fit tbody, table.data.fit tr, table.data.fit td { display: block; width: auto; }
  /* The header row is dropped entirely: once each cell prints its own label,
     a visually-hidden thead only adds a second, conflicting set of headings. */
  table.data.fit thead { display: none; }
  table.data.fit tr {
    border: 1px solid var(--border); border-radius: 14px;
    margin: 0 0 10px; padding: 4px 2px; background: var(--panel);
  }
  table.data.fit tr:last-child { margin-bottom: 0; }
  table.data.fit td {
    display: flex; align-items: flex-start; justify-content: space-between; gap: 14px;
    padding: 9px 13px; border-bottom: 1px solid var(--border); text-align: left !important;
  }
  table.data.fit td:last-child { border-bottom: 0; }
  table.data.fit td::before {
    content: attr(data-label);
    flex: 0 0 42%; min-width: 0;
    font-size: 10px; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase;
    color: var(--faint); padding-top: 2px;
  }
  /* The cell's own content sits in the right-hand half, stacked and right-aligned. */
  table.data.fit td > * { text-align: right; }
  table.data.fit td .ln, table.data.fit td .strip { margin-left: auto; }
  table.data.fit td .strip { justify-content: flex-end; }
  table.data.fit td .ln-strong { white-space: normal; }
  /* The first cell is the card's heading, not a labelled row. */
  table.data.fit td:first-child { flex-direction: column; gap: 2px; padding-top: 12px; }
  table.data.fit td:first-child::before { display: none; }
  table.data.fit td:first-child > * { text-align: left; margin-left: 0; }
  table.data.fit td:first-child .ln-strong { font-size: 14px; }
  table.data.fit tbody tr:hover td { background: transparent; }
  .empty { padding: 32px 16px; }

  /* Controls go full width rather than squeezing onto one line. */
  .toolbar { gap: 8px; }
  .toolbar > .search, .toolbar > .dd, .toolbar > .btn, .toolbar > .btn-primary { width: 100% !important; max-width: none !important; min-width: 0 !important; }
  .toolbar > .seg { width: 100%; }
  .toolbar > .seg button { flex: 1; padding: 9px 6px; }
  .toolbar > .spacer { display: none; }
  .head { flex-wrap: wrap; row-gap: 10px; }
  .head h2 { font-size: 19px; flex: 1; }
  .head > .search { order: 3; width: 100% !important; }
  .rail-actions button { padding: 12px 14px; }
  .stat { min-height: 0; }
  .kv { flex-wrap: wrap; }
  .dd-list { max-width: calc(100vw - 16px); }
}
@media (max-width: 560px) {
  table.data.fit td { flex-direction: column; gap: 3px; }
  table.data.fit td::before { flex: none; }
  table.data.fit td > *, table.data.fit td .ln, table.data.fit td .strip { text-align: left; margin-left: 0; }
  table.data.fit td .strip { justify-content: flex-start; }
  .bar-row { gap: 8px; }
}


/* ---- ring click-filter -------------------------------------------------- */
[data-seg] { cursor: pointer; }
.brk-row[data-seg] { border-radius: 9px; padding-left: 6px; padding-right: 6px; margin: 0 -6px; }
.brk-row[data-seg]:hover { background: var(--panel-2); }
.filter-chip {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 8px 6px 13px; border-radius: 999px;
  background: var(--accent-soft); color: var(--accent);
  font-size: 12px; font-weight: 700; white-space: nowrap;
}
.filter-chip button { border: 0; background: transparent; color: inherit; font-size: 14px; line-height: 1; padding: 0 4px; cursor: pointer; opacity: .7; }
.filter-chip button:hover { opacity: 1; }
.pace svg { width: 100%; height: auto; display: block; }


/* ---- brand logo --------------------------------------------------------- */
.brand-logo { height: 38px; width: auto; flex: none; }
/* The wordmark's dark "zone" needs a light ground in dark mode — a white chip
   reads as intentional branding rather than a missing transparency. */
html.dark .brand-logo { background: #fff; border-radius: 9px; padding: 4px 8px; height: 32px; }
@media (max-width: 900px) { .brand-logo { height: 30px; } html.dark .brand-logo { height: 26px; } }

/* ---- finance board ------------------------------------------------------
   The Head of Finance's dashboard: money and its diagrams only. Softer, larger
   cards than the operational dashboard — the figure is the content here, so it
   is set big and everything else recedes around it. Status colour still never
   carries meaning alone: every segment and series ships with a named legend. */
.fin { display: grid; gap: 16px; }
.fin-top { display: grid; grid-template-columns: 1.55fr 1fr 1fr; gap: 16px; align-items: stretch; }
.fin-mid { display: grid; grid-template-columns: 1.6fr 1fr; gap: 16px; align-items: stretch; }
/* Both columns of .fin-mid stack their panels, and the rail runs to the same
   depth as the main column: the league table sits under the chart, and the
   region list takes whatever height is left over.
   The chart is NOT part of that stretch — its bars are sized as a percentage
   of a fixed height, so letting the card drive its height collapses them. */
.fin-main, .fin-side { display: grid; gap: 16px; }
/* Row 1 of each column keeps its natural height (the chart's fixed height, the
   latest-payment tile); row 2 takes the slack. Symmetrical, so whichever column
   is shorter fills — it is the league table one day and the region list the
   next, depending on the data. */
.fin-main { grid-template-rows: auto 1fr; align-content: stretch; }
.fin-side { grid-template-rows: auto auto 1fr; align-content: stretch; }

/* ---- Track & print card -------------------------------------------------
   A card that behaves like a button: the whole face is the hit target, the
   arrow is the affordance, and the keyboard gets the same door as the mouse. */
.fin-report { cursor: pointer; gap: 10px; padding: 16px 18px; transition: transform .12s, box-shadow .12s, border-color .12s; }
.fin-report:hover { transform: translateY(-1px); box-shadow: var(--shadow); border-color: var(--border-strong); }
.fin-report:active { transform: none; }
.fin-report:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 2px; }
.fin-report-top { display: flex; align-items: center; }
.fin-report-top .spacer { flex: 1; }
.fin-report-ico {
  width: 30px; height: 30px; border-radius: 10px; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 13px; color: var(--faint); background: var(--panel); border: 1px solid var(--border);
}
.fin-report-go {
  width: 32px; height: 32px; border-radius: 999px; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 14px; color: var(--text); background: var(--panel);
  border: 1px solid var(--border-strong); transition: background .12s, color .12s, transform .12s;
}
.fin-report:hover .fin-report-go { background: var(--text); color: var(--panel); transform: translate(1px, -1px); }
.fin-report-tag {
  align-self: flex-start; font-size: 11px; font-weight: 600; color: var(--dim);
  background: var(--panel-2); padding: 5px 10px; border-radius: 999px;
}
.fin-report-title { font-size: 21px; font-weight: 800; letter-spacing: -0.025em; }
/* Each list grows with its card and shares the extra height evenly between its
   rows, each row centred in the space it is given — so a taller card reads as
   a roomier list rather than a short list with a void underneath. */
#fin-region, #fin-top { flex: 1; min-height: 0; align-content: stretch; }
/* The league rows are grids of their own; when the card stretches they centre
   inside the height they are handed rather than being re-flowed into a column
   (an id selector here would otherwise beat .pend-row's own display). */
#fin-top > .pend-row { align-content: center; }
/* The region card is a bar plus a key: the bar keeps its height, the key
   absorbs whatever the rail has spare. */
#fin-region { display: flex; flex-direction: column; gap: 14px; }
.reg-rows { display: grid; gap: 9px; flex: 1; min-height: 0; align-content: stretch; }
.reg-rows > .reg-row { align-content: center; }

/* ---- pending by region: one bar, split by share ------------------------
   The categorical palette in fixed slot order, stepped per mode against the
   card surface (validated: worst adjacent CVD ΔE 9.1 light / 8.4 dark, normal
   vision 19.6 / 19.3). Three light steps sit under 3:1 on white, which is why
   every segment is also named and valued in the key below — colour never
   carries a region on its own. */
.fin { --sr-1: #2a78d6; --sr-2: #eb6834; --sr-3: #1baf7a; --sr-4: #eda100; --sr-5: #e87ba4; --sr-6: #008300; }
html.dark .fin { --sr-1: #3987e5; --sr-2: #d95926; --sr-3: #199e70; --sr-4: #c98500; --sr-5: #d55181; --sr-6: #008300; }
.reg-bar {
  display: flex; gap: 2px;                 /* a surface gap, so touching hues stay two marks */
  height: 15px; border-radius: 999px; overflow: hidden; background: var(--panel-3);
}
.reg-seg { display: block; height: 100%; transition: filter .12s; }
.reg-seg:first-child { border-radius: 999px 0 0 999px; }
.reg-seg:last-child { border-radius: 0 999px 999px 0; }
.reg-seg:hover { filter: brightness(1.08); }
.reg-row { display: grid; grid-template-columns: 9px 1fr auto auto; align-items: center; gap: 9px; min-width: 0; }
.reg-dot { width: 9px; height: 9px; border-radius: 999px; flex: none; }
.reg-name { font-size: 12.5px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.reg-val { font-size: 12.5px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.reg-pct { font-size: 11px; color: var(--dim); font-variant-numeric: tabular-nums; min-width: 30px; text-align: right; }
.fin-card, .fin-hero { padding: 20px 22px; border-radius: 18px; display: flex; flex-direction: column; }
.fin-head { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; }
.fin-head h3 { font-size: 15px; letter-spacing: -0.01em; }
.fin-head .spacer { flex: 1; }
.fin-ico {
  width: 30px; height: 30px; border-radius: 999px; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 14px; line-height: 1; color: #fff;
}
.fin-ico-in { background: var(--st-done); }
.fin-ico-out { background: var(--st-hold); }
.fin-ico-chart { background: var(--info); }
.fin-ico-neutral { background: var(--panel-3); color: var(--dim); }
.fin-tag {
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--dim); background: var(--panel-2); border: 1px solid var(--border);
  padding: 5px 10px; border-radius: 999px; white-space: nowrap;
}
.fin-figure {
  font-size: 40px; font-weight: 800; letter-spacing: -0.03em; line-height: 1.05;
  font-variant-numeric: tabular-nums; overflow-wrap: anywhere;
}
.fin-figure.sm { font-size: 30px; }
.fin-figure.xs { font-size: 24px; }
.fin-figure small { font-size: 0.5em; font-weight: 700; color: var(--dim); margin-left: 3px; }
.fin-sub { margin: 9px 0 0; font-size: 12.5px; color: var(--dim); }
.fin-sub b { color: var(--text); }
.fin-delta {
  display: inline-flex; align-items: center; gap: 5px; margin-left: 10px; vertical-align: middle;
  font-size: 12px; font-weight: 700; padding: 4px 10px; border-radius: 999px;
  background: color-mix(in srgb, var(--c) var(--tint), var(--panel)); color: var(--ink);
}
.fin-delta.up { --c: var(--st-done); --ink: var(--st-done-ink); }
.fin-delta.flat { --c: var(--st-none); --ink: var(--st-none-ink); }
.fin-hero-body { display: flex; gap: 20px; align-items: flex-end; justify-content: space-between; flex: 1; flex-wrap: wrap; }
.fin-actions { display: flex; gap: 9px; margin-top: 16px; flex-wrap: wrap; }
.fin-mosaic-wrap { flex: none; }
.fin-mosaic { display: grid; grid-auto-flow: column; grid-template-rows: repeat(5, 13px); gap: 4px; }
.fin-mosaic i { width: 13px; height: 13px; border-radius: 4px; background: var(--panel-3); display: block; }
.fin-mosaic i.on { background: var(--st-done); }
.fin-mosaic i.on.dim { background: color-mix(in srgb, var(--st-done) 45%, var(--panel-3)); }
/* Two named amounts side by side, each under its own coloured rule. */
.fin-split { display: flex; gap: 20px; margin-top: 16px; padding-top: 15px; border-top: 1px solid var(--border); }
.fin-split > div { border-left: 3px solid var(--c, var(--border-strong)); padding-left: 11px; min-width: 0; }
.fin-split .k { font-size: 11.5px; color: var(--dim); }
.fin-split .v { font-weight: 700; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
/* Segmented meter with the figure called out above the active band. */
.fin-meter { margin-top: 18px; }
.fin-meter .segs { display: flex; gap: 4px; height: 9px; }
.fin-meter .segs span { border-radius: 999px; min-width: 3px; }
.fin-meter .marks { display: flex; justify-content: space-between; font-size: 11.5px; color: var(--dim); margin-bottom: 7px; font-variant-numeric: tabular-nums; }
/* The column chart: rounded stacked bars, a hover readout, and future months
   left as empty ground rather than implied zeros. */
.fin-chart { display: flex; align-items: flex-end; justify-content: center; gap: 10px; height: 230px; padding-top: 6px; }
/* Columns share the width when there are many months and stay a sane bar width
   when there are only one or two — a single month must not become a wall. */
.fin-col { flex: 1 1 0; max-width: 200px; display: flex; flex-direction: column; justify-content: flex-end; gap: 7px; height: 100%; min-width: 0; }
/* The bar sits in a growing area and takes its height as a share of that, so
   the value above it and the month label below it are never squeezed out. */
.fin-col .colarea { flex: 1; min-height: 0; display: flex; align-items: flex-end; }
.fin-col .stackcol {
  width: 100%; display: flex; flex-direction: column-reverse; justify-content: flex-start;
  border-radius: 12px; overflow: hidden; background: var(--panel-2); min-height: 4px;
}
.fin-col .stackcol i { display: block; width: 100%; }
.fin-col .lbl { text-align: center; font-size: 11px; color: var(--dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fin-col.cur .lbl { color: var(--text); font-weight: 700; }
.fin-col .amt { text-align: center; font-size: 11px; font-weight: 700; font-variant-numeric: tabular-nums; }
/* A compact history table that keeps the app's fitted-table promise: no
   sideways scrolling, cards on small screens. */
.fin-hist { width: 100%; border-collapse: separate; border-spacing: 0; table-layout: fixed; font-size: 12.5px; }
.fin-hist th {
  text-align: left; font-size: 10.5px; letter-spacing: 0.05em; text-transform: uppercase;
  color: var(--faint); font-weight: 700; padding: 9px 12px; border-bottom: 1px solid var(--border);
}
.fin-hist td { padding: 12px; border-bottom: 1px solid var(--border); vertical-align: middle; overflow-wrap: anywhere; }
.fin-hist tr:last-child td { border-bottom: 0; }
.fin-hist .site { font-weight: 650; }
.fin-hist .amt { font-weight: 700; font-variant-numeric: tabular-nums; }
.fin-hist .ta-r { text-align: right; }
@media (max-width: 1240px) {
  .fin-top { grid-template-columns: 1fr 1fr; }
  .fin-hero { grid-column: 1 / -1; }
}
@media (max-width: 900px) {
  .fin-top, .fin-mid { grid-template-columns: 1fr; }
  .fin-figure { font-size: 32px; }
  .fin-figure.sm { font-size: 26px; }
  .fin-mosaic-wrap { display: none; }
  .fin-hist thead { display: none; }
  .fin-hist, .fin-hist tbody, .fin-hist tr, .fin-hist td { display: block; width: auto; }
  .fin-hist tr { border: 1px solid var(--border); border-radius: 14px; padding: 4px 2px; margin-bottom: 10px; }
  .fin-hist td { display: flex; justify-content: space-between; gap: 14px; border-bottom: 0; padding: 7px 12px; }
  .fin-hist td::before { content: attr(data-label); color: var(--faint); font-size: 11.5px; flex: none; }
  .fin-hist .ta-r { text-align: right; }
}

/* ---- scope bar ----------------------------------------------------------
   Which bank and which kind of project the whole page is about. It lives in
   the head because it governs the dashboard, the site list, the change log and
   the exports alike — not just the table underneath it. */
.scope { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.scope .i,
.scope .dd-btn { width: auto; min-width: 132px; font-weight: 600; }
@media (max-width: 860px) {
  .head { flex-wrap: wrap; }
  .scope { order: 3; width: 100%; }
  .scope .i,
  .scope .dd-btn { flex: 1; min-width: 0; }
}

/* ---- unread change log --------------------------------------------------
   Colour is never the only signal: an unread row carries the word "New" as
   well as its tint, and the nav badge prints the number rather than glowing. */
.side-nav a .badge,
.side-nav button .badge {
  margin-left: auto;
  min-width: 20px;
  padding: 1px 6px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--on-accent);
  font-size: 10.5px;
  font-weight: 800;
  line-height: 1.6;
  text-align: center;
}
.new-count {
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--accent-soft);
  color: var(--accent-2);
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: .02em;
}
.feed-row.is-new { background: var(--accent-soft); border-radius: 10px; }
.feed-row.is-new > div { padding-right: 6px; }
.new-tag {
  margin-left: 8px;
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--on-accent);
  font-size: 9.5px;
  font-weight: 800;
  letter-spacing: .04em;
  text-transform: uppercase;
}

/* ---- proof pictures -----------------------------------------------------
   The picture that backs a date sits directly under it, so the two are read
   together rather than the photo living in a documents list nobody opens. */
.proof { margin-top: 6px; min-height: 18px; }
.proof a { color: var(--accent-2); font-weight: 700; text-decoration: none; }
.proof a:hover { text-decoration: underline; }
.warn-tag {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--st-prog) var(--tint), transparent);
  color: var(--st-prog-ink);
  font-weight: 700;
}

/* ---- site work, split by project type -----------------------------------
   Solar and UPS are different chains over different branches. Each block owns
   its denominator, and the heading says how many branches its bars measure. */
.workhead {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin: 4px 0 2px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}
.workhead:first-child { padding-top: 0; border-top: 0; }
.workhead b { font-size: 12px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; }
.workhead span { font-size: 11.5px; color: var(--faint); }

/* ================= PRINT =================================================
   What the Track & Print card produces. The app furniture goes (sidebar,
   search, buttons); the figures and their diagrams stay, on a white page with
   the colours forced through — a bar chart that prints as empty outlines is
   not a report. Panels are kept off page breaks so no card is split in half. */
@media print {
  @page { margin: 14mm; }
  html, body { background: #fff !important; }
  .side, .head .search, .rail-actions, .promo, .fin-actions, .fin-report,
  #toast, #drawer-host, .filter-chip, #see-all { display: none !important; }
  /* With the report open, it IS the printout — the dashboard behind it goes. */
  body.reporting .main, body.reporting .head, body.reporting .rep-bar { display: none !important; }
  body.reporting .rep-overlay { position: static !important; display: block !important; background: #fff !important; }
  body.reporting .rep-scroll { overflow: visible !important; padding: 0 !important; }
  body.reporting .rep-sheet {
    max-width: none !important; border: 0 !important; border-radius: 0 !important; padding: 0 !important;
  }
  .rep-block, .rep-kpi, .rep-head { break-inside: avoid; page-break-inside: avoid; }
  .rep-table thead { display: table-header-group; }   /* headings repeat on every page */
  .rep-table tr { break-inside: avoid; page-break-inside: avoid; }
  .rep-seal { -webkit-print-color-adjust: exact !important; print-color-adjust: exact !important; }
  .shell { display: block !important; }
  .main { gap: 12px !important; }
  .head { border: 0 !important; padding: 0 0 6px !important; }
  /* A printed page has to name itself and say when it was taken. */
  #page-title:after {
    content: " — Financial Report · " attr(data-stamp);
    font-size: 12px; font-weight: 600; color: #444;
  }
  .head .who, .head #me-avatar { color: #000 !important; }
  /* The report prints the money picture; the operational views are not part of it. */
  #view-sites, #view-activity, #view-users, #view-awaiting { display: none !important; }
  .pagegrid { display: block !important; }
  .fin-top, .fin-mid { display: grid !important; grid-template-columns: 1fr 1fr !important; gap: 10px !important; }
  .fin-main, .fin-side { display: block !important; }
  .fin-main > *, .fin-side > * { margin-bottom: 10px; }
  .panel, .fin-card, .fin-hero {
    box-shadow: none !important; border: 1px solid #d5dbe0 !important;
    break-inside: avoid; page-break-inside: avoid;
  }
  .fin-figure { font-size: 26px !important; }
  .fin-figure.sm { font-size: 20px !important; }
  /* Colour is data here, not decoration — keep it. */
  .reg-bar, .reg-seg, .reg-dot, .bar span, .stackcol i, .pill, .fin-mosaic i {
    -webkit-print-color-adjust: exact !important; print-color-adjust: exact !important;
  }
  .fin-chart { height: 150px !important; }
  a[href]:after { content: none !important; }
}

/* ---- headline pills & the chart readout ---------------------------------
   A delta pill sits beside the figure it qualifies, in the status ink rather
   than a raw hue, and always carries an arrow and a number — never colour on
   its own. */
.fin-pill {
  display: inline-flex; align-items: center; gap: 5px; vertical-align: middle;
  margin-left: 10px; padding: 4px 10px; border-radius: 999px;
  font-size: 12px; font-weight: 700; letter-spacing: 0; white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.fin-pill.up   { color: var(--st-done-ink); background: color-mix(in srgb, var(--st-done) 15%, transparent); }
.fin-pill.down { color: var(--st-hold-ink); background: color-mix(in srgb, var(--st-hold) 15%, transparent); }
.fin-pill.flat { color: var(--dim); background: var(--panel-2); border: 1px solid var(--border); }

/* A month with nothing in it still holds its place, but it must never read as
   a tall bar: hatching says "no data" where a flat fill would say "a big
   number". Same device the reference dashboards use for months not yet run. */
.fin-col.empty .stackcol {
  background: repeating-linear-gradient(45deg,
    var(--panel-3) 0 5px, transparent 5px 10px);
  border: 1px dashed var(--border-strong);
  opacity: .75;
}
.fin-col.empty .lbl { opacity: .6; }
.fin-col.cur .stackcol { box-shadow: 0 0 0 2px var(--accent-soft); }

/* The chart's readout card: a title, a row per series with its own dot, and the
   total under a rule. */
#tip.tip-card {
  padding: 11px 13px; border-radius: 13px; text-align: left; min-width: 168px;
  background: var(--tip-bg, #14181c); color: #fff; white-space: normal;
}
#tip.tip-card b { display: block; font-size: 12px; margin-bottom: 8px; opacity: .82; font-weight: 700; }
#tip.tip-card .tc-row {
  display: flex; align-items: center; gap: 7px; font-size: 12px; padding: 3px 0;
}
#tip.tip-card .tc-row i { width: 8px; height: 8px; border-radius: 999px; flex: none; }
#tip.tip-card .tc-row em {
  font-style: normal; font-weight: 700; margin-left: auto; font-variant-numeric: tabular-nums;
}
#tip.tip-card .tc-total {
  margin-top: 6px; padding-top: 7px; border-top: 1px solid rgba(255, 255, 255, 0.16); font-weight: 700;
}
#tip.tip-card .tc-none { opacity: .7; }

/* ---- the financial report ----------------------------------------------
   A page you read before you print it. On screen it sits over the app on its
   own scroll; on paper the app disappears and only this sheet remains. */
.rep-overlay { position: fixed; inset: 0; z-index: 70; display: flex; flex-direction: column; background: var(--page); }
.rep-bar {
  display: flex; align-items: center; gap: 10px; padding: 12px 18px;
  background: var(--panel); border-bottom: 1px solid var(--border); flex: none;
}
.rep-bar .spacer { flex: 1; }
.rep-scroll { flex: 1; overflow: auto; padding: 22px 18px 40px; }
.rep-sheet {
  max-width: 920px; margin: 0 auto; background: var(--panel); color: var(--text);
  border: 1px solid var(--border); border-radius: 16px; padding: 34px 38px;
}
.rep-head { display: flex; align-items: flex-start; gap: 16px; border-bottom: 2px solid var(--text); padding-bottom: 16px; }
.rep-head h1 { font-size: 30px; letter-spacing: -0.03em; margin: 2px 0 0; }
.rep-kicker { font-size: 11px; font-weight: 800; letter-spacing: 0.1em; text-transform: uppercase; color: var(--dim); }
.rep-sub { margin: 7px 0 0; font-size: 12.5px; color: var(--dim); }
.rep-seal {
  margin-left: auto; flex: none; width: 54px; height: 54px; border-radius: 999px;
  display: flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 800; color: var(--on-accent); background: var(--accent);
}
.rep-kpis { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin: 20px 0 6px; }
.rep-kpi { border: 1px solid var(--border); border-radius: 12px; padding: 13px 14px; background: var(--panel-2); }
.rep-kpi .cap { font-size: 10.5px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: var(--dim); }
.rep-kpi .val { font-size: 17px; font-weight: 800; margin-top: 6px; font-variant-numeric: tabular-nums; letter-spacing: -0.02em; }
.rep-kpi .note { font-size: 11px; color: var(--dim); margin-top: 4px; }
.rep-block { margin-top: 26px; }
.rep-block h2 { font-size: 15px; letter-spacing: -0.01em; margin-bottom: 10px; }
.rep-note { font-size: 11px; font-weight: 600; color: var(--dim); }
.rep-empty { font-size: 12.5px; color: var(--dim); margin: 0; }
.rep-table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.rep-table th, .rep-table td { padding: 8px 10px; border-bottom: 1px solid var(--border); text-align: left; }
.rep-table th { font-size: 10.5px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: var(--dim); }
.rep-table td.n, .rep-table th.n { text-align: right; font-variant-numeric: tabular-nums; }
.rep-table td.b { font-weight: 700; }
.rep-table tfoot td { border-top: 2px solid var(--border-strong); border-bottom: 0; font-weight: 700; }
.rep-foot { margin-top: 28px; padding-top: 12px; border-top: 1px solid var(--border); font-size: 11px; color: var(--dim); }
@media (max-width: 760px) {
  .rep-kpis { grid-template-columns: 1fr 1fr; }
  .rep-sheet { padding: 22px 18px; }
}

/* ---- payment history & the pending league table -------------------------
   Both read as rows of events rather than rows of a spreadsheet: who, what,
   how much, and — for a debt — how it compares with the rest. */
.hist-search { width: 168px; }
.hist-search .i { height: 32px; font-size: 12px; }
.hist-who { display: flex; align-items: center; gap: 10px; min-width: 0; }
.hist-names { display: flex; flex-direction: column; min-width: 0; line-height: 1.3; }
.hist-names b { font-weight: 650; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hist-names em { font-style: normal; font-size: 11px; color: var(--dim); }
.hist-kind { display: inline-flex; align-items: center; gap: 7px; font-size: 12px; white-space: nowrap; }
.hist-kind i { width: 8px; height: 8px; border-radius: 999px; flex: none; }
/* The state of a payment that has landed. Said in a word, not in a colour. */
.hist-state {
  display: block; margin-top: 3px; font-size: 10.5px; font-weight: 700;
  letter-spacing: 0.03em; text-transform: uppercase; color: var(--st-done-ink);
}

.pend-row { display: grid; grid-template-columns: 20px 1fr auto; align-items: center; gap: 12px; }
.pend-rank {
  font-size: 11px; font-weight: 800; color: var(--faint); font-variant-numeric: tabular-nums; text-align: right;
}
.pend-main { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.pend-name { font-size: 12.5px; font-weight: 650; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pend-meta { font-style: normal; font-size: 11px; color: var(--dim); }
.pend-track { display: block; height: 6px; border-radius: 999px; background: var(--panel-3); overflow: hidden; }
.pend-track i { display: block; height: 100%; border-radius: 999px; background: var(--st-prog); }
.pend-fig { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; white-space: nowrap; }
.pend-fig b { font-size: 13px; font-variant-numeric: tabular-nums; }
.pend-fig em { font-style: normal; font-size: 10.5px; color: var(--dim); font-variant-numeric: tabular-nums; }

@media (max-width: 700px) {
  .hist-search { width: 100%; order: 3; margin-top: 8px; }
  .pend-row { grid-template-columns: 18px 1fr auto; gap: 9px; }
}

/* ---- awaiting payment: the chase list -----------------------------------
   One row per invoice out. The wait is stated in days AND banded by colour,
   never colour alone, and the row is a button: click or Enter opens the site. */
.aw-list { display: grid; }
.aw-row {
  display: grid; grid-template-columns: auto 1fr auto auto; align-items: center; gap: 14px;
  padding: 13px 16px; border-bottom: 1px solid var(--border); cursor: pointer;
  transition: background .12s;
}
.aw-row:last-child { border-bottom: 0; }
.aw-row:hover { background: var(--row-hover); }
.aw-row:focus-visible { outline: 2px solid var(--accent-2); outline-offset: -2px; }
.aw-main { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.aw-name { font-size: 13px; font-weight: 650; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.aw-meta { font-style: normal; font-size: 11.5px; color: var(--dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.aw-wait { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; white-space: nowrap; }
.aw-wait em { font-style: normal; font-size: 11px; color: var(--dim); }
.aw-amt { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; white-space: nowrap; min-width: 128px; }
.aw-amt b { font-size: 13.5px; font-weight: 700; font-variant-numeric: tabular-nums; }
.aw-amt em { font-style: normal; font-size: 10.5px; letter-spacing: 0.03em; text-transform: uppercase; color: var(--faint); }

@media (max-width: 820px) {
  .aw-row { grid-template-columns: auto 1fr; row-gap: 10px; }
  .aw-wait, .aw-amt { grid-column: 2; align-items: flex-start; }
  .aw-wait { flex-direction: row; align-items: center; gap: 9px; }
  .aw-amt { min-width: 0; }
}

/* ---- the activity page --------------------------------------------------
   A log read end to end: grouped by the day it happened, with the clock time
   on the right so two changes a minute apart can be told apart. */
.act-day + .act-day { margin-top: 22px; }
.act-day-head {
  display: flex; align-items: baseline; gap: 10px; padding: 0 2px 9px;
  border-bottom: 1px solid var(--border); margin-bottom: 4px;
}
.act-day-head span { font-size: 12.5px; font-weight: 800; letter-spacing: -0.01em; }
.act-day-head em { font-style: normal; font-size: 11px; color: var(--dim); }
.act-row {
  display: grid; grid-template-columns: auto 1fr auto; align-items: start; gap: 12px;
  padding: 11px 2px; border-bottom: 1px solid var(--border);
}
.act-row:last-child { border-bottom: 0; }
.act-body p { margin: 0; font-size: 12.5px; line-height: 1.5; }
.act-body p b { font-weight: 650; }
.act-time {
  display: flex; align-items: center; gap: 7px; white-space: nowrap;
  font-size: 11px; color: var(--dim); font-variant-numeric: tabular-nums; padding-top: 2px;
}
/* Unread is a word and a tint, never the tint alone. */
.act-row.is-new { background: var(--accent-soft); border-radius: 10px; padding-left: 10px; padding-right: 10px; }

@media (max-width: 620px) {
  .act-row { grid-template-columns: auto 1fr; }
  .act-time { grid-column: 2; padding-top: 0; }
}

/* ---- accounts -----------------------------------------------------------
   A row per person: who they are, what they may do, how far it reaches, and
   whether they can sign in at all. */
.acct-row {
  display: grid; grid-template-columns: auto minmax(0, 1.1fr) minmax(0, 1.3fr) minmax(0, 1fr) auto;
  align-items: center; gap: 14px;
  padding: 14px 16px; border-bottom: 1px solid var(--border); cursor: pointer;
  transition: background .12s;
}
.acct-row:last-child { border-bottom: 0; }
.acct-row:hover { background: var(--row-hover); }
.acct-row:focus-visible { outline: 2px solid var(--accent-2); outline-offset: -2px; }
/* A disabled account is dimmed AND says Disabled — never dimming alone. */
.acct-row.is-off { opacity: .62; }
.acct-main, .acct-role, .acct-scope { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.acct-name { font-size: 13px; font-weight: 650; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.acct-user, .acct-role em, .acct-scope em {
  font-style: normal; font-size: 11px; color: var(--dim);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.acct-scope b { font-size: 12px; font-weight: 600; }
.role-badge {
  align-self: flex-start; font-size: 11px; font-weight: 700; padding: 3px 9px;
  border-radius: 7px; white-space: nowrap;
  background: var(--panel-3); color: var(--dim);
}
/* The badge tints by what the role can reach, so the table can be scanned for
   "who can change the money" without reading every line. */
.role-badge.role-admin    { background: color-mix(in srgb, var(--accent-2) 16%, transparent); color: var(--accent-2); }
.role-badge.role-accounts { background: color-mix(in srgb, var(--info) 16%, transparent); color: var(--info); }
.role-badge.role-finance  { background: color-mix(in srgb, var(--st-prog) 20%, transparent); color: var(--st-prog-ink); }
.role-badge.role-staff    { background: color-mix(in srgb, var(--st-done) 16%, transparent); color: var(--st-done-ink); }
.role-badge.role-bank     { background: var(--panel-3); color: var(--dim); }

@media (max-width: 900px) {
  .acct-row { grid-template-columns: auto 1fr auto; row-gap: 10px; }
  .acct-role, .acct-scope { grid-column: 2 / -1; }
}

/* ---- notification preferences -------------------------------------------
   A row per kind of message, each one a switch that saves itself. The label is
   the hit target, so the whole row responds rather than a 20px box. */
.who-btn {
  background: none; border: 0; padding: 0; font: inherit; color: inherit;
  text-align: right; cursor: pointer; border-radius: 9px;
}
.who-btn:hover b { text-decoration: underline; }
.who-btn:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 3px; }

.prefs { display: flex; flex-direction: column; }
.pref-row {
  display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 16px;
  padding: 13px 2px; border-bottom: 1px solid var(--border); cursor: pointer;
}
.pref-row:last-child { border-bottom: 0; }
.pref-t { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.pref-t b { font-size: 13px; font-weight: 650; }
.pref-t em { font-style: normal; font-size: 11.5px; color: var(--dim); }
/* The checkbox stays in the DOM as the value and the focus target; the switch
   beside it is what gets painted. */
.pref-box { position: absolute; opacity: 0; width: 0; height: 0; }
.pref-switch {
  grid-column: 2; width: 42px; height: 24px; border-radius: 999px; flex: none;
  background: var(--panel-3); border: 1px solid var(--border-strong);
  position: relative; transition: background .14s, border-color .14s;
}
.pref-switch::after {
  content: ''; position: absolute; top: 2px; left: 2px;
  width: 18px; height: 18px; border-radius: 999px; background: var(--panel);
  box-shadow: var(--shadow-sm); transition: transform .14s;
}
.pref-box:checked ~ .pref-switch { background: var(--accent-2); border-color: var(--accent-2); }
.pref-box:checked ~ .pref-switch::after { transform: translateX(18px); }
.pref-box:focus-visible ~ .pref-switch { outline: 2px solid var(--accent-2); outline-offset: 2px; }
