/* Commission dashboard — modern, system-font, green-accent UI.
   Carries the design language of the original wireframe. */
:root {
  --bg: #f4f6f8;
  --surface: #ffffff;
  --surface-2: #f8fafc;
  --border: #e5e8ee;
  --border-strong: #d4d9e2;
  --text: #0d1b2a;
  --text-2: #41506a;
  --muted: #7c899e;
  --accent: #0f9d6b;
  --accent-ink: #097552;
  /* Semantic status hues. Accent (green) is reserved for monetary amounts and
     success; warn (amber) and danger (red) are soft pastels for warnings.
     Pastel backgrounds are derived from these with color-mix at the use site. */
  --danger: #c0392b;
  --warn: #d99a16;
  --warn-ink: #8a6109;
  --success: var(--accent);
  --shadow-sm: 0 1px 2px rgba(13, 27, 42, .04), 0 1px 3px rgba(13, 27, 42, .06);
  --shadow-md: 0 4px 12px rgba(13, 27, 42, .06), 0 2px 6px rgba(13, 27, 42, .05);
  --radius: 14px;
  --radius-sm: 9px;
  --font: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --mono: "SFMono-Regular", ui-monospace, "Cascadia Mono", Menlo, Consolas, monospace;
}
/* Dark tokens — applied by an explicit data-theme="dark", or by the system
   preference when the user hasn't chosen (data-theme unset). A JS toggle sets
   data-theme on <html> and persists it. */
:root[data-theme="dark"] {
  --bg: #0c1118; --surface: #151b24; --surface-2: #1a212c;
  --border: #28323f; --border-strong: #36424f;
  --text: #e7edf5; --text-2: #aab6c7; --muted: #8190a3;
  --accent: #2bd49a; --accent-ink: #2bd49a;
  --warn: #e0b65a; --warn-ink: #e0b65a;
  --shadow-sm: 0 1px 2px rgba(0,0,0,.3); --shadow-md: 0 6px 20px rgba(0,0,0,.35);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #0c1118; --surface: #151b24; --surface-2: #1a212c;
    --border: #28323f; --border-strong: #36424f;
    --text: #e7edf5; --text-2: #aab6c7; --muted: #8190a3;
    --accent: #2bd49a; --accent-ink: #2bd49a;
    --warn: #e0b65a; --warn-ink: #e0b65a;
    --shadow-sm: 0 1px 2px rgba(0,0,0,.3); --shadow-md: 0 6px 20px rgba(0,0,0,.35);
  }
}

/* Theme toggle button */
/* The warm-paper design drops the light/dark toggle — hidden app-wide. */
.theme-toggle { display: none; }

/* Shared sortable data table (earthy) — used across dashboards, profile, etc.
   Click a header to sort; numeric columns get tabular, right-aligned figures.
   Sorting is wired generically in app.js.

   Headings stay on ONE line. Letting them wrap produced ragged two-line labels
   whose lines don't align with each other (worst on right-aligned money
   columns), and sized every column by its heading rather than its data. A
   table genuinely wider than its container scrolls inside `.table-scroll`
   instead, which pins the heading row and the leading column. */
.data-table {
  width: 100%; border-collapse: collapse; font-size: 13px; color: #2A2723;
  /* Tabular figures for the whole grid, so dates and percentages line up
     column-wise too — not just the `.num` money columns. */
  font-variant-numeric: tabular-nums;
}
.data-table thead th {
  text-align: left; font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 10px; letter-spacing: .05em; text-transform: uppercase; color: #8A847A;
  font-weight: 500; padding: 10px 8px 8px; border-bottom: 1px solid #DDD7CB;
  white-space: nowrap; vertical-align: bottom;
  /* Every column shrinks to its content ... */
  width: 1%;
}
/* ... and the leading column (the customer/deal name) absorbs whatever width
   is left over, so a table narrower than its card fills the card instead of
   spreading the slack as a gap in front of every column. */
.data-table thead th:first-child { width: auto; }
.data-table th.num, .data-table td.num { text-align: right; font-variant-numeric: tabular-nums; }
.data-table th[data-sort] { cursor: pointer; user-select: none; }
.data-table th[data-sort]:hover { color: #2A2723; }
/* The sort caret is a zero-width glyph that paints into the cell padding, so
   it costs no column width (it did: ~14px × every column) and nothing reflows
   when it appears. Shown on hover, and kept on for the sorted column. */
.data-table th[data-sort]::after {
  content: "↕"; display: inline-block; width: 0; margin-left: 3px;
  font-size: 9px; opacity: 0;
}
.data-table th[data-sort]:hover::after { opacity: .45; }
.data-table th[aria-sort]::after { opacity: 1; }
.data-table th[aria-sort="ascending"]::after { content: "↑"; }
.data-table th[aria-sort="descending"]::after { content: "↓"; }
.data-table tbody td { padding: 6px 8px; border-bottom: 1px solid #F1ECE4; white-space: nowrap; line-height: 1.35; }
.data-table tbody tr:nth-child(even) { background: #FBF8F2; }
.data-table tbody tr:hover { background: #F6F2EA; }
.data-table tbody tr:last-child td { border-bottom: none; }
.data-table .dt-strong { font-weight: 700; }
.data-table .dt-muted { color: #8A847A; }
.data-table__empty { color: #8A847A; font-size: 14px; padding: 14px 12px; }
/* A wide table scrolls inside its own container rather than pushing the page
   sideways. macOS hides overlay scrollbars until you scroll, which leaves no
   hint that there are more columns — so the bar is kept thin but permanent. */
.table-scroll { scrollbar-width: thin; scrollbar-color: #D2CCC0 transparent; overscroll-behavior-x: contain; }
.table-scroll::-webkit-scrollbar { width: 9px; height: 9px; }
.table-scroll::-webkit-scrollbar-track { background: transparent; }
.table-scroll::-webkit-scrollbar-thumb { background: #D2CCC0; border-radius: 999px; border: 2px solid transparent; background-clip: content-box; }
.table-scroll::-webkit-scrollbar-thumb:hover { background: #B4AEA2; background-clip: content-box; }
/* Coloured source indicator + rate badge for detail tables. */
.src-dot { display: inline-block; width: 7px; height: 7px; border-radius: 50%; margin-right: 7px; vertical-align: middle; }
.src-dot--self { background: #2F7D52; }
.src-dot--inbound { background: #3B6FB0; }
.src-dot--sdr { background: #B5701C; }
.src-dot--bloom { background: #C2557A; }
.rate-badge { font-family: "JetBrains Mono", ui-monospace, monospace; font-size: 11px; background: #F1ECE4;
  color: #6B655B; border: 1px solid #E2DDD3; border-radius: 6px; padding: 2px 7px; }
/* The full (self-sourced) rate is highlighted; reduced rates stay neutral. */
.rate-badge--full { background: #EEF6F0; color: #2F7D52; border-color: #D4E8DB; font-weight: 700; }
/* Filter input that narrows a data table (wired in app.js). */
.dt-filter { padding: 8px 12px; border: 1px solid #E2DDD3; border-radius: 10px; background: #FFFFFF;
  font-size: 13px; font-family: inherit; color: #2A2723; outline: none; min-width: 200px; }
.dt-filter:focus { border-color: #2A2723; }

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  background: var(--bg); color: var(--text); font-family: var(--font);
  font-size: 14px; line-height: 1.5; -webkit-font-smoothing: antialiased;
}
a { color: var(--accent-ink); text-decoration: none; }
.mono { font-family: var(--mono); font-size: 13px; }
.muted { color: var(--muted); }

/* Top nav — shared earthy/warm-paper component used by every page. The whole
   app is moving to this palette, so the nav lives here (one source of truth)
   rather than being re-declared per template via body:has() overrides. */
.topnav {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 26px; background: #FCFAF6;
  border-bottom: 1px solid #E7E2D9;
}
.topnav__brand { font-weight: 700; font-size: 17px; color: #2A2723; letter-spacing: -.2px; }
.brand-mark { color: #2F7D52; margin-right: 4px; }
.topnav__actions { display: flex; align-items: center; gap: 8px; }
/* Earthy nav buttons (shared across pages). */
.topnav .btn { color: #6B655B; background: #FFFFFF; border: 1px solid #E2DDD3; }
.topnav .btn:hover { color: #2A2723; border-color: #2A2723; background: #FFFFFF; }
/* Current section: filled ink chip so "where am I" reads at a glance. */
.topnav .btn[aria-current="page"] { color: #F6F2EA; background: #2A2723; border-color: #2A2723; font-weight: 600; }
.topnav .btn[aria-current="page"]:hover { color: #F6F2EA; background: #2A2723; }

/* Notice banner — the timed announcement every user sees at the top of every
   page. Shares the maintenance banner's geometry on purpose: they can be up at
   once, and two bars of different heights stacked on each other looks like a
   bug.

   What it does NOT share is the meaning. The maintenance bar tells an admin the
   company is locked out; this one tells everybody something while the product
   keeps working normally. Hence the two tones: neutral blue for "heads up",
   amber for "something is off, we know" — the same amber as maintenance,
   because it means the same kind of thing.

   No `display: none` for dismissal: dismissing removes the element (see
   layout.html), so there is never a hidden banner sitting in the DOM. */
.notice-banner {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 26px; font-size: 13px; line-height: 1.4;
  background: #EDF3FA; color: #2C5578; border-bottom: 1px solid #D6E4F0;
}
.notice-banner__dot {
  width: 7px; height: 7px; border-radius: 50%; background: #3B7BB8; flex: 0 0 auto;
}
.notice-banner__text { flex: 1; }
.notice-banner--warning { background: #FBF4E4; color: #8A6109; border-bottom-color: #F0E3C6; }
.notice-banner--warning .notice-banner__dot { background: #D99A16; }
.notice-banner__dismiss {
  flex: 0 0 auto; margin-left: auto;
  background: none; border: 0; padding: 2px 4px;
  font: inherit; font-size: 12px; font-weight: 600; color: inherit; opacity: .75;
  cursor: pointer; text-decoration: underline; text-underline-offset: 2px;
}
.notice-banner__dismiss:hover { opacity: 1; }
/* Focus mode hides the nav; the banner goes with it, exactly as the maintenance
   one does — a full-page view is for reading numbers. Out of the way, not gone:
   leaving focus mode brings it back. */
:root[data-fullpage="on"] .notice-banner { display: none; }

/* Demo banner — shown on every page of a DEMO_MODE instance, to everyone, for
   as long as the instance exists. Purple rather than the notice's blue or the
   maintenance amber: it is neither an announcement nor a warning about the
   site's state, and reusing either palette would make "this is sample data"
   read as the same class of message as "we are back at 14:00". Sits above the
   nav, so it survives into any screenshot of the page. */
.demo-banner {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 26px; font-size: 13px; line-height: 1.4;
  background: #F1ECFA; color: #52397F; border-bottom: 1px solid #DED3F0;
}
.demo-banner__tag {
  flex: 0 0 auto; padding: 1px 7px; border-radius: 3px;
  background: #6B4BA8; color: #fff;
  font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
}
.demo-banner__text { flex: 1; }
/* Focus mode hides the nav and the other banners with it. This one stays: a
   full-page view is the one most likely to be screenshotted, and it is also the
   one where the surrounding context that says "demo" is gone. */

/* The demo's sign-in hint: who the Google gate admits. Only rendered on a
   DEMO_MODE instance, where it is the only thing a viewer needs to know. */
.auth__demo {
  margin: 14px 0 0; padding: 10px 12px;
  background: #F6F3FC; border: 1px solid #DED3F0; border-radius: 8px;
  font-size: 13px; line-height: 1.45; color: #52397F;
}

/* Maintenance banner (DATA-541) — shown only to admins, only while the switch is
   on. Amber rather than red: nothing is broken, but the public is locked out and
   an admin must not be able to forget that. Sits between the nav and the page so
   it is unmissable without displacing the layout. */
.maint-banner {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 26px; font-size: 13px; line-height: 1.4;
  background: #FBF4E4; color: #8A6109; border-bottom: 1px solid #F0E3C6;
}
.maint-banner__dot {
  width: 7px; height: 7px; border-radius: 50%; background: #D99A16; flex: 0 0 auto;
}
.maint-banner a { margin-left: auto; color: #8A6109; font-weight: 600; text-decoration: underline; text-underline-offset: 2px; }
/* Focus mode hides the nav; the banner goes with it (the settings page, where
   the switch lives, never runs full-page). */
:root[data-fullpage="on"] .maint-banner { display: none; }

/* Admin build footer (DATA-636) — which commit is running, and since when.
   Rendered only for admins (the template function returns nothing for anyone
   else), so it needs no CSS-level hiding and must never be given any: a
   `display: none` here would read as a security control while being one view
   source away from useless.

   An ops affordance, styled to sit under the page rather than in it: fixed to
   the bottom-left corner, monospace, dimmed until pointed at. `.app` already
   reserves 60px of bottom padding, so it overlaps nothing at rest. Kept in focus
   mode too, unlike the maintenance banner — "always visible for admins" is the
   requirement, and the answer to "is my change deployed" is most often wanted
   exactly while staring at the numbers full-page. */
.buildbar {
  position: fixed; left: 0; bottom: 0; z-index: 40;
  display: flex; align-items: center; gap: 7px;
  /* Wide enough for a full conventional commit subject alongside the fixed
     fields, capped so the bar never becomes the widest thing on the page. */
  max-width: min(820px, 94vw);
  padding: 5px 12px 5px 10px;
  background: #FCFAF6;
  border: 1px solid #E7E2D9; border-left: 0; border-bottom: 0;
  border-radius: 0 9px 0 0;
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 10.5px; line-height: 1.5;
  color: #8A847A; white-space: nowrap;
  /* Dimmed at rest so it never competes with the page, opaque on hover so it
     can actually be read (and its titles inspected) when it is wanted. */
  opacity: .5; transition: opacity .12s ease;
}
.buildbar:hover { opacity: 1; }
.buildbar__dot { width: 6px; height: 6px; border-radius: 50%; background: #2F7D52; flex: 0 0 auto; }
.buildbar__sha { font: inherit; color: #2A2723; font-weight: 600; }
/* The commit subject is the only free-text field and the only one allowed to
   lose characters: it truncates so a long message can never push the timings —
   the fields with a fixed, small width — off the end of the bar. */
.buildbar__subject { overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.buildbar__author, .buildbar__built, .buildbar__timing { flex: 0 0 auto; }
.buildbar__sep { color: #D8D2C6; flex: 0 0 auto; }
.buildbar__timing { font-variant-numeric: tabular-nums; }
@media print { .buildbar { display: none; } }

.app { max-width: 1280px; margin: 0 auto; padding: 24px 26px 60px; }

/* ── Full-page ("focus") mode ─────────────────────────────────────────────────
   The individual stats view can drop the app chrome and go full-bleed so the
   wide commission tables get every available pixel. Only pages that opt in set
   `data-fullpage` on <html> (rep_dashboard.html does, before first paint, so
   there is no flash of the narrow layout) — nothing else in the app is
   affected, and clearing the attribute restores the normal layout exactly.
   The in-page toggle stays visible while the nav is hidden, so this is never a
   one-way door; Escape also exits (see app.js). */
:root[data-fullpage="on"] .topnav { display: none; }
:root[data-fullpage="on"] .app { max-width: none; padding: 16px 22px 48px; }
@media (max-width: 640px) {
  :root[data-fullpage="on"] .app { padding: 12px 14px 40px; }
}

/* Page head */
.pagehead { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin-bottom: 22px; }
.pagehead__title { margin: 0; font-size: 24px; font-weight: 700; letter-spacing: -.3px; }
.pagehead__sub { margin: 4px 0 0; color: var(--muted); }

/* Cards */
.card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--shadow-sm);
  padding: 22px; margin-bottom: 18px;
}
.card__title { margin: 0 0 14px; font-size: 16px; font-weight: 650; }

/* Buttons */
.btn {
  display: inline-flex; align-items: center; gap: 8px; cursor: pointer;
  border: 1px solid var(--border-strong); background: var(--surface);
  color: var(--text); border-radius: var(--radius-sm);
  padding: 10px 16px; font-size: 14px; font-weight: 600; font-family: inherit;
  transition: filter .12s ease, background .12s ease;
}
.btn:hover { filter: brightness(.98); }
.btn--sm { padding: 6px 12px; font-size: 13px; }
.btn--primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn--primary:hover { background: var(--accent-ink); }
.btn--ghost { background: transparent; }
.btn--google { width: 100%; justify-content: center; background: var(--surface); }
.btn--google .g { font-weight: 800; color: #4285f4; }

/* Forms */
.form { display: flex; flex-direction: column; gap: 14px; }
.form--inline { flex-direction: row; flex-wrap: wrap; align-items: flex-end; }
.form--row { display: flex; gap: 8px; align-items: center; }
.form--row select { min-width: 120px; padding: 6px 10px; }
.form__hint { margin: 0; color: var(--muted); font-size: 13px; }
.field { display: flex; flex-direction: column; gap: 6px; font-size: 13px; color: var(--text-2); }
.field > span { font-weight: 600; }
.field input, .field select {
  padding: 10px 12px; border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm); background: var(--surface-2);
  color: var(--text); font-size: 14px; font-family: inherit; min-width: 220px;
}
.field input:focus, .field select:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
.inline { display: inline; }

/* Auth pages */
.auth { min-height: 70vh; display: grid; place-items: center; }
.auth__card { width: 100%; max-width: 380px; }
.auth__title { margin: 0 0 2px; font-size: 22px; font-weight: 700; }
.auth__sub { margin: 0 0 18px; color: var(--muted); }
.divider { display: flex; align-items: center; gap: 10px; color: var(--muted); font-size: 12px; margin: 16px 0; }
.divider::before, .divider::after { content: ""; flex: 1; height: 1px; background: var(--border); }

/* Collapsed "other sign-in options" */
.advanced { margin-top: 18px; border-top: 1px solid var(--border); padding-top: 6px; }
.advanced > summary {
  cursor: pointer; list-style: none; color: var(--muted); font-size: 13px;
  padding: 8px 0; user-select: none; text-align: center;
}
.advanced > summary::-webkit-details-marker { display: none; }
.advanced > summary:hover { color: var(--text-2); }
.advanced[open] > summary { margin-bottom: 8px; }
.advanced .form { margin-top: 4px; }

/* Alerts */
.alert { background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 12px 14px; font-size: 13px; color: var(--text-2); }
.alert--error { border-color: var(--danger); color: var(--danger); background: rgba(192,57,43,.06); }

/* Table */
.table { width: 100%; border-collapse: collapse; font-size: 13px; }
.table th { text-align: left; color: var(--muted); font-weight: 600; padding: 8px 10px; border-bottom: 1px solid var(--border); }
.table td { padding: 10px; border-bottom: 1px solid var(--border); }

/* Rep dashboard: avatar + employee head */
.emp-head { display: flex; align-items: center; gap: 14px; }
.avatar {
  width: 46px; height: 46px; border-radius: 12px; display: grid; place-items: center;
  font-weight: 700; font-size: 15px; letter-spacing: .5px; color: #fff;
  background: linear-gradient(135deg, var(--accent), var(--accent-ink)); box-shadow: var(--shadow-sm);
}

.avatar--sm { width: 38px; height: 38px; font-size: 13px; border-radius: 10px; }

/* Team roster (grouped by function) */
.section-title { font-size: 14px; font-weight: 700; color: var(--text-2); margin: 24px 0 10px; }
.roster-count { display: inline-block; margin-left: 4px; padding: 1px 8px; border-radius: 999px; background: var(--surface-2); color: var(--muted); font-size: 12px; font-weight: 600; }
.emp-list { display: flex; flex-direction: column; gap: 8px; }
.emp-row {
  display: flex; align-items: center; gap: 13px; background: var(--surface);
  border: 1px solid var(--border); border-radius: 12px; padding: 11px 16px; box-shadow: var(--shadow-sm);
}
.emp-row__id { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.emp-row__name { font-weight: 700; font-size: 15px; color: var(--text); }
.emp-row__sub { font-size: 12px; color: var(--muted); }
.emp-row__meta { margin-left: auto; display: flex; align-items: center; gap: 10px; }
.emp-row__level { font-size: 12.5px; color: var(--muted); white-space: nowrap; }
.emp-row__fn select { padding: 6px 10px; font-size: 13px; min-width: 110px; border: 1px solid var(--border-strong); border-radius: var(--radius-sm); background: var(--surface-2); color: var(--text); }
.emp-row__go { color: var(--muted); font-weight: 700; font-size: 18px; text-decoration: none; padding: 0 4px; }
.emp-row__go:hover { color: var(--accent-ink); }
.emp-row--link { text-decoration: none; color: inherit; transition: background .12s, border-color .12s, transform .1s; }
.emp-row--link:hover { background: var(--surface-2); border-color: var(--border-strong); transform: translateX(2px); }

/* Executive overview */
.ctable th.is-active, .ctable td.is-active { background: rgba(15,157,107,.07); }
.ctable tfoot td { border-top: 2px solid var(--border-strong); }
.role-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.role-chip { padding: 5px 12px; border-radius: 999px; background: var(--surface-2); border: 1px solid var(--border); font-size: 13px; color: var(--text-2); }
.role-chip b { color: var(--text); }

/* Person details page */
.badges { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin: 8px 0 0; }
.detail-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 16px; align-items: stretch; }
/* Equal-height cards with their action row anchored to the bottom, so the
   Save / Restrict / Archive buttons line up across the row. */
.detail-grid .card { margin-bottom: 0; display: flex; flex-direction: column; }
.detail-grid .card > :last-child { margin-top: auto; }
.plan-form { display: flex; flex-wrap: wrap; gap: 16px 18px; align-items: flex-end; }
.plan-form .field { gap: 6px; }
.plan-form .field input, .plan-form .field select { min-width: 140px; }
.plan-form .field--wide input { min-width: 260px; }

/* Key/value list (account & detail readouts) */
.kv { display: grid; gap: 0; margin: 4px 0 0; }
.kv > div { display: flex; justify-content: space-between; gap: 16px; align-items: baseline; padding: 10px 0; border-bottom: 1px solid var(--border); }
.kv > div:last-child { border-bottom: 0; padding-bottom: 0; }
.kv dt { color: var(--text-2); font-size: 13px; }
.kv dd { margin: 0; font-weight: 600; text-align: right; }
.subhead { margin: 22px 0 0; font-size: 13px; font-weight: 650; text-transform: uppercase; letter-spacing: .04em; color: var(--text-2); }

/* Month tabs */
.monthtabs { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 20px; }
.monthtab {
  display: flex; flex-direction: column; gap: 2px; padding: 8px 14px;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--text); font-weight: 600; font-size: 14px;
}
.monthtab small { color: var(--muted); font-weight: 500; font-size: 12px; }
.monthtab.is-active { border-color: var(--accent); background: rgba(15,157,107,.06); }
.monthtab.is-active small { color: var(--accent-ink); }
.mtd-tag { font-size: 10px; background: var(--accent); color: #fff; padding: 1px 5px; border-radius: 4px; vertical-align: middle; }

/* KPI cards */
.kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 14px; margin-bottom: 18px; }
.kpi { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow-sm); padding: 16px 18px; }
.kpi--accent { border-color: var(--accent); background: rgba(15,157,107,.05); }
.kpi__label { color: var(--muted); font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; }
.kpi__value { font-size: 24px; font-weight: 750; letter-spacing: -.4px; margin: 6px 0 4px; }
.kpi__sub { color: var(--muted); font-size: 12px; }
.delta { font-weight: 700; margin-left: 4px; }
.delta--up { color: var(--accent-ink); }
.delta--down { color: var(--danger); }
.delta--flat { color: var(--muted); }

/* Charts */
.chart-wrap { position: relative; height: 300px; }
.chart-wrap--sm { height: 260px; }
.chart-wrap--donut { display: grid; place-items: center; }
.donut-center { position: absolute; top: 44%; left: 0; right: 0; text-align: center; pointer-events: none; transform: translateY(-50%); }
.donut-center b { display: block; font-size: 18px; font-weight: 750; color: var(--text); letter-spacing: -.3px; }
.donut-center span { font-size: 11px; color: var(--muted); }
.chart-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 18px; }

/* Customer table */
.table-card { padding-top: 18px; }
.table-scroll { overflow-x: auto; }
.ctable { width: 100%; border-collapse: collapse; font-size: 13px; white-space: nowrap; }
.ctable th { text-align: left; color: var(--muted); font-weight: 600; padding: 8px 12px; border-bottom: 1px solid var(--border);
  white-space: normal; vertical-align: bottom; }
.ctable th.num { text-align: right; }
.ctable td { padding: 9px 12px; border-bottom: 1px solid var(--border); }
.ctable .num { text-align: right; font-variant-numeric: tabular-nums; }
.ctable .strong { font-weight: 650; }
.ctable tbody tr:hover { background: var(--surface-2); }
/* Customers with no commission in the selected month — de-emphasised. */
.ctable tbody tr.is-zero { opacity: .5; }
.ctable tbody tr.is-zero:hover { opacity: 1; }
.src { display: inline-block; padding: 2px 9px; border-radius: 999px; font-size: 12px; font-weight: 600; }
.src--self { background: rgba(15,157,107,.12); color: var(--accent-ink); }
.src--inbound { background: rgba(37,99,235,.12); color: #2563eb; }
.src--sdr { background: rgba(245,158,11,.14); color: #b4790a; }
.src--bloom { background: rgba(236,72,153,.12); color: #db2777; }
.src--unspec { background: var(--surface-2); color: var(--muted); }
.src--outbound { background: rgba(245,158,11,.14); color: #b4790a; }

/* Badges & status */
.badge { display: inline-block; padding: 2px 9px; border-radius: 999px; font-size: 12px; font-weight: 600; background: var(--surface-2); border: 1px solid var(--border-strong); }
.badge--admin { background: rgba(15,157,107,.12); border-color: var(--accent); color: var(--accent-ink); }
.badge--finance { background: color-mix(in srgb, var(--warn) 14%, var(--surface)); border-color: var(--warn); color: var(--warn-ink); }
.badge--manager { background: rgba(66,133,244,.12); border-color: #4285f4; color: #2c5cc5; }
.status { font-weight: 600; text-transform: capitalize; }
.status--active { color: var(--accent-ink); }
.status--pending { color: #8a6109; }
.status--restricted { color: var(--danger); }
.status--disabled { color: var(--muted); }
