docs/qa/ui-2026-09-29.md

Native UI refinement verification, 2026-09-29–30

Baseline: fbe9409469e5f1b12c20d7f627e1674ba2806fd7; source: d2de1ef. Scope: spec009. Verification used the real GTK/libadwaita/VTE client on KDE Plasma, isolated servers and real PTYs. Agent output and approval hooks are deterministic fixtures, without paid requests.

What changed

BeforeAfterWhy
Approval text ellipsized beside choices; a long choice forced an 823px minimum paneComplete question above wrapping native choices; tested at 320pxThe decision stays readable in a split
Inactive-pane controls stayed invisible under keyboard focusImmediate reveal and inset focus outlineKeyboard users can see the control they operate
Close replaced the workspace statusIndependent reserved target beside persistent urgencyClosing and triaging no longer compete for one slot
Very faint metadata, animated status/focus paintClearer hierarchy, instant focus/state stylingFrequent navigation stays calm
Press scaling survived disabled animation interpolationExplicit active-state reduced-motion overrideDesktop preferences remove static transforms too

The implementation retains system fonts, semantic Adwaita colors, existing attention/decision IDs and mounted terminals. Native tab-view interaction remains toolkit-owned; the custom content Stack no longer crossfades during navigation.

Native visual evidence

The scene helper checks its own process, active-window state and actual client width before capture. Screenshots were visually inspected; temporary paths are fixture data. Wide scenes have two panes; narrow scenes use one pane and a long choice, with the sidebar collapsed by the existing breakpoint.

SceneBeforeAfter
Light, 1280×800BaselineRefined
Dark, 1280×800BaselineRefined
Narrow, 360×800—Light, dark
High contrast—Native contrast
Enlarged UI font, Sans 18—Native typography

Reproduce after cargo build --workspace:

sh
1ADW_DEBUG_COLOR_SCHEME=prefer-light python3 scripts/qa-ui-scenes.py --output /tmp/ui-light.png
2ADW_DEBUG_COLOR_SCHEME=prefer-dark python3 scripts/qa-ui-scenes.py --width 360 --long-choice --output /tmp/ui-narrow.png
3ADW_DEBUG_HIGH_CONTRAST=1 python3 scripts/qa-ui-scenes.py --output /tmp/ui-contrast.png
4python3 scripts/qa-ui-scenes.py --font 'Sans 18' --output /tmp/ui-font.png

The helper uses temporary GTK configuration and disables portal font overrides for the font scene; it does not change the desktop's preferences.

Behavioral proof and gates

Validation records 188 workspace tests and 10 separate graphical tests, all passing. Build, fmt and Clippy pass; the two existing server warnings remain untouched. Graphical results cover actual 320px allocation, complete labels, original answer IDs and VTE identity; rendered inactive-pane control pixels; launch/runtime motion preferences; and native render transforms under pointer, reduced-motion and keyboard activation.

The approval and focus tests first failed against the original behavior. The motion test also failed with the initial, insufficient-specificity override, then passed with the final CSS. It observes rendered transforms, not CSS strings.

Reliability passes single-window activation, preserved approval/answer, reconnect output, responsive GTK during server stall, split/close and restored exited status. Refresh measurement passes 400 hooks across eight workspaces: 34 workspace reads for the 200-message burst, no full list refresh.

Standards and Spec reviews pass. Motion review approves after the specificity correction. Clipboard, IME, desktop notification clicks and live paid providers retain the separate coverage limits documented in the verification feature map.

Source and verification were pushed to main in d2de1ef and 8aa5f84. Remote CI passed fmt, workspace Clippy and workspace tests on 8aa5f84.