Shell vs loaded for the list and hub pages this PR covers. Local dev server on the branch (stage data, smoke user, 1440×900); each page was held 6 s by a temporary, uncommitted server delay so its shell could be photographed after a router.push click-in. Times are when [role=status][aria-label=Loading] appeared. Loaded frames are cropped to the page chrome where rows carry names or phone numbers. Detail pages render the page’s own in-flight DetailPage branch and are not re-shot.
Tab row and table card at the same y as the loaded page after round 1 reserved the subtitle line; real pill TabSwitcher; Sessions column headers.
Real underline tabs, customer columns, action ghost re-measured to the live 136×32 button.
Six columns now match (round 1 was missing “What it’s for”); action ghost 148×32.
Header, subtitle, 144×32 action ghost, toolbar and headers line up; Status pill arrives with the page.
One ghost card per registered tool in the same 4-column grid. Round 1 crashed here (server shell importing icon components) — fixed.
Header and the 320px | 1fr grid line up; the “Your number” card uses the page’s own three cold rows.
Back link, title, subtitle and card column line up; the loaded Messages card is taller and grows downward.