Skip to main content
app_theme.dart is where tokens become a Flutter theme. A single private builder produces every theme the app uses:
Brightness is the only axis — the persona palette parameter was retired with Sundial 2.0.

Build sequence

1

Pick base tokens

DesignSystemTypography.base (colorless metrics) and DesignSystemColors.light or .dark by brightness.
2

Resolve the accent

AccentColors.lavenderLight or .lavenderDark by brightness — the single lavender accent, nested into the color tokens.
3

Style every Material component

Buttons, inputs, chips, menus, switch, slider, bottom sheet, divider, dialog, navigation bar, drawer, text selection — all wired to tokens. See Material bridge.
4

Install the ThemeExtensions

extensions: [colorThemeExtension, DesignSystemTypography.light|dark] — what context.colorTheme / context.textTheme read.

App wiring

MaterialApp is configured in lib/main.dart:
main.dart
Flutter selects theme or darkTheme from the platform brightness; every token, component theme, and extension flips with it.

Global behaviors baked into the theme

Cupertino transitions everywhere

Every Navigator.push slides in from the right, iOS-style, on Android too — one consistent motion language.

Consistent back icon

actionIconTheme forces Icons.arrow_back as the back button icon on all platforms.

Scaffold background

scaffoldBackgroundColor: colorTheme.surfaceBg — screens start on the correct surface without any per-screen setup.

Notable component wiring

A few representative mappings (the full set is in Material bridge):

Theme instances are cached

AppTheme.light/.dark are static final — built once, pure functions of tokens. Either is safe to install anywhere — which is exactly what ThemeOverride does per subtree. Note the static-final consequence: token edits need a full restart, not a hot reload.