ROOT CAUSE (proven, not guessed): the lazily-created row viewport was
constructed 0x0 with Left|Top|Right|Bottom fill-anchors. Its first
ApplyAnchor captured mR = parentW - (0+0) = parentW, so
ComputeAnchoredRect's l&&r branch (w = parentW - mR - mL) kept it 0x0
forever. A 0-tall viewport makes UiScrollablePanel.LayoutScrollableChildren
cull every row, so Character/Chat/Config rendered blank while Gameplay
(no viewport — authored static children sized at Build) worked. This is
the exact Gameplay-vs-rest split the user's first connected gate found.
FIX: seed the viewport to the ListBox's current extent at creation, so the
fill-anchor baseline is mR = parentW - parentW = 0 and the viewport tracks
the parent. The ListBox is a static dat child sized at Build, so its extent
is authored by the time the viewport is lazily created during Bind.
Dormancy preserved — the viewport is still created only on the first row.
Reproduced RED then GREEN by UiTemplateListBoxViewportTests (viewport fills;
rows stay visible after the anchor+cull layout pass) — the layout path the
whole fixture conformance suite structurally never drove, which is why
every OP2-OP6 test was green over a live-only blank-tab failure. Full
Release suite 13,131 / 4 skips / 0 failed.
Still owed (NOT fixed here, no evidence yet): the 'only Exit Game worked'
Gameplay-buttons observation needs a re-gate (two buttons are correctly
INERT; the other four have dialog/chat effects that may have gone
unnoticed); and the 13 ID_ChatOption_TextFilter_* labels fail to resolve
(blank captions, behaviour unaffected). See #372.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>