Harden contextual thread layout - #135
Conversation
leaf-agent
left a comment
There was a problem hiding this comment.
Two of the three tests this PR adds fail on the merged tree. They live in tests/test_render_margin.py, which is nightly-marked, and .github/workflows/ci.yaml runs --run-nightly only on push to main — so this PR's green test check never ran them. Running the owning file here:
FAILED test_the_shipped_long_thread_opens_beside_its_source_in_the_right_margin
AssertionError: {'mainRight': 952, 'cardLeft': 646, 'cardRight': 966, 'cardWidth': 320}
assert 952 <= (646 + 0.5)
FAILED test_the_full_thread_posture_follows_the_page_container_and_left_claims
Locator ".lf-margin-thread" expected to have count '1'; actual 0
2 failed, 19 passed in 34.44s
#138's body already names both of these as red from 0d7e0d0, so this is the same pair rather than a new one.
The container is body's box, not the window. lf-shell is named on body at inline-size (container: lf-shell / inline-size in theme.css), and a classic scrollbar takes that box 15px below the viewport. Measured on this tree, same page, same runner:
| viewport | body inline-size | --lf-thread-beside |
|---|---|---|
| 1208 | 1193 | 0 |
| 1440 | 1425 | 1 |
| 1472 | 1457 | 1 |
So @container lf-shell (min-width: 1208px) first matches at a 1223px window and the 1472px rule at 1487px. Both tests resize the window to the threshold number and land 15px short of it.
The thresholds themselves read as right: main is laid out inside body, so 640 + 520 + 48 = 1208 and + 264 = 1472 are body-box budgets and the container query is the right place to ask them. It is the tests that put a body-box number into a window call.
The responsive boundary is untested either way. In test_the_shipped_long_thread_opens_beside_its_source_in_the_right_margin, the 1208/1207 pair was meant to straddle the crossing; on this runner both sit below it, so the "beside" half asserts the compact posture a second time and the pair proves nothing about the boundary. A hardcoded window pair also cannot straddle it on two platforms — the suite already records the gutter as "nothing under macOS's overlay ones, 15px of gutter on the Linux" (tests/test_render_outbox.py). Deriving the straddle from the container's own inline size states the arrangement the posture actually turns on.
The other 19 cases in the file pass. The two test_render_conversations.py failures I also see here reproduce without this branch and are #138's.
Separately: #138 is open on three of the same files (living-margin.js, theme.css, chrome-layout.js) and #141 on chrome-layout.js. Different concerns, but whichever lands second wants the rebase read.
leaf-agent
left a comment
There was a problem hiding this comment.
The three threads from the last pass are answered, and tests/test_render_margin.py is green on this runner — 22 passed, including both cases that were red at 22efe47. resized_shell reads the container's own box, so the 1208 and 1472 stops land on the container query rather than 15px short of it, and the straddle is derived rather than hardcoded.
One thing the new helper leaves on the table. With the shell now pinned, the containment bound is the one place still measured against innerWidth — the one width that keeps the scrollbar. At the 1208 stop this runner reports {'cardRight': 1200, 'viewportWidth': 1223, 'shellWidth': 1208}, so cardRight <= viewportWidth + 0.5 admits 15px of overflow into the gutter, and admits it only on Linux: with macOS's overlay scrollbars the two widths are equal and the same assertion is tight. That is the viewport/shell conflation this PR removes from the resize, reappearing on the assertion. The card is a popover, so its containing block is the shell rather than the viewport, and measuring body's box states the bound the card is actually held to. I ran both tests with the two suggestions below applied — they pass.
Contextual right-margin threads landed on main while this PR was under review. This follow-up hardens that implementation at the cross-platform and interaction boundaries the review exposed.
Breakpoint regressions now resize from the measured body container rather than assuming viewport width, so overlay and classic scrollbars exercise the same 1208px and 1472px shell thresholds. Routine margin rerenders preserve the exact focused descendant, keyboard tray entry retires a pinned contextual thread, and conditional selectors no longer outweigh the documented cascade order. The browser file covers tall-card containment, tray handoff, retained focus, and both responsive postures.