/* finance.css — KPI cards, chart, per-account cards, invoice table. */

.finance { display: flex; flex-direction: column; gap: var(--space-4); }
.finance__monthnav { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-2); }
.finance__month-label { font-weight: 600; min-width: 130px; text-align: center; }

/* ---- KPI cards ---- */
.finance__kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(215px, 1fr)); gap: var(--space-4); }
/* The 3px accent runs down the left edge, so the card's own padding has to
   clear it — otherwise the label sat on top of the stripe. */
.kpi {
  padding: var(--space-4) var(--space-4) var(--space-4) calc(var(--space-4) + 3px);
  display: flex; flex-direction: column; gap: 6px; position: relative; overflow: hidden;
  min-width: 0;
}
.kpi::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 3px; background: var(--text-subtle); }
.kpi--green::before { background: var(--status-invoiced); }
.kpi--amber::before { background: var(--sunkissed); }
.kpi--blue::before { background: var(--status-can-be-invoiced); }
.kpi--plain::before { background: var(--elke); }
.kpi--paid::before { background: var(--status-paid); }
.kpi--lost::before { background: var(--status-not-selected); }
.kpi--barter::before { background: var(--deal-barter); }
.kpi--counter-invoice::before { background: var(--deal-counter-invoice); }
/* Gewonnen deze maand — the stripe borrows the Gepland colour, because that is
   the status this card counts and the others do not. */
.kpi--won::before { background: var(--status-planned); }

/* The product half of a mixed deal, riding along in the invoice title cell.
   Its own line so a long title never pushes it out of the row. */
.finance__barter-note {
  display: block;
  margin-top: 2px;
  font-size: var(--text-label);
  color: var(--deal-barter);
  white-space: nowrap;
}

/* A tegenfactuur amount sitting in the invoice table's cash column. Coloured
   and marked, because the column's own total deliberately excludes it: this is
   an invoice she has to send, not money that will arrive. */
.finance__counter-amount {
  color: var(--deal-counter-invoice);
  white-space: nowrap;
}
/* Gewonnen werk dat nog moet gebeuren — Gepland grey, the status it counts. */
.kpi--upcoming::before { background: var(--phase-expected); }

/* Label and phase chip share a row. The chip states the time basis the figure is
   computed on, which prose hints were not doing: `Ontvangen` counted delivered
   work while `Barterwaarde` beside it counted won work, and nothing on the card
   said which. Neither gate was wrong — the silence was. */
.kpi__top { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-2); }
.kpi__phase {
  flex: none;
  font-size: 10px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase;
  padding: 2px 6px; border-radius: var(--radius-badge); white-space: nowrap;
}
.kpi__phase--realised { color: var(--phase-realised); background: var(--status-paid-bg); }
.kpi__phase--ontheway { color: var(--phase-ontheway); background: var(--status-can-be-invoiced-bg); }
.kpi__phase--expected { color: var(--phase-expected); background: var(--status-planned-bg); }
.kpi__phase--whole { color: var(--phase-whole); background: var(--surface-2); }

.kpi__label { font-size: var(--text-label); color: var(--text-muted); }
/* clamp: a five-figure amount must shrink rather than spill past its card. */
.kpi__value {
  font-size: clamp(20px, 1.55vw + 12px, 26px);
  font-weight: 700; font-variant-numeric: tabular-nums;
  line-height: 1.2; overflow-wrap: anywhere;
}
.kpi__hint { font-size: 12px; color: var(--text-subtle); }
/* Misgelopen geld is information, not an alarm — same weight, quieter ink. */
.kpi--lost .kpi__value { color: var(--status-not-selected); }
.kpi--paid .kpi__value { color: var(--status-paid); }

/* ---- Charts ---- */
.finance__chart { padding: var(--space-5); }
/* A card heading and a nowrap note on one line had nowhere to go once the note
   grew: they overlapped instead of stacking. Wrapping is the fix; the gap keeps
   the two rows apart when they do stack. */
.finance__chart-head {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: var(--space-2) var(--space-4);
  margin-bottom: var(--space-4);
}
.finance__chart-head h2 { font-size: var(--text-heading); min-width: 0; }
.finance__chart-body { height: 320px; position: relative; }
.finance__chart-body--sm { height: 210px; }
.finance__chart-note {
  font-size: var(--text-label); font-weight: 600; color: var(--text-muted);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.finance__toolbar { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-3); }
.finance__search { min-width: 200px; width: auto; }
.chart-slot { position: relative; height: 100%; }
.chart-slot canvas { width: 100%; }
/* "No data" message occupies the chart's box so the card keeps its height. */
.chart-slot .state-line {
  display: flex; align-items: center; justify-content: center;
  height: 100%; margin: 0; text-align: center; color: var(--text-subtle);
}
.chart-slot .state-line[hidden] { display: none; }

/* Two doughnuts side by side: won/lost and paid/outstanding. auto-fit rather
   than a hard 1fr 1fr, so each keeps enough width for its heading and legend. */
.finance__splits { display: grid; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); gap: var(--space-4); }
.finance__legend { list-style: none; margin: var(--space-3) 0 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.finance__legend-row { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: var(--space-2); font-size: var(--text-label); }
.finance__legend-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--text-subtle); }
.finance__legend-row.tone-paid .finance__legend-dot { background: var(--status-paid); }
.finance__legend-row.tone-lost .finance__legend-dot { background: var(--status-not-selected); }
.finance__legend-row.tone-proposed .finance__legend-dot { background: var(--status-proposed); }
.finance__legend-row.tone-owed .finance__legend-dot { background: var(--status-can-be-invoiced); }
.finance__legend-label { color: var(--text-muted); }
.finance__legend-value { font-weight: 600; font-variant-numeric: tabular-nums; }
.finance__toggle { display: inline-flex; gap: 2px; background: var(--surface-2); padding: 3px; border-radius: var(--radius-badge); }
.finance__toggle-btn { padding: 5px 12px; border-radius: 5px; font-size: var(--text-label); font-weight: 500; color: var(--text-muted); }
/* The inset ring carries the active state in dark mode, where --surface and
   --surface-2 sit too close together for the fill alone to read. */
.finance__toggle-btn.is-active {
  background: var(--surface); color: var(--text);
  box-shadow: var(--shadow-sm), inset 0 0 0 1px var(--border-strong);
}

/* ---- Per-account cards ---- */
/* auto-fit: adding a fourth account never needs a CSS change. */
.finance__accounts { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: var(--space-4); }
.finance__account { padding: var(--space-5); border-left: 4px solid var(--border); }
.finance__account.account-accent-elke { border-left-color: var(--elke); }
.finance__account.account-accent-sunkissed { border-left-color: var(--sunkissed); }
.finance__account.account-accent-mood { border-left-color: var(--mood); }
.finance__account-title { margin-bottom: var(--space-3); font-size: var(--text-heading); }
.finance__stats { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4) var(--space-3); }
.finance__stat { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.finance__stat-label { font-size: 12px; color: var(--text-muted); }
.finance__stat-value {
  font-size: var(--text-heading); font-weight: 600;
  font-variant-numeric: tabular-nums; overflow-wrap: anywhere;
}

/* ---- Goals ---- */
.finance__goals { padding: var(--space-5); display: flex; flex-direction: column; gap: var(--space-4); }
.finance__goal { display: flex; flex-direction: column; gap: 6px; }
.finance__goal-head {
  display: flex; justify-content: space-between; flex-wrap: wrap;
  gap: var(--space-2); font-size: var(--text-label);
}

/* ---- Invoice table ---- */
.finance__invoices { padding: var(--space-5); }
.finance__invoice-wrap { margin-top: var(--space-3); }
.finance__invoice-row.status-row-invoiced { background: rgba(46, 125, 94, 0.07); }
.finance__invoice-row.status-row-can_be_invoiced { background: rgba(224, 122, 47, 0.08); }
.finance__invoice-row.status-row-paid { background: rgba(21, 101, 74, 0.10); }
/* Incl.-btw is the figure on the invoice — give it the weight, keep btw quiet. */
.finance__gross { font-weight: 600; }
.finance__invoices td.is-zero { color: var(--text-subtle); }

/* Two date columns (Betaald op, Herinnerd) at Chromium's native 145px intrinsic
   width spend 290px on two short dates, which is what pushed the ninth column
   into a horizontal scroll.
   130px is the floor, and the margin above it is deliberate. At 118px Chromium
   clips the year off the value ("06/15/202") and it clips *silently*: a date
   input's scrollWidth never exceeds its clientWidth, so no overflow assertion
   can see it — this was found in a screenshot, the only instrument that works
   here. The empty placeholder is wider than a value, and its format follows the
   browser's UI language rather than the page, so leave the slack. */
.finance__invoices input[type="date"].field__input--inline {
  width: 130px; min-width: 0; padding-inline: var(--space-2);
}
/* Nine columns, of which three are currency, two are date pickers and one is a
   status select — so this table runs out of width well before the Posts table
   does, despite having fewer columns. It gets the tighter gutters at every
   width rather than only below 1200 where responsive.css already applies them.
   Worth 72px: the difference between fitting a 1280 laptop and making her swipe
   the table sideways to reach the Status dropdown. */
.finance__invoices .posts__table th,
.finance__invoices .posts__table td { padding-inline: var(--space-3); }
/* The reminder filter carries its own count, so it is the one control on the
   toolbar that says something rather than just offering a choice. Marked only
   while there is actually something to chase — a permanent accent would make
   "0 te herinneren" look like a warning. */
.finance__reminder-filter--due {
  border-color: var(--status-can-be-invoiced);
  color: var(--status-can-be-invoiced);
  font-weight: 600;
}
