Type: Crimson Pro, pinned chapter heading, floating footer pill (#95) #144

Merged
claude-bot merged 6 commits from feat/lectern-type-footer into main 2026-10-31 09:09:21 +00:00
Collaborator

Closes #75. Part 3 of #95.

What

  • Crimson Pro (OFL, bundled; Liberation Serif fallback) is the default reading face; the Serif setting turns it off for the system sans.
  • Every chapter has a heading (book name in small capitals, chapter number in lapis, hairline), pinned at the top while reading inside a chapter; the next chapter's heading pushes it off.
  • The footer is a floating pill: Back as a Lucide arrow, the reference centred (equal-width Back slot, #75), the Bible in lapis, ⋮.

Blast radius

Tier: trunk
Trunk paths touched: qml/pages/ReadingPane.qml, core/src/bible/{chapter,reader}.rs, core/src/worker.rs, qt/src/reading_model.rs, tools/e2e/
Testing tier: standard (also: ship on sight: styling, docs)
Gate / rollback: no flag; revert this merge. The Serif setting (Display) switches the new default face off per user. No schema change.

Proof

  • CI on 4c19391 green (run 287): rust (fmt, clippy, tests + coverage, deny, audit), app (C++/QML lint, -Werror build, clang-tidy, PSS mem-check), e2e (all cases, 13 min), click.
  • Fails without the change: heads_chapters_in_the_module_language with the old rule (book name on chapter 1 only) restored → FAILED at reader.rs:249, book: "" vs "1. Mose" (Kapitel 2). The settings and worker tests expect text.serif=1 and fail on the old default 0.
  • Memory: peak PSS 170888 kB normal / 169157 kB slow, budget 176000 kB (app-docker on d2f50de; CI's mem-check green on 4c19391). Fonts add about 240 kB to the click.
  • E2E: new case pinned-heading (inline heading, pinned mid-chapter, push-off by the next chapter); light-ground, import-url (new e2e_page_menu: the page bar's ⋮ stays at the edge), language-switch adapted.
  • Shots retaken on 4c19391 (cargo make shots, 3 cases passed), below.
  • Phone (Suru, Paper) on efb08eb, comment 2788: heading pinned, a tap on it opens nothing, it follows chapters, pill legible.
  • Phone re-check on 4c19391, comment 2799: journal feat/lectern-type-footer@4c193915b; Crimson Pro by default; arrow Back; reference centred ("Ps 25" centre at 542 of 1080 px, #75); Back from Ruth 2 returns to BSB 14780 0.920 (Ps 25). Owner (comment 2801): dark mode and bottom-edge swipe (scrolls the text, not caught by the pill) work; reading feel signed off.

Review

Reviewer: fresh-context review at high (374) + mockup check (375): 6 findings, 5 fixed in d2f50de, 1 declined (text 18 vs artboard 20 px: existing default with the size slider, a new default reflows saved places; owner kept 18 for now). Re-review 376 (medium): clean. Delta 377 (efb08eb, CI fix): clean. Delta 378 (4c19391, owner's changes): 1 low, refuted (comment 2796). Deferred by the owner: nicer sans #145, search in the pill #138. Left open: none.
Review-Confidence: 100/100, every trunk file reviewed at the right depth through the final commit, each finding fixed or refuted, and fails-without-change, CI and the phone check on 4c19391 all hold (first audit 85, for the then-unchecked swipe and dark mode on the phone).

Confidence by part

  • Heading data (core, glue): high; tested with module data, fails without the change.
  • Pinned heading (ReadingPane section delegate, restore offsets): medium; e2e and phone on efb08eb, but scroll-restore with the heading offset is the part to read.
  • Pill (layout, #75 centring): high; measured centred on the phone, Back checked there.
  • Fonts, colours, docs: high.

Mockup deviations (artboard: board C, target/mockup/Lapis.dc.html):

  • Text stays 18 px (artboard 20), owner's call.
  • Chapter number bold, not weight 600 (DemiBold went over the PSS budget).
  • Heading size does not follow the text scale (the pinned heading must stay small).
  • No search icon in the pill yet (#138).

Screenshots

Desktop (Xvfb, Default style, 4c19391; the ✕ is the Xvfb mouse cursor).

pill

Paper, mid-chapter (pinned) Paper, chapter start (inline) Paper, next chapter took over
paper pinned paper inline paper push-off
White, mid-chapter White, chapter start (Matt 7) Dark, mid-chapter (pinned) Dark, chapter start
white white start dark pinned dark inline

Phone (4c19391, Suru, Paper), see comment 2799:

phone pill

Mid-chapter (pinned) Chapter start (Ruth 2)
phone pinned phone inline

🤖 Generated with Claude Code

Closes #75. Part 3 of #95. ## What - Crimson Pro (OFL, bundled; Liberation Serif fallback) is the default reading face; the Serif setting turns it off for the system sans. - Every chapter has a heading (book name in small capitals, chapter number in lapis, hairline), pinned at the top while reading inside a chapter; the next chapter's heading pushes it off. - The footer is a floating pill: Back as a Lucide arrow, the reference centred (equal-width Back slot, #75), the Bible in lapis, ⋮. ## Blast radius **Tier:** trunk **Trunk paths touched:** `qml/pages/ReadingPane.qml`, `core/src/bible/{chapter,reader}.rs`, `core/src/worker.rs`, `qt/src/reading_model.rs`, `tools/e2e/` **Testing tier:** standard (also: ship on sight: styling, docs) **Gate / rollback:** no flag; revert this merge. The Serif setting (Display) switches the new default face off per user. No schema change. ## Proof - CI on 4c19391 green (run 287): rust (fmt, clippy, tests + coverage, deny, audit), app (C++/QML lint, -Werror build, clang-tidy, PSS mem-check), e2e (all cases, 13 min), click. - Fails without the change: `heads_chapters_in_the_module_language` with the old rule (book name on chapter 1 only) restored → FAILED at reader.rs:249, `book: ""` vs `"1. Mose"` (Kapitel 2). The settings and worker tests expect `text.serif=1` and fail on the old default `0`. - Memory: peak PSS 170888 kB normal / 169157 kB slow, budget 176000 kB (app-docker on d2f50de; CI's mem-check green on 4c19391). Fonts add about 240 kB to the click. - E2E: new case `pinned-heading` (inline heading, pinned mid-chapter, push-off by the next chapter); `light-ground`, `import-url` (new `e2e_page_menu`: the page bar's ⋮ stays at the edge), `language-switch` adapted. - Shots retaken on 4c19391 (`cargo make shots`, 3 cases passed), below. - Phone (Suru, Paper) on efb08eb, comment 2788: heading pinned, a tap on it opens nothing, it follows chapters, pill legible. - Phone re-check on 4c19391, comment 2799: journal `feat/lectern-type-footer@4c193915b`; Crimson Pro by default; arrow Back; reference centred ("Ps 25" centre at 542 of 1080 px, #75); Back from Ruth 2 returns to `BSB 14780 0.920` (Ps 25). Owner (comment 2801): dark mode and bottom-edge swipe (scrolls the text, not caught by the pill) work; reading feel signed off. ## Review **Reviewer:** fresh-context review at high (374) + mockup check (375): 6 findings, 5 fixed in d2f50de, 1 declined (text 18 vs artboard 20 px: existing default with the size slider, a new default reflows saved places; owner kept 18 for now). Re-review 376 (medium): clean. Delta 377 (efb08eb, CI fix): clean. Delta 378 (4c19391, owner's changes): 1 low, refuted (comment 2796). Deferred by the owner: nicer sans #145, search in the pill #138. Left open: none. **Review-Confidence:** 100/100, every trunk file reviewed at the right depth through the final commit, each finding fixed or refuted, and fails-without-change, CI and the phone check on 4c19391 all hold (first audit 85, for the then-unchecked swipe and dark mode on the phone). ## Confidence by part - Heading data (core, glue): high; tested with module data, fails without the change. - Pinned heading (ReadingPane section delegate, restore offsets): medium; e2e and phone on efb08eb, but scroll-restore with the heading offset is the part to read. - Pill (layout, #75 centring): high; measured centred on the phone, Back checked there. - Fonts, colours, docs: high. Mockup deviations (artboard: board C, target/mockup/Lapis.dc.html): - Text stays 18 px (artboard 20), owner's call. - Chapter number bold, not weight 600 (DemiBold went over the PSS budget). - Heading size does not follow the text scale (the pinned heading must stay small). - No search icon in the pill yet (#138). ## Screenshots Desktop (Xvfb, Default style, 4c19391; the ✕ is the Xvfb mouse cursor). ![pill](https://code.austinschaefer.com/schaefera/utStudyBIble/wiki/raw/images/pr-144/paper-pill.png) | Paper, mid-chapter (pinned) | Paper, chapter start (inline) | Paper, next chapter took over | |---|---|---| | ![paper pinned](https://code.austinschaefer.com/schaefera/utStudyBIble/wiki/raw/images/pr-144/paper-pinned.png) | ![paper inline](https://code.austinschaefer.com/schaefera/utStudyBIble/wiki/raw/images/pr-144/paper-inline.png) | ![paper push-off](https://code.austinschaefer.com/schaefera/utStudyBIble/wiki/raw/images/pr-144/paper-pushoff.png) | | White, mid-chapter | White, chapter start (Matt 7) | Dark, mid-chapter (pinned) | Dark, chapter start | |---|---|---|---| | ![white](https://code.austinschaefer.com/schaefera/utStudyBIble/wiki/raw/images/pr-144/white-pinned.png) | ![white start](https://code.austinschaefer.com/schaefera/utStudyBIble/wiki/raw/images/pr-144/white-inline.png) | ![dark pinned](https://code.austinschaefer.com/schaefera/utStudyBIble/wiki/raw/images/pr-144/dark-pinned.png) | ![dark inline](https://code.austinschaefer.com/schaefera/utStudyBIble/wiki/raw/images/pr-144/dark-inline.png) | Phone (4c19391, Suru, Paper), see comment 2799: ![phone pill](https://code.austinschaefer.com/schaefera/utStudyBIble/wiki/raw/images/pr-144/phone-4c19391-pill.png) | Mid-chapter (pinned) | Chapter start (Ruth 2) | |---|---| | ![phone pinned](https://code.austinschaefer.com/schaefera/utStudyBIble/wiki/raw/images/pr-144/phone-4c19391-pinned.png) | ![phone inline](https://code.austinschaefer.com/schaefera/utStudyBIble/wiki/raw/images/pr-144/phone-4c19391-inline.png) | 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
ui: pinned chapter heading and floating footer pill, e2e case and shots (#95)
Some checks failed
CI / changes (pull_request) Successful in 9s
CI / rust (pull_request) Successful in 5m23s
CI / audit (pull_request) Successful in 10s
CI / app (pull_request) Successful in 2m57s
CI / e2e (pull_request) Has been cancelled
CI / click (pull_request) Has been cancelled
2832e3eba9
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
claude-review requested changes 2026-10-30 21:52:56 +00:00
Dismissed
claude-review left a comment

Fresh-context review (posted by claude-review)

Level: high (blast radius: trunk)
Reviewed commit: 2832e3eba9
Range: origin/main...HEAD (base b258394)

Files reviewed: NOTICES.md, core/src/bible/chapter.rs, core/src/bible/reader.rs, docs/06-sources.md, docs/10-design.md, qml/fonts/OFL.txt (fonts themselves not opened), qml/pages/DisplaySettings.qml, qml/pages/ReadingPane.qml, qml/qml.qrc, qml/theme/Theme.qml, qt/src/reading_model.rs, tools/e2e/lib.sh, tools/e2e/cases/{back-after-kill,install-queue-cancel,light-ground,note-sheet,picker-back,pinned-heading,switch-bible-back,verse-sheet}.sh, plus callers of Heading.book and of the old footer (no remaining users of pane.footer; e2e coordinates for the pill, menu, Back and the installs strip check out against the 52 px / 20 px / 24 px geometry).

Findings outside the diff: none.

Findings inline:

  • medium · qml/pages/ReadingPane.qml:716 · the section delegate (pinned heading) has no mouse handling, so taps pass through it to the verse hidden underneath (see inline).

The Rust side (Heading.book now a String on every chapter, Span::of, tests) and the placeTop/topVerse/restore offset by Theme.headingHeight are consistent with each other and with the docs.

Fresh-context review (posted by claude-review) Level: high (blast radius: trunk) Reviewed commit: 2832e3eba977de75dbb35d962b8893b1f3b58f26 Range: origin/main...HEAD (base b258394) Files reviewed: NOTICES.md, core/src/bible/chapter.rs, core/src/bible/reader.rs, docs/06-sources.md, docs/10-design.md, qml/fonts/OFL.txt (fonts themselves not opened), qml/pages/DisplaySettings.qml, qml/pages/ReadingPane.qml, qml/qml.qrc, qml/theme/Theme.qml, qt/src/reading_model.rs, tools/e2e/lib.sh, tools/e2e/cases/{back-after-kill,install-queue-cancel,light-ground,note-sheet,picker-back,pinned-heading,switch-bible-back,verse-sheet}.sh, plus callers of Heading.book and of the old footer (no remaining users of `pane.footer`; e2e coordinates for the pill, menu, Back and the installs strip check out against the 52 px / 20 px / 24 px geometry). Findings outside the diff: none. Findings inline: - medium · qml/pages/ReadingPane.qml:716 · the section delegate (pinned heading) has no mouse handling, so taps pass through it to the verse hidden underneath (see inline). The Rust side (Heading.book now a String on every chapter, Span::of, tests) and the placeTop/topVerse/restore offset by Theme.headingHeight are consistent with each other and with the docs.
@ -658,0 +713,4 @@
// list has placed the verses below it. A fixed height, the same
// for every heading, also keeps the verses' offset below the
// pinned one (Theme.headingHeight) a constant.
section.delegate: Rectangle {
Collaborator

medium: this Rectangle is the pinned heading, drawn over the verses, but it has no MouseArea (the pill got one for exactly this reason). A Rectangle without mouse handling is not a hit target, so a tap on the pinned heading falls through to whatever verse text or verse-number area (min Theme.touch square) sits under it, and the hidden verse's sheet opens (reading.showVerse). Scenario: read mid-chapter, tap the chapter name at the top; the VerseSheet of a verse the reader cannot see opens. Fix: add MouseArea { anchors.fill: parent } inside this delegate (it does not steal flicks; it sets no preventStealing) so the heading's ground swallows taps like the pill's.

medium: this Rectangle is the pinned heading, drawn over the verses, but it has no MouseArea (the pill got one for exactly this reason). A Rectangle without mouse handling is not a hit target, so a tap on the pinned heading falls through to whatever verse text or verse-number area (min Theme.touch square) sits under it, and the hidden verse's sheet opens (reading.showVerse). Scenario: read mid-chapter, tap the chapter name at the top; the VerseSheet of a verse the reader cannot see opens. Fix: add `MouseArea { anchors.fill: parent }` inside this delegate (it does not steal flicks; it sets no preventStealing) so the heading's ground swallows taps like the pill's.
claude-review requested changes 2026-10-30 21:53:52 +00:00
Dismissed
claude-review left a comment

Mockup check

Compared: artboard target/mockup/Lapis.dc.html (board C "Ink and lapis": screens 6 John 3 on paper, 7 on white, and the pill) against target/shots/pinned-heading-04-heading-inline.png, -05-heading-pinned.png and -06-heading-pinned-next.png (dark only; there are no light shots of this case in target/shots/, so paper and white were checked from the QML colour roles, not pixels) and the code in qml/pages/ReadingPane.qml and qml/theme/Theme.qml.

The PR body lists the deviations ("full Chapter 3 line, SmallCaps 17 px book, text kept at 18 px, no search icon, chapter number always Crimson Pro, fixed heading size, rule width") but gives no reason for any of them. docs/09 asks for a reason each, so the ones below are findings, not accepted deviations.

Medium

  1. qml/pages/ReadingPane.qml ~line 745 (book name). Artboard: "JOHN" in all caps, Ubuntu sans, 12 px, letter-spacing .18em, #6B6458. Shot: "John" in Font.SmallCaps at 17 px with 2.5 px spacing. It renders as a large J with tiny "OHN", which reads as a different treatment, not the artboard's quiet label. Qt has Font.AllUppercase, so Qt's rich-text subset is no reason. Use uppercase at about 12 px, or give the reason.
  2. qml/pages/ReadingPane.qml ~line 760 (chapter line). Artboard: just the number ("3", "23"), 34 px, weight 600, lapis, with the book name above. Shot: the words "Chapter 3" at 30 px bold. The word and the size are listed but not explained. The localised "Kapitel 3" is a plausible reason, but then the PR must say so (the core still has the number it could pass).
  3. qml/pages/ReadingPane.qml ~lines 266-320 (floating pill labels). Artboard: "John 3:16" at 15 px weight 500 in full text colour, a 1 px divider, then "KJV" bold, 13 px, letter-spaced, in lapis. Shot (05): the pill is there and shaped right, but "Back", "John 3", "KJV" and the menu glyph are almost invisible dark grey on #211F24 (very low contrast). KJV is not lapis and there is no divider. The ToolButtons were given background: null but their labels do not use colours.textColour / colours.accent. This is a legibility bug in dark, not a theme-colour choice.
  4. Text size: the PR keeps 18 px against the artboard's 20 px, with no reason. Either follow the artboard (text scale already exists for users) or state why 18 is kept (old low-memory phones, line length).

Low

  1. Pinned shot (05) and the artboard: the artboard's own screen 6 also shows "JOHN / 3" over verse 14, so a mid-chapter heading above verse 14 matches the mockup. But the owner's feedback is right that it does not read well as a PR shot: the viewer cannot tell that 14 is mid-chapter, and the hairline is under "Chapter 3" while verse 13 is cut off. Consider noting in the PR what the pinned heading is for, or choosing a shot that shows the push-off (06) beside it.
  2. Chapter lapis in dark (#8FB0F0-like) is a same-role dark variant of #1E4FA8: fine.
  3. No search icon in the pill: matches the artboard (it has none); the PR body's "no search icon" is not a deviation.

Not checked: paper and white pixel shots (not in target/shots/); run cargo make shots for pinned-heading and light-ground in the light theme and attach them.

## Mockup check Compared: artboard `target/mockup/Lapis.dc.html` (board C "Ink and lapis": screens 6 John 3 on paper, 7 on white, and the pill) against `target/shots/pinned-heading-04-heading-inline.png`, `-05-heading-pinned.png` and `-06-heading-pinned-next.png` (dark only; there are no light shots of this case in `target/shots/`, so paper and white were checked from the QML colour roles, not pixels) and the code in `qml/pages/ReadingPane.qml` and `qml/theme/Theme.qml`. The PR body lists the deviations ("full Chapter 3 line, SmallCaps 17 px book, text kept at 18 px, no search icon, chapter number always Crimson Pro, fixed heading size, rule width") but gives no reason for any of them. docs/09 asks for a reason each, so the ones below are findings, not accepted deviations. **Medium** 1. `qml/pages/ReadingPane.qml` ~line 745 (book name). Artboard: "JOHN" in all caps, Ubuntu sans, 12 px, letter-spacing .18em, `#6B6458`. Shot: "John" in `Font.SmallCaps` at 17 px with 2.5 px spacing. It renders as a large J with tiny "OHN", which reads as a different treatment, not the artboard's quiet label. Qt has `Font.AllUppercase`, so Qt's rich-text subset is no reason. Use uppercase at about 12 px, or give the reason. 2. `qml/pages/ReadingPane.qml` ~line 760 (chapter line). Artboard: just the number ("3", "23"), 34 px, weight 600, lapis, with the book name above. Shot: the words "Chapter 3" at 30 px bold. The word and the size are listed but not explained. The localised "Kapitel 3" is a plausible reason, but then the PR must say so (the core still has the number it could pass). 3. `qml/pages/ReadingPane.qml` ~lines 266-320 (floating pill labels). Artboard: "John 3:16" at 15 px weight 500 in full text colour, a 1 px divider, then "KJV" bold, 13 px, letter-spaced, in lapis. Shot (05): the pill is there and shaped right, but "Back", "John 3", "KJV" and the menu glyph are almost invisible dark grey on `#211F24` (very low contrast). KJV is not lapis and there is no divider. The `ToolButton`s were given `background: null` but their labels do not use `colours.textColour` / `colours.accent`. This is a legibility bug in dark, not a theme-colour choice. 4. Text size: the PR keeps 18 px against the artboard's 20 px, with no reason. Either follow the artboard (text scale already exists for users) or state why 18 is kept (old low-memory phones, line length). **Low** 5. Pinned shot (05) and the artboard: the artboard's own screen 6 also shows "JOHN / 3" over verse 14, so a mid-chapter heading above verse 14 matches the mockup. But the owner's feedback is right that it does not read well as a PR shot: the viewer cannot tell that 14 is mid-chapter, and the hairline is under "Chapter 3" while verse 13 is cut off. Consider noting in the PR what the pinned heading is for, or choosing a shot that shows the push-off (06) beside it. 6. Chapter lapis in dark (`#8FB0F0`-like) is a same-role dark variant of `#1E4FA8`: fine. 7. No search icon in the pill: matches the artboard (it has none); the PR body's "no search icon" is not a deviation. Not checked: paper and white pixel shots (not in `target/shots/`); run `cargo make shots` for `pinned-heading` and `light-ground` in the light theme and attach them.
ui: heading and pill follow the artboard, taps on a heading stop at it (review 1, #95)
Some checks failed
CI / changes (pull_request) Successful in 5s
CI / rust (pull_request) Successful in 5m28s
CI / audit (pull_request) Successful in 10s
CI / app (pull_request) Successful in 3m3s
CI / e2e (pull_request) Failing after 11m27s
CI / click (pull_request) Has been skipped
d2f50de5e4
Book in capitals at 12 px, chapter as its number at 34 px, pill text in
the theme's colours with the Bible in lapis and a divider, a MouseArea on
the heading. Peak PSS 170888 kB normal, 169157 kB slow (budget 176000).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Author
Collaborator

Author answers to review round 1 (reviews 374 and 375), fixed in d2f50de:

  1. Taps through the pinned heading (ReadingPane.qml:716): fixed. The heading delegate has a MouseArea like the pill.
  2. Book name: fixed. Font.AllUppercase, 12 px (Theme.bookSize), letter-spacing 0.18 em, sans.
  3. Chapter line: fixed. Only the number, 34 px, lapis. It is taken from the first digits of the core's localised line ("Psalm 23" gives 23); the whole line is the accessible name and the fallback if there are no digits. I used bold, not DemiBold: DemiBold pushed peak PSS over the 176000 kB budget (176.6 to 180.6 MB, three attempts), bold stays at 170.9 MB normal and 169.2 MB slow.
  4. Pill legibility: fixed. Back, reference and menu labels use colours.textColour at 15 px (the menu glyph at 24), the Bible name uses colours.accent, and a hairline divider sits before it. Paper and White shots checked: legible.
  5. Text size 18 vs 20: refuted, kept at 18. It is the app's existing default (Display has a text-size slider), and a bigger default reflows every chapter, shifting saved places and the e2e cases' scroll counts, and adds to memory on the low-memory phones. Not part of this PR's scope; the artboard value stays a separate decision for the owner.
  6. Pinned shot: the mid-chapter shot is the pinned heading by design (artboard screen 6 shows the same), so the PR body will say so and point to heading-inline (chapter start) and heading-pinned-next (push-off) next to it. Paper and White shots now exist (light-ground-04/05/09/10) and look right after the fix.

Checks: app-docker passes (PSS 170888 kB normal, 169157 kB slow, budget 176000); e2e pinned-heading, light-ground and picker-back: 3 passed.

Author answers to review round 1 (reviews 374 and 375), fixed in d2f50de: 1. Taps through the pinned heading (ReadingPane.qml:716): fixed. The heading delegate has a MouseArea like the pill. 2. Book name: fixed. Font.AllUppercase, 12 px (Theme.bookSize), letter-spacing 0.18 em, sans. 3. Chapter line: fixed. Only the number, 34 px, lapis. It is taken from the first digits of the core's localised line ("Psalm 23" gives 23); the whole line is the accessible name and the fallback if there are no digits. I used bold, not DemiBold: DemiBold pushed peak PSS over the 176000 kB budget (176.6 to 180.6 MB, three attempts), bold stays at 170.9 MB normal and 169.2 MB slow. 4. Pill legibility: fixed. Back, reference and menu labels use colours.textColour at 15 px (the menu glyph at 24), the Bible name uses colours.accent, and a hairline divider sits before it. Paper and White shots checked: legible. 5. Text size 18 vs 20: refuted, kept at 18. It is the app's existing default (Display has a text-size slider), and a bigger default reflows every chapter, shifting saved places and the e2e cases' scroll counts, and adds to memory on the low-memory phones. Not part of this PR's scope; the artboard value stays a separate decision for the owner. 6. Pinned shot: the mid-chapter shot is the pinned heading by design (artboard screen 6 shows the same), so the PR body will say so and point to heading-inline (chapter start) and heading-pinned-next (push-off) next to it. Paper and White shots now exist (light-ground-04/05/09/10) and look right after the fix. Checks: app-docker passes (PSS 170888 kB normal, 169157 kB slow, budget 176000); e2e pinned-heading, light-ground and picker-back: 3 passed.
claude-review left a comment

Review level: medium. Blast radius: trunk. Reviewed commit: d2f50de5e4. Range: 2832e3eba977de75dbb35d962b8893b1f3b58f26..HEAD (one commit, d2f50de).

Files in range: qml/pages/ReadingPane.qml (trunk), qml/theme/Theme.qml.

I read the hunks in context, along with the heading format from core (Heading.chapter, names.chapter) and the colour tokens (colours.hairline, accent and textColour exist). No defects found.

  • The MouseArea in the heading delegate sits under the Text children, so it only swallows taps on the heading background, as intended.
  • The chapter-number extraction falls back to the whole line when there are no ASCII digits, and Accessible.name keeps the full label.
  • The footer Label contentItems and the new hairline Rectangle (visible-bound to moduleButton) are well-formed.

Not checked: CI results and the shots, since I review commits only.

Review level: medium. Blast radius: trunk. Reviewed commit: d2f50de5e4fa1a34a26171bf659a371b11a6d31d. Range: 2832e3eba977de75dbb35d962b8893b1f3b58f26..HEAD (one commit, d2f50de). Files in range: qml/pages/ReadingPane.qml (trunk), qml/theme/Theme.qml. I read the hunks in context, along with the heading format from core (`Heading.chapter`, `names.chapter`) and the colour tokens (`colours.hairline`, `accent` and `textColour` exist). No defects found. - The MouseArea in the heading delegate sits under the Text children, so it only swallows taps on the heading background, as intended. - The chapter-number extraction falls back to the whole line when there are no ASCII digits, and Accessible.name keeps the full label. - The footer Label contentItems and the new hairline Rectangle (visible-bound to moduleButton) are well-formed. Not checked: CI results and the shots, since I review commits only.
e2e: a page bar's ⋮ menu is still at the edge, only the footer pill floats (#95)
All checks were successful
CI / changes (pull_request) Successful in 7s
CI / rust (pull_request) Successful in 5m33s
CI / audit (pull_request) Successful in 11s
CI / app (pull_request) Successful in 3m5s
CI / e2e (pull_request) Successful in 10m53s
CI / click (pull_request) Successful in 2m4s
efb08ebdd0
e2e_menu now taps the reading pane's pill, so import-url, which opens the
Modules bar's ⋮ menu, missed it (CI run 285). e2e_page_menu taps the bar's
corner as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
claude-review left a comment

Delta review, level medium, commit efb08ebdd0, range d2f50de..efb08eb.
Files: tools/e2e/lib.sh, tools/e2e/cases/import-url.sh.

No defects found. e2e_page_menu taps (e2e_w-24, e2e_h-20) = (516, 940). PageBar's ⋮ ToolButton is Theme.touch (48 px) wide, last in a RowLayout filling the bottom-edge ToolBar, so it spans x 492..540 and 940 lies inside the bar. The "utsb: menu import x y" log comes from PageBar's onOpened, which e2e_tap_until waits for. The only caller of the old e2e_menu with a page-bar entry was import-url.sh, now switched; e2e_menu (modules/settings) remains reading-pane-only and unchanged. e2e_tap_menu is unaffected.
Findings outside the diff: none.

Delta review, level medium, commit efb08ebdd09a2ad9154848e5040007d75879d96f, range d2f50de..efb08eb. Files: tools/e2e/lib.sh, tools/e2e/cases/import-url.sh. No defects found. e2e_page_menu taps (e2e_w-24, e2e_h-20) = (516, 940). PageBar's ⋮ ToolButton is Theme.touch (48 px) wide, last in a RowLayout filling the bottom-edge ToolBar, so it spans x 492..540 and 940 lies inside the bar. The "utsb: menu import x y" log comes from PageBar's onOpened, which e2e_tap_until waits for. The only caller of the old e2e_menu with a page-bar entry was import-url.sh, now switched; e2e_menu (modules/settings) remains reading-pane-only and unchanged. e2e_tap_menu is unaffected. Findings outside the diff: none.
Author
Collaborator

Phone check (efb08eb, Paper, Suru style)

Build on the phone confirmed by the journal: feat/lectern-type-footer@efb08ebdd built 11:27 PM installed 11:28 PM.

Checked by me with ute2e:

  • Chapter heading pinned mid-chapter ("ESTHER 2" above verse 7); verses scroll under it.
  • A tap on the pinned heading opens nothing; a tap on a verse below opens its sheet as before.
  • Scrolling from Esther 2 into 5: the pinned heading follows each chapter, the pill's reference follows too.
  • The pill on Suru: white with its hairline, no grey plate, labels legible, the Bible in lapis, clear of the bottom edge.

Checked by the owner:

  • Holding the reference in the pill shows the build info. (The ute2e long press is a 1 px swipe the list takes as a drag and opened the verse behind the pill; a real finger shows the build info.)

For the owner (feel and system settings I don't change):

  • Dark mode on the phone: heading and pill read well.
  • The swipe up from the bottom edge still works and doesn't catch the pill.
  • The heading and pill feel right while reading; sign-off.
Paper, pinned Next chapter
phone paper pinned phone paper next
## Phone check (efb08eb, Paper, Suru style) Build on the phone confirmed by the journal: `feat/lectern-type-footer@efb08ebdd built 11:27 PM installed 11:28 PM`. Checked by me with ute2e: - [x] Chapter heading pinned mid-chapter ("ESTHER 2" above verse 7); verses scroll under it. - [x] A tap on the pinned heading opens nothing; a tap on a verse below opens its sheet as before. - [x] Scrolling from Esther 2 into 5: the pinned heading follows each chapter, the pill's reference follows too. - [x] The pill on Suru: white with its hairline, no grey plate, labels legible, the Bible in lapis, clear of the bottom edge. Checked by the owner: - [x] Holding the reference in the pill shows the build info. (The ute2e long press is a 1 px swipe the list takes as a drag and opened the verse behind the pill; a real finger shows the build info.) For the owner (feel and system settings I don't change): - [ ] Dark mode on the phone: heading and pill read well. - [ ] The swipe up from the bottom edge still works and doesn't catch the pill. - [ ] The heading and pill feel right while reading; sign-off. | Paper, pinned | Next chapter | |---|---| | ![phone paper pinned](https://code.austinschaefer.com/schaefera/utStudyBIble/wiki/raw/images/pr-144/phone-paper-pinned.png) | ![phone paper next](https://code.austinschaefer.com/schaefera/utStudyBIble/wiki/raw/images/pr-144/phone-paper-next.png) |
ui: Back is a Lucide arrow, the reference stays centred, Crimson Pro by default (#75, #95)
All checks were successful
CI / changes (pull_request) Successful in 13s
CI / rust (pull_request) Successful in 8m11s
CI / audit (pull_request) Successful in 15s
CI / app (pull_request) Successful in 3m57s
CI / e2e (pull_request) Successful in 13m2s
CI / click (pull_request) Successful in 3m14s
4c193915bd
Back's slot is as wide as the hairline, Bible and menu, shown or not, so
the book name stays centred on the pill. The reading text uses Crimson Pro
unless Sans is chosen (owner). language-switch waits until the last option
is on screen after the scroll.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
claude-review left a comment

Delta review, level medium
Commit: 4c193915bd
Range: efb08eb..4c19391

Files reviewed:

  • assets/icons/arrow-left.svg
  • core/src/settings.rs
  • core/src/worker.rs
  • docs/06-sources.md
  • docs/10-design.md
  • qml/icons/arrow-left.png
  • qml/pages/ReadingPane.qml
  • qml/qml.qrc
  • qml/theme/Theme.qml
  • tools/e2e/cases/language-switch.sh
  • qt/src/reading_model.rs (consumer of SERIF)
  • qml/pages/DisplaySettings.qml (consumer)
  • tools/e2e/lib.sh, tools/icons/render.sh (helpers)

Findings outside the diff:

  • low · qt/src/reading_model.rs:291,319 · ReadingModelRust derives Default, so serif starts false while the core default is now "1". ReadingPane.qml:214 copies it to Theme.serif on completion, so at start-up the text can first lay out in the system sans and then switch to Crimson Pro when the settings arrive (a relayout and a font flash). If the settings never arrive, it stays sans. Initialise serif: true in the model's default, as Theme.serif was.

No high or medium defects found.

Delta review, level medium Commit: 4c193915bd6853e57211e2af099b0122e409a653 Range: efb08eb..4c19391 Files reviewed: - assets/icons/arrow-left.svg - core/src/settings.rs - core/src/worker.rs - docs/06-sources.md - docs/10-design.md - qml/icons/arrow-left.png - qml/pages/ReadingPane.qml - qml/qml.qrc - qml/theme/Theme.qml - tools/e2e/cases/language-switch.sh - qt/src/reading_model.rs (consumer of SERIF) - qml/pages/DisplaySettings.qml (consumer) - tools/e2e/lib.sh, tools/icons/render.sh (helpers) Findings outside the diff: - low · qt/src/reading_model.rs:291,319 · `ReadingModelRust` derives `Default`, so `serif` starts false while the core default is now "1". ReadingPane.qml:214 copies it to `Theme.serif` on completion, so at start-up the text can first lay out in the system sans and then switch to Crimson Pro when the settings arrive (a relayout and a font flash). If the settings never arrive, it stays sans. Initialise `serif: true` in the model's default, as `Theme.serif` was. No high or medium defects found.
Author
Collaborator

Author answer to the delta review 378 (efb08eb..4c19391):

  • low · qt/src/reading_model.rs:291,319 (serif starts false, so the text could flash from sans to serif at start-up): refuted. Initialize (reading_model.rs:330–337) runs every setting in settings::ALL through setting() when the object is created, before QML reads a property. SERIF (default "1") is in ALL (core/src/settings.rs:71), and setting() sets rust.serif (line 518). So the model starts with serif on; the derived false is never seen. No change.
Author answer to the delta review 378 (efb08eb..4c19391): - low · qt/src/reading_model.rs:291,319 (`serif` starts false, so the text could flash from sans to serif at start-up): refuted. `Initialize` (reading_model.rs:330–337) runs every setting in `settings::ALL` through `setting()` when the object is created, before QML reads a property. `SERIF` (default `"1"`) is in `ALL` (core/src/settings.rs:71), and `setting()` sets `rust.serif` (line 518). So the model starts with serif on; the derived `false` is never seen. No change.
Author
Collaborator

Phone re-check (4c19391, Suru, Paper)

Installed 4c19391 (cargo make click + clickable install, click-review pass). Checked by me with ute2e:

  • Journal: utsb: build 0.0.1 feat/lectern-type-footer@4c193915b built 10/31/26 9:59 AM installed 9:59 AM; window loaded after 431 ms.
  • Reading text in Crimson Pro by default (restored place opened straight in serif).
  • Pill: Back is the arrow icon; the reference is centred on the screen (#75): "Ps 25" spans x 499–585 of 1080 px, centre 542 vs 540.
  • Back: Ps 25 → Go to → Ruth 2 (chapter start, heading inline), arrow → back to BSB 14780 0.920, showing Ps 25 at the same place.
  • Pinned heading ("PSALMS 25" mid-chapter) and pill as in comment 2788.

For the owner (feel and system settings I don't change):

  • Dark mode on the phone: heading and pill read well.
  • The swipe up from the bottom edge still works and doesn't catch the pill.
  • Feel while reading; sign-off.

pill

Mid-chapter (pinned) Chapter start (Ruth 2)
phone pinned phone inline
## Phone re-check (4c19391, Suru, Paper) Installed 4c19391 (`cargo make click` + `clickable install`, click-review pass). Checked by me with ute2e: - [x] Journal: `utsb: build 0.0.1 feat/lectern-type-footer@4c193915b built 10/31/26 9:59 AM installed 9:59 AM`; window loaded after 431 ms. - [x] Reading text in Crimson Pro by default (restored place opened straight in serif). - [x] Pill: Back is the arrow icon; the reference is centred on the screen (#75): "Ps 25" spans x 499–585 of 1080 px, centre 542 vs 540. - [x] Back: Ps 25 → Go to → Ruth 2 (chapter start, heading inline), arrow → `back to BSB 14780 0.920`, showing Ps 25 at the same place. - [x] Pinned heading ("PSALMS 25" mid-chapter) and pill as in comment 2788. For the owner (feel and system settings I don't change): - [ ] Dark mode on the phone: heading and pill read well. - [ ] The swipe up from the bottom edge still works and doesn't catch the pill. - [ ] Feel while reading; sign-off. ![pill](https://code.austinschaefer.com/schaefera/utStudyBIble/wiki/raw/images/pr-144/phone-4c19391-pill.png) | Mid-chapter (pinned) | Chapter start (Ruth 2) | |---|---| | ![phone pinned](https://code.austinschaefer.com/schaefera/utStudyBIble/wiki/raw/images/pr-144/phone-4c19391-pinned.png) | ![phone inline](https://code.austinschaefer.com/schaefera/utStudyBIble/wiki/raw/images/pr-144/phone-4c19391-inline.png) |
Author
Collaborator

Owner's phone items on 4c19391 (from the session, 2026-10-31): "The swipe up from the bottom just moves text right? If so, that and dark mode are working. The reading experience seems to be as good as ever".

  • Dark mode on the phone: heading and pill read well.
  • Swipe up from the bottom edge scrolls the text; the pill doesn't catch it (the reading pane has no bottom-edge action of its own, so scrolling is expected).
  • Feel while reading; signed off.
Owner's phone items on 4c19391 (from the session, 2026-10-31): "The swipe up from the bottom just moves text right? If so, that and dark mode are working. The reading experience seems to be as good as ever". - [x] Dark mode on the phone: heading and pill read well. - [x] Swipe up from the bottom edge scrolls the text; the pill doesn't catch it (the reading pane has no bottom-edge action of its own, so scrolling is expected). - [x] Feel while reading; signed off.
claude-bot changed title from WIP: Type: Crimson Pro, pinned chapter heading, floating footer pill (#95) to Type: Crimson Pro, pinned chapter heading, floating footer pill (#95) 2026-10-31 09:07:35 +00:00
claude-review left a comment

Merge gate (claude-review) on 4c19391.

Checked:

  • 374 medium (tap-through on the pinned heading): fixed. The section delegate now has a MouseArea (ReadingPane.qml:757).
  • 375 mediums: book name uses Font.AllUppercase (:786). Pill labels use colours.textColour and colours.accent (:279-322). The chapter-line wording and the 18 px text size are stated as deviations with reasons in the PR body (owner's call, DemiBold over the PSS budget).
  • Head is still 4c19391. There are no commits after the last reviewed one (git log 4c19391..origin/feat/lectern-type-footer is empty).
  • CI: all 6 contexts green on 4c19391 (changes, rust, audit, app, e2e, click).
  • Tier: standard. The diff has fonts, assets, QML, core/Rust glue, e2e scripts and docs. It has no Cargo.toml or lockfile change and no .forgejo/CI-config change. Proof lists no unrun elevated, maximum or AI-behavior gate.
  • Phone checks (comments 2788, 2799, 2801) cover the pinned heading, the pill, dark mode and the bottom-edge swipe.

Nothing left open.

Merge gate (claude-review) on 4c19391. Checked: - 374 medium (tap-through on the pinned heading): fixed. The section delegate now has a MouseArea (ReadingPane.qml:757). - 375 mediums: book name uses Font.AllUppercase (:786). Pill labels use colours.textColour and colours.accent (:279-322). The chapter-line wording and the 18 px text size are stated as deviations with reasons in the PR body (owner's call, DemiBold over the PSS budget). - Head is still 4c19391. There are no commits after the last reviewed one (`git log 4c19391..origin/feat/lectern-type-footer` is empty). - CI: all 6 contexts green on 4c19391 (changes, rust, audit, app, e2e, click). - Tier: standard. The diff has fonts, assets, QML, core/Rust glue, e2e scripts and docs. It has no Cargo.toml or lockfile change and no .forgejo/CI-config change. Proof lists no unrun elevated, maximum or AI-behavior gate. - Phone checks (comments 2788, 2799, 2801) cover the pinned heading, the pill, dark mode and the bottom-edge swipe. Nothing left open.
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
3 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
schaefera/utStudyBIble!144
No description provided.