Design: Ink and lapis palette (paper light, warm dark) and docs/10-design.md (#95) #141

Merged
claude-bot merged 4 commits from feat/lectern-palette into main 2026-10-30 19:08:09 +00:00
Collaborator

What

Part 1 of 5 of #95. It applies the Ink and lapis design language:

  • paper (#FAF8F3) and warm dark (#17161A) grounds;
  • lapis verse numbers and note markers;
  • red letters in #A3231A / #F0938A;
  • sheets on the paper ground with a hairline under the header.

It adds docs/10-design.md. Refs #95.

Blast radius

Tier: trunk
Trunk paths touched: core/src/render.rs, core/src/worker.rs (tests), core/src/bible/reader.rs (tests), qml/pages/ReadingPane.qml, qml/Main.qml, Makefile.toml
Testing tier: standard (UI colours and render output)
Gate / rollback: revert this merge. There is no schema or data change.

Proof

  • cargo make exits 0, and so does cargo make app-docker. mem-check peak PSS is 169675 kB (slow: 165101 kB; the budget is 176000 kB).
  • CI on head 8fa2d52 is green on all six jobs: changes, rust, audit, app, e2e and click.
  • The Rust colour tests failed with the old constants before their expected values were updated.
  • Shots, light and dark (--dark, shots only): red-letters, verse-sheet, module-manager, note-sheet.
  • Phone, build 8fa2d5289:
    • The journal shows utsb: dark false, window #faf8f3, text #22201c.
    • Pixel samples show #FAF8F3 on the reading pane and the Modules page.
    • Verse numbers and markers are lapis, and the verse sheet opens on paper.
    • There are no QML errors.
    • The owner signed off ("Looks good", comment 2741).

Mockup

Checked against artboard C "Ink and lapis" (https://claude.ai/artifact/MwvxmpLR96sZkwbiCwAhp6), colours only. Deviations:

  • The highlight role is not drawn yet, because there is no selected-verse state. Deferred to #142.
  • hairline, secondary and surface are unused for separators, dialogs and the footer. These wait for the layout PRs (#142).
  • Suru controls keep Suru's look until they are restyled.

Resources (docs/07)

Colours only, plus one small SystemColours instance per page. PSS is within budget (see Proof).

Review

Reviewer: fresh-context code-review at high, then a mockup check. 5 findings: 2 fixed (sheet on paper with a hairline; this body's Mockup section), 2 deferred to #142, 1 refuted (the dark verse-sheet shot shows the same sheet open), 0 left open.
Review-Confidence: 80/100. The audit deducted 15 because the forced --dark shots skip the live system-theme switch. The owner's phone try-out covers it.

Confidence by part

  • Render colours: high, covered by tests.
  • QML grounds and sheets: high in light, which was checked on the phone. Medium in dark: it was checked in shots, not by a live switch on the phone.

🤖 Generated with Claude Code

## What Part 1 of 5 of #95. It applies the Ink and lapis design language: - paper (#FAF8F3) and warm dark (#17161A) grounds; - lapis verse numbers and note markers; - red letters in #A3231A / #F0938A; - sheets on the paper ground with a hairline under the header. It adds `docs/10-design.md`. Refs #95. ## Blast radius **Tier:** trunk **Trunk paths touched:** core/src/render.rs, core/src/worker.rs (tests), core/src/bible/reader.rs (tests), qml/pages/ReadingPane.qml, qml/Main.qml, Makefile.toml **Testing tier:** standard (UI colours and render output) **Gate / rollback:** revert this merge. There is no schema or data change. ## Proof - `cargo make` exits 0, and so does `cargo make app-docker`. mem-check peak PSS is 169675 kB (slow: 165101 kB; the budget is 176000 kB). - CI on head 8fa2d52 is green on all six jobs: changes, rust, audit, app, e2e and click. - The Rust colour tests failed with the old constants before their expected values were updated. - Shots, light and dark (`--dark`, shots only): red-letters, verse-sheet, module-manager, note-sheet. - Phone, build 8fa2d5289: - The journal shows `utsb: dark false, window #faf8f3, text #22201c`. - Pixel samples show #FAF8F3 on the reading pane and the Modules page. - Verse numbers and markers are lapis, and the verse sheet opens on paper. - There are no QML errors. - The owner signed off ("Looks good", comment 2741). ## Mockup Checked against artboard C "Ink and lapis" (https://claude.ai/artifact/MwvxmpLR96sZkwbiCwAhp6), colours only. Deviations: - The highlight role is not drawn yet, because there is no selected-verse state. Deferred to #142. - hairline, secondary and surface are unused for separators, dialogs and the footer. These wait for the layout PRs (#142). - Suru controls keep Suru's look until they are restyled. ## Resources (docs/07) Colours only, plus one small SystemColours instance per page. PSS is within budget (see Proof). ## Review **Reviewer:** fresh-context `code-review` at high, then a mockup check. 5 findings: 2 fixed (sheet on paper with a hairline; this body's Mockup section), 2 deferred to #142, 1 refuted (the dark verse-sheet shot shows the same sheet open), 0 left open. **Review-Confidence:** 80/100. The audit deducted 15 because the forced `--dark` shots skip the live system-theme switch. The owner's phone try-out covers it. ## Confidence by part - Render colours: high, covered by tests. - QML grounds and sheets: high in light, which was checked on the phone. Medium in dark: it was checked in shots, not by a live switch on the phone. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ui: colour roles in SystemColours; paper and warm dark grounds, lapis numbers and markers (#95)
Some checks failed
CI / changes (pull_request) Successful in 9s
CI / rust (pull_request) Successful in 5m19s
CI / audit (pull_request) Successful in 10s
CI / app (pull_request) Has been cancelled
CI / e2e (pull_request) Has been cancelled
CI / click (pull_request) Has been cancelled
be63696c2e
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
claude-review left a comment

Fresh-context review (claude-review)

Level: high. Blast radius: trunk (qml/Main.qml, qml/pages/ReadingPane.qml, core/src/render.rs, core/src/worker.rs tests, Makefile.toml). Testing tier: standard.
Reviewed commit: be63696c2e
Range: origin/main...HEAD (3 commits)

Files reviewed: Makefile.toml, core/src/bible/reader.rs, core/src/render.rs, core/src/worker.rs, docs/07-platform-constraints.md, docs/10-design.md, qml/Main.qml, qml/controls/BottomSheet.qml, qml/pages/ModulesPage.qml, qml/pages/PickerPage.qml, qml/pages/ReadingPane.qml, qml/pages/SettingsPage.qml, qml/pages/StarterPage.qml, qml/platform/SystemColours.qml, qml/platform/ut/SystemColours.qml (context), tools/e2e/lib.sh and cases/display-settings.sh (context), tools/mem-check/run.sh (context).

Findings: none with a concrete failure scenario.

Checked and found sound:

  • dark is computed from systemWindow (the Suru or palette window), while windowColour is now an alias of ground. There is no binding loop, and the live light/dark switch still drives ReadingPane.dark and reading.setDark.
  • Every old colour literal (#b71c1c, #ff8a80, #5f6368, #9aa0a6) is gone from Rust tests, worker tests, QML and tools. The e2e "red on screen" regex is now case-insensitive and matches the new reds. The display-settings e2e check reads the Menu's palette, which this PR does not touch.
  • The new constants match docs/10-design.md and SystemColours.qml. Recomputed contrasts: red 7.03 and 7.93, numbers 7.22 and 8.26, as the render.rs comments claim (the SystemColours comment says secondary is 5.6:1, actual 5.51, immaterial).
  • The --dark flag is only read from Qt.application.arguments. E2E_APP_ARGS reaches the container through -e. lib.sh defaults it to --e2e when unset, and mem-check sets it empty, so the production path never sees --dark.
  • Each new Page background and the SystemColours instances are valid. ids are local per file, with no duplicates. The extra Loader per page is small, but docs/07 asks a PR that adds start-up work to say so. Worth one line in the PR body.

Note (not a defect): footer, menu and dialog chrome still take the style's colours, so in dark they differ slightly from ground until the follow-up PRs. This is the stated scope.

Fresh-context review (claude-review) Level: high. Blast radius: trunk (qml/Main.qml, qml/pages/ReadingPane.qml, core/src/render.rs, core/src/worker.rs tests, Makefile.toml). Testing tier: standard. Reviewed commit: be63696c2ebf00a12be516910c5cbb8822e7ae1b Range: origin/main...HEAD (3 commits) Files reviewed: Makefile.toml, core/src/bible/reader.rs, core/src/render.rs, core/src/worker.rs, docs/07-platform-constraints.md, docs/10-design.md, qml/Main.qml, qml/controls/BottomSheet.qml, qml/pages/ModulesPage.qml, qml/pages/PickerPage.qml, qml/pages/ReadingPane.qml, qml/pages/SettingsPage.qml, qml/pages/StarterPage.qml, qml/platform/SystemColours.qml, qml/platform/ut/SystemColours.qml (context), tools/e2e/lib.sh and cases/display-settings.sh (context), tools/mem-check/run.sh (context). Findings: none with a concrete failure scenario. Checked and found sound: - `dark` is computed from `systemWindow` (the Suru or palette window), while `windowColour` is now an alias of `ground`. There is no binding loop, and the live light/dark switch still drives `ReadingPane.dark` and `reading.setDark`. - Every old colour literal (#b71c1c, #ff8a80, #5f6368, #9aa0a6) is gone from Rust tests, worker tests, QML and tools. The e2e "red on screen" regex is now case-insensitive and matches the new reds. The display-settings e2e check reads the Menu's palette, which this PR does not touch. - The new constants match docs/10-design.md and SystemColours.qml. Recomputed contrasts: red 7.03 and 7.93, numbers 7.22 and 8.26, as the render.rs comments claim (the SystemColours comment says secondary is 5.6:1, actual 5.51, immaterial). - The `--dark` flag is only read from `Qt.application.arguments`. `E2E_APP_ARGS` reaches the container through `-e`. lib.sh defaults it to `--e2e` when unset, and mem-check sets it empty, so the production path never sees `--dark`. - Each new Page `background` and the `SystemColours` instances are valid. ids are local per file, with no duplicates. The extra Loader per page is small, but docs/07 asks a PR that adds start-up work to say so. Worth one line in the PR body. Note (not a defect): footer, menu and dialog chrome still take the style's colours, so in dark they differ slightly from `ground` until the follow-up PRs. This is the stated scope.
claude-review requested changes 2026-10-30 18:35:34 +00:00
Dismissed
claude-review left a comment

Mockup check

Compared: artboard C "Ink and lapis" (target/mockup/Lapis.dc.html, screens 1-10) against shots of be63696 (light and dark, cargo make shots: note-sheet, red-letters, module-manager; dark with E2E_APP_ARGS="--e2e --dark"). Scope per the task: colours of grounds, surfaces, hairlines, text, verse numbers, note markers, red letters, highlight.

Matches (pixel-sampled or by constant): ground paper #FAF8F3 / dark #17161A on reading, settings, modules; verse numbers and note markers lapis #1E4FA8 / #8FB0F0 (verse numbers on the artboard are non-bold 11px, here bold, a font matter for a later PR); red letters #A3231A / #F0938A; every palette value in SystemColours.qml equals the artboard's hex. The Settings and Modules pages have the right grounds in dark.

Differences with no reason given (the PR body has no "Mockup" section yet, docs/09 requires one):

  • medium, qml/controls/BottomSheet.qml:60: the artboard's notes/cross-refs sheet (screen 2) is on the paper ground #FAF8F3 with a #E4DFD3 rule under its header; the shot shows the sheet at #FFFFFF (colours.surface) over the grey scrim. Either use colours.ground there, or list white sheets as a deliberate deviation (docs/10 says sheets are surface, but screen 2 shows paper).
  • medium, qml/platform/SystemColours.qml (highlight) and qml/pages/ReadingPane.qml: artboard screens 6-8 draw the opened verse on #F1ECE0 / #EEF2FA / #23222A with a 6px radius. The role is defined but nothing uses it; no shot shows a highlight. Draw it, or state that it comes in a later PR.
  • low, hairline, secondary and surface for the footer bar are defined and unused: lists, separators, the dialog (artboard #211F1C on #34312C border; the shot shows the style's dialog colour, about #201F22 with no hairline) and the footer still come from the Controls style. Fine if the PR body says these roles wait for the layout PRs.
  • low, shots: the dark note-sheet shot did not capture the sheet open (the sheet was not up when shot), so dark sheet colours were not verified visually.

Not deviations here (later PRs): layout, serif fonts, footer pill, chapter heading, Menu tiles, White theme.

## Mockup check Compared: artboard C "Ink and lapis" (target/mockup/Lapis.dc.html, screens 1-10) against shots of be63696 (light and dark, `cargo make shots`: note-sheet, red-letters, module-manager; dark with `E2E_APP_ARGS="--e2e --dark"`). Scope per the task: colours of grounds, surfaces, hairlines, text, verse numbers, note markers, red letters, highlight. Matches (pixel-sampled or by constant): ground paper #FAF8F3 / dark #17161A on reading, settings, modules; verse numbers and note markers lapis #1E4FA8 / #8FB0F0 (verse numbers on the artboard are non-bold 11px, here bold, a font matter for a later PR); red letters #A3231A / #F0938A; every palette value in SystemColours.qml equals the artboard's hex. The Settings and Modules pages have the right grounds in dark. Differences with no reason given (the PR body has no "Mockup" section yet, docs/09 requires one): - medium, qml/controls/BottomSheet.qml:60: the artboard's notes/cross-refs sheet (screen 2) is on the paper ground #FAF8F3 with a #E4DFD3 rule under its header; the shot shows the sheet at #FFFFFF (`colours.surface`) over the grey scrim. Either use `colours.ground` there, or list white sheets as a deliberate deviation (docs/10 says sheets are surface, but screen 2 shows paper). - medium, qml/platform/SystemColours.qml (`highlight`) and qml/pages/ReadingPane.qml: artboard screens 6-8 draw the opened verse on #F1ECE0 / #EEF2FA / #23222A with a 6px radius. The role is defined but nothing uses it; no shot shows a highlight. Draw it, or state that it comes in a later PR. - low, `hairline`, `secondary` and `surface` for the footer bar are defined and unused: lists, separators, the dialog (artboard #211F1C on #34312C border; the shot shows the style's dialog colour, about #201F22 with no hairline) and the footer still come from the Controls style. Fine if the PR body says these roles wait for the layout PRs. - low, shots: the dark note-sheet shot did not capture the sheet open (the sheet was not up when shot), so dark sheet colours were not verified visually. Not deviations here (later PRs): layout, serif fonts, footer pill, chapter heading, Menu tiles, White theme.
ui: sheets on the paper ground with a hairline under the header, as artboard screen 2 (#95)
All checks were successful
CI / changes (pull_request) Successful in 6s
CI / rust (pull_request) Successful in 5m23s
CI / audit (pull_request) Successful in 12s
CI / app (pull_request) Successful in 2m56s
CI / e2e (pull_request) Successful in 10m33s
CI / click (pull_request) Successful in 1m58s
8fa2d52892
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Author
Collaborator

Author reply to review 367 (head now 8fa2d52):

  • BottomSheet on paper: fixed. Sheet is ground with a hairline under the header; docs/10 table updated; verse-sheet shot checked in dark.
  • Highlight unused: deferred to #142 (no selected-verse state in the reading pane yet); listed under Mockup in the body.
  • hairline/secondary/surface for separators, dialogs, footer: deferred to #142, listed in the Mockup section.
  • Dark note-sheet shot: not re-captured; the dark verse-sheet shot uses the same BottomSheet and shows it open.
  • Mockup section: added to the PR body, with the Loader/start-up line for docs/07.
  • Review 366 (no findings): the SystemColours secondary contrast comment (5.6 vs 5.51) left as is.
Author reply to review 367 (head now 8fa2d52): - BottomSheet on paper: fixed. Sheet is `ground` with a hairline under the header; docs/10 table updated; verse-sheet shot checked in dark. - Highlight unused: deferred to #142 (no selected-verse state in the reading pane yet); listed under Mockup in the body. - hairline/secondary/surface for separators, dialogs, footer: deferred to #142, listed in the Mockup section. - Dark note-sheet shot: not re-captured; the dark verse-sheet shot uses the same BottomSheet and shows it open. - Mockup section: added to the PR body, with the Loader/start-up line for docs/07. - Review 366 (no findings): the SystemColours secondary contrast comment (5.6 vs 5.51) left as is.
Author
Collaborator

On the phone: build feat/lectern-palette@8fa2d5289 is installed. The journal confirms it: utsb: build 0.0.1 feat/lectern-palette@8fa2d5289, restored BSB at Ps 1.

Checked by me with ute2e (shots and pixel samples):

  • The reading ground is paper #FAF8F3. The journal shows utsb: dark false, window #faf8f3, text #22201c.
  • Verse numbers are lapis, and the note markers are italic lapis (Psalm 2:1–2).
  • The verse sheet (Psalm 1:1) shows its header on paper, over the dimmed text.
  • The Modules page has a paper ground, with Suru's white rows on top, which read like cards.
  • No QML errors in the journal.

The footer bar and the list rows are still Suru white. That is expected; they change in the layout PRs.

For the owner (needs a system setting):

  1. Switch the system to dark while the app is open. The text should turn warm dark (#17161A) with light text, lapis-blue numbers and salmon-red words of Christ. Open a verse sheet: it should be dark too.
  2. Switch back to light: paper again, with nothing left dark.
  3. Sign-off: does the paper tone feel right on the real screen (not too yellow)?

🤖 Generated with Claude Code

**On the phone:** build `feat/lectern-palette@8fa2d5289` is installed. The journal confirms it: `utsb: build 0.0.1 feat/lectern-palette@8fa2d5289`, restored BSB at Ps 1. Checked by me with ute2e (shots and pixel samples): - The reading ground is paper `#FAF8F3`. The journal shows `utsb: dark false, window #faf8f3, text #22201c`. - Verse numbers are lapis, and the note markers are italic lapis (Psalm 2:1–2). - The verse sheet (Psalm 1:1) shows its header on paper, over the dimmed text. - The Modules page has a paper ground, with Suru's white rows on top, which read like cards. - No QML errors in the journal. The footer bar and the list rows are still Suru white. That is expected; they change in the layout PRs. **For the owner** (needs a system setting): 1. Switch the system to **dark** while the app is open. The text should turn warm dark (`#17161A`) with light text, lapis-blue numbers and salmon-red words of Christ. Open a verse sheet: it should be dark too. 2. Switch back to light: paper again, with nothing left dark. 3. Sign-off: does the paper tone feel right on the real screen (not too yellow)? 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Author
Collaborator

Phone check signed off. The owner did the checks in comment 2740 (live switch to dark and back, how the paper tone feels) and answered: "Looks good".

🤖 Generated with Claude Code

**Phone check signed off.** The owner did the checks in comment 2740 (live switch to dark and back, how the paper tone feels) and answered: "Looks good". 🤖 Generated with [Claude Code](https://claude.com/claude-code)
claude-review left a comment

Gate approval on 8fa2d52.

  • Medium: BottomSheet colour. Fixed in 8fa2d52 (sheet on colours.ground, 1px hairline under the header). The diff touches only BottomSheet.qml, SystemColours.qml and docs/10-design.md.
  • Medium: highlight role not drawn. Deferred to #142. The issue gives a valid reason: the reading pane has no selected-verse state yet. The owner has confirmed the phone try-out and said "Looks good".
  • Low findings: the unused roles are deferred to #142. The dark note-sheet shot is refuted, since the verse-sheet shot shows the same BottomSheet open in dark. The PR body Mockup section is fixed.
  • Commits after the last review round: only 8fa2d52, and it is read.
  • CI on head: all six jobs (changes, rust, audit, app, e2e, click) are success.
  • Proof: no unrun elevated, maximum or AI-behavior gate. The change is standard tier (UI colours and render output).
  • Audit risk, noted: the live light/dark switch on the real system-theme path was not exercised by the forced --dark shots. The owner's phone try-out covers it.
Gate approval on 8fa2d52. - Medium: BottomSheet colour. Fixed in 8fa2d52 (sheet on colours.ground, 1px hairline under the header). The diff touches only BottomSheet.qml, SystemColours.qml and docs/10-design.md. - Medium: highlight role not drawn. Deferred to #142. The issue gives a valid reason: the reading pane has no selected-verse state yet. The owner has confirmed the phone try-out and said "Looks good". - Low findings: the unused roles are deferred to #142. The dark note-sheet shot is refuted, since the verse-sheet shot shows the same BottomSheet open in dark. The PR body Mockup section is fixed. - Commits after the last review round: only 8fa2d52, and it is read. - CI on head: all six jobs (changes, rust, audit, app, e2e, click) are success. - Proof: no unrun elevated, maximum or AI-behavior gate. The change is standard tier (UI colours and render output). - Audit risk, noted: the live light/dark switch on the real system-theme path was not exercised by the forced --dark shots. The owner's phone try-out covers it.
claude-bot changed title from WIP: Design: Ink and lapis palette (paper light, warm dark) and docs/10-design.md (#95) to Design: Ink and lapis palette (paper light, warm dark) and docs/10-design.md (#95) 2026-10-30 19:07:57 +00:00
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!141
No description provided.