Context
Who: people checking a chronic condition several times a day, often at night. Jobs: see the current status, run a guided session, review a weekly report. Constraints: one hand, variable light, OS font scaling, two schemes that are both first-class. The system governs whole screens and states — component samples alone would hide how they meet on a phone.
Scenes
Pan the strip. Six screens run real scenarios: status, an immersive session, a report, a whole-screen empty state, onboarding, and a stacked sheet.
Leaving early is always allowed; the session is saved to history.
No sessions yet
A report needs at least three sessions. They take ten minutes and the first one counts tomorrow morning.
Three short sessions set your baseline
No account, no wearable. Everything stays on this phone unless you share it.
Typography and color
The system owns the face (SF Pro on iOS, Roboto on Android) and the app owns the scale. Color is two designed palettes with separate measurements — never one palette inverted.
Swatches follow the scheme switch above. Semantic colors (ok, warn, bad) follow the mode, never the scheme; chart colors are data, not decoration.
- Text scales with the OS to 2.0×; layouts reflow instead of truncating meaning.
- Weights carry hierarchy (700 title / 600 action / 400 body) — a second face is not the answer.
Components and states
Samples shrink to phone width rather than assuming a desktop canvas. States appear inline exactly where they occur.
Actions
All ≥ 48px tall; primary carries the accent, never two primaries.
Inline states
Inline placeholder for a chart inside a populated screen — different from the whole-screen empty state.
Rows and pills
Icon scale
Every inline SVG carries a default size and is overridden per context — 16/20/24/32/48/64.
Motion
| Token | Duration | Used for | Never |
|---|---|---|---|
| fast | 120 ms | state change, pressed feedback | data values |
| base | 200 ms | sheet and overlay entrance | scrolling content |
| slow | 320 ms | screen transitions, scene change | interruptions |
| breathe | 6 s loop | the guided breathing pace | anything not breathing |
- Discrete data changes discretely: a score, a count, a health state never tweens — it cuts.
- Motion is reserved for guidance and transitions, so the breathing guide stays the loudest thing on screen.
- Under
prefers-reduced-motiontransitions cross-fade, and the guide is a static ring.
Accessibility
Targets
Every control is at least 48×48 dp; primary actions sit in thumb reach. Toggle the annotations above to see the boxes.
Text scaling
System scaling to 2.0× with reflow, not truncation; the scenes above are the proof.
Not by color alone
Status is color + icon + word; the chart carries labels and a sentence, not only a hue.
Screen readers
Icon-only controls carry labels; overlays trap and restore focus; headings follow the reading order.
Contrast is measured per scheme in Verification — dark is not an inversion, so both tables must pass independently.
Ergonomics
Toggle annotations to see thumb targets and safe areas; switch type scale to stress the layout with OS font scaling.
- Status bar and home indicator are reserved bands; the bottom bar never overlaps them.
- Primary actions sit in thumb reach; destructive or rare actions stay out of it.
- At 2.0× the screens reflow: tiles wrap, labels truncate with an ellipsis, buttons grow — nothing clips.
- Motion budget: only the breathing guide animates, and it is static under
prefers-reduced-motion.
Verification
Live probes
Icon sizes, per-frame overflow, equal frame heights, and reduced-motion support are asserted on this page; resize the window to re-run the overflow probe.
Contrast, per scheme
| Pair | light | dark |
|---|
Both schemes are measured independently; dark is a designed palette, not an inversion of light.