Skip to content

ui: one vertical stack — vstack facade, Item::before, AlertHead; y ladders moved, no pixel moves - #901

Merged
GLinnik21 merged 16 commits into
mainfrom
crx-vs-int
Oct 21, 2026
Merged

GLinnik21 merged 16 commits into
mainfrom
crx-vs-int

Conversation

@GLinnik21

Copy link
Copy Markdown
Owner

This is the vertical counterpart to the horizontal equal-spacing mechanism (plx_ui::hstack, merged in #886, #888–#891 and #896). It moves the hand-summed y ladders (y += h + GAP) onto one shared stack. No pixel moves.

Mechanism

  • plx_ui::vstack (new, ui/src/vstack.rs): a thin facade over hstack's engine, with no second copy of the arithmetic.
    • VStack provides new, heights, height, placed and span.
    • VFlow places lines one at a time as they are painted.
    • Anchor is Top, Bottom or Centre, and VSpan is the placed result.
  • hstack::Item::before(gap): an item can set the gap in front of it. The gap between two items is b.before, else a.after, else the stack's own gap. Flow::place debug-asserts that no before is set.
  • vstack::AlertHead (with ::ruled): the eyebrow, title and path ladder shared by the tracks panel, the person biography and the About panel. Each panel now measures (head_h / body_rect) and paints from the same stack instead of keeping two copies.
  • landing_hero::stack_top is removed. Its callers use hero_stack.

Sites moved onto VStack / VFlow

  • ui:
    • StatusOverlay bands and note band
    • still_line
    • the Watchlist read-out
    • hero_chain (detail layout)
    • the landing hero
    • the decision alert
    • route_screen's narrative flow
    • the table_screen hint
    • card_row tile labels
    • collection_tile
    • document_reader
    • the login QR
    • the table two-line row
  • appkit: info_panel, up_next, chapters_panel.
  • screens:
    • the tracks, person bio and About panels
    • the person header
    • the catalog hero
    • the people lines
    • the About columns
    • the episode meta
    • the login code and status
    • the PIN pad
    • the search empty pair
  • app: the diagnostics header, sections and fields ladder.

Left as they are

  • The Collection header (header_ys). Its meta and summary offsets are absolute cap tops. Expressed as a stack, the gap would depend on the font, so it would not be a token.
  • The filmography preview top. It is a single item, so it stays a plain sum.

Evidence

  • Gates on the committed tree (git status empty before and after):
    • make check: every test result: line ok, 0 failed. The largest suites are 1846 passed with 64 ignored, then 1669, 1372 and 1120 passed.
    • make test-hostsim: ok, 285 passed.
    • make check-nodef: ok.
    • make check-replay: 6 replays, every one verdict=SAME, diverged=0.
  • Simulator plus mock server, base dbe7b014b against head:
    • 46 scenes, diffed in RGB with the clock masked. Each one was matched against several base samples, because animation phase alone moves up to about 90k px between base runs.
    • Byte-identical:
      • Home, the Continue Watching row and shelves
      • every Detail state, including the About sheet and the deep scrolls
      • Library grids
      • a collection and an empty collection
      • Watchlist, with and without items
      • Search, with and without results
      • the profile picker and PIN pad
      • the tracks panels
      • person pages, with and without a bio
      • the decision alert
      • the login QR
      • every Settings sub-page, including two-line rows and the hold hint
      • the legal document reader
    • The animated Collections fan grid never settles, so it is within noise but cannot be proven identical.
  • Not covered by a capture:
    • Labelled still tiles (still_line). The mock cannot produce one. A unit test pins the label baseline at its old position (still_line_label_baseline_is_where_it_always_stood).
    • The chapters panel and the diagnostics page. The simulator cannot reach them headless. Both are covered by unit tests.
  • One Opus review of the whole change. Its must-fix items (a still_line baseline that moved, and one lane's work missing from the branch) are fixed.
  • Doc-claim audit: 0 findings.

🤖 Generated with Claude Code

GLinnik21 and others added 16 commits October 21, 2026 15:49
…ad ladder builder

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…k, pixel-neutral

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…out stand on VStack (pixel-neutral)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… one VStack each

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…(one alert head ladder, explicit absent + before)

Pixel-neutral: the Tracks panel and the person biography read the shared AlertHead for both
measure and draw; About's 0.0-means-absent ladder becomes Item::before over a VStack.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… episode meta on VStack/VFlow (pixel-neutral)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… filmography preview and diagnostics header on VStack/VFlow

Pixel-neutral: each site's hand-written y sums now come from one stack
the measure and draw both read. The PIN pad's dot row keeps its 67-point
air as the named PAD_DOT_GAP; the diagnostics column headings keep their
4-point gap as SECTIONS_GAP. Existing tests unedited; new painted-gap
tests added per site.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
…ction_tile, document_reader, qr, table)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…rson/decision_alert gaps, hint stack, drop stack_top shim, doc claims

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…e flow

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@GLinnik21
GLinnik21 merged commit 5946665 into main Oct 21, 2026
22 of 23 checks passed
@GLinnik21
GLinnik21 deleted the crx-vs-int branch October 21, 2026 15:57
GLinnik21 added a commit that referenced this pull request Oct 21, 2026
…ead-out uses the overlay's bands (#903)

Owner-approved spacing follow-ups to the vertical stack (#901):

- Detail About: Accessibility's badge rows stand 68 under the heading
  like Information and Languages (were 64; down 4 px).
- Detail episodes: an empty summary is absent, so a date row sits one
  gap under the title and a title-only platter has no trailing gap; the
  date row stays present when it paints a rating chip without a date.
- Watchlist read-out: places its bands through StatusOverlay's own
  failed_page_text_bands instead of a copy (no visible change).

Painted-position tests seen red on main; check, hostsim, nodef green;
check-replay 6/6 SAME.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant