Skip to main content
Sundial lives entirely in code, in the Ash mobile app repository at lib/design_system/. There is no separate token pipeline or generated theme — the Dart source is the single source of truth, and this documentation mirrors it.

The three-layer color model

Sundial’s color system is built in three layers. Each layer references the one below it, and app code should almost always consume the top layers.

Layer 1 — Reference

Primitive swatches. Raw material — avoid using directly in app code.

Layer 2 — Semantic

Purpose-named tokens that adapt to light/dark mode. Use these.

Layer 3 — Accent

Persona-driven accents, nested inside the semantic layer as colors.accent.

Delivery: Flutter ThemeExtensions

Sundial does not invent its own theming mechanism. It uses Flutter’s built-in ThemeExtension API — the idiomatic way to attach custom design tokens to a Material ThemeData: Both extensions are installed on every ThemeData built by AppTheme and read back through two BuildContext extension getters:
theme_extensions.dart
Because both extensions implement copyWith and lerp for every field, Flutter can animate theme changes — switching brightness or persona smoothly interpolates every token.
Why ThemeExtension and not an InheritedWidget or Riverpod provider? Tokens ride along with Theme, so any subtree can be re-themed with a plain Theme widget (see ThemeOverride), and all of Flutter’s theme plumbing — animation, inheritance, Theme.of scoping — works for free. The design system itself has no Riverpod dependency.

Directory layout

Everything is exported from the barrel file, so consuming code needs a single import:

Typography system

Typography is a flat set of 15 tokens — 5 categories × 3 sizes — using two typefaces: Libertinus Serif for display styles and Inter (a variable font) for everything else. Weights are applied via FontVariation.weight(...), which is how the body styles achieve their signature in-between weight of 425. See Typography.

What the theme layer adds

app_theme.dart turns the tokens into a complete ThemeData:
  • Styles every stock Material widget (buttons, inputs, chips, switches, sliders, dialogs, navigation bar…) with Sundial tokens, so even non-Styled* widgets look on-system — see Material bridge
  • Forces Cupertino page transitions on all platforms
  • Bridges tokens into Material’s ColorScheme and TextTheme for third-party widgets that read them
  • Installs the two ThemeExtensions
Entry points: AppTheme.light and AppTheme.dark — brightness is the only theme axis.