Skip to content

feat(reading): larger default text, a Text Size setting and fixed tab labels - #73

Merged
kazo0 merged 7 commits into
masterfrom
dev/sb/reading-text-size
Oct 12, 2026
Merged

kazo0 merged 7 commits into
masterfrom
dev/sb/reading-text-size

Conversation

@kazo0

@kazo0 kazo0 commented Oct 12, 2026 •

Copy link
Copy Markdown
Owner

Closes #70, closes #71. #69 stays open for its favorites half.

Why

Since the Uno port (4.0.x) the reading is set in Material's BodyMedium (14) with a HeadlineSmall title (24). The Xamarin app used iOS Body 17 / Title 28, so the body text got 18% smaller, and on iPad the #27 column cap turned it into a small block at the top of an empty screen. Every store review and issue since (#69, #70, #71) is about the small print. Reproduced in the iOS 27 simulator; the Text Size setting in iOS does reach the app (Uno's Skia host scales it), but only after a relaunch, and at the accessibility sizes the tab labels ran into each other ("ReflecticSober TiSettings").

The other tabs shrank the same way (compared against the 2020 Xamarin screenshots in images/ios): Sober Time's count and date 28 → 24, its tagline 22 italic → 14; the Settings rows 17 → 14 with 12 details. The nav bar title (17 → 22) and tab labels (10 → 12) grew and stay as they are.

What changes (spec 013)

  1. Reading sizes are the Xamarin app's again. DailyReflectionPage binds each FontSize to the model's TextScale through a ScaleConverter with the base as parameter: title 28, quote and thought 17, source line and copyright 13. The Material styles only supply family and weight now.
  2. New Settings → Readings → Text Size picker: Normal, Large, Extra Large, Huge (×1 / 1.2 / 1.4 / 1.65). Stored as ReadingTextSize (Normal = 0, so existing installs are unchanged) and sent as an EntityMessage<ReadingTextSizeSelection>, same shape as the secular toggle. The device text size still applies on top.
  3. The 720px column scales with the text, so the line length stays the same at every size.
  4. Tab labels no longer scale with the OS text size, like native iOS tab bars: each is an explicit TextBlock with IsTextScaleFactorEnabled="False". Not a ContentTemplate — Uno's ContentPresenter also binds it for the Icon presenter, which then showed the template instead of the icon (reproduced; see the comment in MainPage.xaml).
  5. Sober Time is back to 28 for the date and count and 22 italic for the tagline, and follows the Text Size setting: SobrietyTimeModel projects its own TextScale and the page binds the icon, date, count blocks and tagline through the same converter. ScaleConverter now treats a non-positive scale as unbound, because the generated view model exposes the feed as 0 before its first value and these TextBlocks (no FeedView) render before that.
  6. Settings rows are 17 with 15 for the value / description line through a page-scoped override of the Material BodyMediumFontSize / BodySmallFontSize tokens in SettingsPage.xaml (Uno Themes lightweight styling), which the SettingsRows.xaml templates pick up too. Page-scoped on purpose: app-wide it would resize the tab labels. Section headers stay 22; nothing is smaller than in 4.0.39.
  7. Uno.Fonts 2.10.0-dev.12 (ahead of the Sdk's 2.10.0-dev.9): the first Roboto with italic faces, so FontStyle="Italic" renders again on the Skia heads (the quote, the Sober Time tagline, the book title). Uno.Material only brings Roboto transitively, so the csproj references it directly and Directory.Packages.props pins it through UnoFontsVersion. Drop both once the Sdk catches up.
  8. The settings dropdowns are an elevated, outlined menu surface. The Material ComboBox popup is a flat Surface, the same brush as the filled cards, with no border or shadow, so an open menu merged with the rows under it (pre-existing on Sober Time Display; the new Text Size picker made it obvious). DRSettingsComboBoxStyle now wraps the list in an ElevatedView (the Toolkit card's elevation 6 / radius 12, translucent shadow) with the 1px OnSurfaceLow outline the picker presenters use, which carries the edge in dark theme.
  9. release_notes.txt rewritten for the next release (prepare-release refuses an unchanged file).

Verified

  • iOS 27 simulator, iPhone 16 Pro: Normal renders at 17/28 (matches the old app); forcing Huge through the preference store scales the whole reading and the column; at the largest accessibility text size the tab labels stay fixed and apart, icons intact, selected state intact.
  • Local WebAssembly build driven headlessly with Playwright at phone width: Sober Time shows the date and "5 Years / 3 Months / 28 Days" at 28 and the tagline at 22; with Huge stored, Sober Time and the Reflection tab rescale while the Settings rows (17/15) and the tab labels do not. Desktop width: the Settings rows are 17/15 and the side rail's labels are unchanged.
  • Web preview (pr-73, driven headlessly with Playwright): Settings shows "Text Size / Normal"; the picker lists Normal, Large, Extra Large, Huge; picking Huge updates the row and the Reflection tab rescales with a wider column — the full settings → reflection path through the real UI.
  • iPad Pro 11" simulator, Normal: the reading is 17pt in the column (was 14pt).
  • Installed and launched on a physical iPhone 14 (signed with the team profile).
  • iOS 27 simulator after the fonts bump: the quote and the book title render italic (they were upright before).
  • Settings dropdowns (web head, Playwright): Text Size and Sober Time Display open as a shadowed, outlined menu at phone width in light theme and at desktop width in dark theme.
  • 52 presentation + 58 services tests green; ViewSurfaceTests pins the six scaled reading FontSizes, the scaled MaxWidth, the eleven scaled Sober Time bindings, the two Settings token overrides (and their absence from App.xaml), the picker binding and the six fixed labels.

Notes for the merge

  • Which release? These users are on 4.0.39. Merging to master ships it with the v4.1 cut; backporting to release/v4.0 (after feat(stores): App Store and Play listing text (backport #63, #65, #67 → release/v4.0) #72) would ship it as 4.0.4x. Your call — note that this PR's release_notes.txt replaces the 4.0 "rebuilt" text, so a backport would carry the new notes too.
  • The FontSize bindings through ScaleConverter on styled TextBlocks are a stopgap: the sizes belong in the Material type-scale tokens (lightweight styling), but nothing re-resolves those after a runtime write. Kept as is pending DefaultFontScale: runtime-settable root token for the type scale, exposed through SemanticThemeHelper unoplatform/Uno.Themes#1758 (a runtime-settable DefaultFontScale through SemanticThemeHelper); when that ships, the bindings become page-scoped token overrides.
  • The Text Size picker sits under the Readings header but now drives Sober Time as well. Renaming or moving it is a product call; not done here.
  • The Sober Time tagline is an unstyled TextBlock, so it takes the Material body typeface (medium weight) and reads heavier than the HeadlineSmall count above it; the old one was regular italic. Pre-existing; one FontWeight attribute if you want it regular. (The upright italic is fixed by the fonts bump above.)
  • The known desktop compositor issue (stale rendering after a tab switch, AGENTS.md) reproduces with this setting as with the secular toggle: change the size, return to Reflection, overlap until the window resizes. Not new.
  • On iOS a Text Size change in the system Settings only applies after the app is relaunched (framework behaviour on the Skia host). Not addressed here.

🤖 Generated with Claude Code

https://claude.ai/code/session_01DxndQ1L7ruaSHzi9voExNb

kazo0 and others added 2 commits October 12, 2026 10:05
… labels (spec 013)

Since the Uno port the reading was set in Material's BodyMedium (14) with a
HeadlineSmall title (24); the Xamarin app used iOS Body 17 / Title 28. Every
store review and issue since has been about the small print, and on iPad the
#27 column cap made it a small block at the top of an empty screen.

- DailyReflectionPage sizes its text from the Xamarin bases (28 / 17 / 13)
  times the model's TextScale through a ScaleConverter; the 720 column scales
  the same way so the line length stays put. The OS text size still applies
  on top (verified in the iOS simulator; it needs a relaunch).
- Settings > Readings gets a Text Size picker (Normal, Large, Extra Large,
  Huge), persisted as ReadingTextSize and sent to the Reflection tab as an
  EntityMessage<ReadingTextSizeSelection>, like the secular toggle.
- Tab labels opt out of the OS text scale as explicit TextBlock content, so
  they no longer run into each other at the accessibility sizes. Not a
  ContentTemplate: Uno's ContentPresenter applies it to the Icon presenter
  too, which then rendered the label template instead of the icon.
- release_notes.txt rewritten for the next release.

Closes #70, closes #71. #69 stays open for the favorites half.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DxndQ1L7ruaSHzi9voExNb
At Normal the column is still 720px; it only widens with a larger Text Size.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DxndQ1L7ruaSHzi9voExNb
@github-actions

github-actions Bot commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

🌐 Web preview deployed

https://pr-73.dailyreflection.pages.dev

Built from 2f40d96. Updates on every push.

kazo0 and others added 4 commits October 12, 2026 12:38
…ec 013 §D)

The other tabs had shrunk the same way as the reading (compared against the
2020 screenshots in images/ios): the Sober Time count and date went from 28
to HeadlineSmall 24 and the tagline from 22 italic to the unstyled 14; the
Settings rows from the iOS cells' 17 to BodyMedium 14 / BodySmall 12.

- SobrietyTimeModel projects the Text Size setting into its own TextScale,
  like DailyReflectionModel; the page binds the icon, date and count from 28
  and the tagline from 22 through ScaleConverter (no FeedView, so no Parent.).
- ScaleConverter treats a non-positive scale as unbound: the generated view
  model exposes the feed as 0 before its first value and these TextBlocks
  render before that.
- SettingsPage overrides BodyMediumFontSize (17) and BodySmallFontSize (15)
  in Page.Resources (Uno Themes lightweight styling), which also reaches the
  SettingsRows.xaml templates; page-scoped so the tab labels and the other
  pages keep the theme's sizes. Section headers, nav bar and tabs unchanged.
- Tests: SobrietyTimeModelTests (scale is 1 by default, follows the setting),
  ViewSurfaceTests pins the eleven scaled bindings, the two overrides and
  their absence from App.xaml.
- Spec 013 §D, AGENTS.md, release notes.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DxndQ1L7ruaSHzi9voExNb
…ot back to

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DxndQ1L7ruaSHzi9voExNb
FontStyle="Italic" (the reading's quote, the Sober Time tagline, the book
title in the copyright) rendered upright on the Skia heads: the Roboto the
Sdk pins (2.10.0-dev.9) ships no italic files. 2.10.0-dev.12 adds them.
Uno.Material only brings Roboto transitively, so the csproj references it
directly and Directory.Packages.props pins it through UnoFontsVersion
(central package management needs the PackageVersion entry).

Verified in the iOS 27 simulator: quote and book title italic.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DxndQ1L7ruaSHzi9voExNb
The Material ComboBox popup is a flat Surface — the same brush as the
filled cards and the page — with no border or shadow, so an open menu
was indistinguishable from the rows under it. Pre-existing on the Sober
Time Display row; the Text Size picker added in this PR made it obvious
(iPad, Steve's screenshot).

DRSettingsComboBoxStyle now builds the dropdown as an MD menu surface:
an Uno.UI.Toolkit ElevatedView with the Toolkit card's elevation (6)
and corner radius (12), a translucent shadow, and the 1px OnSurfaceLow
outline the picker presenters already use, which is what carries the
edge in dark theme. PopupBorder stays the Popup's direct child (Uno
sizes it to the ComboBox) and is transparent; the ElevatedView owns the
background, since a null one draws no shadow.

Verified on the web head at phone width (light) and desktop width
(dark) for both the Text Size and Sober Time Display menus; the
simulator build for the iPad Pro 11" is updated. 58 services tests
pass (no ViewSurfaceTests pin this template).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DxndQ1L7ruaSHzi9voExNb
Steve's call on the device: the "— TWELVE STEPS AND TWELVE TRADITIONS,
p. 91" line under the quote read too heavy at the body size. It now
scales from 13, the same base as the copyright block, so it sits under
the quote the way a caption does. Still through ScaleConverter, so the
Text Size setting applies. Test pin, spec 013 and the page header
comment follow.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DxndQ1L7ruaSHzi9voExNb
@kazo0

kazo0 commented Oct 12, 2026

Copy link
Copy Markdown
Owner Author

/steve-ops backport release/v4.0

@kazo0
kazo0 merged commit 2b1a982 into master Oct 12, 2026
10 checks passed
@kazo0
kazo0 deleted the dev/sb/reading-text-size branch October 12, 2026 23:43
@steve-ops-bot

steve-ops-bot Bot commented Oct 12, 2026

Copy link
Copy Markdown
Contributor

✅ Backport to release/v4.0 opened as #76.

kazo0 added a commit that referenced this pull request Oct 13, 2026
… labels (backport #73 → release/v4.0) (#76)

* feat(reading): larger default text, a Text Size setting and fixed tab labels (spec 013)

Since the Uno port the reading was set in Material's BodyMedium (14) with a
HeadlineSmall title (24); the Xamarin app used iOS Body 17 / Title 28. Every
store review and issue since has been about the small print, and on iPad the
#27 column cap made it a small block at the top of an empty screen.

- DailyReflectionPage sizes its text from the Xamarin bases (28 / 17 / 13)
  times the model's TextScale through a ScaleConverter; the 720 column scales
  the same way so the line length stays put. The OS text size still applies
  on top (verified in the iOS simulator; it needs a relaunch).
- Settings > Readings gets a Text Size picker (Normal, Large, Extra Large,
  Huge), persisted as ReadingTextSize and sent to the Reflection tab as an
  EntityMessage<ReadingTextSizeSelection>, like the secular toggle.
- Tab labels opt out of the OS text scale as explicit TextBlock content, so
  they no longer run into each other at the accessibility sizes. Not a
  ContentTemplate: Uno's ContentPresenter applies it to the Icon presenter
  too, which then rendered the label template instead of the icon.
- release_notes.txt rewritten for the next release.

Closes #70, closes #71. #69 stays open for the favorites half.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DxndQ1L7ruaSHzi9voExNb
(cherry picked from commit 5f0eba1)

* docs(release): say what the Text Size change does to the column

At Normal the column is still 720px; it only widens with a larger Text Size.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DxndQ1L7ruaSHzi9voExNb
(cherry picked from commit 99129aa)

* feat(text-size): Xamarin-era sizes on Sober Time and Settings too (spec 013 §D)

The other tabs had shrunk the same way as the reading (compared against the
2020 screenshots in images/ios): the Sober Time count and date went from 28
to HeadlineSmall 24 and the tagline from 22 italic to the unstyled 14; the
Settings rows from the iOS cells' 17 to BodyMedium 14 / BodySmall 12.

- SobrietyTimeModel projects the Text Size setting into its own TextScale,
  like DailyReflectionModel; the page binds the icon, date and count from 28
  and the tagline from 22 through ScaleConverter (no FeedView, so no Parent.).
- ScaleConverter treats a non-positive scale as unbound: the generated view
  model exposes the feed as 0 before its first value and these TextBlocks
  render before that.
- SettingsPage overrides BodyMediumFontSize (17) and BodySmallFontSize (15)
  in Page.Resources (Uno Themes lightweight styling), which also reaches the
  SettingsRows.xaml templates; page-scoped so the tab labels and the other
  pages keep the theme's sizes. Section headers, nav bar and tabs unchanged.
- Tests: SobrietyTimeModelTests (scale is 1 by default, follows the setting),
  ViewSurfaceTests pins the eleven scaled bindings, the two overrides and
  their absence from App.xaml.
- Spec 013 §D, AGENTS.md, release notes.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DxndQ1L7ruaSHzi9voExNb
(cherry picked from commit c1d01d4)

* docs(release): the Settings detail line is 15, so say larger again, not back to

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DxndQ1L7ruaSHzi9voExNb
(cherry picked from commit 1006b21)

* build(fonts): Uno.Fonts 2.10.0-dev.12 — Roboto with italic faces

FontStyle="Italic" (the reading's quote, the Sober Time tagline, the book
title in the copyright) rendered upright on the Skia heads: the Roboto the
Sdk pins (2.10.0-dev.9) ships no italic files. 2.10.0-dev.12 adds them.
Uno.Material only brings Roboto transitively, so the csproj references it
directly and Directory.Packages.props pins it through UnoFontsVersion
(central package management needs the PackageVersion entry).

Verified in the iOS 27 simulator: quote and book title italic.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DxndQ1L7ruaSHzi9voExNb
(cherry picked from commit c73571e)

* fix(settings): elevated, outlined dropdown for the settings ComboBoxes

The Material ComboBox popup is a flat Surface — the same brush as the
filled cards and the page — with no border or shadow, so an open menu
was indistinguishable from the rows under it. Pre-existing on the Sober
Time Display row; the Text Size picker added in this PR made it obvious
(iPad, Steve's screenshot).

DRSettingsComboBoxStyle now builds the dropdown as an MD menu surface:
an Uno.UI.Toolkit ElevatedView with the Toolkit card's elevation (6)
and corner radius (12), a translucent shadow, and the 1px OnSurfaceLow
outline the picker presenters already use, which is what carries the
edge in dark theme. PopupBorder stays the Popup's direct child (Uno
sizes it to the ComboBox) and is transparent; the ElevatedView owns the
background, since a null one draws no shadow.

Verified on the web head at phone width (light) and desktop width
(dark) for both the Text Size and Sober Time Display menus; the
simulator build for the iPad Pro 11" is updated. 58 services tests
pass (no ViewSurfaceTests pin this template).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DxndQ1L7ruaSHzi9voExNb
(cherry picked from commit c8253b1)

* feat(reading): the quote source line at the caption size (13)

Steve's call on the device: the "— TWELVE STEPS AND TWELVE TRADITIONS,
p. 91" line under the quote read too heavy at the body size. It now
scales from 13, the same base as the copyright block, so it sits under
the quote the way a caption does. Still through ScaleConverter, so the
Text Size setting applies. Test pin, spec 013 and the page header
comment follow.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DxndQ1L7ruaSHzi9voExNb
(cherry picked from commit 2f40d96)

---------

Co-authored-by: Steve Bilogan <steve.bilogan@gmail.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Text size Size of print

1 participant