Appearance Settings¶
The Settings tab lets a senior shape how every screen reads: a color theme (System, Light, or Dark), a text size (Large or Extra large), and a font (Sans-serif, Serif, or Monospace). The choices apply to every presentation of text in the app — screen content, buttons, captions, text inputs, tab bar labels, and navigation headers — and they are saved on the device, so the app opens the way it was left.
The choices¶
| Setting | Options | Default | What it does |
|---|---|---|---|
| Color theme | System, Light, Dark | System | Forces the light or dark palette, or follows the OS setting |
| Text size | Large, Extra large | Large | Extra large multiplies the whole type scale by 1.25 |
| Font | Sans-serif, Serif, Monospace | Sans-serif | Switches every text surface to a platform system font (Georgia and Menlo on iOS, serif and monospace on Android) |
Each font option's label is rendered in the font it selects, so the choice is visible before it is made.
Two deliberate compositions:
- Text size composes with OS font scaling. The multiplier applies to the
base type scale and Dynamic Type still applies on top; the app never sets
allowFontScaling={false}. - Video captions stay proportionally larger. The caption enlargement in the video quiz multiplies the chosen text size instead of replacing it.
How it works¶
- settings-storage.ts persists the three choices as one JSON value in AsyncStorage under a versioned key. Anything unreadable falls back to the defaults.
- appearance.tsx
provides
AppearanceProvider(mounted once in the root layout),useAppearance()for the values and persisting setters, anduseEffectiveColorScheme()— the user's theme, or the OS scheme while the theme is System. The provider holds back its children until the stored settings are in state, so launch never flashes the wrong theme before the load resolves. Without a provider the hooks serve the defaults, which is why existing tests can render screens bare. - typography.ts
holds the Daybreak tokens behind the feature:
fontSizeMultipliers,fontFamilies, andresolveTypeStyle(variant, fontSize, fontFamily). At the defaults it returns exactly the base type scale, so the standard look never drifts. ThemedTextresolves its style throughresolveTypeStyle, which is how the settings reach nearly all text. The exceptions are styled directly: the pattern-builderTextInput(including itskeyboardAppearance), video captions, tab bar labels (tabBarLabelStyle), and stack headers (headerTitleStyle,headerBackTitleStyle). Navigation text styles only set the keys that deviate from the platform defaults, so untouched settings render exactly the stock chrome.
Accessibility¶
- Each setting is a
radiogroupof large tap targets; every option is aradiowithaccessibilityState.checkedand a hint like "Sets color theme to Dark". - Selection is carried by a checkmark and the border, never by color alone.
- The option rows wrap, so every option stays reachable at the largest text settings.
- Both palettes carry measured contrast ratios (see colors.ts), and the theme override drives the navigation theme and status bar too, so chrome and content never disagree.