# Home ↔ real See all viewport restoration ## Failure The original real-grid test reached the eighteenth personal movie, Bleach the Movie: Fade to Black. Back restored the Home row and selected card fields but did not display `home-card:pk-m:5`, even after UI idle. This was a real viewport ownership/order bug, not a reason to weaken the display assertion. ## Cause and correction `WolfskinApp` synchronizes `ShellState.route` in a destination `LaunchedEffect`. New content composes before that effect. Both screen implementations formerly read the mutable current `shell.view`; the incoming Library grid could therefore attach to Home's actual `LazyListState`, clamp its index to the much shorter grid and start a Library scroll on that Home memory. - `ShellState.rememberedView(destination)` uses main's existing per-person/per-route registry. It supersedes Home's earlier `viewFor` name rather than introducing an alias or another memory mechanism. - `HomeScreen` and `HomeFocus` bind Home's remembered view explicitly. `WolfskinLibraryContent` binds the actual target route and supplies that view to `LibraryScreen` before effects. - Home memory retains each row's actual horizontal `LazyListState`, not merely a selected column or intended first card. Re-entry restores horizontal state before vertical state with `scrollToItem(index, offset)`, without return animation. - Horizontal focus-follow still animates new target changes. The initial collector emission does not overwrite a restored pixel offset. - Android focus is owned by the existing `ShellSurface`. Home cards are logical focus/ring projections, not individual native FocusRequester nodes. No offscreen-card focus request or second focus/back mechanism is introduced. ## Exercised native proof `HomeSeeAllNavigationTest` uses production Home action routing, the real `WolfskinSeeAllLists`, `LibraryScreen` and `NavigationManager` back stack, with local frozen data/artwork and a read facade that is not called for See all. | Case | Required consumer-visible result | |---|---| | Personal movie continuation | Full 18-title list; actual keys reach the eighteenth title; Back displays original continuation card 5 | | Horizontally scrolled Trending continuation | Leave continuation card 20, navigate the real mixed grid and return to the original displayed Home card | | Both cases | Same route memory and horizontal state; exact vertical/horizontal first index and pixel offset; exact selected-row viewport offset | The clock is explicitly frozen. Frame/layout barriers precede key replay and complete the scroll animation before observations. Every original count, title, selected-ID and visible-card assertion remains. Failures include route, row/card, nav/key owner, grid index, horizontal/vertical offsets and visible row offsets. Checkpoint `14a74ac4` preserved the main merge and three review corrections before this investigation. First authorized run compiled the ownership fix and passed all 89 design tests, but the new fixed-clock app harness stopped during grid traversal. Second authorized run passed both cases after explicit native measure/layout barriers. The final full `make test` then passed all 666 tests on committed viewport fix `9c8fceb1`; `make apk-debug` passed on the same head. Logs and final XML are included in the complete evidence bundle. After that successful viewport checkpoint, final visual proof found the shared tail's 10px gap leaking into Home's locked 8px See all column. `e99ed2d3` supplies the existing Home gap through the canonical component without changing Library defaults. Steering 010 authorized the exact-final-head full gate pair: all 666 tests and debug packaging pass again on `e99ed2d3`, regenerating capture proof. No additional narrow test was run. Steering 011 subsequently required merging newly landed Requests from main. Additive merge `4cd75cfa` and callback migration `5033c171` preserve that viewport correction; the exact latest head passes all 684 tests and debug packaging. Requests reuses the canonical image cache with bitmap/URI models and the strict four-read limit; all eight approved Requests native frames remain pixel-identical. No further narrow run was used. Steering 012 required additive Discover integration from main `86d3432fb0078935a40785764f1eab536068668c`. Merge `575103ce` preserves the viewport fix while reusing main's canonical `rememberedView`, `FocusLift`, shared 8px See all gap and real Discover root. Its full pair passes all 732 tests and debug packaging. Evidence assembly then exposed st-030/st-035/st-039 being overwritten between Library and Discover capture producers; `06167084` namespaces both families without changing a test/assertion. The exact final head again passes all 732 tests and all four branded debug APK checks, with both independent outputs retained.