ADR-0084: Report selection outlives its tooltip; Home keeps one hero
- Status: Accepted
- Date: 2026-11-01
- Related: ADR-0009, ADR-0028, ADR-0036, ADR-0069, ADR-0071, ADR-0079
Context
Three W05 review findings shared one cause: transient feedback was carrying persistent meaning. On Reports the selected category lived in the same state as the four-second tooltip, so the timeout also removed View transactions. On Home a missing FX rate made the shared budget summary incomplete, and the hero's "budget unavailable" line appeared even when no budget was configured. The review strip also used an attention-container fill and a filled tertiary button in a different vertical position per breakpoint, so it competed with the monthly hero and moved between wide and narrow layouts.
Decision
Reports selection is persistent until the user or the period changes it.
The donut keeps two separate states: the selected slice index and whether the
tap tooltip is visible. The tooltip still dismisses after four seconds so it
never covers the chart indefinitely; the selected legend row, its
Role.Checkbox state and the slice's View transactions action remain. A
second tap on the selected row toggles it off, a changed slice set or month
clears it, and the existing callback reports exactly those transitions. The
drill-down keeps the viewed month and resolves the scope once: a normal slice
uses its category id, an uncategorised slice uses UNCATEGORISED_CATEGORY_ID
(0), and the merged Other bucket stays month-only (categoryId = null).
The drill-down button carries a unique accessible name including the slice
label, because the insight card shows the same visible label.
The Home budget marker means a configured budget is unavailable. The shared
BudgetSummaryCalculator remains the only owner of limits, spend, percent and
availability. Home additionally records whether any positive limit was
configured; only then may an incomplete summary render the hero's budget
unavailable line. No limit, a zero cleared-limit sentinel, or an unrelated
missing FX rate hides the budget line entirely. Spending FX gaps keep their own
footnote, exact configured-limit percentages stay exact, and an unconvertible
configured limit remains honestly unavailable.
Home has one primary hero and quiet supporting surfaces. The review strip
uses AppSurface.grouping with the paired AppSurface.primaryText /
AppSurface.supportingText roles and a tonal action, matching the existing
manual-capture guidance; it does not introduce a palette or a second strong
fill. The revoked-listener warning keeps errorContainer /
onErrorContainer because it is a repair error, not ordinary support. Both
breakpoints show capture status, then the single review strip, then the hero
(and any availability footnote), so the supporting order never changes with
width. The hero remains the only AppSurface.hero surface. The Home month
control keeps fillMaxWidth only to give its label a bounded width at narrow
or large-text sizes; the visible control stays intrinsic between two 48 dp
arrows and paints no pill.
Consequences
A selected report category and its drill-down no longer disappear while the user reads the figures, and the timeout has one meaning. A no-budget month can never imply a budget error, while configured-limit failures stay visible. Home's supporting notices remain readable and actionable without competing with the monthly total in light, dark or dynamic colour. The strip's tonal action container is a deliberately low-contrast step against the grouping surface (about 1.2:1); its label clears 4.5:1 and its target is at least 48 dp, which is the affordance M3 tonal buttons rely on rather than a second strong fill. No schema, route, money or dependency contract changes.