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

# Robustness & Readability

> Design rationale: line length, accessible contrast, content overflow, and alignment — where generated UIs fail

These rules target the places where UIs — especially generated ones — consistently fail with real content and real users.

## Respect line length

Body text sits between **45–75 characters per line**; the sweet spot is 60–70. Under 40, the eye develops a jittery rhythm; over 80, it loses its place on the return sweep. This is a documented perceptual constraint, not an aesthetic preference.

Watch for the classic failures: full-width card descriptions, hero subtitles spanning the viewport, helper text stretching under a wide form. Give prose its own max-width, independent of its container. Longer lines also need more generous line height — see [Typography](https://design.slingshotai.com/philosophy/craft/typography.md) for the pairing table.

## Never sacrifice accessibility for hierarchy

De-emphasis (lighter, muted text) taken too far produces text real humans can't read.

| Text type | WCAG AA minimum |
| - | - |
| Normal text (under 18px, or under 14px bold) | **4.5:1** |
| Large text (18px+, or 14px+ bold) | **3:1** |
| Non-text UI (icons, borders, focus rings) | **3:1** |

Your “tertiary” color is the lightest color that *still passes 4.5:1* at body sizes. When in doubt, err toward slightly too much contrast: a secondary color that's a touch dark still reads as secondary through size and weight; a color that fails contrast is actively harmful.

Rules of thumb:

* Never use color as the **only** differentiator — vary size or weight too.
* Test the extremes: lightest text on lightest background is the most dangerous pair. In Sundial terms: verify `contrastWeak` on `surfaceBg` in **both** brightness modes before using it for anything that must be read.
* Dark mode reverses the math but not the ratios — light-on-dark still needs 4.5:1.
* Placeholder text usually fails by default; ensure contrast or don't rely on it for essential information.

## Design for content overflow and edge cases

Sample data is always perfectly sized; real data never is.

* **Truncate supplementary content, wrap primary content.** Single-line ellipsis for names in constrained spaces; 2–3-line clamping for previews; never truncate an error message. (Sundial components use `AutoSizeText` with `maxLines` + ellipsis — see [StyledListTile](https://design.slingshotai.com/components/styled-list-tile.md).)
* **Empty states are mandatory.** Every list, table, or feed will eventually be empty. Each empty state needs: what would be here, why it's empty, and an action to resolve it.
* **Stress-test the extremes** before calling a layout done:

| Scenario | Check |
| - | - |
| Very long text (40+ char name) | Overflow? Pushes elements off-screen? |
| Very short text (1 char) | Component collapse? Alignment break? |
| Empty / null content | Blank void? Layout collapse? |
| 1 item in a list | Still looks intentional? No “showing 1 of 1” noise? |
| 100+ items | Pagination or lazy loading? |
| Very large numbers | Column overflow? Abbreviate? |
| User-generated content | Sanitized? URLs and line breaks handled? |

When writing sample data, include at least one stress-test data point — it forces edge-case handling during the build, not after.

## Maintain alignment consistency

Center-aligning everything produces a wedding invitation: decorative, impossible to scan. The eye scans by returning to a consistent starting edge — left-aligned text creates that edge.

| Content | Alignment |
| - | - |
| Body text, paragraphs, lists, form labels | Left |
| Table text / table numbers | Left / **right, tabular figures** |
| Short hero text, empty states | Center acceptable |
| Card content | Left internally — even when the card is centered |

**Pick an edge and stick to it** within any section. And the key distinction: **center the container, left-align the content within it.**


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