Since #71 the phone's "More" navigation is a bottom sheet, and on the
reference viewport it does not fit. Measured at 424x439 with the seed's
eight visible destinations, the sheet's body is scrollHeight412
against clientHeight373 — 39px, most of a row, below a fold that
nothing announced. Where the cut lands on a row boundary the sheet ends
in a clean edge that reads as the end of the list, which is exactly what #207 was filed for one sheet over. It gets worse with the destinations
the seed does not show: eleven items at 48px is 528px of content in a
373px body, and since #25 that count is the user's.
What changed, and why this shape
#207's rule moves to frontend/src/styles/sheet-scroll.css.ts and
both sheets adopt it, rather than being copied into the second one — a
second copy is how two sheets come to disagree about what a fold looks
like. The mechanism is unchanged: a cover of the sheet's own colour
painted at the end of the content (local) over a shadow pinned to
the box (scroll), so the fade is absent on a sheet that fits, present
the moment one does not, and gone again at the end of the list, with no
scroll listener and nothing reaching into anyone's shadow root for the
scroller.
The colour stays with each host, as --yj-sheet-surface set on the
same box: the nav sheet paints the sidebar's --yj-bg-surface, the
context sheet the menus' --yj-bg-elevated. A shared rule hard-coding
either would draw that seam across the other one, which is the issue's
own condition on the fragment.
And nothing inside the sheet may repaint the surface, which is the
half the issue does not name and the only reason it took a measurement
rather than a read. These are background layers on the scroller, and app-sidebar's host carries the same grey — its own background in the
shell, a second opaque copy of the sheet's here, drawn over the fade.
With the fragment adopted and that rule missing, the running app
measured a flat 52,58,64 to the bottom edge with 39px still below: the
defect unchanged, and every assertion about background-attachment
green. menu-surface already meets the same requirement from the other
side, where .context-menu-panel[data-sheet] is background-color: transparent.
Verification
make ui-test — 1130 passed, 103 files. Two assertions added
(bottom-nav.test.ts, menu-surface.test.ts), and both halves proved
non-vacuous by defeating each in turn:
without the fragment, the nav sheet's body reports background-attachment: scroll alone;
without the host's --yj-sheet-surface, its cover comes out rgb(52, 58, 64) — the menus' grey on the sidebar's sheet, which is
the seam the parameterisation exists to prevent.
Pixels, which is the tier this actually rests on.make dev-headless SEED=default, 424x439, sheet open. The body reproduces the
issue's numbers exactly (412 / 373). At x=300, dark ramp:
y
more below
scrolled to the end
400
33,37,41
52,58,64
410
31,35,39
52,58,64
420
27,30,33
52,58,64
430
20,22,25
52,58,64
438
14,15,17
33,37,41
So the fade is there while there is more below and flat once there is
not — with the last destination fully drawn. On the light ramp (the --yj-* overridden on :root, as #207 measured it) the last fully
visible label sits at 13.0:1 and the darkening starts below it,
which is the contrast argument that made #207's curve steep rather than
linear. Screenshots were cropped and scaled before judging, per .planning/NOTES.md.
make e2e — 244 passed (chromium) against that same app: the shared
fragment is adopted by all fourteen context menus, so the regression
risk is theirs as much as the nav sheet's.
make css-check, npx tsc --noEmit, make skill-check — clean. No
Go, no .sql, no .templ and no bound signature, so make lint, make test, make generate and make bindings were not run.
Deliberately not done
No e2e spec, matching #207: the mechanism is asserted in the
component tier and the rendered result is measured here. The nav
sheet's overflow-y/overscroll-behavior half already has a spec.
make ui-visual not run. No geometry moved, and the only baseline
anywhere near this is app-sidebar rendered standalone — whose own
stylesheet is untouched, since the transparency is a rule in bottom-nav's shadow root.
The sheet is still capped at 85vh and still overflows at eleven
destinations. That is the state the fade exists to announce, not a
defect to fix here.
## What the issue was
Since #71 the phone's "More" navigation is a bottom sheet, and on the
reference viewport it does not fit. Measured at 424x439 with the seed's
eight visible destinations, the sheet's body is `scrollHeight` **412**
against `clientHeight` **373** — 39px, most of a row, below a fold that
nothing announced. Where the cut lands on a row boundary the sheet ends
in a clean edge that reads as the end of the list, which is exactly what
#207 was filed for one sheet over. It gets worse with the destinations
the seed does not show: eleven items at 48px is 528px of content in a
373px body, and since #25 that count is the user's.
## What changed, and why this shape
**#207's rule moves to `frontend/src/styles/sheet-scroll.css.ts` and
both sheets adopt it**, rather than being copied into the second one — a
second copy is how two sheets come to disagree about what a fold looks
like. The mechanism is unchanged: a cover of the sheet's own colour
painted at the end of the *content* (`local`) over a shadow pinned to
the box (`scroll`), so the fade is absent on a sheet that fits, present
the moment one does not, and gone again at the end of the list, with no
scroll listener and nothing reaching into anyone's shadow root for the
scroller.
**The colour stays with each host**, as `--yj-sheet-surface` set on the
same box: the nav sheet paints the sidebar's `--yj-bg-surface`, the
context sheet the menus' `--yj-bg-elevated`. A shared rule hard-coding
either would draw that seam across the other one, which is the issue's
own condition on the fragment.
**And nothing inside the sheet may repaint the surface**, which is the
half the issue does not name and the only reason it took a measurement
rather than a read. These are background layers on the scroller, and
`app-sidebar`'s host carries the same grey — its own background in the
shell, a second *opaque* copy of the sheet's here, drawn over the fade.
With the fragment adopted and that rule missing, the running app
measured a flat 52,58,64 to the bottom edge with 39px still below: the
defect unchanged, and every assertion about `background-attachment`
green. `menu-surface` already meets the same requirement from the other
side, where `.context-menu-panel[data-sheet]` is
`background-color: transparent`.
## Verification
**`make ui-test` — 1130 passed, 103 files.** Two assertions added
(`bottom-nav.test.ts`, `menu-surface.test.ts`), and both halves proved
non-vacuous by defeating each in turn:
- without the fragment, the nav sheet's body reports
`background-attachment: scroll` alone;
- without the host's `--yj-sheet-surface`, its cover comes out
`rgb(52, 58, 64)` — the menus' grey on the sidebar's sheet, which is
the seam the parameterisation exists to prevent.
**Pixels, which is the tier this actually rests on.** `make
dev-headless SEED=default`, 424x439, sheet open. The body reproduces the
issue's numbers exactly (412 / 373). At x=300, dark ramp:
| y | more below | scrolled to the end |
|---|---|---|
| 400 | 33,37,41 | 52,58,64 |
| 410 | 31,35,39 | 52,58,64 |
| 420 | 27,30,33 | 52,58,64 |
| 430 | 20,22,25 | 52,58,64 |
| 438 | 14,15,17 | 33,37,41 |
So the fade is there while there is more below and flat once there is
not — with the last destination fully drawn. On the light ramp (the
`--yj-*` overridden on `:root`, as #207 measured it) the last fully
visible label sits at **13.0:1** and the darkening starts below it,
which is the contrast argument that made #207's curve steep rather than
linear. Screenshots were cropped and scaled before judging, per
`.planning/NOTES.md`.
**`make e2e` — 244 passed** (chromium) against that same app: the shared
fragment is adopted by all fourteen context menus, so the regression
risk is theirs as much as the nav sheet's.
**`make css-check`, `npx tsc --noEmit`, `make skill-check` — clean.** No
Go, no `.sql`, no `.templ` and no bound signature, so `make lint`,
`make test`, `make generate` and `make bindings` were not run.
## Deliberately not done
- **No e2e spec**, matching #207: the mechanism is asserted in the
component tier and the rendered result is measured here. The nav
sheet's `overflow-y`/`overscroll-behavior` half already has a spec.
- **`make ui-visual` not run.** No geometry moved, and the only baseline
anywhere near this is `app-sidebar` rendered standalone — whose own
stylesheet is untouched, since the transparency is a rule in
`bottom-nav`'s shadow root.
- The sheet is still capped at 85vh and still overflows at eleven
destinations. That is the state the fade exists to announce, not a
defect to fix here.
Closes #210
Since #71 the phone's "More" is a bottom sheet, and at the reference
viewport it does not fit: measured at 424x439 with the seed's eight
destinations, the body is scrollHeight 412 against clientHeight 373, so
39px is below a fold nothing announces. Where the cut lands on a row
boundary the sheet ends in a clean edge that reads as the end of the
list, which is what #207 fixed one sheet over.
The rule is that sheet's, not a second answer to the same question:
#207's two background layers move into styles/sheet-scroll.css.ts and
both sheets adopt them, with the colour left to each host as
--yj-sheet-surface. The nav sheet paints the sidebar's --yj-bg-surface
and the context sheet the menus' --yj-bg-elevated, so a shared rule that
hard-coded either would draw that seam across the other one.
The half that makes it visible is that nothing inside the sheet may
repaint the surface. These are layers on the scroller, and app-sidebar's
host carries the same grey -- in the shell its own background, in the
sheet a second opaque copy of the sheet's, over the fade. With the
fragment adopted and that rule missing, the running app measured a flat
52,58,64 to the bottom edge with 39px still below: the defect unchanged,
with every assertion about background-attachment passing. menu-surface
already meets it from the other side, where the sheet's panel is
background-color: transparent.
Closes#210
CI is green on 20c3376: check success (run 22194) and e2e success (run 22196) — both required checks, including the WebKit pass, which is the one signal this repo cannot produce locally.
CI is green on `20c3376`: **`check` success** (run 22194) and **`e2e` success** (run 22196) — both required checks, including the WebKit pass, which is the one signal this repo cannot produce locally.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
What the issue was
Since #71 the phone's "More" navigation is a bottom sheet, and on the
reference viewport it does not fit. Measured at 424x439 with the seed's
eight visible destinations, the sheet's body is
scrollHeight412against
clientHeight373 — 39px, most of a row, below a fold thatnothing announced. Where the cut lands on a row boundary the sheet ends
in a clean edge that reads as the end of the list, which is exactly what
#207 was filed for one sheet over. It gets worse with the destinations
the seed does not show: eleven items at 48px is 528px of content in a
373px body, and since #25 that count is the user's.
What changed, and why this shape
#207's rule moves to
frontend/src/styles/sheet-scroll.css.tsandboth sheets adopt it, rather than being copied into the second one — a
second copy is how two sheets come to disagree about what a fold looks
like. The mechanism is unchanged: a cover of the sheet's own colour
painted at the end of the content (
local) over a shadow pinned tothe box (
scroll), so the fade is absent on a sheet that fits, presentthe moment one does not, and gone again at the end of the list, with no
scroll listener and nothing reaching into anyone's shadow root for the
scroller.
The colour stays with each host, as
--yj-sheet-surfaceset on thesame box: the nav sheet paints the sidebar's
--yj-bg-surface, thecontext sheet the menus'
--yj-bg-elevated. A shared rule hard-codingeither would draw that seam across the other one, which is the issue's
own condition on the fragment.
And nothing inside the sheet may repaint the surface, which is the
half the issue does not name and the only reason it took a measurement
rather than a read. These are background layers on the scroller, and
app-sidebar's host carries the same grey — its own background in theshell, a second opaque copy of the sheet's here, drawn over the fade.
With the fragment adopted and that rule missing, the running app
measured a flat 52,58,64 to the bottom edge with 39px still below: the
defect unchanged, and every assertion about
background-attachmentgreen.
menu-surfacealready meets the same requirement from the otherside, where
.context-menu-panel[data-sheet]isbackground-color: transparent.Verification
make ui-test— 1130 passed, 103 files. Two assertions added(
bottom-nav.test.ts,menu-surface.test.ts), and both halves provednon-vacuous by defeating each in turn:
background-attachment: scrollalone;--yj-sheet-surface, its cover comes outrgb(52, 58, 64)— the menus' grey on the sidebar's sheet, which isthe seam the parameterisation exists to prevent.
Pixels, which is the tier this actually rests on.
make dev-headless SEED=default, 424x439, sheet open. The body reproduces theissue's numbers exactly (412 / 373). At x=300, dark ramp:
So the fade is there while there is more below and flat once there is
not — with the last destination fully drawn. On the light ramp (the
--yj-*overridden on:root, as #207 measured it) the last fullyvisible label sits at 13.0:1 and the darkening starts below it,
which is the contrast argument that made #207's curve steep rather than
linear. Screenshots were cropped and scaled before judging, per
.planning/NOTES.md.make e2e— 244 passed (chromium) against that same app: the sharedfragment is adopted by all fourteen context menus, so the regression
risk is theirs as much as the nav sheet's.
make css-check,npx tsc --noEmit,make skill-check— clean. NoGo, no
.sql, no.templand no bound signature, somake lint,make test,make generateandmake bindingswere not run.Deliberately not done
component tier and the rendered result is measured here. The nav
sheet's
overflow-y/overscroll-behaviorhalf already has a spec.make ui-visualnot run. No geometry moved, and the only baselineanywhere near this is
app-sidebarrendered standalone — whose ownstylesheet is untouched, since the transparency is a rule in
bottom-nav's shadow root.destinations. That is the state the fade exists to announce, not a
defect to fix here.
Closes #210
CI is green on
20c3376:checksuccess (run 22194) ande2esuccess (run 22196) — both required checks, including the WebKit pass, which is the one signal this repo cannot produce locally.