From 5634c067c4d08ff5175c0af8d421fe54f38aa414 Mon Sep 17 00:00:00 2001 From: Dave Date: Thu, 5 Nov 2026 01:42:23 +0200 Subject: [PATCH] feat(running): the year to date AND the live month on the running-cost pages The client asked for two things on the running-cost pages: drop the two prose notes, and show the year-to-date figure next to the total for the current month. - /running loses the "Shown to Jan, Feb..." and "A re-cut of costs..." paragraphs. The tiles carry the year and the month instead. - /running shows "Nov so far" beside "YTD running cost", and the "made of" line is printed for the month as well as for the year, so the month's total is explained on the page and not only in the grid. - The cards follow the income cards: YTD spend | Nov so far side by side from md, the month on its own line below md, and the sparkline yields its width below xl so the vehicle NAME is never truncated to pay for a decorative trend. Below sm the name wraps instead of being cut short. - /running/insurance shows the premium in force this month, and its year-to-date figure now stops at the months that have happened. December is a rate on file, not money spent, so including it made this page a full year while the Overview showed eleven months - the same cost kind reading as two different numbers on two screens. - /running/financing shows "Committed for Nov" beside a new year-to-date instalment figure. One rule, three screens. elapsedMonths() in lib/income-month.ts counts the months that have happened and is the same clock the income pages use, and financeByAsset() / fleetFinanceByMonth() in lib/running-costs.ts are the only finance rule the Overview and the financing register both read. The Overview's insurance and finance year-to-date figures now equal the insurance and financing pages' figures exactly. lib/running-month.test.ts asserts it, including the insurance cross-check between the register and the Overview. A settled agreement still contributes nothing to any month - the instalments TLB06 was paying in January-October are not in the Overview's finance figure. The client confirmed the financing is correct as it stands, so that is left alone and recorded in AGENTS.md rather than quietly changed. --- AGENTS.md | 39 ++++++- app/(dashboard)/running/financing/page.tsx | 37 +++++- app/(dashboard)/running/insurance/page.tsx | 47 ++++++-- app/(dashboard)/running/page.tsx | 105 +++++++++++------ components/InsuranceView.tsx | 34 +++--- components/RunningView.tsx | 64 +++++++++-- lib/income-month.ts | 12 ++ lib/rows.ts | 24 +++- lib/running-costs.ts | 43 ++++++- lib/running-month.test.ts | 126 +++++++++++++++++++++ 10 files changed, 450 insertions(+), 81 deletions(-) create mode 100644 lib/running-month.test.ts diff --git a/AGENTS.md b/AGENTS.md index d4178e7..1728c0f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -38,6 +38,11 @@ Every page must pass the mobile checklist before it is considered complete: 2. **No text under 12px on mobile.** Bump `text-[10px]` labels up. 3. **No tap target under 44×44px.** Keep the visual size if you like — add padding to the hit area. 4. **Wide tables scroll inside their own container** with a sticky first column and `-webkit-overflow-scrolling: touch`. Add a visible scroll affordance (e.g. right-edge fade). + Modern Chrome does not SUPPORT that property any more (`CSS.supports` returns false), so it + is inert either way. React's client renderer drops the literal string when a grid is + rendered client-side (a Cards/Grid toggle), while a server-rendered grid keeps it - so the + audit script can report `touchScroll: false` on a grid that is functionally correct. Judge + it on the container, the sticky column and the affordance, not on that string. 5. **Filter controls collapse** below `lg` — pills become a `