AGENTS.md: record the rules the charts and the site cards now depend on
Three things in here cost real time to work out, so they are written down rather than left to be re-derived: - The Recharts constraints behind the profit line (a Line is one <Curve>, so <Cell> cannot recolour a segment; a Line with its own `data` corrupts the shared categorical axis; profit Lines must be direct children or they vanish silently; the tooltip needs custom `content`). - globals.css hard-codes the axis tick font size, which beats Recharts' tick.fontSize prop — so the 12px mobile bump has to happen in that CSS rule or nowhere. - /sites now defaults to Cards and must be kept in step with IncomeView. Plus the two deliberate palette exceptions (--color-chart-loss, --color-chart-profit) and the client rulings behind them.
This commit is contained in:
parent
649e495f49
commit
123484a8c4
1 changed files with 59 additions and 1 deletions
60
AGENTS.md
60
AGENTS.md
|
|
@ -94,6 +94,12 @@ Other rules worth not re-learning:
|
|||
Months from other years are dropped, not folded in, and the panel says so.
|
||||
- `SiteSummary.pinned` exists because the table is a client component and cannot look
|
||||
the site up in the `sites` collection itself.
|
||||
- **`/sites` defaults to the Cards view, deliberately mirroring `IncomeView`** — same
|
||||
toolbar, same card shape, same 12-month strip on expand, same three-up footer. The
|
||||
client likes the vehicles overview and asked for the sites to read the same way, so
|
||||
keep the two in step when either changes. Grid is the old table, kept as a toggle.
|
||||
The site detail link lives **inside the expanded panel only** — a card is a
|
||||
`<button>`, so a nested `<a>` would be invalid HTML.
|
||||
|
||||
## Money on invoices — VAT is NOT revenue
|
||||
|
||||
|
|
@ -139,7 +145,59 @@ Coolors:
|
|||
Chart marks (deeper steps of the same hues — see HANDOFF-PROMPT-3 §A.4):
|
||||
- `--color-chart-income` (light `#0090A6`, dark `#00A6BE`)
|
||||
- `--color-chart-fixed` (`#BE851F` both)
|
||||
- `--color-chart-running` (light `#C13B4D`, dark `#D94F60`)
|
||||
- `--color-chart-running` (`#8B5CF6` both) — the project's existing
|
||||
`--color-brand-purple`, so Running introduces no new hue. **Client ruling, 2026-10-02:**
|
||||
Running was moved off red because red is now reserved for a month that made a loss, and a
|
||||
red Running line sitting next to a red loss segment was unreadable. Yellow was considered
|
||||
and rejected — `--color-chart-fixed` is already a gold.
|
||||
- `--color-chart-loss` (light `#C13B4D`, dark `#D94F60`) — a month that did not make
|
||||
profit. **It has its own token on purpose:** it used to read
|
||||
`--color-chart-running`, so recolouring Running silently dragged the loss red with it.
|
||||
- `--color-chart-profit` (`#7A9E06` both) — the profit line's green. **Client ruling,
|
||||
2026-10-02: this is a second deliberate exception to the "never change the palette" rule.**
|
||||
It is a bright yellow-green, chosen so the profit line reads as its own series instead of
|
||||
blending into the teal income line.
|
||||
|
||||
`globals.css` hard-codes `.recharts-cartesian-axis-tick text { font-size: 11px }`, which
|
||||
**beats Recharts' `tick.fontSize` prop**. Any "bump chart text to 12px on mobile" work has to
|
||||
happen in that CSS rule or it silently does nothing.
|
||||
|
||||
## The profit line on `/charts` — Recharts constraints, do not re-derive
|
||||
|
||||
`MachineLineChart` draws profit as teal where the month made money and red where it did not,
|
||||
fading across each sign crossing. Three things make this fragile:
|
||||
|
||||
- **A `Line` is one `<Curve>` path.** `<Cell>` does **not** recolour a segment — Cells only
|
||||
work for `Bar`. Per-segment colour therefore requires **one `<Line>` per same-sign run**,
|
||||
plus one extra `<Line>` per crossing for the gradient.
|
||||
- **Never give a `Line` its own `data` prop inside a shared chart.** Recharts builds a
|
||||
categorical axis by concatenating the data of *every* series, so a short sliced `data`
|
||||
re-adds the month labels: the axis renders "Jan … Aug, Jan … Aug" while that series plots
|
||||
at the wrong months. Put each variant on the shared dataset as its own key
|
||||
(`profitRun0`, `profitCross0`) and null it outside its run; `connectNulls={false}` then
|
||||
draws just that run in the right place.
|
||||
- **Profit `Line`s must be direct children of the chart.** Recharts parses only known child
|
||||
types, so wrapping them in a `<g>` makes the entire profit line disappear without an error.
|
||||
- **The tooltip needs a custom `content` component** (`ChartTooltip` in `MachineLineChart`).
|
||||
Recharts feeds the tooltip one entry per series, so the per-run keys would surface as
|
||||
`profitRun0` / `profitCross0` and "profit" would appear three or four times. The component
|
||||
drops every profit-backed series and adds one computed row, coloured by the month's sign.
|
||||
The base series carry an explicit `name`, because Recharts otherwise labels them by key
|
||||
(`running` reads as "Running cost", which is what the key is called).
|
||||
|
||||
Two deliberate honesty rules: profit stays **null** in a month with no income figure (never
|
||||
treated as 0, which would draw a green dot for a month that was never billed), and a month
|
||||
with no `monthly_running_costs` row gets a **hollow dot** because its profit is optimistic.
|
||||
`/charts` alone reads profit including running cost — `lib/profit.ts` keeps its workbook
|
||||
default for every other surface, and the card badge, the profit line and the Profit bars
|
||||
view all share the one flag in `ChartsGrid`.
|
||||
|
||||
The toolbar's **Series** button toggles which lines a card draws (`mp:chartsSeries` in
|
||||
localStorage, so the choice survives a reload). Two rules keep it honest: a hidden series
|
||||
leaves the legend **and its Y axis** with it, so there is never an axis for a line that is
|
||||
not drawn; and the last visible series cannot be switched off, because an empty chart reads
|
||||
as broken. The Profit toggle also owns the loss colour, since red is a sign of the profit
|
||||
line rather than a series of its own.
|
||||
|
||||
## Cost model
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue