Skip to content

Mota — Interface Design

SDLC phase: Design (Chapter 4.6)
Purpose: Screen inventory, key journeys, input/output design, and security design.

Design thesis: the product's only real feature is persistence without effort. Every screen is judged against one question: does this make the record easier to keep? A beautiful screen that adds a tap to logging is a worse screen.


1. Screen inventory — consumer app

# Screen Purpose Priority
S1 Onboarding / phone OTP Get in with one field M
S2 Add vehicle Capture make/model/year/odometer M
S3 Home (dashboard) What's due, what's next, one action M
S4 Log service Fast capture, ≤4 taps M
S5 Log fill-up Even faster than service M
S6 Vehicle timeline History, chronological M
S7 Record detail Single event, edit/delete M
S8 Service history PDF preview The shareable artefact M
S9 Garage directory Browse, filter, call M
S10 Garage detail Services, prices, contact M
S11 Booking request Convert intent to lead M
S12 Reminder inbox All notifications, actionable M
S13 Price index search "What should this cost?" M
S14 Settings / privacy / delete account Compliance M
S15 Cost summary Spend, cost/km S
S16 Multiple vehicles switcher S
S17 Garage console Web app, separate surface M

2. Home screen — the one that decides retention

This is where 80% of sessions start and most end. It must answer one question in under two seconds: "is anything wrong with my car right now?"

┌─────────────────────────────────────┐
│  Honda Fit · 78,400 km       [▾]    │  ← vehicle switcher, odometer prominent
├─────────────────────────────────────┤
│  ⚠  1 item needs attention          │  ← state-driven banner
│                                     │
│  CVT fluid                          │
│  2,800 km to go · due at 81,200 km  │  ← the reason (FR-DUE-06)
│  Based on your records              │
│                                     │
│              [ Find a garage → ]    │  ← revenue CTA, only when due
├─────────────────────────────────────┤
│  Next up                            │
│  ○ Engine oil     4,100 km          │
│  ○ ZINARA licence 62 days           │
│  ○ Insurance      88 days           │
├─────────────────────────────────────┤
│  [ + Log ]  [ Fuel ]  [ History ]   │  ← primary actions, thumb zone
└─────────────────────────────────────┘

Rules baked into this layout:

Rule Reason
Odometer is displayed, not buried If the number isn't visible, users don't notice it's stale
One primary CTA, not a grid of six Decision fatigue kills logging apps
Every due item explains itself Trust; a bare "service due" is indistinguishable from noise
Actions in the bottom 40% One-handed use (NFR-USE-05)
Nothing loads on the home screen that isn't cached Offline cold start (NFR-COMP-04)

3. Log service — the 30-second requirement

The single most important interaction. Budget: ≤4 taps, ≤30 seconds, works offline.

Step 1 — What did you do?
┌─────────────────────────────────────┐
│  What did you do?                   │
│                                     │
│  [Engine oil]  [CVT fluid]          │  ← chips from reference data,
│  [Brakes]      [Tyres]              │    not a blank text field
│  [Service]     [Other]              │
│                                     │
│  Date: [Today          ▾]           │  ← pre-filled
│  Odometer: [78,400      ]           │  ← pre-filled from last known + estimate
│                                     │
│            [ Continue ]             │
└─────────────────────────────────────┘

Step 2 — Cost (optional but nudged)
┌─────────────────────────────────────┐
│  How much?                          │
│                                     │
│  US$ [ 145        ]                 │  ← numeric keypad, USD default
│                                     │
│  Garage: [ Select (optional)     ▾] │
│                                     │
│  [ Skip ]              [ Save ]     │
└─────────────────────────────────────┘

Why chips and not free text: free text ("oil change", "changed oil", "oil") creates garbage data and makes interval completion detection unreliable. Chips map directly to service_keys. "Other" opens free text but is measured — if it exceeds 30% of entries, the chip list is wrong.

Why pre-fill aggressively: every empty field is a reason to abandon. A wrong pre-filled value is corrected in one tap; an empty field requires thought.


4. The service history PDF — the growth engine

This is the marketing artefact. It is the thing that gets shown to a buyer, a friend, or a WhatsApp group. It must look credible enough to be believed by a stranger.

┌──────────────────────────────────────────┐
│  VEHICLE SERVICE RECORD                  │
│  ─────────────────────────────────────   │
│  Honda Fit 2014 · ABC 1234               │
│  Record maintained by: T. Moyo           │
│  Generated: 10 Nov 2026                  │
│                                          │
│  SUMMARY                                 │
│  Records: 14    Period: Mar 2023 – Nov 2026│
│  Total spend: US$1,847                   │
│  Distance: 41,200 → 78,400 km (37,200 km)│
│  Cost per km: US$0.05                    │
│                                          │
│  HISTORY                                 │
│  2026-10-28  72,100 km  Engine oil     US$85 │
│  2026-08-14  68,900 km  Fuel (38L)     US$61 │
│  ...                                     │
│                                          │
│  [QR]  Verify at mota.co.zw/v/8f3a2      │
│  ─────────────────────────────────────   │
│  Generated by Mota · Records are          │
│  self-reported and not independently     │
│  verified.                               │
└──────────────────────────────────────────┘

Design decisions that matter here:

Decision Reason
Includes a "self-reported, not verified" disclaimer Honesty is the product. An overclaiming PDF destroys credibility with the exact buyer we want to impress
QR verification link (FR-HIS-04) Turns a static document into a verifiable artifact. Even a simple "this record exists and was created on date X" raises trust substantially
Cost per km is headline data It is the single most useful number for a buyer and nobody else computes it
Footer branding with the product name This is a marketing channel, not just an export

5. Garage console

Different user, different constraints: mobile-first, ≤10 minutes to set up, no training.

Screen Purpose
G1 Registration + listing (services, location, contact)
G2 Lead inbox — sorted by recency, unread highlighted
G3 Lead detail — vehicle, service requested, contact (only if released), status buttons
G4 Price submission — category, amount, one screen per item
G5 Invoice — leads, subscription, total, pay via Paynow or record cash
G6 Profile / listing management

The lead inbox is the whole product from the garage's side. If a garage doesn't see value in 60 seconds there, no amount of pricing, features, or onboarding will retain them.

┌─────────────────────────────────────┐
│  Leads                    [Inbox 3] │
├─────────────────────────────────────┤
│  ● NEW   Honda Fit · CVT fluid      │
│          Tino M. · 2 hours ago      │
│          [ Call ]  [ Booked ] [ No ]│
├─────────────────────────────────────┤
│  ● BOOKED  Toyota Wish · Brakes     │
│           Yesterday · US$3.00       │
└─────────────────────────────────────┘

6. Input design

Principles applied across every form:

Principle Implementation
Pre-fill everything knowable Date = today; odometer = last known + estimated usage; currency = USD
Chips over free text for structured data Maps to service_keys; keeps data clean
Only two mandatory fields per record date + type. Everything else is optional and nudgeable
Numeric keypads for numeric fields One fewer tap, one fewer error
No multi-step wizards for logging Wizards are for onboarding, not for daily actions
Save on blur, not on submit If the user backgrounds the app mid-form, nothing is lost
Undo instead of confirmation dialogs A 5-second undo toast beats a "are you sure?" modal

Anti-patterns explicitly rejected:

  • Required field asterisks everywhere (creates a wall)
  • Dropdowns for things that should be chips (extra tap for both parties)
  • Date pickers for "today" (which is 80% of use)
  • Currency selectors (USD is the default; ZiG is a display conversion)

7. Output design

The product has three output surfaces, and all three matter:

Output Purpose Requirement
In-app dashboard Daily check Answers "is anything wrong?" without scrolling
Push notification The reminder Must contain the reason and the action, not just "you have a notification"
WhatsApp message / PDF Post-session artefact Everything that must survive outside the app

Push notification copy — a worked example:

❌ BAD:  "Mota: You have a reminder"
❌ BAD:  "Service due"

✅ GOOD: "CVT fluid due in 900km — 3 garages in Harare can do it"

The notification must be actionable on its own. A notification that requires opening the app to understand is a notification the user will disable.


8. Security design

Authentication

Actor Method Notes
Consumer Phone OTP via Supabase Auth No passwords. Password reset flows are a support burden and a security liability in a low-trust market
Garage Email + password (console) Desktop-ish usage; MFA optional in v1
Admin Email + password + MFA Required — this role can read all data

Authorisation

Enforced in Postgres via RLS (06-data-design.md §3), not in the client. The client is treated as hostile.

The PII boundary

The single most sensitive design decision: a consumer's phone number is not exposed to garages unless and until the consumer requests a booking.

State Garage sees
Directory browse only Garage name, location, services. No user data at all.
User viewed garage detail Nothing (no tracking of users by garage)
User requested booking Vehicle, service, first name, phone — released and timestamped
Lead marked booked Same as above

This prevents the directory from becoming a harvesting tool for phone numbers, which would destroy user trust on first contact.

Payment security

  • No card or wallet credentials stored, ever.
  • Paynow handles the full payment flow; we store only the transaction reference and status.
  • Webhooks are signature-verified and idempotent.
  • Cash payments are recorded as an explicit state with an audit trail — never inferred.

Transport & storage

  • TLS 1.2+ enforced.
  • Supabase Storage with signed URLs for attachments (no public buckets).
  • Backups encrypted at rest by the provider.

Data protection (CDPA)

Requirement Implementation
Lawful basis Contract performance for account data; legitimate interest for product analytics
Data minimisation Phone + name + vehicle only
Right of access In-app export
Right to erasure In-app deletion, 30-day purge, audited
Cross-border transfer Deferred to legal review — see 13-open-questions.md Q3
Breach notification Documented in 10-operations-manual.md

9. Accessibility & low-end device design

Constraint Design response
Small screens (5"–6.1") Single-column layouts; no horizontal scroll; critical content above the fold
Unreliable touch 44×44dp minimum targets (NFR-USE-02)
Font scaling Layouts use flexible height; no fixed-height text containers
Bright sunlight High contrast (4.5:1); avoid low-contrast grey-on-white
Low literacy in English Short labels, icons paired with text, no jargon ("CVT fluid" is jargon — include a one-line explainer on first encounter)
Data cost sensitivity No images on the dashboard by default; no auto-play; no polling
Storage pressure Cache limited to 20MB; attachments uploaded and evicted locally