/* ════════════════════════════════════════════════════════════════════════════
   CASH FLOW FORECAST
   ────────────────────────────────────────────────────────────────────────────
   Uses the dashboard tokens from style.css :root — no hex literals below this
   line. Red and amber stay reserved, as everywhere else: amber marks money that
   is late, red marks a balance below zero. Neither is decorative.
   ══════════════════════════════════════════════════════════════════════════ */

.cf-flash {
  background: var(--jade-50); color: var(--jade-800);
  border-radius: var(--r-md); padding: var(--s-3) var(--s-4);
  margin-bottom: var(--s-4); font-size: 0.875rem; font-weight: 500;
}
.cf-flash--error { background: var(--alert-50); color: var(--alert-700); }

/* ── Opening balance strip ─────────────────────────────────────────────────── */
.cf-top {
  display: flex; align-items: flex-end; gap: var(--s-6); flex-wrap: wrap;
  background: var(--surface); border-radius: var(--r-lg);
  box-shadow: var(--shadow-raised); padding: var(--s-5); margin-bottom: var(--s-4);
}
.cf-open-label, .cf-control-label {
  font-size: 0.6875rem; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.12em; color: var(--ink-400);
}
.cf-open-figure {
  font-family: var(--font-display); font-size: 2rem; line-height: 1.1;
  color: var(--navy-900); margin-top: var(--s-2);
}
.cf-open-figure.cf-absent { color: var(--ink-300); font-size: 1.5rem; }
.cf-open-note { font-size: 0.75rem; color: var(--ink-500); margin-top: var(--s-2); }
.cf-inline-form { display: flex; align-items: flex-end; gap: var(--s-2); }
.cf-inline-form label { font-size: 0.75rem; color: var(--ink-500); display: block; }
.cf-inline-form input {
  display: block; margin-top: 4px; padding: 7px 10px; width: 130px;
  border: 1px solid var(--ink-200); border-radius: var(--r-sm);
  font-family: var(--font-ui); font-variant-numeric: tabular-nums; font-size: 0.875rem;
}
.cf-controls { margin-left: auto; display: flex; align-items: center; gap: var(--s-2); }

.cf-chip {
  font-size: 0.78rem; font-weight: 600; color: var(--ink-500);
  padding: 5px 12px; border-radius: 999px; background: var(--ink-100);
}
.cf-chip:hover { text-decoration: none; background: var(--jade-50); color: var(--jade-700); }
.cf-chip.is-on { background: var(--navy-700); color: var(--surface); }

/* ── Caveats, said before any chart ────────────────────────────────────────── */
.cf-caveats { display: flex; flex-direction: column; gap: var(--s-2); margin-bottom: var(--s-4); }
.cf-caveat {
  background: var(--surface); border-left: 3px solid var(--ink-300);
  border-radius: var(--r-sm); padding: var(--s-3) var(--s-4);
  font-size: 0.8125rem; color: var(--ink-700);
}
.cf-caveat--warn { border-left-color: var(--warn-600); background: var(--warn-50); }
.cf-caveat strong { color: var(--navy-900); }

/* ── Tabs ──────────────────────────────────────────────────────────────────── */
.cf-tabs { display: flex; gap: var(--s-2); margin-bottom: var(--s-4); }
.cf-tab {
  font-size: 0.875rem; font-weight: 600; color: var(--ink-500);
  padding: var(--s-2) var(--s-4); border-radius: 999px;
}
.cf-tab:hover { text-decoration: none; background: var(--jade-50); color: var(--jade-700); }
.cf-tab.is-on { background: var(--jade-600); color: var(--surface); }

/* ── Panels ────────────────────────────────────────────────────────────────── */
.cf-panel {
  background: var(--surface); border-radius: var(--r-lg);
  box-shadow: var(--shadow-raised); padding: var(--s-5); margin-bottom: var(--s-5);
}
.cf-panel-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--s-3); margin-bottom: var(--s-4);
}
.cf-panel-title { font-family: var(--font-display); font-size: 1.25rem; color: var(--navy-900); font-weight: 400; }
.cf-panel-note { font-size: 0.75rem; color: var(--ink-400); }
.cf-empty { padding: var(--s-5) 0; color: var(--ink-400); font-size: 0.875rem; line-height: 1.6; }
.cf-footnote { margin-top: var(--s-4); font-size: 0.75rem; color: var(--ink-400); line-height: 1.6; }

/* ── Calendar ──────────────────────────────────────────────────────────────── */
.cf-month {
  background: var(--surface); border-radius: var(--r-lg);
  box-shadow: var(--shadow-raised); padding: var(--s-5); margin-bottom: var(--s-4);
}
.cf-month-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--s-4); flex-wrap: wrap; margin-bottom: var(--s-4);
}
.cf-month-title { font-family: var(--font-display); font-size: 1.375rem; color: var(--navy-900); font-weight: 400; }

/* ── Month stepper ────────────────────────────────────────────────────────────
   One month at a time needs a way out of it in both directions, and a way to
   tell where in the horizon you are — an isolated grid otherwise gives no clue
   whether there are two months left or twenty. */
.cf-mnav { display: flex; align-items: center; gap: var(--s-3); }
.cf-mnav-arrow {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; flex-shrink: 0;
  border: 1px solid var(--ink-200); border-radius: 999px;
  background: var(--surface); color: var(--ink-700);
  font-size: 1.125rem; line-height: 1;
}
.cf-mnav-arrow:hover {
  text-decoration: none; background: var(--jade-50);
  border-color: var(--jade-400); color: var(--jade-700);
}
/* At either end of the horizon the arrow stays in place rather than vanishing:
   a control that disappears moves everything next to it. */
.cf-mnav-arrow.is-off { color: var(--ink-300); border-color: var(--ink-100); background: transparent; }
.cf-mnav-of {
  font-size: 0.6875rem; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.1em; color: var(--ink-400); white-space: nowrap;
}
.cf-month-empty {
  margin-top: var(--s-4); text-align: center;
  font-size: 0.8125rem; color: var(--ink-400);
}
.cf-month-figures {
  display: flex; gap: var(--s-4); align-items: baseline;
  font-family: var(--font-ui); font-variant-numeric: tabular-nums; font-size: 0.8125rem;
}
.cf-in { color: var(--good-600); font-weight: 600; }
.cf-out { color: var(--ink-500); font-weight: 600; }
.cf-net { font-weight: 600; color: var(--navy-900); }
.cf-net.is-neg { color: var(--alert-600); }
.cf-bal { color: var(--ink-500); }
.cf-bal strong { color: var(--navy-900); }

.cf-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; }
.cf-dow {
  font-size: 0.625rem; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.1em; color: var(--ink-400); text-align: center; padding-bottom: 4px;
}
/* The outline is drawn as an inset shadow rather than a border so it costs no
   layout: a 1px border on a 7-column grid of fixed-height cells would push the
   contents around. --ink-300 is the palette's blue-grey rule — the palette has
   no paler blue than the inks, and inventing one would put a hex literal in a
   file that has none. --ink-200, tried first, was too faint against the sunk
   surface to do the one job asked of it. */
.cf-cell {
  min-height: 74px; border-radius: var(--r-sm);
  background: var(--surface-sunk); padding: 5px 6px; overflow: hidden;
  box-shadow: inset 0 0 0 1px var(--ink-300);
}
.cf-cell--blank { background: transparent; box-shadow: none; }
.cf-cell.has-items { background: var(--jade-50); }
/* Commission paydays are a rhythm, not an event. Marking them makes the monthly
   pulse visible instead of something to work out from dates. The jade ring
   replaces the grey outline rather than sitting inside it — two rings on one
   cell reads as an error state.

   It has to out-weigh that grey outline. At jade-100 it did, back when it was
   the only ring on the grid; once every day had one, the marked day was the
   faintest square on the page and the emphasis had quietly inverted. */
.cf-cell.is-payday { box-shadow: inset 0 0 0 2px var(--jade-400); }

/* A day with movement opens its full list, so it is a button. These reset it to
   look like the cell it replaces. */
button.cf-cell {
  display: block; width: 100%; text-align: left;
  font: inherit; color: inherit; border: 0; cursor: pointer; -webkit-appearance: none; appearance: none;
}
button.cf-cell:hover { box-shadow: inset 0 0 0 1px var(--jade-400); }
/* A payday already rests at jade-400, so hover has to go a step further or the
   cell gives no answer to being pointed at. */
button.cf-cell.is-payday:hover { box-shadow: inset 0 0 0 2px var(--jade-600); }
button.cf-cell:focus-visible { outline: 2px solid var(--jade-600); outline-offset: 1px; }
.cf-daynum { font-size: 0.6875rem; color: var(--ink-400); font-variant-numeric: tabular-nums; }
.cf-cell-in, .cf-cell-out {
  font-size: 0.6875rem; font-weight: 700; font-variant-numeric: tabular-nums;
}
.cf-cell-in { color: var(--good-600); }
.cf-cell-out { color: var(--ink-700); }
.cf-items { list-style: none; margin-top: 3px; }
.cf-item {
  display: flex; align-items: center; gap: 4px;
  font-size: 0.625rem; color: var(--ink-500);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cf-item--more { color: var(--ink-400); font-style: italic; }
.cf-item-dot {
  width: 6px; height: 6px; border-radius: 2px; flex-shrink: 0;
  background: var(--ink-300); display: inline-block;
}
/* The day detail carries the same dots as the cells it opens from, so the rows
   there have to answer these selectors too — a legend that only holds on one
   surface teaches the reader nothing. */
.cf-item-dot.is-actual, .cf-item.is-actual .cf-item-dot, .cf-day-row.is-actual .cf-item-dot { background: var(--jade-700); }
.cf-item-dot.is-expected, .cf-item.is-expected .cf-item-dot, .cf-day-row.is-expected .cf-item-dot { background: var(--jade-400); }
.cf-item-dot.is-overdue, .cf-item.is-overdue .cf-item-dot, .cf-day-row.is-overdue .cf-item-dot { background: var(--warn-600); }
.cf-item-dot.is-planned, .cf-item.is-planned .cf-item-dot, .cf-day-row.is-planned .cf-item-dot { background: var(--navy-500); }

.cf-key {
  display: flex; flex-wrap: wrap; gap: var(--s-3) var(--s-5);
  font-size: 0.75rem; color: var(--ink-500); padding: var(--s-4) 0;
}
.cf-key-item { display: flex; align-items: center; gap: 6px; }
.cf-key-payday { color: var(--ink-400); font-style: italic; }

/* ── Day detail ───────────────────────────────────────────────────────────────
   The cell shows four items and says how many it is holding back. This is where
   the rest of them are. */
.cf-day {
  border: 0; border-radius: var(--r-lg); padding: var(--s-5);
  width: min(580px, calc(100vw - var(--s-6)));
  max-height: min(80vh, 760px);
  background: var(--surface); color: var(--ink-700);
  box-shadow: var(--shadow-float);
  /* Stated rather than inherited: a modal dialog is centred by the browser with
     margin:auto, and the reset in style.css zeroes it, which drops the dialog
     into the top-left corner. */
  margin: auto;
}
.cf-day[open] { display: flex; flex-direction: column; }
/* Tokens only — the scrim is the ink of the palette at low opacity, not a new
   colour mixed for the occasion. */
.cf-day::backdrop { background: var(--navy-900); opacity: 0.28; }
.cf-day-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--s-4); margin-bottom: var(--s-4);
}
.cf-day-title { font-family: var(--font-display); font-size: 1.125rem; color: var(--navy-900); font-weight: 400; }
.cf-day-figures {
  display: flex; flex-wrap: wrap; gap: var(--s-3); margin-top: var(--s-2);
  font-family: var(--font-ui); font-variant-numeric: tabular-nums; font-size: 0.8125rem;
}
.cf-day-x {
  border: 0; background: transparent; color: var(--ink-400);
  font-size: 1.25rem; line-height: 1; padding: 2px 7px;
  border-radius: var(--r-sm); cursor: pointer;
}
.cf-day-x:hover { background: var(--ink-100); color: var(--ink-700); }
/* Sixty-five trainer payments is a real day here, so the list scrolls inside the
   dialog and the date and totals stay put above it. */
.cf-day-body { overflow-y: auto; min-height: 0; }
.cf-day-group + .cf-day-group { margin-top: var(--s-5); }
/* Sticky because a day can hold fifty-five rows: twenty of them in, the reader
   has scrolled the heading away and every line reads the same. Which side of the
   day you are looking at has to stay on screen. */
.cf-day-group-head {
  position: sticky; top: 0; z-index: 1; background: var(--surface);
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-3);
  font-size: 0.625rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.1em;
  color: var(--ink-400); padding: var(--s-2) 0; border-bottom: 1px solid var(--ink-200);
}
.cf-day-group-head .cf-in, .cf-day-group-head .cf-out {
  font-size: 0.8125rem; letter-spacing: 0; font-variant-numeric: tabular-nums;
}
.cf-day-list { list-style: none; }
.cf-day-row {
  display: grid; grid-template-columns: auto 1fr auto; gap: 2px var(--s-3);
  align-items: baseline; padding: var(--s-2) 0;
  border-bottom: 1px solid var(--ink-100); font-size: 0.8125rem;
}
.cf-day-row .cf-item-dot { grid-column: 1; grid-row: 1; align-self: center; }
.cf-day-label { grid-column: 2; grid-row: 1; color: var(--navy-900); }
.cf-day-amt {
  grid-column: 3; grid-row: 1; text-align: right; white-space: nowrap;
  font-weight: 600; font-variant-numeric: tabular-nums; color: var(--ink-700);
}
/* The reason the money sits on this date, under the thing it belongs to. A
   figure whose date cannot be explained is a guess with a chart on top. */
.cf-day-why { grid-column: 2 / -1; grid-row: 2; font-size: 0.6875rem; color: var(--ink-400); }
.cf-day-row.is-overdue .cf-day-amt { color: var(--warn-600); }

/* ── Charts ────────────────────────────────────────────────────────────────── */
.cf-chart { margin: var(--s-4) 0; }
.cf-chart-svg { width: 100%; height: 240px; display: block; }
.cf-chart-line {
  fill: none; stroke: var(--jade-600); stroke-width: 2.5;
  stroke-linejoin: round; vector-effect: non-scaling-stroke;
}
.cf-chart-line--modelled { stroke: var(--navy-500); stroke-dasharray: 6 4; }
.cf-chart-zero { stroke: var(--ink-300); stroke-width: 1; stroke-dasharray: 4 4; vector-effect: non-scaling-stroke; }
.cf-chart-danger { fill: var(--alert-50); }
.cf-chart-dot { fill: var(--jade-600); }
.cf-chart-dot.is-neg { fill: var(--alert-600); }

.cf-bars { display: flex; gap: 6px; align-items: flex-end; margin: var(--s-5) 0 var(--s-2); }
.cf-bar-col { flex: 1; text-align: center; }
.cf-bar-stack { display: flex; gap: 2px; align-items: flex-end; height: 70px; justify-content: center; }
.cf-bar { width: 46%; border-radius: 3px 3px 0 0; min-height: 2px; }
.cf-bar--in { background: var(--jade-500); }
.cf-bar--out { background: var(--ink-200); }
.cf-bar-label { font-size: 0.625rem; color: var(--ink-400); margin-top: 5px; }

/* ── Tables ────────────────────────────────────────────────────────────────── */
.cf-table { width: 100%; border-collapse: collapse; font-size: 0.8125rem; margin-top: var(--s-4); }
.cf-table th {
  text-align: left; padding: var(--s-2) var(--s-3);
  font-size: 0.625rem; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.08em; color: var(--ink-400);
  border-bottom: 1px solid var(--ink-100); white-space: nowrap;
}
.cf-table td {
  padding: var(--s-2) var(--s-3); border-bottom: 1px solid var(--ink-100);
  font-variant-numeric: tabular-nums; color: var(--ink-700);
}
.cf-table .cf-r { text-align: right; }
.cf-table tr.is-neg td { background: var(--alert-50); color: var(--alert-700); }
.cf-table--months tbody tr:hover td { background: var(--jade-50); }
.cf-table input[type="text"], .cf-table input[type="date"], .cf-table select {
  padding: 5px 7px; border: 1px solid var(--ink-200); border-radius: 6px;
  font-family: var(--font-ui); font-size: 0.8125rem; width: 100%;
}
.cf-amt { width: 90px !important; text-align: right; font-variant-numeric: tabular-nums; }
.cf-dir { width: 52px !important; }
.cf-actions { white-space: nowrap; }
.cf-actions form { display: inline; }

.cf-mini {
  font-size: 0.6875rem; font-weight: 600; padding: 5px 10px;
  border-radius: 999px; border: 1px solid var(--ink-200);
  background: var(--surface); color: var(--ink-700); cursor: pointer;
}
.cf-mini:hover { background: var(--jade-50); border-color: var(--jade-400); color: var(--jade-700); }
.cf-mini--danger:hover { background: var(--alert-50); border-color: var(--alert-600); color: var(--alert-700); }
.cf-mini--on { background: var(--jade-600); color: var(--surface); border-color: var(--jade-600); }

/* ── Entry forms ───────────────────────────────────────────────────────────── */
.cf-adhoc-form {
  display: flex; flex-wrap: wrap; gap: var(--s-2); align-items: center;
  padding: var(--s-3); background: var(--surface-sunk);
  border-radius: var(--r-md); margin-bottom: var(--s-4);
}
.cf-adhoc-form input, .cf-adhoc-form select {
  padding: 7px 10px; border: 1px solid var(--ink-200); border-radius: var(--r-sm);
  font-family: var(--font-ui); font-size: 0.8125rem;
}
.cf-adhoc-form input[type="text"] { min-width: 150px; }
.cf-adhoc-form--nested { background: transparent; padding: var(--s-2) 0 0; }
.cf-narrow { width: 90px; }
.cf-check { font-size: 0.75rem; color: var(--ink-500); display: flex; align-items: center; gap: 4px; }

/* ── Planning scenarios ────────────────────────────────────────────────────── */
.cf-plan {
  border: 1px solid var(--ink-100); border-radius: var(--r-md);
  padding: var(--s-4); margin-bottom: var(--s-3);
}
.cf-plan.is-on { border-color: var(--jade-400); background: var(--jade-50); }
.cf-plan-head { display: flex; justify-content: space-between; gap: var(--s-4); flex-wrap: wrap; }
.cf-plan-name { font-weight: 600; color: var(--navy-900); font-size: 0.9375rem; }
.cf-plan-cond { font-size: 0.75rem; color: var(--ink-500); margin-top: 2px; }
.cf-plan-actions { display: flex; gap: var(--s-2); }
.cf-plan-items { list-style: none; margin: var(--s-3) 0 0; }
.cf-plan-items li {
  display: flex; align-items: center; gap: var(--s-2);
  font-size: 0.8125rem; color: var(--ink-700); padding: 5px 0;
}
.cf-plan-items form { margin-left: auto; }
.cf-kind {
  font-size: 0.625rem; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--jade-700); background: var(--jade-100);
  padding: 2px 7px; border-radius: 999px;
}

/* ── Trajectory ────────────────────────────────────────────────────────────── */
.cf-traj-figures { display: flex; gap: var(--s-7); flex-wrap: wrap; margin-bottom: var(--s-4); }
.cf-traj-label {
  font-size: 0.625rem; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.1em; color: var(--ink-400);
}
.cf-traj-value {
  font-family: var(--font-display); font-size: 1.875rem; color: var(--navy-900);
  line-height: 1.1; margin-top: var(--s-2);
}
.cf-traj-value.is-neg { color: var(--alert-600); }
.cf-traj-value span { font-family: var(--font-ui); font-size: 0.8125rem; color: var(--ink-400); }
.cf-traj-note { font-size: 0.6875rem; color: var(--ink-400); margin-top: 4px; }
.cf-multi { display: flex; align-items: center; gap: var(--s-2); flex-wrap: wrap; margin-bottom: var(--s-3); }
.cf-multi-note { font-size: 0.75rem; color: var(--ink-500); margin-left: var(--s-3); }

/* The pipeline layer. Dashed and lighter than the committed line, because it is
   weighted maybes sitting above what has actually been sold — it should never
   be mistaken for the firmer figure it sits above. */
.cf-chart-line--pipeline {
  stroke: var(--jade-400); stroke-width: 2; stroke-dasharray: 7 5;
}
.cf-chip--layer { border: 1px dashed var(--ink-300); background: transparent; }
.cf-chip--layer.is-on { background: var(--jade-600); color: var(--surface); border-color: var(--jade-600); }
