Design system
Instrument at first light
The reference object is a precision measuring instrument — a barometer, a Braun weather station — not a hospital and not a fitness tracker. Neutral graphite surfaces, mono numerals that read like a readout, and saturated colour held back almost entirely for clinical state.
Every colour on this page is verified by tools/verify-contrast.mjs —
47 checks, 0 failures, all values inside sRGB gamut. Use the toggle above to inspect
both themes.
Colour
assets/css/tokens.cssStrategy is restrained. Surfaces carry chroma exactly 0 — the mood lives in the brand colour and the typography, never in a tinted background. No cream, no warm near-white.
Surfaces & ink
--ink-3 is permitted on real text, placeholders included.
Light grey “for elegance” is the single most common reason an interface becomes unreadable,
and this product’s users are over 50.
Clinical status ramp
Blue → sand → amber → orange → red. Deliberately no green. A green→red ramp is indistinguishable under protanopia and deuteranopia — roughly 8% of men, which is precisely the demographic that develops hypertension — and it collapses in greyscale. Running the scale along the blue↔orange axis survives both.
--brand is free to mean
you did the thing — streak, check-in complete, synced, adherent. It never
describes a blood-pressure value.
Typography
Instrument Sans · Azeret MonoTwo families on a real contrast axis — humanist sans against grotesk mono. Fixed rem scale at ratio ~1.2; product UI is viewed at consistent DPI, so a fluid heading that shrinks inside a sidebar looks worse, not better.
--fs-display128/79--fs-xxl · 32pxKnow what moves your numbers--fs-xl · 24pxYour personal drivers--fs-lg · 19pxThis morning--fs-md · 16pxBody text. The mobile floor — never smaller for prose.--fs-sm · 14pxSecondary text and table cells.--fs-xs · 12.5pxLabels, captions, badge text.Tabular figures mean a value changing from 98 to 102 doesn’t shove the layout around it — and a mono readout is the whole “instrument” concept in one element.
Space & radius
4px base--sp-1 · 4px--sp-2 · 8px--sp-3 · 12px--sp-4 · 16px--sp-6 · 24px--sp-7 · 32px--sp-9 · 48px--sp-10 · 64pxStatus & data
colour is never the only signalEvery state carries a glyph and a word alongside its colour, so a greyscale screenshot and a screen-reader description both still work.
Form controls
44px targets, no typing where a tap will doThe daily check-in has to close in under 60 seconds or the data stops arriving and the model starves. That budget is why chips, steppers and sliders carry the questionnaire and text inputs barely appear.
Surfaces
cards, rows, tables, empty & loadingUsed only where a card is genuinely the best affordance. Never nested.
4 of 7 readings logged. Two more mornings and your first insights unlock.
Charts
13 types · hand-rolled SVG · zero dependencies
Every chart carries role="img" and an aria-label summarising what it
shows. Line weights use vector-effect: non-scaling-stroke so they stay constant as
the viewBox scales.
Hover for the reading and its category.
Motion
custom curves only
ease-in never appears. It delays the initial movement — the exact moment the user
is watching — and makes an interface feel sluggish at identical duration.
--ease-outcubic-bezier(0.23, 1, 0.32, 1)entrances, exits--ease-in-outcubic-bezier(0.77, 0, 0.175, 1)on-screen movement--dur-press140msbutton feedback--dur-screen220msscreen change--dur-sheet280mssheets, drawersscale(0) — entrances start at 0.96 with opacity, because
nothing in the physical world appears from nothing. Screen changes use CSS transitions rather
than keyframes, so a rapid double-tap retargets instead of restarting.
prefers-reduced-motion drops every transform to a crossfade.
Accessibility
WCAG 2.1 AA floor, AAA on bodyA genuine requirement rather than a compliance box: the target user is over 50, often reading a small screen in a dim room before their first coffee.
- Body text ≥ 4.5:1; large text ≥ 3:1; placeholders held to the body threshold
- Touch targets ≥ 44×44px
- Visible 3px focus ring on every interactive element — tab through this page
- Every input has a
<label for>; icon-only buttons carryaria-label - Colour is never the sole carrier of meaning
- Charts expose a text summary to assistive technology
- Coloured side-stripe borders as accents
- Gradient text
- Glassmorphism as a default surface
- Tiny uppercase tracked eyebrows above every section
- Numbered section markers as default scaffolding
- Display fonts in UI labels, buttons or data
- Emoji standing in for icons
- Modal as the first thought
Icons
—
One hand-authored sprite at a single visual weight, injected once and referenced with
<use href="#i-name">. No icon library, no emoji.