/* Overhead screen — additive only. app.css already carries the card surface
   (.proj-card), the table (.est-block, .est-table), the modal shell
   (.modal-overlay, .modal-box, .modal-title, .modal-actions) and the form
   fields (.form-grid, .field). Nothing here restyles them; this file is the
   handful of things those components don't already do. */

/* ── The Summary Card ───────────────────────────────────────────────────────
   A .proj-card with its navigation affordances taken back off. The card is a
   tile everywhere else in the app — click it and an estimate or a client
   opens — so it carries cursor:pointer, a hover border and an accent underline
   that sweeps in. Nothing happens when you click this one: it is a stat
   display wearing the card's surface, per the IA doc's Component Reuse Map.
   Leaving the affordances on would promise a destination that isn't there. */
.oh-summary {
  display: flex;
  gap: 48px;
  flex-wrap: wrap;
  cursor: default;
  margin-bottom: 14px;
}
.oh-summary:hover {
  border-color: var(--border);
}
.oh-summary:hover::after {
  transform: scaleX(0);
}

.oh-stat-value {
  font-family: 'Delight', 'Georgia', serif;
  font-weight: 700;
  font-size: 26px;
  color: var(--text);
  letter-spacing: 0.02em;
}

/* The GST convention, stated where the totals are rather than only inside the
   modal — the number it affects is the one directly above it. */
.oh-note {
  margin: 0 0 14px;
  font-size: 11px;
  line-height: 1.7;
  color: var(--muted);
  max-width: 78ch;
}

/* ── The expense table ──────────────────────────────────────────────────────
   Edit and delete share the last cell. width:1% shrink-wraps it so the five
   data columns keep the rest, the same trick .pricing-act uses on the rate
   card. */
.oh-table td.oh-act {
  width: 1%;
  white-space: nowrap;
  text-align: right;
  padding: 7px 14px 7px 6px;
}
.oh-table td.oh-act .btn {
  margin-right: 6px;
}
/* .est-table's rows are 12px; a first column that is the row's subject reads
   better at the weight the rate card gives its own. */
.oh-table td:first-child {
  color: var(--text);
  font-weight: 500;
}

.oh-empty {
  padding: 16px;
  font-size: 12px;
  line-height: 1.7;
  color: var(--muted);
}

/* ── The Add / Edit modal ───────────────────────────────────────────────────
   app.css styles .field input and .field textarea but never had a .field
   select to style — the app's other selects (.svc-select, .doc-type-select)
   live outside .field and carry their own rules. These are the first, and the
   Goals form will want the same, so it is written as the general case rather
   than scoped to this modal. font:inherit because a bare <select> otherwise
   renders in the UA's font at the UA's size, which on a dark surface reads as
   a control from a different application. */
.field select {
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text);
  font-family: inherit;
  font-size: 13px;
  padding: 9px 12px;
  outline: none;
  width: 100%;
  transition: 0.15s;
}
.field select:focus {
  border-color: var(--accent);
}

/* Sits under the Cost field it describes, inside the same .field, so the
   6px .field gap doesn't double up into a paragraph break. */
.oh-hint {
  margin: 0;
  font-size: 11px;
  line-height: 1.55;
  color: var(--muted);
}

/* ── The double-count hint (Add Expense) ────────────────────────────────────
   A hint, not an error: not the red error box, and not role="alert". Marked
   the way the Dashboard marks a below-floor row — a 1px accent rule, text in
   --text/--muted — so it reads as "look at this" rather than "this is wrong". */
.oh-asset-hint {
  margin-top: 14px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-left: 2px solid var(--accent);
  background: var(--surface);
}
.oh-asset-hint p {
  margin: 0;
  font-size: 12px;
  line-height: 1.6;
  color: var(--muted);
}
.oh-asset-hint strong {
  display: block;
  margin-bottom: 4px;
  color: var(--text);
  font-weight: 600;
}
.oh-asset-hint-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 10px;
}

/* ── Errors ─────────────────────────────────────────────────────────────────
   Same treatment as #pricing-error and #settings-error: inline, next to the
   work it is refusing, rather than an alert() covering the fields it names.
   Two of them because there are two surfaces — the screen (a failed delete)
   and the modal (a failed or rejected save) — and a message about one shown on
   the other would point at nothing. */
#overhead-error,
#oh-modal-error {
  display: none;
  margin: 0 0 14px;
  padding: 10px 14px;
  border: 1px solid var(--err-border);
  background: var(--err-bg);
  color: var(--err-text);
  font-size: 12px;
  line-height: 1.5;
}
#oh-modal-error {
  margin: 18px 0 0;
}
#overhead-error.show,
#oh-modal-error.show {
  display: block;
}
/* The actions bar sits directly under the error when one is showing, so it
   drops the top border it would otherwise double up on. */
#oh-modal-error.show + .modal-actions {
  border-top: 0;
  padding-top: 12px;
  margin-top: 12px;
}

/* ── The chart accent ───────────────────────────────────────────────────────
   Both charts draw their terracotta from this one token, not from --accent.
   --accent is 3.71:1 on --bg: over WCAG 1.4.11's 3:1 for graphics, under the
   brief's 4.5:1 for "chart colours". Put to the user in the accessibility pass
   (HANDOVER.md decision 72) and settled as a chart-only tint rather than
   reading the brief's figure as text-only: --accent mixed 12% toward white,
   which keeps its hue and measures **4.70:1 on --bg**. #c06759 is the lightest
   that clears 4.5:1 at all and sits on 4.50 exactly — no margin for a
   rounding difference between browsers — so this is one step past it.

   Against --surface it is 3.55:1, and that is deliberate rather than missed:
   neither chart ever sits on --surface (an .est-block has a border and no
   background, checked by walking the tree), and reaching 4.5:1 there too would
   take the colour most of the way to pink. --accent everywhere else in the app
   is untouched; this is a chart colour, not a second brand accent.

   One token for the line, its dots, its wash and the donut's largest slice, so
   the two charts cannot drift apart on which terracotta they mean. */
:root {
  --oh-chart-accent: #c26b5d;
}

/* ── The charts ─────────────────────────────────────────────────────────────
   The trend chart (and, next, the donut) sit in an .est-block like the table
   above them, so the screen reads as three framed blocks rather than a table
   and then some loose graphics. Only the inside of the block is new. */
.oh-chart {
  padding: 18px 16px 14px;
}

/* width:100% on top of the svg's own width/height attributes: the attributes
   are the size it was drawn at — one user unit to one CSS pixel, which is what
   keeps the axis labels at their real size — and this scales it smoothly if
   the window is dragged between redraws. height:auto keeps that proportional. */
.oh-chart-svg {
  display: block;
  width: 100%;
  height: auto;
}

/* Horizontal only. Vertical gridlines on an event-ordered axis would imply
   regular time intervals that aren't there. --muted2 is app.css's own
   "structural, not informational" tone, which is exactly what these are. */
.oh-chart-grid {
  stroke: var(--muted2);
  stroke-width: 1;
  shape-rendering: crispEdges;
}

.oh-chart-tick,
.oh-chart-date {
  fill: var(--muted);
  font-family: var(--font-family-body);
  font-size: 11px;
  letter-spacing: 0.04em;
}
.oh-chart-date {
  text-transform: uppercase;
  font-family: var(--font-family-mono);
  font-size: var(--font-size-xs);
  letter-spacing: var(--letter-spacing-wide);
}

.oh-chart-line {
  fill: none;
  stroke: var(--oh-chart-accent);
  stroke-width: 2;
  stroke-linejoin: round;
  stroke-linecap: round;
}

/* A wash, not a block of colour: the fill is there to give the line a floor to
   sit on, and anything heavier competes with the table above it for the eye. */
.oh-chart-area {
  fill: var(--oh-chart-accent);
  fill-opacity: 0.09;
  stroke: none;
}

/* Ringed rather than solid, so a run of close points stays countable. The last
   one is filled — it is the total the rate card is computed from right now. */
.oh-chart-dot {
  fill: var(--bg);
  stroke: var(--oh-chart-accent);
  stroke-width: 2;
}
.oh-chart-dot.is-now {
  fill: var(--oh-chart-accent);
}
/* The transparent hover target over each point. Nothing to draw; the cursor is
   the only hint that there is something to hover. */
.oh-chart-hit {
  cursor: help;
}

/* Says out loud that the horizontal spacing is event order, not elapsed time.
   The chart would otherwise be quietly making a claim about time that its data
   can't support — see the header comment in js/views/overhead-charts.js. */
.oh-chart-caption {
  margin: 10px 0 0;
  font-size: 11px;
  line-height: 1.7;
  color: var(--muted);
  max-width: 78ch;
}

/* No snapshots, or only one — a plain sentence rather than an axis drawn
   around nothing, per the brief's empty-state rule for both charts. */
.oh-chart-empty {
  padding: 2px 0 4px;
  font-size: 12px;
  line-height: 1.7;
  color: var(--muted);
}

/* ── The Category Breakdown donut ───────────────────────────────────────────
   THE ONE PLACE THIS FEATURE BREAKS THE SINGLE-ACCENT RULE.
   The brief scopes the exception to this chart and nothing else: terracotta
   (--accent) marks the largest category, and the rest run a small, desaturated
   warm ramp — ochre, warm grey, pale sand, rose-taupe, light grey — that reads
   as "the one chart with colour" rather than as a rainbow. The classes are
   ranks, not categories: .oh-c1 is always the biggest slice, so the accent
   always lands on the number that matters most and the palette does not
   re-order itself when the expenses do.

   MEASURED, NOT EYEBALLED. Against --bg (#181818, which is what an .est-block
   actually sits on — it has a border and no background of its own) the five
   ramp steps are 6.23, 7.08, 9.96, 6.41 and 10.14:1, and against --surface
   4.71, 5.35, 7.53, 4.84 and 7.66:1 — every step clears the brief's 4.5:1 on
   both. The largest slice is --oh-chart-accent (see its own block above), 4.70:1
   on --bg: the brand --accent it replaced was 3.71:1, and the accessibility pass
   settled that with the user as a chart-only tint (HANDOVER.md decision 72).
   It sits closer to the ochre beside it than --accent did (1.33:1 between them
   against 1.73:1), which is why the 2px --bg separators below matter: rank is
   carried by the separators, the hue shift and the legend, never by luminance.

   Adjacent slices are separated by a 2px --bg stroke, so no slice is ever
   judged against the colour beside it — each one is read against the page. */
/* The ramp is also the Depreciation tab's decline curve's (brief: the donut's
   exception extends to it "on the same terms"), so it is declared for both
   here, once — two copies of these hexes would be two chances to drift. The
   curve uses --oh-c3 and the accent; depreciation.css says why. */
.oh-donut-wrap,
.dep-decline {
  --oh-c1: var(--oh-chart-accent);
  --oh-c2: #ce8a4f;
  --oh-c3: #a8a39b;
  --oh-c4: #dcbe8b;
  --oh-c5: #b0968a;
  --oh-c6: #c9c3b9;
}
.oh-donut-wrap {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 24px 32px;
}

/* One custom property per rank, set once and read by both the slice and its
   legend swatch — so a swatch cannot drift out of step with the segment it
   stands for, which is the whole job a legend has. */
.oh-c1 { --seg: var(--oh-c1); }
.oh-c2 { --seg: var(--oh-c2); }
.oh-c3 { --seg: var(--oh-c3); }
.oh-c4 { --seg: var(--oh-c4); }
.oh-c5 { --seg: var(--oh-c5); }
.oh-c6 { --seg: var(--oh-c6); }

/* margin-inline:auto centres the ring once the legend has wrapped below it,
   and does nothing before that: auto margins only take *leftover* free space,
   and on a wide row .oh-legend's flex-grow has already taken all of it. So the
   same rule gives a centred donut on a phone and a left-aligned one on a
   desktop without a media query deciding which. Checked both, not reasoned
   about — the svg's left edge is unmoved at 1280px. */
.oh-donut {
  flex: 0 0 auto;
  margin-inline: auto;
}
/* No width:100% here, unlike .oh-chart-svg. The trend scales because it is
   drawn to its container; this is a fixed square, and stretching it would blow
   a 200px ring up to 900px on a desktop and make a restrained chart the loudest
   thing on the screen. */
.oh-donut-svg {
  display: block;
}

.oh-seg {
  fill: var(--seg);
  /* Not decoration: it is what keeps two slices from being read against each
     other rather than against the page. */
  stroke: var(--bg);
  stroke-width: 2;
  cursor: help;
}
/* One category owning the whole ring — a stroked circle rather than a sector,
   because a 360° arc paints nothing. See wholeRing() in overhead-charts.js. */
.oh-ring {
  fill: none;
  stroke: var(--seg);
  cursor: help;
}

/* No font-size here on purpose — centreSize() sets it per figure as a
   presentation attribute, because how big it can be depends on how long the
   number is. A rule here would win over the attribute and undo that. */
.oh-donut-total {
  fill: var(--text);
  font-family: 'Delight', 'Georgia', serif;
  font-weight: 700;
  letter-spacing: 0.02em;
}
/* 10px tracked uppercase — the app's own smallest label size (.est-table th,
   .card-gross-label), not a new smaller one invented for the hole. */
.oh-donut-total-label {
  fill: var(--muted);
  font-family: var(--font-family-body);
  font-size: 10px;
  letter-spacing: 0.16em;
}

/* ── The legend ─────────────────────────────────────────────────────────────
   The same figures as text. The brief asks for this by name and for a reason:
   it is what makes the chart readable without the colours, so the scoped
   palette is an aid rather than the only carrier of the data. Deliberately not
   interactive — nothing happens on click, and a focusable row that does nothing
   costs a keyboard user a stop for no return. */
.oh-legend {
  flex: 1 1 260px;
  list-style: none;
  margin: 0;
  padding: 0;
  min-width: 0;
}
/* max-width on the rows, not on .oh-legend. Uncapped, a 1280px screen spread
   each row ~700px and left "Hosting" ~350px from its $1,800.00. Capping the
   list itself would do the same job visually but hand its freed space to
   .oh-donut's auto margins (see the note above it) and slide the ring right;
   the list keeps its flex-grow and only the rows stop growing.

   480px still left "Other" ~300px from its $24,000.00 at 1280 (Finance & Price
   design review, should-fix 10), so it is 340 now. The names are a fixed list
   (overhead.js, CATEGORIES) and the longest, "Admin / Legal", is ~80px; at 340
   the name column is ~170px beside a six-figure amount, so nothing truncates.
   Mostly inert below 768px, where the legend is about this wide anyway. */
.oh-legend-row {
  display: grid;
  grid-template-columns: 10px minmax(0, 1fr) auto 52px;
  align-items: center;
  gap: 10px;
  max-width: 340px;
  padding: 7px 0;
  border-bottom: 1px solid var(--color-border-hairline);
  font-size: 12px;
}
.oh-legend-row:last-child {
  border-bottom: none;
}
/* Square, not a dot: it reads as a sample of the fill rather than as a bullet,
   and a 10px square holds its colour better than a 10px circle does. */
.oh-swatch {
  width: 10px;
  height: 10px;
  background: var(--seg);
}
.oh-legend-name {
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.oh-legend-amt {
  color: var(--text);
  text-align: right;
  font-variant-numeric: tabular-nums;
}
/* The share is the secondary reading — the dollars are the number people act
   on — so it sits muted and in its own fixed column, where a run of them lines
   up as a column rather than ragging against the amounts. */
.oh-legend-pct {
  color: var(--muted);
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* The caption spans the full row under both, rather than being squeezed into
   the legend column beside the ring. */
.oh-donut-caption {
  flex: 1 1 100%;
  margin: 0;
}

/* ── Inner tabs: Operating Costs / Depreciation ────────────────────────────
   The horizontal .nav-link row the Finance & Price rail replaced, reused here
   so the area keeps one navigation idea (IA doc, "Tertiary navigation"): the
   header's own uppercase 11px links, accent underline on the active one. The
   negative margin pulls the first link's 10px padding back so its text lines
   up with the page title above. No rule under the row — .page-head already
   draws one just above it, and two close rules read as a ladder. */
.oh-inner-tabs {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: -10px 0 20px -10px;
}
/* responsive.css narrows .nav-link's side padding to 8px below 1100px for the
   header; held at 10px here so the -10px offset above keeps the first label on
   the page title's edge at every width. */
.oh-inner-tabs .nav-link {
  padding-left: 10px;
  padding-right: 10px;
}

/* The categories folded into the donut's "N more categories" slice
   (overhead-charts.js, ringGroups): listed under it, unswatched, in --muted,
   so they read as the slice's contents rather than as slices of their own. */
.oh-legend-sub {
  padding: 4px 0;
  font-size: 11px;
}
.oh-legend-sub .oh-legend-name,
.oh-legend-sub .oh-legend-amt {
  color: var(--muted);
}

/* ── The car's cost per km (task 6b) ────────────────────────────────────────
   A .tax-setting block, as Depreciation's write-off threshold is: copy left,
   field and Save right. Between the table and the charts: an input, not part
   of either. */
.oh-km {
  margin-top: 22px;
}
.oh-km-copy {
  color: var(--muted);
  font-size: 11px;
  line-height: 1.55;
}
.oh-km-ctl {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}
