2026-09-23 · branch commit 768ee391d0 (review round 2: labels kept in the missing states) · local dev server on the anonymized stage table · smoke user
How these were produced. A healthy server never returns these states, and the standard evidence tool deliberately never rewrites a response. So /api/leasing/stats was forced in the browser only (Playwright request interception): a 500, a needs_one_org refusal, and a request held open. Nothing server-side changed.
Read failed
Dashboard. Both tiles read “— Couldn’t load”. Before this PR: “0 available · 0 vacant · 0 on notice” and “0 move-out notices”./leasing two-column row. The card takes the Renewals card’s row height; the headline sits at the top./maintenance Turnovers card.
Selection refused
“— Not available for this selection” on both tiles.
Still loading
A ghost bar in the headline slot beside the kept caption, with the window caption and the four stage labels in place — no digits, no dash.
Critique against the brand and design runbook
Round 1. The unavailable headline sits in the same slot and baseline as a real number, so nothing shifts sideways when data lands. The dash is muted where the Renewals card’s own “—” is full ink; the muted one reads as “no reading” rather than a value, which is the intent. Copy is two plain words, no internal terms.
Round 3 (after review round 2). The static captions (“available”, “move-out notices”), the window caption and the four stage labels now stay in every state; only value slots are ghosted or “—”. The /leasing card no longer sits mostly empty beside Renewals, and the layout does not pop when numbers land.
Round 2. On /leasing the failed card is mostly empty because the grid row takes the Renewals card’s height. Acceptable (Collections’ ghost does the same) and the reviewer’s nit 5 records ghost rows as the later option. No layout defect, so no code change.
Visible here, not fixed in this PR: the Renewals pipeline card beside it still shows “Due in 90d 0 · Contacted 0” under the same failure — the identical ?? 0 shape in RenewalsSection, named in the PR body as follow-up.