Skip to content

ADR-0088: Home statistics reflow by measured token; section actions reserve the FAB column

Context

W10 evidence at 411 dp / 200 % text (#406) showed three Home statistic cells that had returned to a fixed three-way weight split. Each cell was narrower than the words and formatted amounts it held, so MERCHANTS broke mid-word, RM 1,500.00 broke inside the digits, and the recent section's View all action sat beneath the shell's floating add button. The same source also let a section action squeeze or wrap unpredictably whenever the title and action did not fit together.

The stats already have a measured grid contract (ADR-0043), and the shell owns the single FAB and its clearance (ShellMetrics). This ADR restores the measured behaviour and gives the section-header action a safe relationship with that one FAB.

Decision

Home statistics choose a column count from measured words, not from the viewport alone. For each label and formatted value, measure the widest space-delimited token with the active AppTextRole typography and the current font scale. Prefer the familiar three equal columns; fall back to two, then one, when a cell would be narrower than that token. Every cell keeps the full value and the same semantic order. Labels wrap only between words, and monetary tokens (+RM, 1,500.00) stay whole at supported widths and scales; a token wider than the whole card still wraps inside that one full-width cell with every character retained. Values are never shrunk, abbreviated or hidden. The decision function is pure and JVM-tested, while HomeHeroCardTest covers the rendered layouts at 320/411 dp and 100/150/200 % in light and dark.

A section action moves below its title rather than sharing an impossible row. SectionHeader measures the title and trailing composable once through their intrinsic widths. When both cannot keep their text in the available row it stacks the action under the title, start-aligned, instead of squeezing or wrapping either. Home passes the shell FAB's end column as the inline trailing clearance, so even when the action stays inline it can never be covered by the floating add button in either layout direction. The clearance is a named ShellMetrics value derived from the FAB size; it is not a per-screen literal. The one-FAB policy is unchanged.

Consequences

At large text or narrow widths the hero grows vertically and Home scrolls, which is the accepted cost of keeping every exact figure readable. At ordinary text on a 411 dp phone the three-column row and the inline View all are unchanged; on a 320 dp phone or at large text the action stacks under its title, and the inline form always ends before the FAB column instead of under it. Section headers on other destinations adopt the measured stacking behaviour but pass no FAB clearance, because they do not host the add action. Long minor units, formatting, drafts, lock state and route contracts are untouched.

Verification

HomeStatLayoutTest covers the column boundaries; HomeHeroCardTest covers glyph, wrapping and containment at 320/411 dp, 100/150/200 % and light/dark, including large multi-group amounts; HomeLargeTextRegressionTest renders the real shell at 411 x 914 / 200 %, 320 x 568 / 200 %, 411 x 500 / 100 % (inline and RTL), 150 %, dark dynamic colour, empty and revoked-capture states, asserts whole tokens, checks the action and FAB stay inside the simulated/physical viewport, performs a real touch click on the 48 dp View all target and navigates through the month-scoped Activity route and Back; SectionHeaderTest covers inline clearance, inline RTL mirroring and large-text stacking; the shell chrome test pins the named action clearance. The fixed-size cases scale the simulated density so the logical 411/320 dp viewport fits the physical CI window, then assert the simulated viewport maps inside the real px bounds while the root keeps its requested logical size; this preserves the 411 audit locally and the 320 CI lane without falling back to unclipped roots. Manual API 26 captures and the W12 evidence archive are review artifacts for this run and are not committed binaries. TalkBack traversal and cutout/foldable evidence remain manual scope; #407 is being fixed separately in W13. #393's tracker state (closed at review time) must not be read as acceptance for those cases.