Five layout, charting, and accessibility defects on /reports. Grouped because they share one fix pass; happy to split if preferred.
1. The Money Flow Sankey has no labels
Not one node on the Cash Flow tab is named — colored ribbons and nothing to read. This is the tab titled "Money Flow". Node labels + values are the minimum.
2. Net Worth has no legend, and a meaningless headline percentage
Three series render (solid green, red, dashed green) with no key — nothing identifies assets vs liabilities vs net worth.
The Change tile reads "+$53,457.38 / +10381.3%". The percentage is computed off a near-zero opening balance and is noise presented as the headline. Suppress the percentage when the base rounds to zero and show the absolute change alone.
The x-axis also ends Aug 28 while the selected range runs to Sep 2.
3. Trends: colliding series colours and fabricated curve shape
- Education and Restaurants both render blue and are indistinguishable in the chart.
- The line uses smooth interpolation across three monthly points, drawing Education arcing up to ~$3,500 mid-July and back to zero. Education is a lump sum on one day; the curve depicts spending that never happened. Use a linear/step interpolation, or plot the actual transaction dates.
4. Mobile is broken below ~570px
At a 390px viewport (emulated, deviceScaleFactor: 3):
document.scrollWidth 569 vs clientWidth 390 — the page overflows by 179px and scrolls sideways.
- The third summary tile is clipped to just its icon.
- Trends and Net Worth are off-screen, and the tablist computes
overflow-x: visible — there is no scroll affordance, so those two tabs are effectively unreachable.
report-summary-bar.tsx:62 sets gridTemplateColumns: repeat(n, 1fr) as an inline style, so no breakpoint can reach it. Measured widths are also uneven (173 / 133 / 180px) because 1fr yields to content min-width.
5. Overlapping chrome and no keyboard access
- The sidebar avatar and the AI assistant FAB sit on top of page content on every tab — they cover the table header ("Category", "Amount") and, on Trends, the Groceries and Subscriptions checkboxes.
- All drill-down targets are unreachable by keyboard: 18 table rows, 9 legend rows and the pie sectors all measure
tabIndex: -1 with no role. Drill-down is mouse-only.
- The donut legend paints a stray horizontal scrollbar:
scrollWidth 660 > clientWidth 656, because spending-chart.tsx:81 sets overflow-y-auto alone and CSS then computes overflow-x: auto. Add overflow-x-hidden.
Information design (smaller, same pass)
- "Top: Uncategorized" puts a crown on a data-quality failure.
report-spending.tsx:46 takes data[0] blindly; skip the null-category row (the real answer is Education, $3,500).
- Uncategorized draws
CHART_COLORS[0], the most saturated blue, making "we don't know" the visual hero at 61%. It should take var(--chart-neutral), the treatment the synthetic "Other" slice already gets (spending-chart.tsx:27).
- "Categories: 18" is a metric no decision turns on.
- The resolved date range appears nowhere on the page — only "Last 3 months".
- Blank cells in the Change column are ambiguous:
prevTotal defaults to 0 (reports.ts:77) and ComparisonBadge renders nothing, so "new category" and "no change" look identical.
A mock of the reworked Spending tab, built on the existing tokens, is at https://claude.ai/code/artifact/9ed146ee-85de-4a73-8075-7c39fcca43d5
Five layout, charting, and accessibility defects on
/reports. Grouped because they share one fix pass; happy to split if preferred.1. The Money Flow Sankey has no labels
Not one node on the Cash Flow tab is named — colored ribbons and nothing to read. This is the tab titled "Money Flow". Node labels + values are the minimum.
2. Net Worth has no legend, and a meaningless headline percentage
Three series render (solid green, red, dashed green) with no key — nothing identifies assets vs liabilities vs net worth.
The Change tile reads "+$53,457.38 / +10381.3%". The percentage is computed off a near-zero opening balance and is noise presented as the headline. Suppress the percentage when the base rounds to zero and show the absolute change alone.
The x-axis also ends Aug 28 while the selected range runs to Sep 2.
3. Trends: colliding series colours and fabricated curve shape
4. Mobile is broken below ~570px
At a 390px viewport (emulated,
deviceScaleFactor: 3):document.scrollWidth 569vsclientWidth 390— the page overflows by 179px and scrolls sideways.overflow-x: visible— there is no scroll affordance, so those two tabs are effectively unreachable.report-summary-bar.tsx:62setsgridTemplateColumns: repeat(n, 1fr)as an inline style, so no breakpoint can reach it. Measured widths are also uneven (173 / 133 / 180px) because1fryields to content min-width.5. Overlapping chrome and no keyboard access
tabIndex: -1with norole. Drill-down is mouse-only.scrollWidth 660 > clientWidth 656, becausespending-chart.tsx:81setsoverflow-y-autoalone and CSS then computesoverflow-x: auto. Addoverflow-x-hidden.Information design (smaller, same pass)
report-spending.tsx:46takesdata[0]blindly; skip the null-category row (the real answer is Education, $3,500).CHART_COLORS[0], the most saturated blue, making "we don't know" the visual hero at 61%. It should takevar(--chart-neutral), the treatment the synthetic "Other" slice already gets (spending-chart.tsx:27).prevTotaldefaults to0(reports.ts:77) andComparisonBadgerenders nothing, so "new category" and "no change" look identical.A mock of the reworked Spending tab, built on the existing tokens, is at https://claude.ai/code/artifact/9ed146ee-85de-4a73-8075-7c39fcca43d5