TwendeDesign System & FoundationsFoundationsβ Gallery
Twende Design System
Foundations for the Passenger, Driver, and Admin surfaces β color tokens, typography, components, microcopy, accessibility rules, and target viewports. Use this page as the canonical reference when implementing in Flutter (mobile) or React (admin).
π¨ Color Tokens
Semantic naming β never use raw hex in code. Tokens map 1:1 to Flutter ColorScheme and Tailwind config.
primary / green-60
#0FA958
CTAs, online state, success, brand
primary-pressed / green-70
#0a7a3f
Button :active, hover
primary-soft / green-10
#e6f7ee
Selected chip background, success badge bg
danger / red-60
#DC2626
SOS, fraud alert, destructive actions
warning / amber-50
#F59E0B
Demand hints, weak network, surge, KYC pending
info / blue-60
#2563EB
Driver app accent, informational links
accent / purple-60
#7c3aed
Admin/Ops badges, secondary tags
text / dark
#0F172A
Body text, headings, top bars
text-muted / muted
#64748B
Secondary text, captions, helper
surface
#FFFFFF
Cards, sheets, inputs
surface-alt / gray-10
#f8fafc
App background, subtle dividers
border / gray-20
#e2e8f0
Card borders, input borders, dividers
π€ Typography
Inter (primary) with system fallback to Roboto / Segoe UI for low-end Android. Weights: 400 / 500 / 600 / 700 / 800.
H1 Β· Twende ride you can trust
Inter 24/32 Β· Semibold
H2 Β· Confirm your ride
Inter 20/28 Β· Semibold
Body Β· Your driver Kato is 4 minutes away. Plate UBD 123X.
Inter 16/24 Β· Regular
Body strong Β· Fare estimate UGX 9,200
Inter 14/20 Β· Semibold
Caption Β· Includes UGX 700 fuel adjustment
Inter 12/16 Β· Regular Β· Muted
π Spacing Scale
8pt grid. Use the named scale tokens β never hard-code px values. All padding, margins, gaps follow this scale.
Always show every line item β radical fare transparency is a core trust principle.
Status Badges
β Verifiedβ Pendingβ Frozen
Status badges used across KYC, driver verification, account state.
TextLink / Tertiary
No background, blue-60 text. For low-emphasis fallback actions.
π± Target Viewports
Always validate critical flows on the smallest target (Android low-end 360Γ640) before larger devices.
360 Γ 640
Low-end Android Itel A56, Tecno Pop Β· ~70% UG market
414 Γ 736
Standard mid-range Tecno Camon, Samsung A series
768 Γ 1024+
Admin desktop Min web target 1024Γ768
βΏ Accessibility Standards
Non-negotiable for low-end Android, low-literacy users, and ageing fleet drivers.
Tap targets β₯ 44 Γ 44 px
All interactive elements meet Android Material accessibility guideline. Smaller icons get padding to satisfy.
Contrast β₯ 4.5:1
All body text passes WCAG AA on white surface. Muted text used for secondary content only.
Body β₯ 14 px
Minimum readable size on low-end screens. Critical info (fares, ETA, plate) always β₯ 16 px.
Color is never the only signal
Status uses color + icon + text. Risk zones use color + dot + label.
SOS button discoverability β₯ 95%
User testing target. Always bottom-right, always visible during in-trip.
No reliance on hover
Mobile-first means every action must work on tap alone. Tooltips replaced by inline help.
π¬ Microcopy Reference
Plain, direct, trust-building. Avoid jargon, dark patterns, and passive voice. Localize to Luganda where shown.
Context
English
Luganda (when localized)
Offline queued ride
No internet. We saved your request and will send it when you reconnect.
Tewali yintaneeti. Twetegese okusaba kwo, tujja kuwereza nga oddamu okufuna.
Fuel adjustment shown
Fare increased by UGX 700 due to fuel adjustment.
β
In-trip safety nudge
For your safety, keep all calls and payments in-app.
Olw'obukuumi bwo, kuuma essimu n'ensimbi mu app.
Surge active
High demand in your area Β· prices may be slightly higher.
β
SOS confirmed
SOS sent. Help is on the way. Stay where you are if safe to do so.
SOS eweerezeddwa. Obuyambi bujja. Sigala awo bw'oba mu bukuumi.
Driver no-show
Driver hasn't arrived. We're finding you another driver β no charge.
β
Permission rationale
We need your location to find drivers near you. We never share it with anyone else.
β
MoMo timeout
No response from MoMo. Try again, or pay with a different method.
β
Cancel fee notice
A small fee of UGX 500 applies because your driver is already on the way.
β
Driver tier unlock
You're in Gold tier β you'll see priority offers and a lower commission rate.
β
β‘ Pricing Intelligence β Twende's Niche
Most ride apps publish a static rate card and leave drivers and passengers fighting over fairness. Twende's pricing is a live, transparent, explainable engine: it ingests fuel, FX, traffic, demand, weather, and time-of-day signals every few minutes, blends them through a clamped formula, and publishes per-zone decisions that any operator, driver, or passenger can audit on demand.
β½ Fuel Index
NITA-U weekly API + retail scrape fallback (Total / Shell / Stabex). Diff vs 30-day moving average β fuel_adj bounded Β±15% of base.
π± FX Rate
Bank of Uganda mid-rate API every 5 min. fx_adj only applied when 7-day drift > 5% β avoids reactive fare thrash from daily noise.
π¦ Traffic
Google Distance Matrix API per H3 zone β actual_time / free_flow_time ratio drives the traffic component.
π Demand
Rolling 5-min quote density per zone, fed into Prophet 30-min-ahead forecast β produces the demand score.
Workday vs weekend, rush windows, late-night premium. Calendar overlay for known events (election, Independence Day).
fare = ( base + dist Γ k_d + time Γ k_t ) Γ surge + fuel_adj β promowheresurge = clamp( 1 + Ξ±Γdemand + Ξ²Γtraffic + Ξ³Γweather, 1.00, 1.80 )
fuel_adj = f( fuel_index_delta_pct ) Β· bounded Β±15% of base
fx_adj = applied only when 7-day USD/UGX drift > 5%// always-enforced floors and shock guards
driver_payout / km β₯ UGX 800 // minimum earnings floor
new_fare / avg_recent β€ 1.20 // EMA smoothing if exceeded
surge β€ 1.80 // Uganda regulatory cap
Explainable, not black-box
Every component visible to admin, driver, and passenger. Same data, same formula, three audiences.
Capped, not extractive
Surge β€ 1.8Γ by Uganda regulation. Driver minimum floor enforced even when formula would go below.
Smoothed, not whiplash
EMA smoothing if a quote would jump > 20% vs recent average. Builds long-term passenger trust.
Multi-currency-ready
Same engine, swappable feeds: KES + Kenya central bank for Nairobi, RWF for Kigali, etc.
Kill-switch ready
SuperAdmin can pause auto-pricing in < 5 s; system reverts to last known-good manual config.
Audited end-to-end
Every signal update, override, and decision stored immutably for 5 years (regulatory + ML retraining).
πΊοΈ Google Maps Integration
Maps are the backbone of every flow. Choice of SDK affects accuracy, cost, and offline behaviour. Twende uses Google Maps as the primary, with thoughtful fallbacks for low-bandwidth and cost control.
Editorial DB primary in Uganda β Places API used to fill gaps and suggest new ones
Cost note: Google Maps APIs are billed per request. Twende keeps spend predictable via: server-side Distance Matrix calls (one per quote, not per render); aggressive client-side caching of map tiles; per-driver position updates batched to one event per 2s rather than firehose; and admin Live Map clustering to keep the marker count bounded. Estimated cost at 10k trips/day: ~USD 350/month.
Offline-lite: Last viewport tiles cached 7 days locally via flutter_cache_manager. Driver positions cached for 30 s during WebSocket reconnects. SOS works without map (text-only fallback).
A real-world failure mode in ride-hailing: driver registered with Vehicle A but shows up driving Vehicle B (accident, sale, expiry, fraud, account-jumping). Twende addresses this end-to-end with five reinforcing layers across the three apps.
Layer
What happens
Where
Failure mode it prevents
1 Β· Onboarding Prevention
Driver photographs vehicle from 4 angles + plate close-up. Logbook owner cross-checked vs KYC name. Vehicle locked to driver_id as a UNIQUE constraint.
Driver app Β· KYC + Vehicle Registration screens
Fake / borrowed vehicle at signup; account-jumping
2 Β· Pre-shift Deterrence
Once every 24 h (or after > 12 h offline), driver photographs current plate. Client + server OCR validate against registered. Mismatch β cannot go online.
Driver app Β· Pre-shift Vehicle Check
Opportunistic vehicle swap; using cousin's bike for the day
3 Β· In-trip Detection
When driver marks "Arrived", passenger sees driver photo, plate, make/model/color in a "Pickup Verification" screen. "Wrong vehicle" β instant trip cancel (no fee), driver auto-suspended pending review.
Passenger app Β· Pickup Verification
Wrong driver picks up; driver swapped vehicles between trips
4 Β· Continuous Monitoring
5% of online sessions sampled for re-verification. Insurance / logbook expiry auto-suspends driver. Anomaly detection on driving patterns (acceleration profile change suggests different vehicle).
Long-running undetected swap; lapsed insurance; expired permits
5 Β· Change mgmt Recovery
Legitimate vehicle change has its own flow: select reason (new / accident / expiry / borrowed), upload new docs and 4 photos. Driver cannot accept rides during 24β48 h review.
Driver app Β· Change Vehicle Request
Honest cases get a clear path; doesn't push drivers to bypass
Why five layers? Each layer alone is bypassable β onboarding photos can be staged, OCR can fail, passengers may not look closely. Defense in depth means a determined attacker has to defeat ALL of them. Failure rate of any single layer is acceptable; the combined miss rate must be near-zero. Target: passenger reports of vehicle mismatch β€ 0.8 per 1,000 trips (industry-leading).
πΆ Connectivity States β Cross-App
How each surface degrades as connection deteriorates. Critical for Uganda's variable 3G/4G coverage.