/* Brand palette pass, 2026-08-05 per Aaron: retint to match the real
   Brentwood MD brand kit (docs/brand/brentwood-md-brand-kit.md) and the
   live website's light, airy look -- approved via a mockup first. Aaron's
   explicit call: go light, but keep body copy dark (smokey black) rather
   than inverting to light-on-dark, for a "clean, elevated" contrast.
   --accent (navy) is the primary interactive color everywhere (active
   tabs, buttons, links). --accent-2 (camel) is a single deliberate accent
   reserved for the Benefits & Payroll nav callout -- see .tab-btn-highlight
   below -- not spread across the whole app. good/bad/warn/purple/teal are
   darkened from their original dark-theme values so they stay readable as
   text on a light background (the originals were tuned to pop against
   near-black panels). */
@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:wght@500;600&display=swap');

:root {
  --bg: #f7f5f1;
  --bg-panel: #ffffff;
  --bg-panel-alt: #f1ece4;
  --border: #e2dcd1;
  --text: #27282d;
  --text-dim: #767268;
  --accent: #3c5164;
  --accent-soft: rgba(60, 81, 100, 0.12);
  --accent-2: #af8f6e;
  --accent-2-soft: rgba(175, 143, 110, 0.18);
  --good: #1f8f5f;
  --bad: #c23b4a;
  --warn: #a66a0a;
  --purple: #6a4fe0;
  --teal: #0e8b7d;
  --sage: #6b8f71; /* Matches app.js's Revenue bar green -- shared brand hue, reused for payroll tier 3. */
  --light-blue: #7fa8c9; /* Matches app.js's Child bar blue -- shared brand hue, reused for payroll tier 4. */
  --sage-soft: rgba(107, 143, 113, 0.18);
  --light-blue-soft: rgba(127, 168, 201, 0.18);
}

* { box-sizing: border-box; }

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

.app-shell { min-height: 100vh; display: flex; flex-direction: column; }

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 24px;
  border-bottom: 1px solid var(--border);
  background: var(--bg-panel);
  flex-wrap: wrap;
  gap: 12px;
}

.brand { display: flex; align-items: center; gap: 10px; }
.brand-mark { height: 26px; width: auto; display: block; }
.brand-text { display: flex; flex-direction: column; line-height: 1.1; }
.brand-name {
  font-family: "Playfair Display", Georgia, serif;
  font-weight: 600;
  font-size: 16px;
  letter-spacing: 0.3px;
  color: var(--text);
}
.brand-subtitle {
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.4px;
  color: var(--text-dim);
  text-transform: uppercase;
}

.tabs { display: flex; gap: 4px; flex-wrap: wrap; }
.tab-btn {
  background: transparent;
  border: 1px solid transparent;
  color: var(--text-dim);
  padding: 8px 14px;
  border-radius: 8px;
  cursor: pointer;
  font-size: 13px;
  font-weight: 500;
}
.tab-btn:hover { color: var(--text); background: var(--bg-panel-alt); }
.tab-btn.active { color: white; background: var(--accent); }

/* Added 2026-08-05 per Aaron: makes the Benefits & Payroll nav button stand
   out in a lighter blue than the rest, so Jen can spot it at a glance
   without it looking like the currently-selected tab. Lighter/softer than
   .tab-btn.active on purpose — a callout, not a state indicator. Revisit
   this design later per Aaron ("we may come back to this design element"). */
.tab-btn.tab-btn-highlight {
  color: #7a5f42;
  background: var(--accent-2-soft);
  border-color: rgba(175, 143, 110, 0.45);
}
.tab-btn.tab-btn-highlight:hover { background: rgba(175, 143, 110, 0.3); }
.tab-btn.tab-btn-highlight.active { color: white; background: var(--accent-2); border-color: var(--accent-2); }

/* Added 2026-08-05 per Aaron: gives Snapshot the same "always called out"
   treatment as Benefits & Payroll, just in navy instead of camel, so both
   of Jen's go-to tabs are easy to spot at a glance whether or not they're
   the active tab -- not just when Snapshot happens to be selected. */
.tab-btn.tab-btn-highlight-accent {
  color: var(--accent);
  background: var(--accent-soft);
  border-color: rgba(60, 81, 100, 0.4);
}
.tab-btn.tab-btn-highlight-accent:hover { background: rgba(60, 81, 100, 0.22); }
.tab-btn.tab-btn-highlight-accent.active { color: white; background: var(--accent); border-color: var(--accent); }

.content { padding: 24px; flex: 1; max-width: 1200px; width: 100%; margin: 0 auto; }

.tab-panel { display: none; }
.tab-panel.active { display: block; }

.banner {
  background: var(--accent-soft);
  border: 1px solid var(--accent);
  color: var(--text);
  padding: 12px 16px;
  border-radius: 8px;
  margin-bottom: 16px;
  font-size: 13px;
}
.hidden { display: none !important; }

.kpi-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 16px;
  margin-bottom: 24px;
}
/* Membership tab's top KPI row, added 2026-08-10 per Aaron: after the
   Projected Annual Revenue card was hidden (see revenueRules.
   showProjectedAnnualRevenue in config.json), the remaining 4 boxes
   (Weighted Total, Adult, Child, Employee) stretched edge-to-edge across
   the full page width via auto-fit/1fr, looking unbalanced against the
   full-width cards below. Capped + centered instead of stretched. */
#kpi-row {
  max-width: 900px;
  margin-left: auto;
  margin-right: auto;
}
.kpi-card {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 20px 22px;
  display: flex;
  align-items: flex-start;
  gap: 14px;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}
/* Hover polish, 2026-08-05 per Aaron: wanted more than just the lift --
   a visible shaded wash over the whole box so it's obvious where the
   cursor is, not just a shadow at the edges. */
.kpi-card:hover {
  background: var(--accent-soft);
  border-color: var(--accent);
  box-shadow: 0 4px 14px rgba(60, 81, 100, 0.16);
  transform: translateY(-2px);
}
.kpi-icon {
  width: 40px;
  height: 40px;
  min-width: 40px;
  border-radius: 9px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
}
.kpi-icon.icon-blue { background: rgba(60, 81, 100, 0.14); color: var(--accent); }
.kpi-icon.icon-slate { background: rgba(154, 165, 186, 0.16); color: var(--text-dim); }
.kpi-icon.icon-teal { background: rgba(14, 139, 125, 0.16); color: var(--teal); }
.kpi-icon.icon-purple { background: rgba(106, 79, 224, 0.16); color: var(--purple); }
.kpi-icon.icon-green { background: rgba(31, 143, 95, 0.16); color: var(--good); }
/* Added 2026-08-06 per Aaron: light red tint for debt-carrying balances
   (Business Loan, Capital One) on CFO, to visually distinguish "money you
   have" (icon-green) from "money you owe" at a glance. */
.kpi-icon.icon-red { background: rgba(194, 59, 74, 0.14); color: var(--bad); }
/* Employee headcount, per Aaron 2026-08-05: matches the Membership &
   Revenue chart's Employee bar, which he asked to be copper (the color
   that used to belong to the Revenue bar before that moved to green). */
.kpi-icon.icon-copper { background: var(--accent-2-soft); color: var(--accent-2); }
/* Fix, 2026-08-05 per Aaron: the text block next to the icon had no
   flex-shrink/min-width, so a long value (e.g. "$5,029,430" in a narrower
   card) could overflow past the card's right edge instead of wrapping. */
.kpi-card > div:not(.kpi-icon) { flex: 1; min-width: 0; }
.kpi-label { font-size: 12px; color: var(--text-dim); margin-bottom: 6px; text-transform: uppercase; letter-spacing: 0.4px; }
/* Highlight, revised 2026-08-05 per Aaron: the earlier pale-fill "chip"
   (tried gray, then light blue) read as muted/disabled rather than
   emphasized -- a flat pale fill behind text is the visual language most
   UIs use for disabled/skeleton states, and both colors were cool tones
   fighting the page's warm cream background. Emphasis now comes from
   color+weight instead of a fill: the headline number is set in navy,
   the same color used for every other "this matters" element in the app
   (active tabs, buttons, links) -- free consistency, no fill needed.
   Table-region highlighting (Detailed Results weighted-total column/row,
   Financial Reports current-year column) still uses a soft wash, since
   those need to visually group a whole column/row, not just one number --
   but that wash is now warm camel, not navy, so it sits naturally on the
   warm page background instead of clashing with it. Same "meaning",
   different mechanism per context: navy text = the headline figure,
   camel wash = the region to focus on. */
.kpi-value {
  font-size: 26px;
  font-weight: 700;
  overflow-wrap: break-word;
  word-break: break-word;
  color: var(--accent);
}
.kpi-sub { font-size: 12px; color: var(--text-dim); margin-top: 5px; }

/* Dashboard Snapshot — two wide horizontal panels per row instead of the
   Membership tab's grid of square cards, with content centered in each panel. */
.snapshot-kpi-row {
  grid-template-columns: repeat(2, 1fr);
  gap: 14px;
}
.snapshot-kpi-row .kpi-card {
  align-items: center;
  justify-content: center;
  padding: 24px 30px;
  text-align: center;
}
.snapshot-kpi-row .kpi-icon {
  width: 50px;
  height: 50px;
  min-width: 50px;
  border-radius: 11px;
  font-size: 21px;
}
.snapshot-kpi-row .kpi-value { font-size: 30px; }
.snapshot-kpi-row .kpi-sub { font-size: 13px; }

@media (max-width: 720px) {
  .snapshot-kpi-row { grid-template-columns: 1fr; }
}

/* Membership row (Total Active Members + 2 Net New Members boxes), added
   2026-08-04 above the Revenue/EBITDA/Expenses KPI row per Aaron. Same
   centered-panel look as .snapshot-kpi-row, just 3 columns instead of 2 so
   all the top-row boxes stay visually symmetrical with each other. */
.membership-kpi-row { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 900px) {
  .membership-kpi-row { grid-template-columns: 1fr; }
}
.membership-kpi-row .kpi-card { flex-direction: column; }
.membership-trend-arrow { font-size: 15px; font-weight: 700; margin-left: 4px; }
.membership-trend-arrow.up { color: var(--good); }
.membership-trend-arrow.flat { color: var(--warn); }
.membership-trend-arrow.down { color: var(--bad); }
.membership-breakdown {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--border);
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px 14px;
}
.membership-breakdown-item {
  font-size: 12px;
  color: var(--text-dim);
  white-space: nowrap;
}
.membership-breakdown-item strong { color: var(--text); font-weight: 600; }
.membership-placeholder-note {
  font-size: 12px;
  color: var(--text-dim);
  line-height: 1.5;
}

/* Revenue (YTD) + configurable KPI row, added 2026-08-04 per Aaron's prior
   tool (Revenue card + a "KPIs (N)" picker), modeled at the top of the
   Dashboard Snapshot above the existing balance cards. */
.trend-kpi-section { margin-bottom: 24px; }
.trend-kpi-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
}
.trend-kpi-title { text-transform: uppercase; letter-spacing: 0.5px; }
.kpi-picker-wrap { position: relative; }
.kpi-picker-btn {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 6px 12px;
  border-radius: 7px;
  cursor: pointer;
  font-size: 12px;
  font-weight: 500;
  display: flex;
  align-items: center;
  gap: 4px;
}
.kpi-picker-btn:hover { background: var(--bg-panel-alt); }
.kpi-picker-caret { font-size: 10px; color: var(--text-dim); }
.kpi-picker-panel {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  background: var(--bg-panel-alt);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 12px;
  min-width: 200px;
  z-index: 20;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
}
.kpi-picker-option {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 2px;
  font-size: 13px;
  cursor: pointer;
}
.kpi-picker-option input { cursor: pointer; }
.kpi-picker-note { font-size: 11px; color: var(--text-dim); margin-top: 4px; padding: 0 2px; }

.trend-kpi-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 14px;
}
.trend-kpi-card {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 18px 20px;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}
.trend-kpi-card:hover {
  background: var(--accent-soft);
  border-color: var(--accent);
  box-shadow: 0 4px 14px rgba(60, 81, 100, 0.16);
  transform: translateY(-2px);
}
.trend-kpi-card-label { font-size: 12px; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.4px; }
.trend-kpi-card-value {
  font-size: 26px;
  font-weight: 700;
  margin-top: 6px;
  color: var(--accent);
}
.trend-kpi-card-sub { font-size: 12px; color: var(--text-dim); margin-top: 5px; }
.trend-kpi-card-margin { font-size: 12px; color: var(--text-dim); margin-top: 2px; }
.trend-kpi-chart-wrap { position: relative; width: 100%; height: 90px; margin-top: 14px; }

/* Fidelity cards (manual entry, since Fidelity doesn't support Plaid) —
   small edit pencil in the corner reveals an inline form to update the
   balance / last deposit. */
.kpi-card-editable { position: relative; }
.snapshot-edit-btn {
  position: absolute;
  top: 10px;
  right: 12px;
  background: transparent;
  border: none;
  color: var(--text-dim);
  cursor: pointer;
  font-size: 15px;
  line-height: 1;
  padding: 4px;
}
.snapshot-edit-btn:hover { color: var(--accent); }
.snapshot-edit-panel {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  left: auto;
  width: 260px;
  text-align: left;
}
.snapshot-edit-panel .btn-primary { width: 100%; margin-top: 4px; }

/* Shared Fidelity quick-update — one screenshot, top number = Strategic
   Reserve, bottom number = Tax Holding, both balances saved at once. */
.fid-quick-update-card {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 20px 22px;
  margin-top: 20px;
}
.fid-quick-update-header { display: flex; flex-direction: column; gap: 4px; margin-bottom: 14px; }
.fid-quick-update-header strong { font-size: 14px; }

.fid-dropzone {
  border: 1.5px dashed var(--border);
  border-radius: 8px;
  padding: 14px 10px;
  text-align: center;
  font-size: 12px;
  color: var(--text-dim);
  cursor: pointer;
  margin-bottom: 10px;
  transition: border-color 0.15s, background 0.15s;
}
.fid-dropzone:hover,
.fid-dropzone.fid-drop-hover {
  border-color: var(--accent);
  background: rgba(60, 81, 100, 0.05);
}
.fid-dropzone-wide { padding: 22px 10px; }
.fid-ocr-status { font-size: 12px; color: var(--text-dim); min-height: 14px; }

/* Restyled to look like a compact action button (matching "+ Upload New
   Hint CSV") instead of a large dashed drop zone, per Aaron 2026-08-08.
   Same underlying element/ids as .fid-dropzone -- still a real drop target
   (drag-and-drop JS listeners are unchanged) and still opens the file
   browser on click, purely a visual restyle. */
.fid-dropzone-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: auto;
  border: none;
  border-radius: 7px;
  padding: 9px 16px;
  background: var(--accent);
  color: white;
  font-size: 13px;
  font-weight: 600;
  margin-bottom: 0;
}
.fid-dropzone-button:hover,
.fid-dropzone-button.fid-drop-hover {
  border-color: transparent;
  filter: brightness(1.08);
  background: var(--accent);
}
.fid-dropzone-button .fid-dropzone-text { color: white; }

/* Account Balances & Transactions sub-tab, per Aaron 2026-08-08 (second
   pass -- first pass was a single narrow column, see git history/comments
   in prior version of this file): "move them back to First Horizon...
   Capital One... top row, Fidelity Tax Holding and Strategic Reserve...
   second row, stacked centered on the page." Two columns x two rows,
   centered as a block (not stretched full-width) instead of the default
   .snapshot-kpi-row look, and moderately smaller than the original large
   cards. Scoped to this specific row via an added class (not a change to
   .snapshot-kpi-row itself, which is shared by the Snapshot tab's revenue
   row and the Membership KPI row too). */
.kpi-row-compact-2x2 {
  grid-template-columns: repeat(2, minmax(240px, 280px));
  max-width: 580px;
  margin-left: auto;
  margin-right: auto;
  gap: 16px;
}
.kpi-row-compact-2x2 .kpi-card {
  align-items: center;
  justify-content: center;
  padding: 22px 24px;
  text-align: center;
}
.kpi-row-compact-2x2 .kpi-icon {
  width: 46px;
  height: 46px;
  min-width: 46px;
  border-radius: 10px;
  font-size: 19px;
}
.kpi-row-compact-2x2 .kpi-label { font-size: 12px; }
.kpi-row-compact-2x2 .kpi-value { font-size: 26px; }
.kpi-row-compact-2x2 .kpi-sub { font-size: 12.5px; }
@media (max-width: 620px) {
  .kpi-row-compact-2x2 { grid-template-columns: 1fr; max-width: 280px; }
}

/* Centered to match the balance grid above it, per Aaron 2026-08-08 ("so it
   all looks symmetrical") -- same 580px column width, header text and
   button both centered instead of left-aligned. */
.fid-quick-update-card-centered {
  max-width: 580px;
  margin-left: auto;
  margin-right: auto;
  text-align: center;
}
.fid-quick-update-card-centered .fid-quick-update-header { align-items: center; }
.fid-quick-update-card-centered .fid-dropzone-button { margin-left: auto; margin-right: auto; }

/* Nested directly inside the Account Balances card 2026-08-08 per Aaron --
   strips the standalone box look (own background/border) it had when it
   was its own separate card, replaced with just a divider line + spacing
   so it reads as one continuous card instead of a box-within-a-box. */
.fid-quick-update-inline {
  background: none;
  border: none;
  border-top: 1px solid var(--border);
  border-radius: 0;
  padding: 20px 0 0;
  margin-top: 20px;
}

.grid-2 {
  display: grid;
  grid-template-columns: 1.1fr 1fr;
  gap: 16px;
  margin-bottom: 16px;
}
@media (max-width: 880px) { .grid-2 { grid-template-columns: 1fr; } }

.card {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 24px 26px;
  margin-bottom: 20px;
}
.card-header { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 18px; flex-wrap: wrap; gap: 6px; }
.card-header h2 { font-size: 16px; margin: 0; }
.card-sub { font-size: 12px; color: var(--text-dim); }

/* Marketing tab: quick-link list to external Google Docs (Brand & Content Docs card) */
.resource-link-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.resource-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--text);
  font-size: 14px;
  font-weight: 500;
  text-decoration: none;
  transition: border-color 0.15s, color 0.15s;
}
.resource-link:hover { border-color: var(--accent); color: var(--accent); }
.resource-link i { font-size: 15px; color: var(--text-dim); }
.resource-link:hover i { color: var(--accent); }

.chart-wrap { position: relative; width: 100%; }

.table-wrap { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
th, td { text-align: left; padding: 14px 16px; border-bottom: 1px solid var(--border); white-space: nowrap; }
th { color: var(--text-dim); font-weight: 600; font-size: 11px; text-transform: uppercase; letter-spacing: 0.3px; padding-top: 0; padding-bottom: 12px; }
tbody tr:hover { background: var(--bg-panel-alt); }

/* Highlight treatment, 2026-08-05 per Aaron: same soft accent wash used
   for KPI box values, reused here so the Weighted Total column and the
   Total row draw the eye first when scanning Detailed Results. */
td.col-highlight { background: var(--accent-2-soft); font-weight: 700; }
tr.row-highlight td { background: var(--accent-2-soft); font-weight: 700; }
tr.row-highlight td.col-highlight { background: rgba(175, 143, 110, 0.32); }

.changes-row { display: flex; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid var(--border); font-size: 13px; }
.changes-row:last-child { border-bottom: none; }
.changes-name { color: var(--text-dim); }
.pos { color: var(--good); font-weight: 600; }
.neg { color: var(--bad); font-weight: 600; }
.neutral { color: var(--text-dim); }

.placeholder-box {
  background: var(--bg-panel-alt);
  border: 1px dashed var(--border);
  border-radius: 8px;
  padding: 18px;
  font-size: 13px;
  color: var(--text-dim);
  line-height: 1.6;
}
.placeholder-box p { margin: 0 0 10px 0; }
.placeholder-box p:last-child { margin-bottom: 0; }
.placeholder-box code { background: var(--bg); padding: 1px 6px; border-radius: 4px; color: var(--text); }

.dq-tabs { display: flex; gap: 6px; margin-bottom: 14px; flex-wrap: wrap; }
.dq-tab-btn {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  color: var(--text-dim);
  padding: 7px 12px;
  border-radius: 7px;
  cursor: pointer;
  font-size: 12px;
}
.dq-tab-btn.active { color: white; background: var(--accent); border-color: var(--accent); }

.dq-note { font-size: 12px; color: var(--text-dim); margin: 0 0 12px 0; }

.dropzone {
  border: 2px dashed var(--border);
  border-radius: 10px;
  padding: 24px;
  text-align: center;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.dropzone-text { color: var(--text-dim); font-size: 13px; margin-bottom: 14px; line-height: 1.6; }
.dropzone-text strong { color: var(--text); }
.dropzone.drag-over {
  border-color: var(--accent);
  background: var(--accent-soft);
}

.upload-row { display: flex; gap: 10px; align-items: center; justify-content: center; flex-wrap: wrap; }
.btn-primary {
  background: var(--accent);
  color: white;
  border: none;
  padding: 9px 16px;
  border-radius: 7px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}
.btn-primary:hover { filter: brightness(1.08); }
.btn-primary:disabled { opacity: 0.5; cursor: default; }

.btn-secondary {
  background: var(--bg-panel-alt);
  color: var(--text);
  border: 1px solid var(--border);
  padding: 8px 14px;
  border-radius: 7px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}
.btn-secondary:hover { border-color: var(--accent); }
.btn-secondary:disabled { opacity: 0.4; cursor: default; }
.btn-secondary:disabled:hover { border-color: var(--border); }

/* Login page (task #166, 2026-08-07). */
.login-shell {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}
.login-card {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 36px 32px;
  width: 100%;
  max-width: 360px;
  box-shadow: 0 8px 28px rgba(39, 40, 45, 0.08);
}
.login-brand { display: flex; flex-direction: column; align-items: center; gap: 4px; margin-bottom: 28px; }
.login-brand .brand-mark { height: 34px; width: auto; margin-bottom: 6px; }
.login-brand .brand-name {
  font-family: "Playfair Display", Georgia, serif;
  font-weight: 600;
  font-size: 17px;
  color: var(--text);
  text-align: center;
}
.login-brand .brand-subtitle {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.4px;
  color: var(--text-dim);
  text-transform: uppercase;
  text-align: center;
}
.login-form { display: flex; flex-direction: column; gap: 6px; }
.login-label { font-size: 12px; font-weight: 600; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.4px; margin-top: 12px; }
.login-input {
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 14px;
  font-family: inherit;
  color: var(--text);
  background: var(--bg);
}
.login-input:focus { outline: none; border-color: var(--accent); }
.login-submit { margin-top: 20px; width: 100%; padding: 11px; font-size: 14px; }
.login-error { color: var(--bad); font-size: 13px; font-weight: 600; margin: 10px 0 0; }
.login-note { color: var(--text-dim); font-size: 13px; margin: 0 0 4px; }

/* Permission system (task #166, 2026-08-07) -- app.js adds "read-only" to
   <body> for any user with canEdit: false, which hides every element
   (static or dynamically-rendered) marked .edit-only. See server/lib/auth.js
   for the full permission model; this is purely cosmetic -- every mutating
   endpoint is ALSO enforced server-side regardless of what's hidden here. */
body.read-only .edit-only { display: none !important; }

.topbar-user { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--text-dim); }
.topbar-user strong { color: var(--text); }
#logout-btn { padding: 5px 10px; font-size: 11.5px; }
/* Log Out button: hidden until you hover the "Logged in as ___" text next to
   it, per Aaron 2026-08-07 -- reserves its layout space so nothing shifts,
   just fades into view. visibility (not display) so it's also skipped in
   tab order while hidden. */
.topbar-logout { visibility: hidden; }
.topbar-user:hover .topbar-logout { visibility: visible; }

/* Admin panel (task added 2026-08-07 per Aaron). body.not-full is added by
   app.js for anyone who isn't role "full" (Aaron/Jen) -- hides the Admin
   link entirely for restricted users, on top of the server-side fullOnly
   enforcement in auth.js (this is cosmetic only, not the real boundary). */
body.not-full .full-only { display: none !important; }

/* Styled to look like the old topbar Back Up Code button, since that button
   moved into the Admin panel itself 2026-08-07 per Aaron and this became the
   one clickable thing left in the topbar besides the user menu. */
.admin-link,
.notes-link {
  display: inline-flex;
  align-items: center;
  background: var(--bg-panel-alt);
  color: var(--text);
  border: 1px solid var(--border);
  padding: 5px 10px;
  border-radius: 7px;
  font-size: 11.5px;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
}
.admin-link:hover,
.notes-link:hover { border-color: var(--accent); color: var(--accent); }

.admin-tabs-checkboxes { display: flex; flex-wrap: wrap; gap: 12px; margin: 6px 0 14px; font-size: 13px; }
.admin-tabs-checkboxes label { display: flex; align-items: center; gap: 5px; font-weight: 500; }
.admin-checkbox-label { display: flex; align-items: center; gap: 6px; font-size: 13px; margin-top: 4px; }
.admin-role-toggle { display: flex; flex-direction: column; gap: 6px; margin: 6px 0 14px; font-size: 13px; }
.admin-role-toggle label { display: flex; align-items: center; gap: 6px; }
.admin-form-actions { display: flex; gap: 8px; margin-top: 14px; }
.admin-add-submit { margin-top: 18px; }
.admin-temp-password-banner {
  background: var(--accent-soft);
  border: 1px solid var(--accent);
  border-radius: 10px;
  padding: 14px 16px;
  margin: -6px 0 20px;
  font-size: 13.5px;
}
.admin-temp-password-banner strong { font-family: monospace; font-size: 15px; }
.admin-temp-password-banner .admin-banner-close {
  float: right;
  background: none;
  border: none;
  cursor: pointer;
  color: var(--text-dim);
  font-size: 12px;
}
#admin-users-table .admin-user-actions { display: flex; gap: 6px; flex-wrap: wrap; }
#admin-users-table .admin-user-actions button {
  background: var(--bg-panel-alt);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 4px 9px;
  font-size: 11.5px;
  cursor: pointer;
  color: var(--text);
}
#admin-users-table .admin-user-actions button:hover { border-color: var(--accent); }
#admin-users-table .admin-user-actions button.admin-remove-btn:hover { border-color: var(--bad); color: var(--bad); }

.topbar-backup { display: flex; align-items: center; gap: 10px; }
/* Back Up Code button + status now live in the Admin panel's Code Backup
   card, not the topbar -- moved 2026-08-07 per Aaron. Full-size .btn-secondary
   here since it's no longer competing for topbar space. */
.admin-backup-row { display: flex; align-items: center; gap: 12px; }
.backup-code-status { font-size: 12px; color: var(--text-dim); max-width: 260px; }
.backup-code-status.is-good { color: var(--good); font-weight: 600; }
.backup-code-status.is-bad { color: var(--bad); font-weight: 600; }

.tx-pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  padding: 14px 0 4px;
}

input[type="file"] {
  color: var(--text-dim);
  font-size: 13px;
}

#upload-status { margin-top: 14px; font-size: 13px; }
#upload-status.ok { color: var(--good); }
#upload-status.err { color: var(--bad); }

.mr-pull-status { font-size: 13px; margin-right: 4px; }
.mr-pull-status.ok { color: var(--good); }
.mr-pull-status.err { color: var(--bad); }

.mr-actions { display: flex; align-items: center; justify-content: flex-end; gap: 10px; margin-top: 14px; }

.status-active { color: var(--good); }
.status-planned { color: var(--warn); }

/* ---------- Membership & Revenue header ---------- */
.mr-header {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 18px;
}
.mr-header-icon {
  width: 46px;
  height: 46px;
  min-width: 46px;
  border-radius: 10px;
  background: var(--accent-soft);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
}
.mr-header h1 {
  margin: 0;
  font-size: 23px;
  font-family: "Playfair Display", Georgia, serif;
  font-weight: 600;
  color: var(--text);
}
.mr-subtitle { margin: 4px 0 0 0; font-size: 13px; color: var(--text-dim); }

.mr-controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 18px;
}
.mr-subtabs { display: flex; gap: 6px; flex-wrap: wrap; }
.mr-subtab-btn {
  position: relative;
  background: var(--bg-panel);
  border: 1px solid var(--border);
  color: var(--text-dim);
  padding: 7px 14px;
  border-radius: 7px;
  cursor: pointer;
  font-size: 12px;
  font-weight: 500;
}
.mr-subtab-btn.active { color: white; background: var(--accent); border-color: var(--accent); }
.mr-subtab-btn:disabled { cursor: default; opacity: 0.45; }
.mr-subtab-btn:disabled:hover { background: var(--bg-panel); }

/* Added 2026-08-04 per Aaron: retention/"Trends Over Time" is a brand-new
   feature, easy to overlook next to the other two subtabs. A small "New"
   badge + soft pulsing glow (while not the active tab) calls it out during
   the early days of adoption. Remove once it's no longer new. */
.mr-subtab-btn.mr-subtab-trends { overflow: visible; }
.mr-subtab-btn.mr-subtab-trends:not(.active) {
  border-color: var(--accent);
  animation: mr-trends-pulse 2.4s ease-in-out infinite;
}
.mr-subtab-btn.mr-subtab-trends:not(.active):hover { animation-play-state: paused; }
.mr-new-badge {
  position: absolute;
  top: -8px;
  right: -8px;
  background: var(--good);
  color: #08130d;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.04em;
  padding: 2px 6px;
  border-radius: 999px;
  box-shadow: 0 0 0 2px var(--bg);
}
@keyframes mr-trends-pulse {
  0%, 100% { box-shadow: 0 0 0 1px var(--accent), 0 0 6px rgba(60, 81, 100, 0.25); }
  50% { box-shadow: 0 0 0 1px var(--accent), 0 0 14px rgba(60, 81, 100, 0.55); }
}

/* ---------- Chart toggle ---------- */
.chart-toggle { display: flex; gap: 4px; }
.chart-toggle-btn {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-dim);
  padding: 5px 12px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 12px;
  font-weight: 500;
}
.chart-toggle-btn:hover { color: var(--text); }
.chart-toggle-btn.active { color: white; background: var(--accent); border-color: var(--accent); }

/* ---------- Detailed results tfoot ---------- */
#detailed-table tfoot td {
  font-weight: 600;
  border-bottom: none;
  border-top: 1px solid var(--border);
  color: var(--text);
}
#detailed-table tfoot tr.tfoot-subtle td {
  font-weight: 500;
  color: var(--text-dim);
  border-top: none;
  padding-top: 4px;
}

/* ---------- Membership Growth Trends (Membership page, replaced the old
   Changes Since Last Upload table 2026-08-08) ---------- */
.mg-col-note {
  display: block;
  font-size: 10px;
  font-weight: 400;
  text-transform: none;
  color: var(--text-dim);
  letter-spacing: 0;
}
.mg-cell { text-align: center; cursor: default; }
.mg-practice-row { font-weight: 600; border-top: 2px solid var(--border); background: var(--bg-panel-alt); }
.mg-practice-row td:first-child { border-radius: 0; }
.mg-partial-marker { color: var(--text-dim); margin-left: 1px; }
.mg-footnote { margin-top: 12px; }

/* ---------- Upload footer bar ---------- */
.upload-footer-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px;
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 18px 22px;
  margin-bottom: 20px;
}
.ufb-label { display: block; font-size: 11px; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.4px; }
.ufb-value { display: block; font-size: 14px; font-weight: 600; margin-top: 2px; }

/* ---------- Collapsible (Previous Uploads) ---------- */
.collapsible-toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  background: transparent;
  border: none;
  color: var(--text-dim);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  padding: 8px 0;
}
.collapsible-toggle:hover { color: var(--text); }
.collapsible-toggle .chev { display: inline-block; transition: transform 0.15s ease; font-size: 11px; }
.collapsible-toggle.open .chev { transform: rotate(90deg); }
.collapsible-body { margin-top: 8px; }

/* Header-scale variant -- used when the toggle itself stands in for a card's
   <h2> title (e.g. Recent Transactions), rather than a smaller sub-section
   link like Category Rules. */
.collapsible-toggle-h2 { font-size: 16px; color: var(--text); padding: 0; }
.collapsible-toggle-h2 .chev { font-size: 13px; }
.count-badge {
  background: var(--bg-panel-alt);
  border: 1px solid var(--border);
  color: var(--text-dim);
  font-size: 11px;
  font-weight: 600;
  padding: 1px 8px;
  border-radius: 999px;
}

.delete-snapshot-btn {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-dim);
  padding: 5px 10px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 12px;
}
.delete-snapshot-btn:hover { color: var(--bad); border-color: var(--bad); }
.delete-snapshot-btn:disabled { opacity: 0.5; cursor: default; }

/* ---------- Financial Reports ---------- */
.fr-header-icon { color: var(--accent); }

.fr-report-subtabs {
  display: flex;
  gap: 22px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 20px;
}
.fr-report-subtab-btn {
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  color: var(--text-dim);
  padding: 0 2px 12px 2px;
  margin-bottom: -1px;
  cursor: pointer;
  font-size: 13.5px;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 7px;
}
.fr-report-subtab-btn:hover { color: var(--text); }
.fr-report-subtab-btn.active { color: var(--accent); border-bottom-color: var(--accent); }

.fr-section-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 14px;
  margin-bottom: 18px;
}
.fr-section-title { margin: 0; font-size: 17px; }
.fr-section-sub { margin: 4px 0 0 0; font-size: 12.5px; color: var(--text-dim); }

.fr-select {
  appearance: none;
  -webkit-appearance: none;
  background-color: var(--bg-panel-alt);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%23767268' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  border: 1px solid var(--border);
  color: var(--text);
  padding: 8px 30px 8px 14px;
  border-radius: 7px;
  cursor: pointer;
  font-size: 13px;
  font-weight: 600;
}
.fr-select:hover { border-color: var(--accent); }

.fr-table-card { padding: 0; overflow: hidden; }
.fr-table-card .table-wrap { padding: 6px 0 16px; }

/* Transaction categorization (task #43) */
.tx-category-select {
  background-color: var(--bg-panel-alt);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 5px 8px;
  border-radius: 6px;
  font-size: 12.5px;
  max-width: 180px;
}
.tx-category-select:hover { border-color: var(--accent); }

.category-rule-form {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}
.category-rule-form select,
.category-rule-form input[type="text"] {
  background-color: var(--bg-panel-alt);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 8px 10px;
  border-radius: 7px;
  font-size: 13px;
}
.category-rule-form input[type="text"] { flex: 1; min-width: 140px; }

/* Top Cost Drivers (Financial Reports > Financial Summary) */
.cd-card .card-header { margin-bottom: 4px; }

.cd-stats-row {
  display: flex;
  gap: 28px;
  flex-wrap: wrap;
  margin: 18px 0 22px 0;
  padding-bottom: 18px;
  border-bottom: 1px solid var(--border);
}
.cd-stat-value { font-size: 22px; font-weight: 700; }
.cd-stat-label { font-size: 12px; color: var(--text-dim); margin-top: 4px; }

.cd-list { display: flex; flex-direction: column; gap: 14px; }
.cd-row {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 14px 16px;
}
.cd-row-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.cd-name-line { display: flex; align-items: center; gap: 10px; }
.cd-rank {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: rgba(60, 81, 100, 0.14);
  color: var(--accent);
  font-size: 11px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.cd-name { font-weight: 600; font-size: 14px; }
.cd-name-sub { font-size: 12px; color: var(--text-dim); margin-top: 2px; margin-left: 32px; }
.cd-amount-block { text-align: right; }
.cd-amount { font-weight: 700; font-size: 14px; }
.cd-amount-sub { font-size: 12px; color: var(--text-dim); margin-top: 2px; }

.cd-bar-row { display: flex; align-items: center; gap: 10px; margin-top: 12px; }
.cd-bar-label { font-size: 11px; color: var(--text-dim); flex-shrink: 0; width: 80px; }
.cd-bar-track {
  flex: 1;
  height: 7px;
  border-radius: 4px;
  background: var(--bg-panel-alt);
  overflow: hidden;
}
.cd-bar-fill { height: 100%; background: var(--accent); border-radius: 4px; }
.cd-bar-pct { font-size: 12px; font-weight: 600; width: 44px; text-align: right; flex-shrink: 0; }

/* Upcoming Expenses (Dashboard Snapshot) */
.upcoming-exp-list { display: flex; flex-direction: column; }
.upcoming-exp-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 0;
  border-bottom: 1px solid var(--border);
}
.upcoming-exp-row:last-child { border-bottom: none; }
/* Needs Attention "Reviewed" button (added 2026-08-07 per Aaron) -- reuses
   this same row shell, just with the label taking the flexible middle space
   so the button pins to the right. edit-only, so restricted/read-only users
   (e.g. Sarah) never see it even though they can see the list itself. */
.attn-row-body { flex: 1; min-width: 0; }
.attn-review-btn { padding: 5px 10px; font-size: 11.5px; flex-shrink: 0; }

/* Light copper shadow to make this card stand out on Snapshot, per Aaron
   2026-08-07 -- same --accent-2 (copper) tint as .admin-link/.tab-btn-highlight
   elsewhere, just as a soft outer glow + warm border instead of a fill,
   since this card needs to stay scannable, not look like an alert banner. */
.card-attention-highlight {
  border-color: var(--accent-2);
  box-shadow: 0 6px 22px rgba(175, 143, 110, 0.22);
}

/* Same tan fill as the Admin button/link, applied to the EOS Quarterly
   Metrics card per Aaron 2026-08-07. */
.card-tan-fill { background: var(--bg-panel-alt); }
.upcoming-exp-freq {
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.3px;
  color: var(--accent);
  background: rgba(60, 81, 100, 0.12);
  padding: 3px 8px;
  border-radius: 5px;
  flex-shrink: 0;
}
.upcoming-exp-name { flex: 1; font-size: 13.5px; font-weight: 600; }
.upcoming-exp-due { font-size: 12px; color: var(--text-dim); text-align: right; min-width: 150px; }
.upcoming-exp-due.due-soon { color: var(--warn); font-weight: 600; }

/* Recurring Vendors (Transactions & Connections), added 2026-08-06 per Aaron */
.rv-columns {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 28px;
}
@media (max-width: 720px) {
  .rv-columns { grid-template-columns: 1fr; }
}
.rv-column { min-width: 0; }
.rv-column + .rv-column { border-left: 1px solid var(--border); padding-left: 28px; }
@media (max-width: 720px) {
  .rv-column + .rv-column { border-left: none; padding-left: 0; border-top: 1px solid var(--border); padding-top: 20px; margin-top: 4px; }
}
.rv-column-title {
  display: inline-block;
  font-size: 12.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  color: #fff;
  margin: 0 0 8px 0;
  padding: 6px 12px;
  border-radius: 6px;
  box-shadow: 0 2px 6px rgba(39, 40, 45, 0.18);
}
.rv-column-sub { font-size: 11.5px; color: var(--text-dim); margin: 0 0 10px 0; }

/* Two-tone theme (per Aaron 2026-08-06): each column keeps one consistent
   hue throughout -- a darker solid wash on the header to anchor/label the
   column, a lighter soft tint on every row within it. Rows reuse the
   existing --light-blue-soft/--sage-soft brand tints (same ones the payroll
   tier rows use). Headers use a deliberately DARKER shade of each hue than
   the base --light-blue/--sage tokens -- those tokens read as too pale for
   white text at this size (fails WCAG contrast), and Aaron specifically
   asked for "a darker variation" for the header anyway, so this isn't a
   compromise, it's the actual ask. */
.rv-column-subscriptions .rv-column-title { background: #3d6488; }
.rv-column-variable .rv-column-title { background: #3f5f47; }

.rv-row {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 2px;
  padding: 10px 12px;
  border-radius: 8px;
  margin-bottom: 6px;
  /* Added 2026-08-07 per Aaron: fixes a row-height mismatch between the two
     Recurring Vendors columns -- both already cap at RV_PAGE_SIZE (10) rows
     per page, but a flagged row's subtext can wrap to a 2nd line (e.g. "Up
     112.63% vs average -- 4 months rising in a row"), making that card
     taller than a plain single-line Subscriptions row. A shared min-height
     (tall enough for a 2-line subtext) keeps every row -- and therefore
     both 10-item columns -- the same height regardless of content length. */
  min-height: 72px;
}
.rv-row:last-child { margin-bottom: 0; }
.rv-column-subscriptions .rv-row { background: var(--light-blue-soft); }
.rv-column-variable .rv-row { background: var(--sage-soft); }
.rv-row-top { display: flex; align-items: center; gap: 6px; }
.rv-name {
  font-size: 13.5px;
  font-weight: 600;
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.rv-rename-btn {
  flex-shrink: 0;
  border: none;
  background: none;
  cursor: pointer;
  color: var(--text-dim);
  font-size: 12px;
  padding: 2px 4px;
  border-radius: 4px;
  opacity: 0.55;
}
.rv-rename-btn:hover { opacity: 1; background: var(--bg); color: var(--accent); }
.rv-amount { flex-shrink: 0; font-weight: 700; font-size: 13.5px; }
.rv-sub { font-size: 12px; color: var(--text-dim); }

/* Price-change / spend-swing flags (Recurring Vendors), added 2026-08-06
   per Aaron: a small dot next to the vendor name for a quick visual scan,
   plus the full detail spelled out in the row's subtext -- see
   server/lib/recurringVendors.js (priceChange / trend) and app.js's
   loadRecurringVendors() for how these are computed. */
.rv-flag-dot {
  flex-shrink: 0;
  display: inline-block;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  box-shadow: 0 0 0 2px rgba(39, 40, 45, 0.08);
}
.rv-flag-dot-yellow { background: var(--warn); }
.rv-flag-dot-red { background: var(--bad); }
.rv-flag-dot-green { background: var(--good); }
.rv-flag-note { font-weight: 700; }
.rv-flag-note-yellow { color: var(--warn); }
.rv-flag-note-red { color: var(--bad); }
.rv-flag-note-green { color: var(--good); }
.rv-rename-input {
  flex: 1;
  min-width: 0;
  font: inherit;
  font-weight: 600;
  padding: 3px 6px;
  border: 1px solid var(--accent);
  border-radius: 5px;
  background: var(--bg-panel);
  color: var(--text);
}

.anniversary-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 0;
  border-bottom: 1px solid var(--border);
}
.anniversary-row:last-child { border-bottom: none; }
.anniversary-name { font-weight: 600; flex: 1; }
.anniversary-years {
  font-size: 12px;
  color: var(--text-dim);
}
.anniversary-days {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-dim);
}
.anniversary-days.soon { color: var(--warn); }
.anniversary-note { font-size: 12px; color: var(--accent); }

/* Reviewed & applied checkbox (per Aaron 2026-08-06): Jen checks this once
   an anniversary's payroll adjustment has been reviewed and applied with
   Mahan -- also gates the weekly email reminder. Row dims once checked so
   it's visually clear at a glance which anniversaries still need action. */
.anniversary-resolve {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
  padding: 6px 10px;
  border: 1px solid var(--border);
  border-radius: 7px;
  background: var(--bg);
  box-shadow: 0 1px 4px rgba(39, 40, 45, 0.08);
}
.anniversary-resolve input[type="checkbox"] {
  width: 16px;
  height: 16px;
  cursor: pointer;
  accent-color: var(--accent);
}
.anniversary-resolve-label { font-size: 11px; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.3px; }
.anniversary-row.resolved { opacity: 0.55; }
.upcoming-exp-amount { font-weight: 700; font-size: 13.5px; min-width: 90px; text-align: right; }

/* Payroll tier dots -- color-codes each Physician/Care Coordinator by pay-ladder
   level (see config.payrollTierColors). Purely a small indicator dot next to
   the name; the actual color comes inline from the API's tierColorVar. */
.payroll-name-cell { display: flex; align-items: center; gap: 8px; }
.payroll-tier-dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
}

/* Family bolt-on employees (per Aaron 2026-08-05, darkened 2026-08-05 after
   Aaron flagged that the original light gray read too close to the pastel
   tier tints below): a noticeably darker, warm slate-gray -- distinct in both
   lightness and hue from all four tier tints (navy/copper/sage/light-blue,
   all pastel/high-lightness) -- plus a solid left border so the row reads
   unambiguously as "set apart/excluded" rather than "just another tier
   color". Sorted to the bottom by payrollAllocation.js. Still fully included
   in the totals/share-of-payroll math -- per Aaron, they're genuinely on
   payroll, just not part of active daily operations. */
tr.payroll-row-family td {
  color: var(--text-dim);
  background: #c7c2b8 !important;
  border-left: 3px solid #948d7d;
}
tr.payroll-row-family td:first-child {
  padding-left: calc(var(--cell-pad-left, 16px) - 3px);
}
tr.payroll-row-family:hover td {
  background: #bdb7ab !important;
}

/* Payroll Variance Tracker (traffic light) */
.pv-light-row { display: flex; align-items: center; gap: 12px; margin: 8px 0 4px; }
.pv-light-dot {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  flex-shrink: 0;
  box-shadow: 0 0 0 4px rgba(0, 0, 0, 0.04);
}
.pv-light-label { font-weight: 700; font-size: 15px; }
.pv-light-sub { font-size: 12.5px; color: var(--text-dim); margin-top: 2px; }
.pv-history-table { width: 100%; border-collapse: collapse; margin-top: 6px; }
.pv-history-table th, .pv-history-table td { text-align: right; padding: 6px 8px; font-size: 12.5px; border-bottom: 1px solid var(--border); }
.pv-history-table th:first-child, .pv-history-table td:first-child { text-align: left; }
.pv-history-table th { color: var(--text-dim); font-weight: 600; }

#fr-unified-table th, #fr-unified-table td { text-align: right; }
#fr-unified-table th.fr-period-col,
#fr-unified-table td.fr-period-col { text-align: left; }

.fr-period-col {
  position: sticky;
  left: 0;
  z-index: 2;
}
#fr-unified-table tbody td.fr-period-col,
#fr-unified-table tfoot td.fr-period-col { background: var(--bg-panel); }

.fr-sort-icon { color: var(--text-dim); vertical-align: -1px; margin-left: 2px; }

#fr-unified-table thead th {
  background: var(--bg-panel-alt);
  z-index: 3;
}

.fr-group-header {
  text-align: center !important;
  font-size: 11px;
  letter-spacing: 0.4px;
  color: var(--text-dim);
}

.fr-cell-value { font-weight: 600; }
.fr-cell-badge { font-size: 11px; font-weight: 600; margin-top: 3px; }
.fr-cell-badge.pos { color: var(--good); }
.fr-cell-badge.neg { color: var(--bad); }
.fr-cell-badge.neutral { color: var(--text-dim); }

#fr-unified-table tbody td.fr-period-col,
#fr-unified-table tfoot td.fr-period-col { font-weight: 600; }

#fr-unified-table tfoot tr { font-weight: 700; border-top: 2px solid var(--border); }
#fr-unified-table tfoot td { background: var(--bg-panel-alt); }
#fr-unified-table tfoot td.fr-period-col { background: var(--bg-panel-alt); }

.fr-toolbar-group { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.fr-dropdown-wrap { position: relative; }
.fr-toolbar-btn {
  background: var(--bg-panel-alt);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 8px 14px;
  border-radius: 7px;
  cursor: pointer;
  font-size: 13px;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 8px;
}
.fr-toolbar-btn:hover { border-color: var(--accent); }
.fr-toolbar-btn.open { border-color: var(--accent); color: var(--accent); }
.fr-toolbar-btn-icon { font-size: 12px; }
.fr-btn-icon { color: var(--text-dim); flex-shrink: 0; }
.fr-chevron { color: var(--text-dim); flex-shrink: 0; margin-left: 2px; }
.fr-export-btn svg { flex-shrink: 0; }

.fr-dropdown-panel {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 20;
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 16px 18px;
  width: 270px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
}

.fr-proj-enable-row { display: flex; align-items: center; gap: 10px; margin-bottom: 16px; cursor: pointer; font-size: 13px; }
.fr-proj-field { margin-bottom: 16px; }
.fr-proj-field:last-child { margin-bottom: 0; }
.fr-proj-field label { display: block; font-size: 12px; color: var(--text-dim); margin-bottom: 8px; font-weight: 600; }
.fr-proj-rate-input { display: flex; align-items: center; gap: 6px; }
.fr-proj-rate-input input {
  width: 90px;
  background: var(--bg);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 6px;
  padding: 6px 8px;
  font-size: 13px;
}
.fr-proj-years-list { display: flex; flex-direction: column; gap: 8px; }
.fr-proj-year-row { display: flex; align-items: center; gap: 8px; font-size: 13px; cursor: pointer; }
.fr-proj-year-row .proj-tag { color: var(--text-dim); font-size: 11px; }

.fr-cat-row { display: flex; align-items: center; gap: 10px; font-size: 13px; padding: 6px 0; cursor: pointer; }
.fr-cat-divider { border: none; border-top: 1px solid var(--border); margin: 4px 0; }

.fr-proj-enable-row input,
.fr-proj-year-row input,
.fr-cat-row input { width: 16px; height: 16px; accent-color: var(--accent); }

.fr-projected-col, .fr-projected-cell {
  color: var(--accent);
  font-style: italic;
  background: var(--accent-soft) !important;
}
#fr-unified-table tfoot .fr-projected-cell { background: rgba(60, 81, 100, 0.18) !important; }
/* Fix, 2026-08-05 per Aaron: the plain "#fr-unified-table tfoot td" rule
   (ID selector) was beating td.fr-current-year-cell's specificity, so the
   current-year highlight silently disappeared in the Total and YTD % rows.
   This override wins back the highlight for those bottom rows too. */
#fr-unified-table tfoot td.fr-current-year-cell { background: var(--accent-2-soft); }

/* Current-year column highlight, revised 2026-08-05 per Aaron -- warm
   camel wash instead of navy, so it sits naturally on the warm page
   background instead of reading as a cool-toned "muted" patch. Matches
   the same treatment used for the Detailed Results weighted-total
   column/row -- one consistent "highlighted region" language. */
th.fr-current-year-col { background: var(--accent-2-soft); color: var(--text); }
td.fr-current-year-cell { background: var(--accent-2-soft); }
td.fr-current-year-cell .fr-cell-value { font-weight: 700; }

.fr-ytd-tag {
  color: var(--text-dim);
  font-style: normal;
  letter-spacing: 0.03em;
  font-size: 10px;
  text-transform: uppercase;
}

/* ---------- Membership & Revenue sub-panels (Current / Trends / Manual) ---------- */
.mr-subpanel { display: none; }
.mr-subpanel.active { display: block; }

/* ---------- Recent Transactions search + vendor billing-history chart,
   added 2026-08-08 per Aaron ---------- */
.tx-search-row { display: flex; gap: 8px; margin-bottom: 8px; }
.tx-search-input {
  flex: 1;
  padding: 8px 12px;
  border: 1px solid var(--border);
  border-radius: 7px;
  font-size: 13px;
  background: var(--bg-panel);
  color: var(--text);
}
.tx-search-input:focus { outline: none; border-color: var(--accent); }
#tx-search-scope-note { margin-bottom: 12px; }
.tx-vendor-chart-wrap {
  background: var(--bg-panel-alt);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 16px 18px;
  margin-bottom: 16px;
}
.tx-vendor-chart-wrap .card-sub { margin-bottom: 8px; font-weight: 600; color: var(--text); }

/* ---------- CFO sub-panels (Financial Reports / Account Balances &
   Transactions / Metrics) ---------- */
/* Long-standing bug found 2026-08-08: these sections have used the class
   "cfo-subpanel" since the CFO tab was first created (2026-08-06), but no
   CSS rule for that class name was ever written -- only .mr-subpanel (the
   Membership tab's equivalent) was. Since a <section> is block-level by
   default with no display:none, this meant ALL THREE cfo-subpanel sections
   have been rendering simultaneously, stacked on the page, this whole time
   -- clicking a sub-tab button correctly swapped which one had the
   "active" class, but nothing was ever hiding the others, so the click
   visibly did nothing. Likely went unnoticed because Financial Reports'
   long table pushed the other panels' content far enough down the page
   that casual scrolling never reached it. */
.cfo-subpanel { display: none; }
.cfo-subpanel.active { display: block; }

/* ---------- Retention (Trends Over Time) ---------- */
.retention-card-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 16px;
}
.retention-card {
  background: var(--bg-panel-alt);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 18px;
}
.retention-card-name { font-size: 13px; font-weight: 700; margin-bottom: 10px; }
.retention-card-pct { font-size: 30px; font-weight: 700; line-height: 1; margin-bottom: 6px; }
.retention-card-note { font-size: 11px; color: var(--text-dim); line-height: 1.5; }
.retention-badge {
  display: inline-block;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  padding: 3px 9px;
  border-radius: 999px;
  margin-bottom: 10px;
}
.retention-empty { font-size: 20px; font-weight: 700; color: var(--text-dim); margin-bottom: 6px; }

.retention-badge-optimal { color: var(--good); background: rgba(53, 201, 143, 0.16); }
.retention-badge-target { color: var(--accent); background: var(--accent-soft); }
.retention-badge-caution { color: var(--warn); background: rgba(242, 184, 75, 0.16); }
.retention-badge-problem { color: var(--bad); background: rgba(239, 91, 107, 0.16); }
.retention-badge-early { color: var(--text-dim); background: rgba(154, 165, 186, 0.16); }
.retention-card-pct.tier-optimal { color: var(--good); }
.retention-card-pct.tier-target { color: var(--accent); }
.retention-card-pct.tier-caution { color: var(--warn); }
.retention-card-pct.tier-problem { color: var(--bad); }
.retention-card-pct.tier-early { color: var(--text-dim); }

/* ---------- Retention manual-entry forms ---------- */
.retention-form-block {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 16px 18px;
  margin-bottom: 14px;
}
.retention-form-block:last-child { margin-bottom: 0; }
.retention-form-title { font-size: 13px; font-weight: 700; margin-bottom: 12px; }
.retention-form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 12px;
  margin-bottom: 12px;
}
.retention-form-grid label { display: block; font-size: 11px; color: var(--text-dim); margin-bottom: 6px; font-weight: 600; }
.retention-form-grid input {
  width: 100%;
  background: var(--bg);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 6px;
  padding: 7px 9px;
  font-size: 13px;
}
.retention-form-status { font-size: 12px; margin-top: 8px; }
.retention-form-status.ok { color: var(--good); }
.retention-form-status.err { color: var(--bad); }
.retention-history-note { font-size: 11px; color: var(--text-dim); margin-top: 10px; }

/* ---------- CFO top-of-page card pair (Revenue Split + Revenue per
   Physician), added 2026-08-10 per Aaron: two cards side by side, centered
   as a pair rather than each stretching full width. Wraps to a single
   centered column on narrow viewports. ---------- */
.cfo-top-row {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  justify-content: center;
  margin-bottom: 20px;
}
.cfo-top-card {
  flex: 1 1 460px;
  max-width: 620px;
  margin-bottom: 0;
}

/* Consolidated column spacing for the Revenue per Physician table, added
   2026-08-10 per Aaron -- the card is narrower now that it shares the CFO
   top row with the Revenue Split card, so this table gets tighter padding
   than the standard .results-table (which was sized for a full-width page). */
.pr-table th, .pr-table td { padding: 12px 10px; font-size: 13px; }
.pr-table th:last-child, .pr-table td:last-child { text-align: right; }

/* Added 2026-08-10 per Aaron: "align the boxes" -- Revenue per Physician's
   dq-note runs ~6 lines, Billing Cadence's only ~3, so the two
   .cfo-highlight-panel boxes below them started at different heights even
   though the cards themselves are the same overall height. Reserving the
   same vertical space for both notes (sized to fit the longer one) forces
   both highlighted boxes to start on the same line, regardless of how much
   each card actually has to say above it. Scoped to just these two cards --
   .dq-note is used broadly elsewhere and shouldn't change size there. */
#physician-revenue-card .dq-note,
#billing-cadence-card .dq-note {
  line-height: 1.5;
  min-height: 108px;
}

/* ---------- CFO page "data area" treatment, added 2026-08-10 per Aaron --
   shared across all three CFO metric cards (Revenue per Physician, Members
   Below Full Rate, Membership vs. Ancillary Revenue) so their core numbers
   read with consistent visual weight: a tinted background panel behind the
   data (Aaron's words: "a highlighted box behind them"), and one shared
   headline-stat typography (26px bold accent, matching the pre-existing
   .kpi-value size) instead of each card inventing its own scale. ---------- */
.cfo-highlight-panel {
  background: var(--accent-2-soft);
  border-radius: 10px;
  padding: 18px 20px;
  margin-top: 4px;
}
/* Cool-navy alternate tint, added 2026-08-10 per Aaron: distinguishes the
   Total Billed vs. Total Deposits tile from its sibling Membership vs.
   Ancillary Revenue tile at a glance -- same "different wash = different
   meaning" language already used elsewhere (warm camel vs. cool navy). */
.cfo-highlight-panel-alt { background: var(--accent-soft); }
.cfo-stat-row {
  display: flex;
  flex-wrap: wrap;
  gap: 28px;
  margin-bottom: 14px;
}
/* Added 2026-08-10 per Aaron for the Billing Cadence card (promoted to a
   standalone top-level card the same day, replacing Members Below Full
   Rate): "let's center the data." Centers the whole stat row instead of the
   left-aligned default used by the taller Revenue per Physician card next
   to it. */
/* Revised 2026-08-10 per Aaron for the Billing Cadence card: "one data
   point per row, and center it" -- was a horizontal row of stats, now a
   vertical centered stack (one stat per row) for a more balanced feel next
   to the taller Revenue per Physician card. */
.cfo-stat-row-center {
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 14px;
}
.cfo-stat { min-width: 90px; }
.cfo-stat-value { font-size: 26px; font-weight: 700; color: var(--accent); display: block; line-height: 1.15; }
.cfo-stat-label { font-size: 11px; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.3px; margin-top: 2px; display: block; }
.rlg-table th, .rlg-table td { padding: 9px 8px; font-size: 12.5px; }
.rlg-table th:not(:first-child), .rlg-table td:not(:first-child) { text-align: right; }
/* Tables inside a highlight panel sit on the tinted background directly --
   drop the table's own row divider color down so it reads against the tint
   instead of the page background. */
.cfo-highlight-panel .results-table,
.cfo-highlight-panel .table-wrap { background: transparent; }
.cfo-highlight-panel .kpi-row { margin-bottom: 0; }

/* Fix, 2026-08-10 per Aaron: the Revenue Split card's 4 KPI cards have no
   icon (unlike every other .kpi-card in the app), so their label/value/sub
   spans are direct children of the flex row .kpi-card -- with no wrapper div
   to group them, flex laid them out as 3 side-by-side COLUMNS (label | value
   | sub) instead of stacked rows, squeezing the value column so narrow that
   real dollar figures wrapped one character group per line even after
   compact-thousandths formatting. Column direction fixes it at the root
   (each span gets the card's full width) and, per Aaron's request, centers
   the content -- same treatment .snapshot-kpi-row already uses for its
   icon-less wide panels. */
/* Selector updated 2026-08-10 -- the card was split into two separate KPI
   rows (#rs-kpi-row-revenue, #rs-kpi-row-deposits) the same day this fix
   was written, so the original single #rs-kpi-row id stopped matching
   either one and the character-by-character wrapping bug silently came
   back. Also added: a hard max-width + line-height/word-break tightening,
   since even with the column layout restored, a bare "$0.168M"-style value
   at 24px can still visually break awkwardly across 2-3 lines in the
   narrower half-width card -- kept on one line at a slightly smaller size
   instead. */
#rs-kpi-row-revenue .kpi-card,
#rs-kpi-row-deposits .kpi-card {
  flex-direction: column;
  align-items: center;
  text-align: center;
  justify-content: center;
  gap: 4px;
  padding: 22px 16px;
}
#rs-kpi-row-revenue .kpi-value,
#rs-kpi-row-deposits .kpi-value {
  font-size: 22px;
  white-space: nowrap;
  line-height: 1.2;
}
#rs-kpi-row-revenue .kpi-label,
#rs-kpi-row-deposits .kpi-label,
#rs-kpi-row-revenue .kpi-sub,
#rs-kpi-row-deposits .kpi-sub {
  white-space: normal;
}

/* ---------- Revenue Split card headline stat, added 2026-08-10 per Aaron:
   an explicit "% of top-line revenue is ancillary" callout, distinct from
   the per-KPI-card sub-percentages below it. ---------- */
.rs-headline {
  font-size: 15px;
  font-weight: 700;
  color: var(--accent);
  margin: 0 0 14px 0;
  /* min-height added 2026-08-10 per Aaron: "line up these two pairs of
     boxes...at the same eye level" -- the two sibling tiles' headline
     sentences are different lengths ("5.8% of top-line billed revenue this
     year is ancillary (non-membership)." wraps to 2 lines; "$124,950
     deposited beyond what's billed." is 1 line), which pushed one tile's
     highlighted box lower than the other's. Reserving space for 2 lines on
     both sides regardless of actual text length keeps the boxes aligned. */
  min-height: 42px;
}
