> ## 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.

# Semantic Colors

> Layer 2 — the 46 purpose-named tokens of DesignSystemColors, with the band grammar that governs them

Semantic colors define color **by purpose**, not by value. They live in [`tokens/semantic_colors.dart`](https://github.com/slingshot-ai/ash-mobile-app/blob/main/lib/design_system/tokens/semantic_colors.dart) as `DesignSystemColors`, a Flutter `ThemeExtension` with two static instances — `DesignSystemColors.light` and `DesignSystemColors.dark` — built from a single brightness factory so the modes cannot drift, installed by `AppTheme`, and read via `context.colorTheme`.

```dart theme={null}
final colors = context.colorTheme;

Text('Hello', style: TextStyle(color: colors.contentPrimary));
Container(color: colors.surfaceComponent);
```

## The grammar

Four rules govern every token below:

1. **Same step, same job.** Light and dark use the same scale position for the same role — optical relationships survive the mode switch.
2. **Containers set loudness; glyphs set legibility.** Surfaces are planes content sits on; content tokens guarantee contrast against the whole surface band they're legal on.
3. **Persistent states get tokens, transient states get ink.** Selection is a token (`stateSelected`); a press is an alpha ink composited over whatever it touches.
4. **Disabled is a collapse.** Container drops to step 5, content to step 8 — deliberately washy, WCAG-exempt.

## Surfaces

| Token | Step | Job |
| - | - | - |
| `surfaceBg` | 1 | The canvas |
| `surfaceSubtle` | 2 | Region tints, resting inputs — a tint, not a boundary |
| `surfaceComponent` | 3 | Bars, tracks, chips, bubbles |
| `surfaceComponentStrong` | 5 | Chips nested on components, notice banners |

## Solids & accent

| Token | Value | Job |
| - | - | - |
| `solidInverse` | step 12 | The full-span labeled primary (CTA discs, send) — pairs with `contentOnInverse` |
| `solidDefault` | step 9 | Toggles, sliders, meters, dots — never text |
| `solidSubtle` | step 8 | Inert small solids: grabbers, scroll indicators |
| `accentSolid` | lavender 9, invariant | Primary accent actions — a **pale** solid that takes **dark** content |
| `accentLine` | lavender-light 8 / lavender-dark 11 | Accent line work and small non-text graphics: selected outlines, checkboxes, progress — 3:1, never text |

## Content

| Token | Value | Job |
| - | - | - |
| `contentPrimary` | step 12 | Titles, values, body emphasis |
| `contentSecondary` | step 11 | Labels, helper text, UI icons — lowest AA-safe tier |
| `contentPlaceholder` | step 10 | Placeholder text only — below AA by design |
| `contentDisabled` | step 8 | Disabled labels — WCAG-exempt |
| `contentOnInverse` | step 1 | Content on `solidInverse` |
| `contentOnAccent` | brand black, invariant | Content on `accentSolid` — pure black in both modes |
| `contentAccent` | lavender-light 12 / lavender-dark 11 | Accent-colored text and selected glyphs |
| `contentOnBrand` | sand-light 12, invariant | Primary ink on light/pastel brand surfaces |
| `contentOnBrandSecondary` | light-alpha 11, invariant | Secondary ink on brand surfaces — an **alpha ink**, so the surface supplies the hue and one token harmonizes on every brand color (a solid grey fails AA on four of five). AA 4.91–5.63:1 across the brand set |
| `contentOnBrandDark` | sand-light 1, invariant | Ink on dark brand surfaces (black) |

## Borders

| Token | Value | Job |
| - | - | - |
| `borderSubtle` | step 6 | Separators, hairlines |
| `borderDefault` | step 7 | Inputs, outlined chips — quiet by design, no 3:1 promise |
| `borderStrong` | step 8 | Emphasized outlines |
| `borderSelected` | lavender-light 8 / lavender-dark 9 | Selection rings — holds ≥3:1 on the step-5 *selected* surface, not just the canvas |
| `focusRing` | same values as `borderSelected` | Where typing goes vs. what you chose — same values today, distinct meaning |
| `borderOnBrand` | dark alpha ink | Rings on brand surfaces |

## States, inks, overlay

| Token | Value | Job |
| - | - | - |
| `stateSelected` | step 5 | Selected surface state |
| `stateDisabledContainer` | step 5 | The disabled collapse — pair with `contentDisabled` |
| `inkPressed` | alpha 4, mode's own ink | The pressed state for surface-polarity fills — maps to `InkWell.highlightColor` |
| `inkPressedOnInverse` | alpha 4, opposite ink | Pressed ink for `solidInverse` and pale solids on dark — the mirror, same step |
| `overlayScrim` | light-alpha 11, invariant | Sheet/modal scrim — always-darkening ink |

## Brand surfaces

Mode-invariant spotlight planes, chosen per card: `surfaceBrandLavender`, `surfaceBrandGreen`, `surfaceBrandOrange`, `surfaceBrandYellow`, `surfaceBrandDarkBeige`, `surfaceBrandLightBeige`, `surfaceBrandWhite`, `surfaceBrandBlack`. Elements sitting on a mode-invariant surface must themselves be invariant — hence the pinned `contentOnBrand*` and `solidOnBrand` inks above.

## Status

Error and warning each carry four roles from the [cherry/amber stops](https://design.slingshotai.com/foundations/colors/reference.md#status-stops): `statusErrorContent` (600 light / 400 dark — AA on the whole surface band), `statusErrorSolid` and `statusErrorBorder` (500 both modes — ≥3:1 non-text), `statusErrorSurface` (100 light / 800 dark — banner tints that pair with status content, never neutral content). Same shape for `statusWarning*`.

> [!NOTE]
>
> Destructive fills borrow the inverse pattern: `statusErrorContent` as the fill with `surfaceBg` as its ink gives an AA pair in both modes (deep red + near-white in light; pale red + near-black in dark).

## Legacy names

The 1.0 names still compile as **forwarding getters** while call sites migrate — `contrastStrong → contentPrimary`, `contrastMedium → contentSecondary`, `contrastWeak → contentPlaceholder`, `surfaceElevated → surfaceComponent`, `surfaceHigh → surfaceComponentStrong`, `disabledContainer → stateDisabledContainer`, `badgeRed → statusErrorSolid`, `badgePurple → accentSolid`, `errorColor → statusErrorContent`, `warningColor → statusWarningContent`, and the `surfaceOpacity01–05` tiers pin to the light alpha scale in both modes (1.0 scrims are always dark ink). New code uses the 2.0 names; the getters are removed once migration completes.


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