Design guide

Based on Apple's Human Interface Guidelines (developer.apple.com/design), adapted for our users: field staff on mid- and low-end Android phones, often outdoors in strong sunlight, often on weak signal. The Payments screen is the reference implementation; building blocks live in src/ui/grouped.js.

Principles

  1. Content first. The interface steps back: no decorative borders, shadows or boxes around everything. Names, amounts and status lead.
  2. Clear hierarchy. One large title per screen, grouped sections with small uppercase headers, quiet secondary text. A screen should read top to bottom without hunting.
  3. Consistency. The same row, sheet, button and icon style everywhere, so learning one screen teaches the rest.
  4. Respect the platform. Borrow Apple's polish, keep Android's behaviour.
  5. Our users' words, not designers' words. Say exactly what the person does, in the team's own vocabulary: "Choose dealer", not "Who paid?"; "Policy", not "Scheme". If a field is needed, the label says so ("required") — an unfamiliar or optional-looking label gets skipped.
  6. Optional second language beside English where it helps: section headers, the main action button, the screen's one-line purpose, and error messages. Turn it on with secondaryLanguage in config/brand.json; strings are wrapped with ur() / SHOW_SECOND_LANG from src/config. English stays first; the second language is a second line, never a replacement. The urdu text style in src/ui/grouped.js is the second-language style (it uses the system font, sized ~3 pt larger for right-to-left scripts).

Type — Inter

Inter is the open-licence face closest to SF Pro (SF Pro itself may only be used on Apple platforms). Loaded in App.js, four weights only.

Style Size / line Weight Use
text.largeTitle 34 / 41 Bold Screen title (collapses on scroll)
text.title 22 / 28 Bold Big numbers, sheet titles
text.headline 17 / 22 SemiBold Bar titles, emphasis
text.body 17 / 22 Regular Row labels and values
text.subhead 15 / 20 Regular Secondary lines
text.footnote 13 / 18 Regular Section headers (uppercase), footers
text.caption 12 / 16 Regular Small labels under a value

Android ignores fontWeight with a custom font, so use font.regular / medium / semibold / bold (separate faces), never fontWeight.

Colour

Token Value Use
g.bg #F2F2F7 Screen background behind groups
g.cell #FFFFFF Group rows
g.label near-black Primary text
g.secondary grey 72% Values, footers (≈5.4:1 — readable outdoors)
g.tertiary grey 45% Placeholders, chevrons
g.tint #0369A1 (our accent) Actions, links, selected state
g.danger / success / warning system-style red / green / orange Status only

Apple's own blue (#007AFF) is only ~4:1 on white — too faint in sunlight — so we keep our darker accent as the tint. Icon tiles may use the iOS system hues (indigo, green, orange) because the glyph on them is white.

Layout

Motion and feedback

Short, purposeful, ease-out; everything goes instant with Reduce motion (src/ui/motion.js). Light haptics on selection, success haptic + sound on a saved payment.

What we deliberately don't copy