Review R4, the shell: the wordmark goes Home, the footer ends the page, a clicked notification clears (#1020) #1024

Merged
claude-bot merged 8 commits from fix/1020-shell-wordmark-footer-bell into main 2026-10-02 02:17:49 +00:00
Collaborator

Part of #1020, the owner's 1 October review. Four items, in their words. Closes #727 (lane 1), which was signed off with the first of these as its one request.

"Clicking on Quest Board at the top to take me back out to home if I'm in a campaign." (lane 1)

The wordmark was a plain <span> on every page. In the app's frame it is now a link to Home (/dashboard), named "Quest Board, home" as the public pages' wordmark is. Same colour, no underline, a visible focus ring. On a phone inside a campaign the wordmark is still hidden to make room for search.

The footer was a fixed strip under the page at every width. It is now the last thing in the page's scroll, at every width:

  • Book renders .book > rail + div.book__scroll > (main#main + footer). The scroller is the new wrapper; <main> holds only the page; the footer is its sibling, so it is a top-level contentinfo (one, not inside main).
  • On a short page the footer sits at the bottom of the window; on a long one it is reached by scrolling. The Contents rail still runs the full height, with the footer under the main column only.
  • What used main as the scroller follows it to the wrapper: useScrollRestoration takes the scroller's ref; the print rules for a character sheet name the new element. #main is still the skip link's and route focus's target.
  • In the frame the footer keeps the page's gutters on a phone, so its text lines up with the page above it.

"Clicking on a notification should clear it." (l7-bell)

It was meant to already, and did in tests. In a browser the frame's link handler closed the panel between the two listeners of the same click, so the row was gone before its handler ran. The row's link now marks it read in the capture phase; a middle-click and a Ctrl-click (new tab) do too. The small "mark read" control is unchanged. IS-160's wording is corrected.

"Selecting anything causes some of the modals to go blank." (lane 0, /design)

Not the Modal specimens: the panels drawn open (Bell, Menu, AccountMenu, Search) closed on a press anywhere else on /design, or on Escape, and nothing reopened them, so one press blanked every open still. The specimens now stay open; the real components are unchanged.

Checked

  • Full vitest on the merged tree: 3649 passed, 1 skipped; eslint 0 errors. Every coverage/lane*.py and the changelog check pass. No backend change.
  • Rendered in an e2e stack at 390×844 (touch) and 1440×900, light and dark, and looked at:
    • Footer: a short page (footer at the window's bottom), Home, This week, Sessions, a session and its Review tab, the prep sheet (its sticky tool margin stays in the window and never meets the footer), a wiki article, the wiki editor, the map, Admin's Audit log; one contentinfo, never inside main, never overlapped, no sideways scroll; the rail full height at 1440. Table mode has no footer, as before. The public pages are unchanged.
    • Scrolling: the skip link shows on the first Tab and moves focus to main; from the last control of a short page, Tab reaches the footer links; a printed character sheet has no bar, rail or footer.
    • Wordmark: link, name, colours and focus ring at both widths and themes; goes to /dashboard.
    • Bell: a click, Enter, a middle-click and a Ctrl-click each sent one mark-read call and dropped the badge by one; the row was read on reopening.
    • /design: 24 open panels before and after a press on the page, Escape, and Light / Dark / Table mode; the Modal specimens open and close.
  • Journeys on that stack: j0-smoke, j0b-you and j1-first-campaign on desktop and phone (18 of 18), and j2-notified-votes-rsvps on desktop (7 of 7).

Seen, not from this change (#1023)

The wiki editor's sticky Save row leaves the screen in the lower half of the page; Back returns short on pages that load after the route; the window itself can scroll under the frame on two pages; the phone bell button is 36px wide.

🤖 Generated with Claude Code

Part of #1020, the owner's 1 October review. Four items, in their words. Closes #727 (lane 1), which was signed off with the first of these as its one request. ## "Clicking on Quest Board at the top to take me back out to home if I'm in a campaign." (lane 1) The wordmark was a plain `<span>` on every page. In the app's frame it is now a link to Home (`/dashboard`), named "Quest Board, home" as the public pages' wordmark is. Same colour, no underline, a visible focus ring. On a phone inside a campaign the wordmark is still hidden to make room for search. ## "The footer never goes away. It should be at the bottom of the page." and, 2 October, "I'd like the footer at the bottom of the page on desktop as well." (l6-phone) The footer was a fixed strip under the page at every width. It is now the last thing in the page's scroll, at every width: - `Book` renders `.book > rail + div.book__scroll > (main#main + footer)`. The scroller is the new wrapper; `<main>` holds only the page; the footer is its sibling, so it is a top-level `contentinfo` (one, not inside `main`). - On a short page the footer sits at the bottom of the window; on a long one it is reached by scrolling. The Contents rail still runs the full height, with the footer under the main column only. - What used `main` as the scroller follows it to the wrapper: `useScrollRestoration` takes the scroller's ref; the print rules for a character sheet name the new element. `#main` is still the skip link's and route focus's target. - In the frame the footer keeps the page's gutters on a phone, so its text lines up with the page above it. ## "Clicking on a notification should clear it." (l7-bell) It was meant to already, and did in tests. In a browser the frame's link handler closed the panel between the two listeners of the same click, so the row was gone before its handler ran. The row's link now marks it read in the capture phase; a middle-click and a Ctrl-click (new tab) do too. The small "mark read" control is unchanged. IS-160's wording is corrected. ## "Selecting anything causes some of the modals to go blank." (lane 0, /design) Not the Modal specimens: the panels drawn open (Bell, Menu, AccountMenu, Search) closed on a press anywhere else on /design, or on Escape, and nothing reopened them, so one press blanked every open still. The specimens now stay open; the real components are unchanged. ## Checked - Full vitest on the merged tree: **3649 passed, 1 skipped**; eslint 0 errors. Every `coverage/lane*.py` and the changelog check pass. No backend change. - Rendered in an e2e stack at 390×844 (touch) and 1440×900, light and dark, and looked at: - **Footer:** a short page (footer at the window's bottom), Home, This week, Sessions, a session and its Review tab, the prep sheet (its sticky tool margin stays in the window and never meets the footer), a wiki article, the wiki editor, the map, Admin's Audit log; one `contentinfo`, never inside `main`, never overlapped, no sideways scroll; the rail full height at 1440. Table mode has no footer, as before. The public pages are unchanged. - **Scrolling:** the skip link shows on the first Tab and moves focus to `main`; from the last control of a short page, Tab reaches the footer links; a printed character sheet has no bar, rail or footer. - **Wordmark:** link, name, colours and focus ring at both widths and themes; goes to /dashboard. - **Bell:** a click, Enter, a middle-click and a Ctrl-click each sent one mark-read call and dropped the badge by one; the row was read on reopening. - **/design:** 24 open panels before and after a press on the page, Escape, and Light / Dark / Table mode; the Modal specimens open and close. - **Journeys on that stack:** j0-smoke, j0b-you and j1-first-campaign on desktop and phone (18 of 18), and j2-notified-votes-rsvps on desktop (7 of 7). ## Seen, not from this change (#1023) The wiki editor's sticky Save row leaves the screen in the lower half of the page; Back returns short on pages that load after the route; the window itself can scroll under the frame on two pages; the phone bell button is 36px wide. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Merge remote-tracking branch 'origin/main' into fix/1020-shell-wordmark-footer-bell
Some checks failed
CI / Backend lint (ruff) (pull_request) Successful in 38s
CI / Bot/backend version sync (pull_request) Successful in 39s
CI / Feedback site tests (pull_request) Successful in 49s
CI / Does this change touch the recording path? (pull_request) Successful in 23s
CI / Synthetic session harness (no GPU, no LLM) (pull_request) Has been skipped
CI / Summarisation accuracy eval harness (stub provider) (pull_request) Successful in 1m9s
CI / Bot tests and audit (pull_request) Successful in 2m3s
CI / Docker image build (pull_request) Successful in 2m17s
CI / End-to-end journeys (phone) (pull_request) Successful in 8m55s
CI / End-to-end journeys (keyboard) (pull_request) Successful in 9m46s
CI / End-to-end journeys (desktop) (pull_request) Successful in 9m51s
CI / Frontend (shard 2/2) (pull_request) Failing after 19m33s
CI / Frontend (shard 1/2) (pull_request) Has been cancelled
CI / Backend migration, tests, and audit (pull_request) Has been cancelled
5f292ccaae
The two whole-page /design tests get the room the third has (#1020)
All checks were successful
CI / Backend lint (ruff) (pull_request) Successful in 39s
CI / Does this change touch the recording path? (pull_request) Successful in 28s
CI / Synthetic session harness (no GPU, no LLM) (pull_request) Has been skipped
CI / Feedback site tests (pull_request) Successful in 53s
CI / Bot/backend version sync (pull_request) Successful in 1m5s
CI / Docker image build (pull_request) Successful in 1m8s
CI / Bot tests and audit (pull_request) Successful in 2m5s
CI / Summarisation accuracy eval harness (stub provider) (pull_request) Successful in 2m7s
CI / Frontend (shard 2/2) (pull_request) Successful in 7m15s
CI / Frontend (shard 1/2) (pull_request) Successful in 8m59s
CI / End-to-end journeys (phone) (pull_request) Successful in 9m3s
CI / End-to-end journeys (keyboard) (pull_request) Successful in 10m3s
CI / End-to-end journeys (desktop) (pull_request) Successful in 10m5s
CI / Backend migration, tests, and audit (pull_request) Successful in 24m29s
8972bead80
Each renders every state of every component. One timed out at the suite's 15s
on a busy runner in #1024's first run, with nothing wrong; both have done so
locally under load.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sign in to join this conversation.
No description provided.