Owner report (2026-08-24): our scrollbar arrows pointed the wrong way,
the thumb vanished when there was nothing to scroll, and neither the
thumb nor the arrow buttons reacted to hover/press.
All three are one retail mechanism we had not ported:
1. Seating: UIElement_Scrollbar::UpdateScrollingArea @0x00470AA0 moves
the INCREMENT designee (attribute 0x77) to the top/left corner and
the DECREMENT designee (0x78) to the bottom/right, ignoring authored
positions. The vertical base skin (0x10000455 in layout 0x2100003E)
authors the DOWN-arrow decrement at Y=0 and the UP-arrow increment
at Y=32 (live-DAT probed; sprite art visually verified from decoded
PNGs), so our authored-Y ordering drew both arrows upside down.
DatWidgetFactory now seats by designation; the hand-wired sites
(CharacterStatController, ExternalContainerController, the
Config/Vendor menu chrome) share the new RetailScrollbarChrome
catalog instead of local constants.
2. Full-track thumb: UpdateLayout @0x004710d0 sizes the thumb from
proportion attribute 0x88, which DEFAULTS to 1.0 — a content-fits
bar shows a thumb filling the whole track; disabled only removes
input and the page regions. Our draw skipped the thumb entirely on
!HasOverflow.
3. States: every arrow button and thumb slice authors Normal (red gem /
dark navy), Normal_rollover (amber gem / bright blue) and
Normal_pressed (gold highlight / dark) media. The widget now tracks
thumb hover and selects rollover media on hover and pressed media
while dragging; the factory extracts the thumb-state media for both
the 3-slice and single-sprite thumb shapes.
ScrollbarSkinLiveDatTests pins the designations and state media against
the installed DAT so a revision or importer regression fails loudly.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>