All projects
Mobile product designBilingualWelfareDesign systemBuilt with AI

MG Foundation

A bilingual welfare app that proves every rupee moved, without ever exposing who received help.

MG Foundation logo
Role
Product designer. Built the app with AI as my engineering pair
Timeline
Aug to Sep 2026, spec to a hardened app
Team
Solo designer, with Claude Code as the engineer
Platform
Android and iOS, English and Urdu
Tools
Figma, Claude Code

My contribution2 roles, 27 app routes, 24 designed screens

01

MG Foundation

MG Foundation is a mobile app for a volunteer-run welfare foundation in a Pakistani city. Around 200 residents give every month for ration, education, health, funerals and city works. The committee records every rupee in one shared ledger and publishes a dated monthly position. Contributors see where money went and their own giving. The people who receive help are never named outside the committee.

Committee adminRecords money in and out, corrects entries and publishes the month.
ContributorSees published figures, where to give, and their own contributions.
Person we helpNever a user of the app. Their record stays with the committee only.
02

A city's giving, kept in notebooks and WhatsApp

Contributions, spending and balances lived across several collectors' notebooks and a committee WhatsApp group. Writing on paper was fast. Answering a question was not.

200+contributors and Rs 1 lac+ a month, with no two collectors holding the same total
01Several truthsEach collector's notebook held a different total. Nobody could say in one sentence what was left.
02Trust tied to one personPeople gave because they knew the treasurer. That breaks the day he moves, falls ill or is accused.
03Proof against privacy“Ration, Rs 22,000, four families” names those families by Friday in a city where everyone knows everyone.
04Urdu first, forms lastMost contributors read Urdu and many are not comfortable with email, passwords or long forms.
03

One ledger, two views, one monthly close

Four connected areas replace the notebooks. Every figure on screen names its fund, and nothing becomes public until a named person publishes the month.

Record money in seconds
Add entryRecord money in secondsDirection, amount, fund and who gave it, on one screen. Recent contributors are one tap away.
The ledger, filtered by fund
RecordsThe ledger, filtered by fundGrouped by month with in and out totals. Correcting an entry keeps the first figure and marks it Corrected.
A named person closes the month
PublishA named person closes the monthDrafts are reviewed with per-fund totals, then published. The public sees a dated position, never live balances.
Your own giving, and where it went
My contributionsYour own giving, and where it wentA contributor sees published figures, where to give, and every rupee recorded against their number.
Prove the money moved, without revealing who received it.
The one rule behind the data model, the rules file and every public screen
04

A month from spec to a hardened app

Design and build ran together. The spec and Figma file set the target; a real phone decided what shipped. Every round started from feedback on the device.

14 Aug15 Aug16 Aug21 Aug24-25 Aug13 Sep
UnderstandDefineBuildTest on deviceHarden
iterate: feedback on the phone, then fixstakeholder round: add a Charity fund
UnderstandRead the full build spec, scanned the Figma tokens and text styles, and mapped the old app screen by screen.
DefineLocked five decisions: frozen dependencies, fresh data model, hand-built components, privacy in the database, phone as key.
BuildTokens, then 17 components, then role-based screens. Beneficiary privacy rules landed before any UI.
Test on deviceRounds on a real Android phone found layout shift, clipped Urdu, hidden inputs and raw ids on screen.
HardenClosed three security holes, added offline saves, record merging, people we help and committee approval.
How the build worked

A designer with an AI engineering pair

72commits co-authored with Claude Code, Aug to Sep 2026

Me, the designer

  • Wrote the spec and set the constraints
  • Designed every screen in Figma
  • Tested each round on a real Android phone
  • Caught layout shift, clipped Urdu, raw ids
  • Decided what shipped and what didn't

Claude Code, the engineer

  • Wrote the app, rules and data migrations
  • Ran typechecks and rules compiles
  • Fixed what I found on the device
  • Flagged security holes before deploy
  • Explained trade-offs so I could choose

AI wrote the code. Every decision, and every bug it missed, came from testing on the phone.

05

Rules of the room that shaped every screen

Some came from the brief, some from money, some from faith. Each one got a design response, not a workaround.

01

Dependencies frozen

package.json could not change.

Design response

17 components hand-built on the installed stack. No UI library added.

02

No paid Firebase

No Cloud Functions, no SMS codes.

Design response

The committee approves new sign-ups. Rules check every published figure.

03

Recipients stay private

A name on the public app is harm.

Design response

People we help live in an admin-only collection the database won't serve.

04

Zakat is restricted

It may only reach eligible people.

Design response

A fund note on every spend, and Zakat published as one total.

05

Urdu readers first

Nastaliq clips at Latin line heights.

Design response

Its own Urdu type ramp, full right-to-left layout, names transliterated.

06

Colour is never alone

Fund hues must survive colour blindness.

Design response

Every fund carries a hue, an icon, a label and a fixed position.

07

No silent corrections

A changed figure erodes trust.

Design response

The first amount stays, with who, when and why, marked Corrected.

08

Paper is faster

A form has to beat a notebook.

Design response

One-screen add entry, recent contributor chips, saves that queue offline.

06

Three people, one shared worry

Role archetypes drawn from the brief, not from interviews: the committee who records, the residents who give, and the families who must never be named.

CT

The committee treasurer

Admin · one of five committee members

Records every dayPublishes monthly

“When someone asks what's left, I want the answer in seconds, not three phone calls.”
Goals
  • One total everyone agrees on
  • Close the month without arguing from memory
Frustrations
  • Totals split across notebooks
  • Being questioned with nothing to point at
Needs on screen

Live balances per fund, and one clear publish step

CO

The contributor

Normal user · one of about 200 residents

Gives monthlyReads Urdu

“I give because I know the committee. I'd like to see where it went.”
Goals
  • See where the money went
  • Know my own giving was recorded
Frustrations
  • Hearing figures second-hand
  • Long forms and passwords
Needs on screen

Published figures in Urdu, and my own contributions

PH

The person we help

Never signs in · kept by the committee

Ration, health, funeralsPrivate

“Nobody on my street should know we took ration.”
Goals
  • Help arrives on time
  • Dignity kept
Frustrations
  • Being identified by a public figure
  • Explaining their situation twice
Needs on screen

Nothing on any screen. Only a category total goes public

Key insight

Nobody asked for faster data entry. They asked for trust that doesn't depend on one person.

07

A warm ledger that stays calm about money

Warm neutrals keep long reading easy. Muted teal marks the one thing to act on. Five fund colours were checked under protanopia and deuteranopia, and every one ships with an icon and a word.

Warm neutrals
Canvas
Raised
Well
Subtle border
Strong border
Input border
Secondary text
Primary text
Inverse
Brand and funds
Brand
General
Zakat
City Fund
Charity
Reserve
Fund tints
Brand
General
Zakat
City Fund
Charity
Reserve

Status: always colour, dot and word

Not published
Published
Corrected
Waiting to send
No internet
13.5:1AAAPrimary text on canvas
6.5:1AASecondary text on canvas
7.9:1AAAWhite on brand teal
3.3:1AA UIInput border on canvas
Regular to Bold. Figures stay Latin and tabular in both languages, so ledger columns line up.Plus Jakarta SansRegular to Bold
Its own ramp: a little smaller than Latin, about 2.1x line height, never letter-spaced.Noto Nastaliq UrduRegular and Bold
Rs 4,82,000Amount / XL32 / 37 · Bold
Live balancesHeading / L20 / 26 · SemiBold
Available as of 31 JulyBody / L16 / 24 · Regular
In this monthLabel14 / 20 · Medium
عنوانUrdu · Heading L20 / 42 · Bold
متنUrdu · Body L16 / 36 · Regular
08

What changed for the committee and the city

The app hasn't lived through a full Ramadan yet, so these aren't usage numbers. They are shifts built into the product, and each one can be checked.

Many1notebooks, now one shared ledger with an owner and a date on every entry
0beneficiary names the public app can read, blocked by the database itself
557interface strings, every one written in both English and Urdu
5funds kept hard-separated, so a rupee sits in exactly one
30security holes found in review and closed before the rules went live
1named person publishes each month; everything else stays a draft
09

Checked on the device, in both languages

Every round ended with a typecheck, and with a compile before any rules deploy. This is what the checks found, including what failed the first time.

Validation run · new-updates branch6 of 6 passed
  • TypeScript typecheck, whole app0 errors
  • Security rules compile, then deployReleased
  • Text keys match across languages557 of 557
  • Phone numbers moved to +92 format4 records, 3 users
  • Urdu names backfilled8 records, 3 users
  • Security holes found before deploy3 closed
27App routes checked
13Admin screens
8Contributor screens
5Sign-in flow
1Role gate
Found on the phone, fixedFund chips jumped when tappedOnly the selected chip had a border. Now every chip has one, and selection just changes its colour.Before: 2 px shift. After: 0 px.
Round 1 · 14 AugMatch FigmaHome and Add entry rebuilt to the frames; Records, Publish and People followed.
Round 2 · 15 AugUrdu and loadingTranslations applied after restart, skeleton loaders, one sticky header per screen.
Round 3 · 16 AugLinking peopleAccounts linked to their records by phone, every number moved to +92.
Round 4 · 25 AugStakeholderCharity added as a fifth public fund, across every screen and both languages.
10

Built for one hand and a busy street

Large amounts, 48-point tap targets and nothing hidden behind a long press. Every screen names its fund, and Urdu mirrors the whole layout rather than swapping words.

Committee

Recording and closing the month

Home
HomeLive balances per fund
Add entry
Add entryOne screen, every rupee
Entry details
Entry detailsCorrected, never silent
Publish July
Publish JulyA named sign-off
Contributor

Seeing where the money went

Home
HomeA dated public position
Where to contribute
Where to contributeVerified account titles
My contributions
My contributionsEverything under my number
Contribution detail
Contribution detailGiven on, recorded on
Front door and reports

Getting in, and getting answers out

Language
LanguageChosen once, in the app
Phone number
Phone numberThe number is the key
Money out
Money outFund rules on every spend
Make a report
Make a reportFilters, then one file
11

A committee treasurer through one month

Following one month of money, from collection on the street to a question in the WhatsApp group after the figures go public.

Stage 1CollectStage 2RecordStage 3CheckStage 4PublishStage 5Answer
Doing

Takes cash, bank and wallet payments across the week

Adds each one: amount, fund and who gave it

Scans Records by fund and fixes a wrong amount

Reviews per-fund totals, then publishes the month

Answers “where did my money go?” in the group

ThinkingWho handed me this cash?Was that Zakat or General?Will a correction look suspicious?Am I sure enough to go public?Can I just send them a screen?
FeelingBusyRushedAnxiousConfidentRelieved
In the appWhere to contributeChannelsAdd entryRecent chipsRecordsCorrected badgePublishPer-fund totalsPublished recordsMake a report
OpportunitiesPhoto of the receipt on the entrySuggest the fund from the channelShow the reason for a correction inlineA second member confirms before publishShare a published month as an image
12

Two apps in one, split by role at the door

One sign-in flow routes people to the committee or the contributor view. The same components work at different scopes, and every navigating control carries a visible label.

MG Foundation
Routed by role
Sign inEveryone
  • Language
  • Phone number
  • Password
  • Sign up
    • Waits for committee approval
CommitteeAdmin
  • Home
  • Records
    • Entry details
  • Add entry
    • Choose or add a person
  • People
    • Contributors
    • People we help
    • Committee
  • Profile
    • Make a report
    • Publish the month
    • Channels and funds
    • App users and roles
ContributorNormal user
  • Home
  • Where to contribute
  • My contributions
    • Contribution detail
  • Profile
    • About
    • Committee
    • Published records

Who sees what

The scope changes; the components don't.

CapabilityCommittee adminApproved contributorWaiting for approvalGuest
Live fund balancesAll fundsNot shownNot shownNot shown
Published figuresAll fundsPublic fundsPublic fundsPublic funds
ContributionsEvery entryOwn onlyAfter approvalNot shown
People we helpAdmin onlyNot shownNot shownNot shown
Publish the monthNamed sign-offNot shownNot shownNot shown
App users and rolesApprove, disableNot shownNot shownNot shown
13

Redrawn in pencil to argue about the model

Lo-fi redraws of shipped screens, used to explain the decisions behind them rather than to fake an early sketching phase.

Add entryamount first, biggest thing on screen · recent people = one tapfund chips: colour + icon + word
Recordsthe fund is always named“Corrected” never goes away
Publish Julyone named person signs off · drafts reviewed before anything goes public
Contributor homedated position, not liveno names, ever
Argue about the model, not the colours
14

One token set, 17 components, two languages

Hand-built from the spec on the stack the app already had. The same components serve the committee and contributors; only the scope changes.

17components in Figma
5fund palettes
23type styles, Latin and Urdu
9spacing steps, 4 px base
557strings in both languages

What the components carry

Pool ChipEvery pool is carried by four signals: hue, label, icon and fixed position. Remove the colour and the chip still reads.Unselected chips carry a 1px base-colour outline so the boundary meets WCAG 1.4.11.
Status BadgePlain-language states: “Corrected” rather than “Amended”, “Not published” rather than “Draft”.A correction is never silent: an edited entry always carries this badge plus a reason.
Stat CardCard fill is the pool's own surface tint, so the fund is identifiable before any text is read.The available figure is always a dated month-close position, never a live balance.
Button48dp height is bound to size/touch-min and must never be reduced. The label is not optional.No icon-only buttons anywhere in this product.
Input FieldBorder uses border/interactive (3.2:1), because a control boundary must meet WCAG 1.4.11.Errors are always icon + sentence, and they say what to do rather than what went wrong.
Language ToggleBoth options always show in their own script, because device locale is unreliable in Pakistan.Someone in the wrong language has to find their way back without reading it.
15

What this project taught me

Six lessons I now carry into any product that handles other people's money.

1Privacy belongs in the databaseHiding names in the interface is one bug away from a leak. The rules file is the only place a promise to a family can actually be kept.
2Colour is the last signalEvery fund carries a hue, an icon, a word and a fixed place. Take the colour away and the ledger still reads.
3Urdu is not a translationNastaliq needed its own sizes and line heights. Treating it as swapped strings clipped every descender on the phone.
4Free can still be safeWithout paid SMS, a committee member approving new sign-ups turned out to be a stronger check than a fake code screen.
5Test on the phone, in the languageLayout shift, clipped Urdu, hidden inputs and raw ids only showed up on a real device, in the language people actually read. Every round started there.
6AI is fast. Judgment is the job.Claude Code wrote 27 app routes in days. A written spec, clear constraints and testing every round on a real phone are what caught its misses and made the app shippable.
16

How we'll know it worked

Downloads and daily actives don't fit a 200-person foundation. Targets are set per promise instead, and checked at every monthly close.

The one-line scorecard

Can anyone on the committee answer “what's left in Zakat?” in seconds, without phoning anyone?

TrustAsked after each close
  • Figure questions the app can answerTarget: all of them
  • Disputes settled by pointing at RecordsTarget: all of them
  • Corrections without a written reasonTarget: zero
Tracked after launch
SpeedAt every close
  • Time to answer “what's left in a fund?”Target: under 10 seconds
  • Days from month end to publishTarget: under 7
  • Entries recorded the same dayTarget: most
Tracked after launch
PrivacyEvery release
  • Beneficiary names the public app can readTarget: zero
  • Categories published under 3 peopleTarget: zero
  • Zakat spend split by categoryTarget: never
Met in build
CraftEvery build
  • Strings missing an Urdu versionTarget: zero
  • Status shown by colour aloneTarget: zero
  • Typecheck errors in a releaseTarget: zero
Met in build

Names and amounts in the screens are sample data. The foundation, its rules and its privacy model are real.

Back to

All projects