/* LegalFenix Scorecard — brand palette per PRD §6 */
:root {
  --brand-primary: #112540;       /* Midnight Blue */
  --brand-secondary: #A0DCEE;     /* Clear Blue */
  --brand-primary-soft: #1c365d;
  --brand-secondary-soft: #d8eef6;

  --bg: #f6f8fb;
  --surface: #ffffff;
  --surface-2: #f0f3f8;
  --border: #e2e8f0;
  --text: #0f172a;
  --text-muted: #334155;

  --good: #16a34a;
  --warn: #d97706;
  --bad: #dc2626;

  --shadow-sm: 0 1px 2px rgba(17,37,64,.06);
  --shadow: 0 4px 14px rgba(17,37,64,.08);
  --radius: 10px;
  --radius-lg: 14px;

  /* Shared data-table component theming — overrides _shared/components/tables.css
     defaults (loaded before this file, so these win). */
  --table-header-bg: #112540;
  --table-header-text: #ffffff;
  --table-header-hover: #1c365d;
  --table-row-odd: #ffffff;
  --table-row-even: #eef6fb;
  --table-row-hover: #dceef6;
  --table-cell-text: #0f172a;
  --table-border: #e2e8f0;
}

* { box-sizing: border-box; }
html, body {
  margin: 0;
  padding: 0;
  font-family: 'Inter', system-ui, -apple-system, sans-serif;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}

.app-layout { height: 100vh; overflow: hidden; display: flex; flex-direction: column; }

.loading-center {
  display: flex; align-items: center; justify-content: center; gap: 12px;
  color: var(--text-muted);
}
.spinner {
  width: 22px; height: 22px;
  border: 3px solid var(--brand-secondary-soft);
  border-top-color: var(--brand-primary);
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* === Login === */
.login-shell {
  min-height: 100vh;
  display: grid;
  grid-template-columns: 1fr 1fr;
  background: linear-gradient(135deg, var(--brand-primary), #0a1830);
}
.login-side {
  color: var(--brand-secondary);
  padding: 48px;
  display: flex; flex-direction: column; justify-content: space-between;
}
.login-side h1 { font-size:42px; line-height: 1.1; margin: 0; color: white; font-weight: 800; letter-spacing: -.02em; }
.login-side p  { color: var(--brand-secondary); opacity: .85; max-width: 460px; line-height: 1.55; }
.login-form-wrap {
  background: var(--surface);
  display: flex; align-items: center; justify-content: center; padding: 32px;
}
.login-form { width: 100%; max-width: 380px; }
.login-form h2 { margin: 0 0 6px; font-size:24px; }
.login-form .sub { margin: 0 0 28px; color: var(--text-muted); font-size:16px; }
.field { margin-bottom: 16px; }
.field label { display: block; font-size:15px; color: var(--text-muted); margin-bottom: 6px; font-weight: 500; }
.field input {
  width: 100%; padding: 10px 12px;
  border: 1px solid var(--border); border-radius: 8px;
  font: inherit; background: var(--surface);
}
.field input:focus { outline: 2px solid var(--brand-secondary); border-color: var(--brand-primary); }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 10px 16px; border: 0; border-radius: 8px; cursor: pointer;
  font: inherit; font-weight: 600;
}
.btn-primary { background: var(--brand-primary); color: white; }
.btn-primary:hover { background: var(--brand-primary-soft); }
.btn-block { width: 100%; }

.error { color: var(--bad); font-size:15px; min-height: 18px; margin: 8px 0 0; }

/* === App shell === */
.topbar {
  background: var(--brand-primary); color: white;
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 24px;
}
.topbar .brand { font-weight: 700; letter-spacing: -.01em; display: flex; align-items: center; gap: 10px; }
.topbar .brand-mark {
  background: var(--brand-secondary); color: var(--brand-primary);
  width: 28px; height: 28px; border-radius: 6px;
  display: inline-flex; align-items: center; justify-content: center; font-weight: 800;
}
.topbar .who { color: var(--brand-secondary); font-size:15px; }

.workspace {
  display: grid;
  grid-template-columns: 240px 1fr;
  flex: 1;
  min-height: 0;
  overflow: hidden;
}
.sidebar {
  background: var(--surface); border-right: 1px solid var(--border);
  padding: 16px 12px;
}
.sidebar .nav-item {
  display: block; padding: 9px 12px; border-radius: 8px; color: var(--text);
  text-decoration: none; margin-bottom: 2px; font-weight: 500; font-size:16px;
}
.sidebar .nav-item:hover { background: var(--surface-2); }
.sidebar .nav-item.active { background: var(--brand-primary); color: white; }

.main { padding: 16px 20px; overflow: auto; display: flex; flex-direction: column; min-height: 0; }
#scorecard-body { flex: 1; min-height: 0; overflow: visible; display: flex; flex-direction: column; }
.table-body-scroll { max-height: 440px; overflow: auto; }

/* Scorecard = single scroll context. The .main panel scrolls; the scorecard's tables flow at
   natural height (no second/third scrollbar) with a sticky header (top) and sticky Total (bottom)
   pinned to the .main viewport while each table is on screen. */
#scorecard-body .data-table-wrap { overflow: visible; }
#scorecard-body .table-body-scroll { max-height: none; overflow: visible; }
/* Width follows the columns: with table-layout:fixed + explicit th widths (set by the shared
   resize component), width:auto makes the table exactly as wide as its columns — so dragging a
   column narrower tightens the whole table instead of leaving dead space. */
#scorecard-body .data-table { width: auto; }
#scorecard-body .data-table tfoot td,
#scorecard-body .data-table tfoot th {
  position: sticky; bottom: 0; z-index: 2;
  background: var(--table-header-bg);
  color: var(--table-header-text) !important;  /* beat the shared component's forced dark cell text */
  border-top: 2px solid var(--table-header-bg);
  border-bottom: none;
  font-weight: 700;
}
.page-header { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 20px; flex-shrink: 0; }
.back-link { flex-shrink: 0; display: block; margin-bottom: 12px; }
.page-header h1 { margin: 0; font-size:24px; font-weight: 700; letter-spacing: -.01em; }
.page-header .sub { color: var(--text-muted); font-size:15px; }

.kpi-row {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px;
  margin-bottom: 20px;
}
.kpi-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 16px; box-shadow: var(--shadow-sm);
}
.kpi-card .label { color: var(--text-muted); font-size:14px; text-transform: uppercase; letter-spacing: .04em; }
.kpi-card .value { font-size:28px; font-weight: 700; margin-top: 4px; }
.kpi-card .delta { font-size:14px; margin-top: 4px; }
.kpi-card .delta.up   { color: var(--good); }
.kpi-card .delta.down { color: var(--bad); }

.card {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 14px; box-shadow: var(--shadow-sm); margin-bottom: 12px;
}
.card h3 { margin: 0 0 12px; font-size:18px; font-weight: 600; }

.placeholder {
  display: flex; align-items: center; justify-content: center; min-height: 220px;
  color: var(--text-muted); border: 1px dashed var(--border); border-radius: 10px;
  background: var(--surface-2); font-size:16px;
}

/* === Tables ===
   Base styling comes from the canonical shared component (_shared/components/tables.css:
   dark brand header, 16px headers, 15px banded cells, resize handles). These are only the
   project-specific additions that sit on top of it. */
.data-table th.num { text-align: right; }
.data-table td.num { text-align: right; font-variant-numeric: tabular-nums; }
.data-table th .sort-icon { font-size:12px; opacity: .9; }
/* +2px over the shared component's 15/16 base (global bump) */
/* 2px down from 17/18, which lands exactly on the house floor: cells 15px,
   headers one step larger. Header text wraps instead of running under the next
   column, so a two-word heading takes two lines rather than an ellipsis. */
.data-table td { font-size: 15px; }
.data-table th {
  font-size: 16px;
  white-space: normal;      /* shared sheet sets nowrap */
  /* Headings centre in the row's height, so a one-line heading sits level with a
     wrapped two-line one instead of dropping to the baseline. */
  vertical-align: middle;
  overflow-wrap: break-word;
  line-height: 1.25;
}

/* Scorecard table toolbar — month chips + filter controls in one dense row above a table */
.sc-toolbar { display: flex; gap: 12px; align-items: center; justify-content: space-between; flex-wrap: wrap; margin-bottom: 10px; }
.sc-toolbar .sc-filters { display: flex; gap: 8px; align-items: center; }
.sc-toolbar input[type="search"], .sc-toolbar select {
  padding: 6px 10px; border: 1px solid var(--border); border-radius: 8px;
  font: inherit; font-size:15px; background: var(--surface); color: var(--text);
}
.sc-toolbar input[type="search"] { width: 200px; }
.sc-chart-title { font-size:15px; font-weight: 600; color: var(--text-muted); margin-bottom: 8px; }

/* Two charts side by side (volume vs dollars), stacking on narrow screens */
.sc-chart-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 12px; }
@media (max-width: 980px) { .sc-chart-grid { grid-template-columns: 1fr; } }

/* Metric glossary — two newspaper-style columns so it scans fast instead of one long list */
.sc-glossary { column-count: 2; column-gap: 40px; }
.sc-glossary dt { break-inside: avoid; break-after: avoid; }
.sc-glossary dt:first-child { margin-top: 0 !important; }
.sc-glossary dd { break-inside: avoid; margin-bottom: 12px; }
@media (max-width: 980px) { .sc-glossary { column-count: 1; } }

/* Compact horizontal funnel (replaces the tall stacked bars) */
.funnel-head { font-weight: 700; font-size: 16px; margin-bottom: 12px; }
.funnel-head span { color: var(--text-muted); font-weight: 500; font-size: 14px; margin-left: 4px; }
.funnel-row { display: flex; align-items: center; }
.funnel-step { flex: 1; min-width: 0; }
.funnel-step-label { font-size: 13px; text-transform: uppercase; letter-spacing: .04em; color: var(--text-muted); }
.funnel-step-val { font-size: 26px; font-weight: 800; line-height: 1.05; margin: 2px 0 8px; }
.funnel-bar-track { background: var(--surface-2); border-radius: 6px; height: 14px; overflow: hidden; }
.funnel-bar-fill { height: 100%; background: var(--brand-secondary); border-radius: 6px; }
.funnel-arrow { flex: 0 0 auto; padding: 0 20px; color: var(--text-muted); font-size: 16px; line-height: 1; text-align: center; align-self: center; }
.funnel-arrow span { display: block; font-weight: 700; color: var(--text); font-size: 15px; margin-top: 2px; }
.funnel-note { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border);
  font-size: 14px; line-height: 1.5; color: var(--text-muted); }
.funnel-note div + div { margin-top: 4px; }
@media (max-width: 720px) {
  .funnel-row { flex-direction: column; align-items: stretch; gap: 10px; }
  .funnel-arrow { padding: 0; }
}

/* Period and breakdown selectors, above the numbers they control. Each carries a visible label so
   "Month by month" can never be mistaken for "last month", which is how the old unlabelled
   Monthly/Weekly pair read next to year-to-date totals. */
.sc-controls { display: flex; gap: 26px; align-items: flex-start; flex-wrap: wrap; margin-bottom: 14px; }
.sc-control { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.sc-control-label { font-size: 13px; font-weight: 700; color: var(--text-muted);
  text-transform: uppercase; letter-spacing: .04em; }
.sc-control .month-select-row { margin-bottom: 0; }
.sc-table-period { font-size: 15px; color: var(--text-muted); }
.sc-table-period strong { color: var(--text); }

/* Prior-period change. Colour carries meaning, so the arrow glyph repeats it for anyone who
   cannot rely on the colour alone. Cost metrics invert: falling CPL is the good direction. */
.kpi-delta { display: inline-block; font-size: 13px; font-weight: 700; border-radius: 999px;
  padding: 1px 8px; white-space: nowrap; }
.kpi-delta.good { background: #dcfce7; color: #14532d; }
.kpi-delta.bad  { background: #fee2e2; color: #7f1d1d; }
.kpi-delta.flat { background: var(--surface-2); color: var(--text-muted); }
.cmp-note { font-size: 14px; color: var(--text-muted); margin: -4px 0 14px; line-height: 1.5; }
.narr-scope { font-size: 14px; color: var(--text-muted); margin-bottom: 8px; }

/* Channel table sections. Media channels earn a CPL/CAC; operations spend does not, and saying so
   in the table is what stops "Systems & Tools" reading as a channel that simply performed badly.
   Both rows set their own background so the shared table's row banding cannot show through. */
/* !important because the shared component force-darkens every cell and span to keep badge colors
   from leaking; these two rows are section headers, not data. Both pass AAA on the brand navy
   (#fff 15.4:1, #cfe4ef 11.7:1). */
#scorecard-body .data-table tr.ch-group td {
  background: var(--brand-primary); color: #fff !important; font-weight: 700; font-size: 15px;
  padding: 8px 16px; letter-spacing: .02em;
}
#scorecard-body .data-table tr.ch-group td span {
  font-weight: 500; color: #cfe4ef !important; margin-left: 8px; font-size: 14px;
}
#scorecard-body .data-table tr.ch-subtotal td {
  background: var(--surface-2); font-weight: 700; border-top: 1px solid var(--border);
}

/* Signed-case counting basis. The firm reconciles this number against its own records, so the
   control that changes it sits on the page with a plain-English note, not in the glossary. */
.basis-switch { display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: 10px;
  padding: 10px 12px; margin-bottom: 12px; }
.basis-label { font-size: 14px; font-weight: 700; color: var(--text); }
.basis-chip { font-size: 14px; font-weight: 600; padding: 5px 12px; border-radius: 999px;
  border: 1px solid var(--border); background: #fff; color: var(--text); cursor: pointer; }
.basis-chip:hover { border-color: var(--brand-primary); }
.basis-chip.active { background: var(--brand-primary); color: #fff; border-color: var(--brand-primary); }
.basis-note { flex: 1 1 100%; font-size: 14px; line-height: 1.5; color: var(--text-muted); }

/* Performance summary: two side-by-side carousels (What's working / Needs focus), each paging one
   insight at a time with a horizontal swipe-reveal (sliding track), plus arrows + dots + counter. */
.narr-overall { font-size: 15px; line-height: 1.55; margin-bottom: 14px; }
/* minmax(0,...) lets each track shrink below its content's min-content so the slide track can be
   clipped by the viewport instead of forcing the grid wider than the card. */
/* align-items:stretch + the flex chain below make BOTH columns (and every card) the same height,
   sized to the tallest insight, so the two carousels never look staggered regardless of text length. */
.narr-cols { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: 18px; align-items: stretch; }
@media (max-width: 860px) { .narr-cols { grid-template-columns: minmax(0,1fr); } }
.narr-col { min-width: 0; display: flex; flex-direction: column; }
.narr-col-head { margin-bottom: 8px; }
.narr-tag {
  display: inline-block; font-size: 12px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .04em; padding: 3px 10px; border-radius: 100px;
}
.narr-tag.pos   { background: #dcfce7; color: #15803d; }
.narr-tag.focus { background: #fef3c7; color: #b45309; }
.narr-carousel2 { display: flex; align-items: stretch; gap: 10px; flex: 1; }
.narr-arrow {
  flex: 0 0 auto; width: 36px; border: none; border-radius: 10px;
  background: var(--brand-primary); color: #fff; font-size: 22px; line-height: 1;
  cursor: pointer; box-shadow: var(--shadow-sm); transition: background .15s;
}
.narr-arrow:hover:not(:disabled) { background: var(--brand-primary-soft); }
.narr-arrow:disabled { opacity: .3; cursor: default; }
.narr-viewport { flex: 1; min-width: 0; overflow: hidden; border-radius: 10px; }
.narr-track { display: flex; height: 100%; transition: transform .35s ease; will-change: transform; }
.narr-slide { flex: 0 0 100%; min-width: 0; display: flex; }
.narr-card {
  flex: 1; box-sizing: border-box;
  border: 1px solid var(--border); border-left-width: 4px; border-radius: 10px;
  padding: 14px 16px; background: var(--surface); min-height: 104px;
  font-size: 15px; line-height: 1.5; color: var(--text); overflow-wrap: anywhere;
}
.narr-card.pos   { border-left-color: #15803d; }
.narr-card.focus { border-left-color: #b45309; }
.narr-card-period { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--text-muted); margin-bottom: 6px; }
.narr-dotsrow { display: flex; align-items: center; gap: 8px; margin-top: 10px; }
.narr-dots { display: flex; align-items: center; gap: 6px; }
.narr-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--border); transition: transform .15s; }
.narr-dot.on { transform: scale(1.3); }
.narr-dot.on.pos   { background: #15803d; }
.narr-dot.on.focus { background: #b45309; }
.narr-count { margin-left: auto; font-size: 12px; color: var(--text-muted); font-weight: 600; }
.narr-foot { font-size: 12px; color: var(--text-muted); margin-top: 12px; }

/* === Badges === */
.badge {
  display: inline-flex; align-items: center;
  padding: 2px 8px; border-radius: 100px; font-size:13px; font-weight: 600;
}
.badge-green  { background: #dcfce7; color: #14532d; }  /* 8.3:1 — was #15803d at 4.6:1 */
.badge-yellow { background: #fef9c3; color: #713f12; }  /* 8.1:1 — was #a16207 at 4.6:1 */
.badge-red    { background: #fee2e2; color: #7f1d1d; }  /* 8.2:1 — was #b91c1c at 5.3:1 */
.badge-blue   { background: var(--brand-secondary-soft); color: var(--brand-primary); }
.badge-gray   { background: var(--surface-2); color: var(--text-muted); }

/* === Tabs === */
.tab-bar {
  display: flex; gap: 4px; border-bottom: 2px solid var(--border);
  margin-bottom: 20px;
}
.tab-btn {
  padding: 8px 16px; border: none; background: none; cursor: pointer;
  font: inherit; font-size:16px; font-weight: 500;
  color: var(--text-muted); border-bottom: 2px solid transparent;
  margin-bottom: -2px; border-radius: 6px 6px 0 0;
}
.tab-btn:hover { color: var(--text); background: var(--surface-2); }
.tab-btn.active { color: var(--brand-primary); border-bottom-color: var(--brand-primary); font-weight: 600; }

/* === Client cards === */
.client-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 16px; }
.client-card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg); padding: 18px;
  box-shadow: var(--shadow-sm); cursor: pointer; transition: box-shadow .15s;
  text-decoration: none; color: inherit; display: block;
}
.client-card:hover { box-shadow: var(--shadow); border-color: var(--brand-secondary); }
.client-card .firm-name { font-size:18px; font-weight: 700; margin-bottom: 4px; }
.client-card .market { font-size:14px; color: var(--text-muted); margin-bottom: 12px; }
.client-card .stat-row {
  display: grid; grid-template-columns: repeat(3,1fr); gap: 8px;
  border-top: 1px solid var(--border); padding-top: 12px; margin-top: 8px;
}
.client-card .stat { text-align: center; }
.client-card .stat .val { font-size:22px; font-weight: 700; }
.client-card .stat .lbl { font-size:12px; color: var(--text-muted); text-transform: uppercase; letter-spacing: .04em; }

/* Onboarding firms: what we are waiting on, in place of a row of zeroes.
   --text-muted (#334155) on --surface-2 (#f0f3f8) is 9.9:1, comfortably AAA. */
.client-card .onboarding-note {
  border-top: 1px solid var(--border); padding-top: 12px; margin-top: 8px;
  font-size: 14px; line-height: 1.45; color: var(--text-muted);
}
.client-card.is-onboarding { border-style: dashed; }

/* === Scorecard month selector === */
.month-select-row { display: flex; gap: 8px; align-items: center; margin-bottom: 20px; flex-wrap: wrap; flex-shrink: 0; }
.month-chip {
  padding: 5px 12px; border: 1px solid var(--border); border-radius: 100px;
  font-size:14px; font-weight: 600; cursor: pointer; background: var(--surface);
  color: var(--text-muted);
}
.month-chip.active { background: var(--brand-primary); color: white; border-color: var(--brand-primary); }

/* === Needs Review === */
.nr-reason {
  font-size:13px; font-weight: 600; text-transform: uppercase;
  letter-spacing: .04em;
}
.nr-reason.unmapped_lead_source { color: #7c3aed; }
.nr-reason.unmapped_line_item   { color: #7c3aed; }
.nr-reason.spend_outlier        { color: #d97706; }
.nr-reason.callrail_crm_delta   { color: #dc2626; }
.nr-reason.kpi_anomaly          { color: #0369a1; }
.nr-detail {
  font-size:14px; color: var(--text-muted); margin-top: 2px;
  max-width: 560px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* === Back link === */
.back-link {
  display: inline-flex; align-items: center; gap: 6px;
  font-size:15px; color: var(--text-muted); text-decoration: none; margin-bottom: 16px;
}
.back-link:hover { color: var(--text); }

/* === Empty state === */
.empty-state {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  min-height: 200px; color: var(--text-muted); font-size:16px; gap: 8px;
}
.empty-state .icon { font-size:34px; }

/* === Inline action buttons === */
.btn-sm {
  padding: 5px 10px; font-size:14px; font-weight: 600;
  border: 1px solid var(--border); border-radius: 6px;
  background: var(--surface); cursor: pointer; color: var(--text);
}
.btn-sm:hover { background: var(--surface-2); }
.btn-danger { border-color: var(--bad); color: #991b1b; }  /* 8.3:1 — was #dc2626 at 4.8:1 */
.btn-danger:hover { background: #fee2e2; }

/* === Needs Review — resolution actions === */
.nr-actions { display: flex; gap: 8px; justify-content: flex-start; white-space: nowrap; }
.btn-sm.primary { background: var(--brand-primary); color: #fff; border-color: var(--brand-primary); }
.btn-sm.primary:hover { background: var(--brand-primary-soft); }
.btn-sm:disabled { opacity: .55; cursor: default; }
.nr-modal-context {
  background: var(--surface-2); border: 1px solid var(--border); border-radius: 8px;
  padding: 12px 14px; margin-bottom: 16px; font-size: 14px; color: var(--text);
}
.nr-modal-context .src { font-weight: 700; color: var(--brand-primary); word-break: break-word; }
.nr-modal-context .meta { color: var(--text-muted); margin-top: 4px; }
/* Selects and textareas inside modal fields match .field input */
.field select, .field textarea {
  width: 100%; padding: 10px 12px;
  border: 1px solid var(--border); border-radius: 8px;
  font: inherit; background: var(--surface); color: var(--text);
}
.field textarea { resize: vertical; min-height: 42px; }
.field select:focus, .field textarea:focus { outline: 2px solid var(--brand-secondary); border-color: var(--brand-primary); }

/* ---- AI chatbot (floating, scoped to the viewed client) ---- */
.lf-chat-fab {
  position: fixed; right: 24px; bottom: 24px; z-index: 60;
  background: var(--brand-primary); color: #fff; border: none;
  padding: 12px 18px; border-radius: 100px; font: inherit; font-size: 15px; font-weight: 600;
  box-shadow: var(--shadow); cursor: pointer;
}
.lf-chat-fab:hover { background: var(--brand-primary-soft); }
.lf-chat-fab.hidden { display: none; }
.lf-chat-panel {
  position: fixed; right: 24px; bottom: 24px; z-index: 61;
  width: 400px; max-width: calc(100vw - 32px); height: 560px; max-height: calc(100vh - 48px);
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg);
  box-shadow: var(--shadow); display: none; flex-direction: column; overflow: hidden;
}
.lf-chat-panel.open { display: flex; }
.lf-chat-head {
  display: flex; align-items: center; justify-content: space-between;
  background: var(--brand-primary); color: #fff; padding: 12px 16px; font-weight: 700; font-size: 16px;
}
.lf-chat-x { background: none; border: none; color: #fff; font-size: 16px; cursor: pointer; opacity: .85; line-height: 1; }
.lf-chat-x:hover { opacity: 1; }
.lf-chat-msgs { flex: 1; overflow-y: auto; padding: 14px; display: flex; flex-direction: column; gap: 10px; background: var(--bg); }
.lf-chat-msg {
  max-width: 86%; padding: 9px 12px; border-radius: 12px; font-size: 15px; line-height: 1.5;
  color: var(--text); word-wrap: break-word; white-space: normal;
}
.lf-chat-msg.bot  { align-self: flex-start; background: var(--surface); border: 1px solid var(--border); border-bottom-left-radius: 4px; }
.lf-chat-msg.user { align-self: flex-end; background: var(--brand-secondary-soft); color: var(--brand-primary); border-bottom-right-radius: 4px; }
.lf-chat-msg strong { font-weight: 700; }
.lf-chat-typing { color: var(--text-muted); }
.lf-chat-input-row { display: flex; gap: 8px; padding: 12px; border-top: 1px solid var(--border); background: var(--surface); }
.lf-chat-input-row input {
  flex: 1; padding: 9px 12px; border: 1px solid var(--border); border-radius: 8px;
  font: inherit; font-size: 15px; background: var(--surface); color: var(--text);
}
.lf-chat-input-row input:focus { outline: 2px solid var(--brand-secondary); border-color: var(--brand-primary); }
.lf-chat-input-row button {
  background: var(--brand-primary); color: #fff; border: none; border-radius: 8px;
  padding: 9px 16px; font: inherit; font-size: 15px; font-weight: 600; cursor: pointer;
}
.lf-chat-input-row button:hover { background: var(--brand-primary-soft); }
.lf-chat-input-row button:disabled { opacity: .55; cursor: default; }

@media (max-width: 900px) {
  .login-shell { grid-template-columns: 1fr; }
  .login-side  { display: none; }
  .workspace   { grid-template-columns: 1fr; }
  .sidebar     { display: none; }
  .kpi-row     { grid-template-columns: repeat(2, 1fr); }
  .client-grid { grid-template-columns: 1fr; }
  .lf-chat-panel { right: 0; bottom: 0; width: 100vw; max-width: 100vw; height: 100vh; max-height: 100vh; border-radius: 0; }
}

/* === Change-password modal === */
.lf-modal-overlay {
  position: fixed; inset: 0; z-index: 1000;
  background: rgba(17, 37, 64, .55);
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
}
.lf-modal-card {
  position: relative;
  background: var(--surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  width: 100%; max-width: 420px;
  padding: 28px;
}
.lf-modal-card h2 { margin: 0 0 4px; color: var(--brand-primary); font-size: 22px; }
.lf-modal-card .sub { margin: 0 0 20px; color: var(--text-muted); font-size: 15px; }
.lf-modal-close {
  position: absolute; top: 12px; right: 16px;
  background: none; border: 0; cursor: pointer;
  font-size: 26px; line-height: 1; color: var(--text-muted);
}
.lf-modal-close:hover { color: var(--text); }
.lf-hint { font-size: 13px; color: var(--text-muted); margin-top: 4px; }
.lf-success { color: var(--good); font-size: 15px; margin: 8px 0 0; line-height: 1.45; }
.lf-modal-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 18px; }
.lf-modal-card .btn { background: var(--surface-2); color: var(--text); }
.lf-modal-card .btn:hover { background: var(--border); }
.lf-modal-card .btn-primary { background: var(--brand-primary); color: #fff; }
.lf-modal-card .btn-primary:hover { background: var(--brand-primary-soft); }

/* === Sortable table headers (LFSort) === */
.data-table th.lf-sortable { cursor: pointer; user-select: none; }
.data-table th.lf-sortable:hover { background: var(--table-header-hover); }

/* The arrow is chrome, not part of the heading. Left in the line flow it can wrap
   onto a line of its own on any column sized close to its text, which makes the
   header row two lines tall and leaves single-line headings sitting at the top.
   Pinned out of flow instead, with reserved padding so it never sits on the text
   (including right-aligned numeric headings). Header width now depends only on
   the words. */
.data-table th.lf-sortable,
.data-table th[data-key] { padding-right: 34px; }
.data-table th.lf-sortable > .lf-sort-icon,
.data-table th[data-key] > .sort-icon {
  position: absolute;
  right: 14px;
  top: 50%;
  transform: translateY(-50%);
  margin-left: 0;
}
.data-table th .lf-sort-icon {
  font-size: 11px; margin-left: 6px; line-height: 1;
  display: inline-block; min-width: 9px; color: currentColor;
}

/* === Users administration === */
.users-actions { display: flex; gap: 8px; white-space: nowrap; }
.lf-you {
  display: inline-block; margin-left: 6px; padding: 1px 7px; border-radius: 100px;
  background: var(--surface-2); color: var(--text-muted);
  font-size: 13px; font-weight: 600; vertical-align: middle;
}
.lf-pw-row { display: flex; gap: 8px; align-items: stretch; }
.lf-pw-row input {
  flex: 1 1 auto; min-width: 0;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; letter-spacing: .02em;
}
.lf-pw-row .btn-sm { flex: 0 0 auto; }
/* Darker than --bad so white button text clears WCAG AA (6.2:1, vs 4.5:1 at #dc2626). */
.lf-modal-card .btn-primary.lf-btn-danger { background: #b91c1c; }
.lf-modal-card .btn-primary.lf-btn-danger:hover { background: #991b1b; }

/* === Login: forgot-password alternate action === */
.login-alt { margin: 16px 0 0; font-size: 15px; text-align: center; }
.login-alt a { color: var(--brand-primary); font-weight: 600; }

/* === Users: open password-reset requests === */
.lf-reset-banner { border-left: 4px solid var(--warn); }
.lf-reset-banner h3 { color: #713f12; margin-bottom: 6px; }  /* 8.1:1 on --surface */
.lf-reset-banner div { font-size: 15px; color: var(--text); }

/* === Client detail editor === */
.lf-form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 16px; }
.lf-form-grid .lf-span-2 { grid-column: 1 / -1; }
.field textarea {
  width: 100%; padding: 10px 12px; font: inherit; font-size: 16px;
  border: 1px solid var(--border); border-radius: 8px; background: var(--surface);
  color: var(--text); resize: vertical;
}
.field textarea:focus { outline: 2px solid var(--brand-secondary); border-color: var(--brand-primary); }
.lf-check { display: flex; align-items: center; gap: 8px; font-size: 15px; margin: 4px 0 8px; }
.lf-muted { color: var(--text-muted); }
@media (max-width: 720px) { .lf-form-grid { grid-template-columns: 1fr; } }

/* === Portfolio column picker === */
.lf-col-list {
  display: grid; grid-template-columns: 1fr 1fr; gap: 2px 16px;
  max-height: 46vh; overflow-y: auto; margin-bottom: 4px;
}
.lf-col-opt { display: flex; align-items: center; gap: 8px; padding: 6px 2px; font-size: 15px; }
.lf-col-opt.locked { color: var(--text-muted); }
.lf-col-opt em { font-style: normal; font-size: 13px; color: var(--text-muted); }
@media (max-width: 620px) { .lf-col-list { grid-template-columns: 1fr; } }

/* === Scorecard help walkthrough === */
.lf-help-card { max-width: 560px; }
.lf-help-body { font-size: 16px; line-height: 1.6; max-height: 52vh; overflow-y: auto; }
.lf-help-body p { margin: 0 0 12px; }
.lf-help-body p:last-child { margin-bottom: 0; }
.lf-help-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--border);
}
.lf-help-dots { display: flex; gap: 7px; }
.lf-help-dot {
  width: 9px; height: 9px; border-radius: 50%; cursor: pointer;
  background: var(--border); transition: background .15s;
}
.lf-help-dot:hover { background: var(--text-muted); }
.lf-help-dot.active { background: var(--brand-primary); }
.lf-modal-card .btn:disabled { opacity: .5; cursor: default; }

/* === In-table primary buttons ===
   The shared table stylesheet forces `.data-table td a` to the near-black cell
   colour with !important, so an anchor styled as a filled button loses its white
   text and renders black-on-navy. Anything with a dark fill inside a cell has to
   win that back explicitly; higher specificity plus !important is what it takes. */
.data-table td a.btn-sm.primary,
.data-table td button.btn-sm.primary,
.data-table td a.btn.btn-primary,
.data-table td button.btn.btn-primary {
  color: #fff !important;   /* 15.2:1 on the #112540 fill */
}
.data-table td a.btn-sm.primary:hover,
.data-table td button.btn-sm.primary:hover {
  color: #fff !important;   /* --brand-primary-soft #1c365d, 12.0:1 */
}

/* ---- Spend Sources -------------------------------------------------------------------
   Contrast measured, not eyeballed, against the project floor (WCAG AA 4.5:1 minimum).
   Every pair below clears AAA; the worst case is body text on a selected row at 8.01:1. */
:root {
  /* Rule 17: a selected row has to read as distinct from BOTH bands and from hover. */
  --table-row-selected: #cfe6f2;
}

.ss-tiles { display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 14px; flex-shrink: 0; }
.ss-tile {
  flex: 1 1 220px; background: var(--surface); border: 1px solid var(--border);
  border-left: 4px solid var(--brand-primary); border-radius: var(--radius); padding: 12px 16px;
}
.ss-tile.ok { border-left-color: #15803d; }
.ss-tile.ex { border-left-color: #b45309; }
.ss-tile.rv { border-left-color: #6d28d9; }
.ss-tile-label { font-size: 14px; color: var(--text-muted); font-weight: 600; }
.ss-tile-value { font-size: 24px; font-weight: 700; color: var(--text); margin: 2px 0; }
.ss-tile-sub   { font-size: 13px; color: var(--text-muted); }

.ss-rules { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 14px; }
.ss-rules-label { font-size: 14px; font-weight: 600; color: var(--text-muted); }
.ss-rule {
  display: inline-flex; align-items: center; gap: 6px; font-size: 14px; color: #7c2d12;
  background: #fff5e6; border: 1px solid #f3d09a; border-radius: 999px; padding: 3px 6px 3px 12px;
}
.ss-rule-x {
  border: 0; background: transparent; cursor: pointer; font-size: 17px; line-height: 1;
  color: #7c2d12; padding: 0 5px; border-radius: 50%;
}
.ss-rule-x:hover { background: #f3d09a; }

.ss-section-label { font-size: 14px; font-weight: 600; color: var(--text-muted); margin-bottom: 6px; }
.ss-groups { margin-bottom: 14px; }
.ss-groups-row { display: flex; gap: 10px; flex-wrap: wrap; }
.ss-group {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 10px 14px; min-width: 190px;
}
.ss-group.off { background: #f8fafc; border-style: dashed; }
.ss-group-name { font-size: 15px; font-weight: 600; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 260px; }
.ss-group-amt  { font-size: 19px; font-weight: 700; color: var(--text); }
.ss-group-meta { font-size: 13px; color: var(--text-muted); margin-bottom: 8px; }

.ss-badge { display: inline-block; font-size: 13px; font-weight: 700; border-radius: 6px; padding: 2px 9px; white-space: nowrap; }
.ss-badge.ss-ok { background: #dcfce7; color: #14532d; }  /* measured 8.30:1 */
.ss-badge.ss-ex { background: #ffedd5; color: #7c2d12; }  /* measured 8.18:1 */
.ss-badge.ss-rv { background: #ede9fe; color: #4c1d95; }  /* measured 9.23:1 */

/* Ordinary cell text, so it holds the 15px floor. Worst case is on a selected row:
   #334155 on #cfe6f2 measures 8.01:1. */
.ss-why { color: var(--text-muted); font-size: 15px; }

/* ---- Raw Data view + LFTip tooltip ---- */
.lf-tip-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; margin-left: 6px; padding: 0;
  border: 1.5px solid var(--brand-primary); border-radius: 50%;
  background: var(--surface); color: var(--brand-primary);
  font: 700 12px/1 'Inter', -apple-system, sans-serif;
  cursor: help; vertical-align: middle; flex: 0 0 auto;
}
/* Inside the dark table header row the outline version would vanish. */
.data-table thead .lf-tip-btn { border-color: var(--brand-secondary); background: transparent; color: var(--brand-secondary); }
.lf-tip-btn:hover, .lf-tip-btn[aria-expanded="true"] { background: var(--brand-primary); color: #fff; border-color: var(--brand-primary); }
.data-table thead .lf-tip-btn:hover, .data-table thead .lf-tip-btn[aria-expanded="true"] { background: var(--brand-secondary); color: var(--brand-primary); border-color: var(--brand-secondary); }
.lf-tip-btn:focus-visible { outline: 2px solid var(--brand-secondary); outline-offset: 1px; }

.lf-tip-pop {
  position: fixed; z-index: 300;
  max-width: min(380px, calc(100vw - 16px));
  background: var(--brand-primary); color: #fff;   /* 16.9:1 on #112540 */
  border-radius: 10px; padding: 14px 16px;
  box-shadow: 0 8px 28px rgba(15, 23, 42, .35);
  font-size: 14px; line-height: 1.5;
}
.lf-tip-title { font-weight: 700; font-size: 15px; margin-bottom: 6px; }
.lf-tip-intro { margin-bottom: 2px; }
.lf-tip-use { padding-top: 8px; margin-top: 8px; border-top: 1px solid rgba(160, 220, 238, .28); }
.lf-tip-how { font-size: 12px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--brand-secondary); }  /* 8.9:1 */
.lf-tip-where { margin-top: 2px; }
.lf-tip-caveat { margin-top: 4px; color: #cfe8f3; font-size: 13.5px; }  /* 12.6:1 */

.rd-systems { display: flex; gap: 10px 22px; flex-wrap: wrap; font-size: 15px; color: var(--text-muted); }
.rd-systems b { color: var(--text); font-weight: 600; }
.rd-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 18px; margin-bottom: 16px; }
.rd-card h2 { font-size: 19px; margin: 0 0 4px; color: var(--text); }
.rd-card .rd-sub { font-size: 15px; color: var(--text-muted); margin-bottom: 12px; }

/* Collapsible section header (native <details>) */
.rd-summary { display: flex; align-items: center; justify-content: space-between; cursor: pointer; list-style: none; }
.rd-summary::-webkit-details-marker { display: none; }
.rd-summary h2 { margin: 0; }
.rd-chev::before { content: '▾'; font-size: 17px; color: var(--text-muted); }
details:not([open]) > .rd-summary .rd-chev::before { content: '▸'; }
details:not([open]).rd-card h2 { margin: 0; }

/* Justification: text left (tables.css default), integers centered, dollars right.
   Totals in a tfoot carry the same class as their column. */
.data-table th.num-int, .data-table td.num-int { text-align: center; font-variant-numeric: tabular-nums; }
.data-table th.num-money, .data-table td.num-money { text-align: right; font-variant-numeric: tabular-nums; }
/* Table hugs its columns instead of stretching to the card (same fix as the
   scorecard), and the bordered wrap hugs the table so no dead space shows. */
#rd-body .data-table { width: auto; }
#rd-body .data-table-wrap { width: fit-content; max-width: 100%; }
.rd-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 16px; align-items: start; }
.rd-block-title { display: flex; align-items: center; font-size: 16px; font-weight: 600; color: var(--text); margin: 10px 0 8px; }
.rd-empty { padding: 18px; font-size: 15px; color: var(--text-muted); background: var(--surface-2); border-radius: 8px; }
.rd-foot { font-size: 14px; color: var(--text-muted); margin: 4px 2px 20px; }
.rd-note { font-size: 14px; color: var(--text-muted); margin: 8px 2px 0; }
/* Rule 12: the QB group path is long; ellipsize so the decision column stays on screen. */
.rd-group { max-width: 380px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* === Portfolio (#page-main) ===
   The one screen whose whole job is "how many firms, and which one do I open".
   Everything above the table is fixed height and the client list scrolls inside
   itself, so the number of firms on screen is set by the window, not by how far
   the reader is willing to scroll. */
#page-main { overflow: hidden; }
#page-main .page-header { margin-bottom: 12px; }
#page-main .kpi-row { margin-bottom: 12px; flex-shrink: 0; }
.kpi-row.kpi-row-5 { grid-template-columns: repeat(5, 1fr); }
@media (max-width: 1180px) { .kpi-row.kpi-row-5 { grid-template-columns: repeat(3, 1fr); } }

/* The needs-review tile is a link to the queue, so it has to read as one. */
.kpi-card.kpi-link { display: block; text-decoration: none; color: inherit; }
.kpi-card.kpi-link:hover { border-color: var(--brand-secondary); box-shadow: var(--shadow); }
.kpi-card.kpi-link .delta { color: var(--brand-primary); font-weight: 600; text-decoration: underline; }

/* The card holding the client list takes whatever height is left and gives it
   all to the table's own scroll area. */
#page-main .portfolio-card {
  flex: 1; min-height: 0; display: flex; flex-direction: column; margin-bottom: 0;
}
#page-main .portfolio-card .data-table-wrap { flex: 1; min-height: 0; }
#page-main .portfolio-card .table-body-scroll { max-height: none; }
#page-main .portfolio-toolbar { display: flex; justify-content: flex-end; margin-bottom: 8px; }

/* Denser than the house default on this table only: the headings never wrap
   (data-rt-header-lines="1"), so the padding around them is what decides how
   narrow a column like Leads can be dragged before its label is clipped. */
#page-main .data-table th {
  padding: 9px 10px; line-height: 1.2;
  white-space: nowrap; overflow-wrap: normal;   /* app default is normal/break-word */
}
#page-main .data-table th.lf-sortable, #page-main .data-table th[data-key] { padding-right: 24px; }
#page-main .data-table th.lf-sortable > .lf-sort-icon,
#page-main .data-table th[data-key] > .sort-icon { right: 7px; }
#page-main .data-table td { padding: 6px 10px; }

/* Rule: actions are links here, not buttons — underlined so they still read as
   clickable, and a row of links is short enough to keep the row padding tight. */
.lf-row-links { display: flex; gap: 12px; white-space: nowrap; }
.data-table td a.lf-row-link,
.data-table td a.lf-count-link {
  color: var(--brand-primary) !important;   /* beats the shared sheet's forced cell colour */
  text-decoration: underline;
  font-weight: 600;
  cursor: pointer;
}
.data-table td a.lf-row-link:hover, .data-table td a.lf-count-link:hover { color: var(--brand-primary-soft) !important; }
/* The needs-review count opens the queue already filtered to that firm. */
.data-table td a.lf-count-link { text-decoration: none; }
.data-table td a.lf-count-link .badge { text-decoration: underline; }

/* Needs Review, scoped to one firm: the chip that says so and clears it. */
.nr-scope {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-bottom: 12px; font-size: 15px;
}
.nr-scope .nr-scope-chip {
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: 100px;
  padding: 5px 14px; font-weight: 600; color: var(--text);
}
.nr-scope a { color: var(--brand-primary); text-decoration: underline; font-weight: 600; }
