diff --git a/.planning/NOTES.md b/.planning/NOTES.md index 40ad8c7..dcc33c0 100644 --- a/.planning/NOTES.md +++ b/.planning/NOTES.md @@ -4429,3 +4429,61 @@ the content starts where the **row above it** ends, which is true with a job running and without one. An assertion against an absolute coordinate was quietly also asserting "and no background job exists", which is not something that spec is about or can arrange. + +## The queue was already the right rectangle; what it lacked was an entry (measured 2026-08-21) + +#55 asks for the queue to be "a real screen instead of a pop-open +sidebar", and its Direction asks for a `DETAIL_LOADERS` mount. Measured +against `880adff` at the reference device's real viewport (424x439), +with #24's overlay open: + +| box | rect | +|---|---| +| `.main-panel` | 424 x 318 | +| `queue-panel` host | 424 x 318 | +| `.panel-content` | 424 x 318 | +| `.scrim` | 424 x 318, entirely underneath the panel | + +So a detail-view mount would have drawn the same rectangle in the same +place. Three things were genuinely missing, and none of them is a +rendering: + +- **Back navigated the page underneath and left the queue up.** Opened + on Artists, pressed back: `data-active-view` went `artists` -> + `albums`, `open` stayed `true`. A press that changes something the + user cannot see, and costs them their place. +- **The scrim has zero reachable pixels at phone width**, because + `panel-content` is `width: 100%` there. #24's tap-outside-to-close + does not exist on the device. +- The only pointer route out was a **25x21px** button. + +The rule that followed is that the queue is a *place* exactly while it +is an overlay and a *control* while it is a column, which reuses #24's +computed mode rather than adding a breakpoint. + +**The containment finding is the reason the Direction was not +followed.** Read off the running app rather than the stylesheet: + +| element | computed `contain` | +|---|---| +| `queue-panel` (open, overlay) | `layout style` | +| `.content-area` | `layout style` | +| `.main-panel` | `content` | +| `.main-panel > *` (a view) | `content` | + +`queue-panel` has a `wa-popup` context menu, and #60's finding is that +`position: fixed` escapes overflow but not paint containment on +Chrome 113. Its ancestry today is paint-free to `body`; a +`DETAIL_LOADERS` mount would have put it under two paint-containing +ancestors. **No tier here can see that** — CI's Chromium and WebKit +both have the Popover API — so the spec asserts the mechanism (the +panel is not under a paint-contained ancestor) rather than the +symptom. This is the second change in a row where the honest assertion +was about where an element *is* rather than how it *looks*. + +One thing worth knowing about the spec: **three of its nine tests fail +on the build before the change and the other six cannot.** "The entry +is not orphaned" and "a docked column is not in the stack" are both +vacuously true of a build that pushes no entry at all. Reverting the +source and re-running is what established which were which, and the +file says so in its header rather than implying all nine reproduce. diff --git a/CLAUDE.md b/CLAUDE.md index 4a22267..0e25a50 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1775,6 +1775,61 @@ along untouched. Escape closes it and returns focus, and is attached only while the overlay is up — it is a dismissal, not a shortcut, which is why it is not a panel-scoped binding. +**And an overlaid queue is a place, which is the whole of #55.** The +pixels were already right: measured at the reference device's 424×439, +the overlaid panel is 424×318 — `.main-panel`'s rect exactly — so a +`DETAIL_LOADERS` mount would draw the same rectangle in the same spot. +What was missing was the navigation model, and the defect was one +measurement: opening the queue on Artists and pressing back moved the +page *underneath* to Albums and left the queue up. So opening an +**overlay** queue dispatches `navigate {view: 'queue'}` and opening a +**column** sets the attribute as it always did — `utils/open-queue.ts` +is that one decision, and both routes end at the same `open` attribute +on the same element. + +Five things about it are load-bearing. + +**The queue is a screen exactly while it is an overlay**, which is the +rule above rather than a second one: a column is a thing the user +docked, so back must not undock it and a navigation must not take it +away, while an overlay is covering the content and has to answer the +platform's gesture. That also inherits the *computed, not +breakpointed* property for free — the panel is drag-resizable, so a +viewport breakpoint would be wrong by up to 180px. + +**It is in neither `VIEW_TAGS` nor `DETAIL_LOADERS`**, because there is +nothing to mount; the panel is already in the document. That is not +tidiness. `.main-panel > *` is paint-contained under a `.main-panel` +that is, and `contain: paint` clips the `position: fixed` a `wa-popup` +falls back to on the reference device's Chrome 113 (#60) — so the +detail-view mount asked for in #55's Direction would have broken +`queue-panel`'s working context menu on the one device the issue is +about. Measured: the panel's ancestry is `layout style` all the way to +`body`; a view inside the main panel is `content` under `content`. +**No tier here can see that consequence** — CI's Chromium and WebKit +both have the Popover API — so `queue-as-a-screen.spec.ts` asserts the +*mechanism*, that the panel is not under a paint-contained ancestor. + +**A navigation to `queue` deliberately writes neither +`dataset.activeView` nor `searchStore.setCurrentView`**, because both +describe what is *in* the main panel and the queue covers that panel +without replacing it. It publishes itself through `activeViewStore` +with `isPrimary: false`, so the tab it was opened from stays lit — +the same rule a detail view gets. + +**The entry is unwound from the panel's `open` attribute**, in the +mutation observer `index.ts` already ran for `aria-expanded`, rather +than at each of the four ways out. Escape, the scrim, the close button +and the toggle all take that route, and a fifth added later gets it +free. Without it the entry is orphaned and the *next* back press is the +one that closes the queue — the reported defect moved one press later, +which looks exactly like a press that did nothing. + +**And the way out is 44px on a phone.** With the panel spanning the +whole width the scrim has no uncovered pixels at all, so the close +button is the only pointer route out of a full-screen surface; it was +**25×21px**. + What this does **not** fix is `page-header` overflowing on its own: at 900×600 "New Smart Playlist" is still clipped to 114 of 162px with the queue *closed*. That is #69, and it cannot be fixed in