> ## Documentation Index
> Fetch the complete documentation index at: https://design.slingshotai.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> This site documents Sundial 2.0, the design system of the Ash mobile app (Flutter). For implementing UI: use the Design System pages — color/typography tokens (foundations/*), Flutter theming (theming/*), and component APIs (components/*) — as your reference; every value there mirrors the Dart source in lib/design_system/. The Philosophy pages (philosophy/*) are design rationale written for humans: consult them when making design decisions, not for API lookups. Golden rules: never hardcode colors or text styles — read tokens via context.colorTheme and context.textTheme; prefer the 2.0 semantic names (contentPrimary, surfaceComponent, accentSolid…) over legacy contrast*/surface* getters and over SundialRef primitives; the accent is a single pale lavender solid that takes dark content — never use accent fills as text, icons, or borders (use contentAccent / borderSelected); brand surfaces are mode-invariant and pair with the contentOnBrand* inks; check lib/design_system/components/ before building custom widgets.

# ThemeExtensions & Context Accessors

> How tokens ride on ThemeData and why theme changes animate for free

Sundial delivers tokens through Flutter's `ThemeExtension` API — the platform-native way to attach custom data to a `ThemeData`.

## The two extensions

| Extension | Contents | Static instances |
| - | - | - |
| `DesignSystemColors` | 25 semantic color tokens (incl. nested `AccentColors`) | `.light`, `.dark` |
| `DesignSystemTypography` | 15 text styles | `.base` (colorless), `.light`, `.dark` |

Both are installed by `AppTheme`:

```dart theme={null}
extensions: brightness == Brightness.dark
    ? [colorThemeExtension, DesignSystemTypography.dark]
    : [colorThemeExtension, DesignSystemTypography.light],
```

## Context accessors

[`theme_extensions.dart`](https://github.com/slingshot-ai/ash-mobile-app/blob/main/lib/design_system/theme_extensions.dart) provides the two getters used throughout the app:

```dart theme={null}
extension ThemeExtensions on BuildContext {
  DesignSystemColors get colorTheme =>
      Theme.of(this).extension<DesignSystemColors>()!;

  DesignSystemTypography get textTheme =>
      Theme.of(this).extension<DesignSystemTypography>()!;
}
```

Two properties worth noting:

* **They resolve against the nearest `Theme`** — inside a [ThemeOverride](https://design.slingshotai.com/components/theme-override.md) subtree you get the overridden tokens, not the app-level ones.
* **They are non-null asserted (`!`)** — any `Theme` a Sundial widget lives under must carry both extensions. In practice that means themes must come from `AppTheme.*`; a bare `ThemeData()` would crash token consumers. When overriding a subtree theme, always go through `AppTheme.light`/`.dark` or `ThemeOverride`.

> [!WARNING]
>
> Don't confuse `context.textTheme` (Sundial's extension getter returning `DesignSystemTypography`) with Flutter's `Theme.of(context).textTheme` (Material's `TextTheme`). The names are close; the types differ.

## Why copyWith and lerp matter

Every `ThemeExtension` subclass must implement `copyWith` and `lerp`. Sundial implements both **for every field** (all 25 colors, all 15 text styles, and the 5 accent fields):

* **`copyWith`** is how `AppTheme` nests the resolved accent: `baseColorTheme.copyWith(accent: accent)`.
* **`lerp`** is what makes theme changes **animate**. When `ThemeData` changes (brightness flip, persona change, `ThemeOverride` boundary), Flutter's `AnimatedTheme` interpolates between old and new extensions — every color cross-fades and every text style transitions smoothly, with zero widget-level work.

```dart theme={null}
// From DesignSystemColors.lerp — every token interpolates
return DesignSystemColors(
  contrastWeak: Color.lerp(contrastWeak, other.contrastWeak, t)!,
  // … 24 more fields …
  accent: accent.lerp(other.accent, t),   // nested extension lerps too
);
```

## Adding a token (checklist)

Adding a field to either extension means updating **four places** in the token file — the field, the constructor, `copyWith`, and `lerp` — plus the `.light`/`.dark` (or `.base`) instances. Missing `lerp` won't fail to compile for nullable fields, so review carefully; a token that doesn't lerp will snap during animated theme changes. See [Contributing](https://design.slingshotai.com/patterns/contributing.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.