// Finance app UI
Personal Finance App UI Design in Expo
This personal finance app UI gives you a friendly first run and a dense but readable dashboard: a shaped debit card, quick actions, recent contacts and activity.
- Screens
- 3
- Built with
- Expo SDK 58
- Fonts
- Outfit, Space Grotesk
- License
- Free (MIT)

Personal Finance app screens

Onboarding
A hand-drawn wallet illustration on lime, a headline with an inline arrow pill, and skip and start actions.

Card home
A notched black debit card with budget and tap controls, quick actions, quick send contacts and recent activity.

Statistics
Period tabs, earning and spending cards with a radar chart, and a monthly overview in stacked bars with a tooltip.
Copy the Personal Finance kit
Use the artifact as a design brief, the skill to generate the UI with an AI agent, or the code to run it right away.
Design artifact
The full design: tokens, screens and source
# Personal Finance: design artifact
This personal finance app UI gives you a friendly first run and a dense but readable dashboard: a shaped debit card, quick actions, recent contacts and activity.
- Type: Finance mobile app UI
- Screens: 3
- Artboard: 390 × 844
- Target: Expo SDK 58, Expo Router, TypeScript, expo-image, react-native-svg
- Live page: https://developermill.com/app-designs/finance-app-ui-design
## Design direction
Fresh lime on pale green with black contrast cards, Space Grotesk figures and a hand-drawn onboarding illustration.
- Notched debit card drawn in SVG
- Radar and stacked bar charts with no chart library
- Working period tabs on statistics
- Illustrated onboarding with a skip path
## Foundations
### Colour
| Token | Hex |
| --- | --- |
| Lime | `#C7E369` |
| Soft green | `#F3F8E6` |
| Ink | `#141414` |
| Card black | `#1B1C1A` |
| Olive grey | `#6B7062` |
| Teal | `#2EC4B6` |
### Typography
- Typefaces: Outfit, Space Grotesk
- Common sizes (px): 9, 10, 11, 12, 13, 14, 15, 16
### Shape and depth
- Common corner radii (px): 4, 6, 20, 23, 24, 26
- Shadows: `0 10px 30px rgba(20,20,20,0.25)`, `0 2px 8px rgba(20,20,20,0.06)`
## Screens
### 1. Onboarding
A hand-drawn wallet illustration on lime, a headline with an inline arrow pill, and skip and start actions.
Preview: https://developermill.com/app-designs/finance-app-ui-design/onboarding.webp
Copy on this screen:
- Digital Banking
- Made for
- Digital Users
- Spend, earn and track financial activity
- Skip
- Let's Start
### 2. Card home
A notched black debit card with budget and tap controls, quick actions, quick send contacts and recent activity.
Preview: https://developermill.com/app-designs/finance-app-ui-design/home.webp
Copy on this screen:
- William Current
- Welcome Back
- VISA
- Balance
- $ 25,453.00
- **** **** **** 7281
- Exp 07/26
- Set Budget
- Send
- Bill
- Mobile
- More
- Quick Send
- See all
- Azie
- Chaoir
- Famdit
- Happy
- Nayu
- Recent Activity
- Food Store
- Monday, 25 January
- -$15.00
- House Rent
- -$290.00
- Metro Card
- Sunday, 24 January
- -$27.00
### 3. Statistics
Period tabs, earning and spending cards with a radar chart, and a monthly overview in stacked bars with a tooltip.
Preview: https://developermill.com/app-designs/finance-app-ui-design/statistics.webp
Copy on this screen:
- Statistics
- Earning
- 24%
- Your current month earning is increased by 24% compared to last month.
- Goal
- $2,567
- / $5,000
- Spending
- $3,250
- .80
- Debit Card
- Credit Card
- Overview
- Total Balance
- $25,453.00
- Debit Card Spending
- Credit Card Spending
- $3000
- $2500
- $2000
- $1500
- $1000
- $500
- $0
- JAN
- FEB
- MAR
- $2,410.00
- APR
- MAY
- JUN
## Full source
The complete design source for each screen. Images point at hosted demo files.
### Main
```html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Onboarding</title>
<script src="./support.js"></script>
</head>
<body>
<x-dc>
<helmet>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600&family=Outfit:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
body{margin:0}
a{color:#141414}a:hover{color:#000}
</style>
</helmet>
<div style="width: 390px; height: 844px; box-sizing: border-box; background: #C7E369; font-family: Outfit, system-ui, sans-serif; color: #141414; display: flex; flex-direction: column; padding: 40px 28px 40px; overflow: hidden">
<div style="flex: 1; min-height: 0; display: flex; align-items: center; justify-content: center">
<img src="https://developermill.com/app-designs/finance-app-ui-design/assets/b81c0d5bb9.jpg" alt="Smiling man popping out of a wallet, pointing up, with a QR code, card, coin and receipt floating around him" style="height: 100%; max-width: 100%; object-fit: contain">
</div>
<h1 style="margin: 8px 0 0; font-family: 'Space Grotesk', sans-serif; font-weight: 500; font-size: 38px; line-height: 1.22; letter-spacing: -0.5px">Digital Banking<br>Made for <span style="display: inline-flex; vertical-align: middle; align-items: center; justify-content: center; width: 64px; height: 30px; border-radius: 15px; background: #141414; margin-left: 4px"><svg width="26" height="14" viewBox="0 0 26 14" fill="none" stroke="#C7E369" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M2 7h21M17 1l6 6-6 6"></path></svg></span><br>Digital Users</h1>
<p style="margin: 14px 0 32px; font-size: 15px; color: #2E3A10">Spend, earn and track financial activity</p>
<div style="display: flex; align-items: center; justify-content: space-between">
<a href="Home.dc.html" style="font-size: 15px; font-weight: 600; text-decoration: none; padding: 12px 4px; min-height: 44px; box-sizing: border-box">Skip</a>
<div style="display: flex; align-items: center; gap: 14px">
<span style="font-size: 15px; font-weight: 600">Let's Start</span>
<a href="Home.dc.html" aria-label="Let's start" style="width: 64px; height: 64px; border-radius: 32px; background: #141414; display: flex; align-items: center; justify-content: center"><svg width="22" height="22" viewBox="0 0 22 22" fill="none" stroke="#FFFFFF" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 18L18 4M8 4h10v10"></path></svg></a>
</div>
</div>
</div>
</x-dc>
<script type="text/x-dc" data-dc-script data-props='{"$preview":{"width":390,"height":844}}'>
class Component extends DCLogic {
renderVals() {
return {};
}
}
</script>
</body>
</html>
```
### Home
```html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Home</title>
<script src="./support.js"></script>
</head>
<body>
<x-dc>
<helmet>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600&family=Outfit:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
body{margin:0}
a{color:#141414}a:hover{color:#000}
</style>
</helmet>
<div style="width: 390px; height: 844px; box-sizing: border-box; background: #F3F8E6; font-family: Outfit, system-ui, sans-serif; color: #141414; position: relative; overflow: hidden">
<nav style="position: absolute; left: 50%; bottom: 24px; transform: translateX(-50%); background: #1B1C1A; border-radius: 34px; padding: 8px; display: flex; gap: 10px; box-shadow: 0 10px 30px rgba(20,20,20,0.25)">
<a href="Statistics.dc.html" aria-label="Statistics" style="width: 52px; height: 52px; border-radius: 26px; background: #2E302B; display: flex; align-items: center; justify-content: center"><svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="#FFFFFF" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="3" width="18" height="18" rx="5"></rect><path d="M8 16v-4M12 16V8M16 16v-6"></path></svg></a>
<a href="#" aria-label="Scan to pay" style="width: 52px; height: 52px; border-radius: 26px; background: {{lime}}; display: flex; align-items: center; justify-content: center"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#141414" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 8V5a2 2 0 0 1 2-2h3M16 3h3a2 2 0 0 1 2 2v3M21 16v3a2 2 0 0 1-2 2h-3M8 21H5a2 2 0 0 1-2-2v-3"></path><rect x="8" y="8" width="8" height="8" rx="1.5"></rect></svg></a>
<a href="#" aria-label="Menu" style="width: 52px; height: 52px; border-radius: 26px; background: #2E302B; display: flex; align-items: center; justify-content: center"><svg width="22" height="22" viewBox="0 0 24 24" fill="#FFFFFF" aria-hidden="true"><circle cx="8" cy="8" r="2"></circle><circle cx="16" cy="8" r="2"></circle><circle cx="8" cy="16" r="2"></circle><circle cx="16" cy="16" r="2"></circle></svg></a>
</nav>
<div style="padding: 52px 20px 0; display: flex; flex-direction: column; gap: 16px">
<div style="display: flex; align-items: center; justify-content: space-between">
<div style="display: flex; align-items: center; gap: 12px">
<img src="https://developermill.com/app-designs/finance-app-ui-design/assets/cbcc3a069b.jpg" alt="William Current" style="width: 48px; height: 48px; border-radius: 24px; object-fit: cover">
<div style="display: flex; flex-direction: column; gap: 2px">
<span style="font-size: 13px; color: #5B6150">William Current</span>
<span style="font-size: 20px; font-weight: 600">Welcome Back</span>
</div>
</div>
<button aria-label="Notifications" style="width: 48px; height: 48px; border-radius: 24px; border: none; background: #FFFFFF; display: flex; align-items: center; justify-content: center; position: relative; box-shadow: 0 2px 8px rgba(20,20,20,0.06)">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="#141414" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6 9a6 6 0 1 1 12 0c0 6 2.5 7.5 2.5 7.5h-17S6 15 6 9"></path><path d="M10 20a2 2 0 0 0 4 0"></path></svg>
<span style="position: absolute; top: 12px; right: 13px; width: 8px; height: 8px; border-radius: 4px; background: #E5484D; border: 2px solid #FFFFFF"></span>
</button>
</div>
<div style="position: relative; height: 207px; color: #FFFFFF">
<div style="position: absolute; left: 0; top: 0; width: 350px; height: 207px; background: repeating-linear-gradient(125deg, rgba(255,255,255,0) 0px, rgba(255,255,255,0) 10px, rgba(255,255,255,0.045) 10px, rgba(255,255,255,0.045) 11px), radial-gradient(circle at 70% 40%, #262824 0%, #161715 75%); clip-path: path('M22 0 H230 Q239 0 244 8 L260 30 Q265 37 274 37 H328 A22 22 0 0 1 350 59 V185 A22 22 0 0 1 328 207 H22 A22 22 0 0 1 0 185 V22 A22 22 0 0 1 22 0 Z')" aria-hidden="true"></div>
<span style="position: absolute; left: 20px; top: 20px; font-family: 'Space Grotesk', sans-serif; font-weight: 700; font-size: 14px; letter-spacing: 0.5px">VISA</span>
<svg width="30" height="30" viewBox="0 0 24 24" style="position: absolute; left: 186px; top: 30px" aria-hidden="true"><path d="M12 0 C12.8 8.5 15.5 11.2 24 12 C15.5 12.8 12.8 15.5 12 24 C11.2 15.5 8.5 12.8 0 12 C8.5 11.2 11.2 8.5 12 0Z" fill="{{lime}}"></path></svg>
<svg width="9" height="9" viewBox="0 0 24 24" style="position: absolute; left: 186px; top: 121px" aria-hidden="true"><path d="M12 0 C12.8 8.5 15.5 11.2 24 12 C15.5 12.8 12.8 15.5 12 24 C11.2 15.5 8.5 12.8 0 12 C8.5 11.2 11.2 8.5 12 0Z" fill="#8FA34A"></path></svg>
<svg width="12" height="12" viewBox="0 0 24 24" style="position: absolute; left: 250px; top: 154px" aria-hidden="true"><path d="M12 0 C12.8 8.5 15.5 11.2 24 12 C15.5 12.8 12.8 15.5 12 24 C11.2 15.5 8.5 12.8 0 12 C8.5 11.2 11.2 8.5 12 0Z" fill="#4A4D44"></path></svg>
<span style="position: absolute; left: 20px; top: 56px; font-size: 11px; color: #9EA295">Balance</span>
<span style="position: absolute; left: 20px; top: 74px; font-family: 'Space Grotesk', sans-serif; font-size: 30px; font-weight: 500; letter-spacing: -0.5px; line-height: 1.2">$ 25,453.00</span>
<span style="position: absolute; left: 20px; top: 136px; font-size: 12px; color: #D6D9CE; letter-spacing: 1px; word-spacing: 10px">**** **** **** 7281</span>
<div style="position: absolute; left: 20px; width: 253px; bottom: 16px; display: flex; justify-content: space-between; font-size: 11px; color: #D6D9CE">
<span>William Current</span><span>Exp 07/26</span>
</div>
<div style="position: absolute; right: 9px; top: 49px; bottom: 9px; width: 52px; border-radius: 20px; background: {{lime}}; display: flex; align-items: center; justify-content: center">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="#141414" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M8 7.5a6 6 0 0 1 0 9"></path><path d="M12 5a10 10 0 0 1 0 14"></path><path d="M16 3a13 13 0 0 1 0 18"></path></svg>
</div>
<button style="position: absolute; right: 2px; top: -6px; width: 106px; border: none; background: {{lime}}; border-radius: 17px; height: 34px; padding: 0 0 0 5px; display: flex; align-items: center; gap: 8px; font-family: Outfit, sans-serif; font-size: 11px; font-weight: 600; color: #141414; white-space: nowrap">
<span style="width: 24px; height: 24px; border-radius: 12px; background: #141414; display: flex; align-items: center; justify-content: center"><svg width="10" height="10" viewBox="0 0 24 24" aria-hidden="true"><path d="M12 0 C12.8 8.5 15.5 11.2 24 12 C15.5 12.8 12.8 15.5 12 24 C11.2 15.5 8.5 12.8 0 12 C8.5 11.2 11.2 8.5 12 0Z" fill="#FFFFFF"></path></svg></span>Set Budget
</button>
</div>
<div style="display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px">
<button style="height: 80px; border-radius: 24px; border: 1px solid #E3EAD3; background: #FFFFFF; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; font-family: Outfit, sans-serif; font-size: 13px; font-weight: 500; color: #141414">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="#141414" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 21l3-3"></path><circle cx="12" cy="12" r="5"></circle><path d="M17 7l4-4M17 3h4v4"></path></svg>Send</button>
<button style="height: 80px; border-radius: 24px; border: 1px solid #E3EAD3; background: #FFFFFF; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; font-family: Outfit, sans-serif; font-size: 13px; font-weight: 500; color: #141414">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="#141414" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6 2h12v20l-3-2-3 2-3-2-3 2z"></path><path d="M9 7h6M9 11h6M9 15h3"></path></svg>Bill</button>
<button style="height: 80px; border-radius: 24px; border: 1px solid #E3EAD3; background: #FFFFFF; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; font-family: Outfit, sans-serif; font-size: 13px; font-weight: 500; color: #141414">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="#141414" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="6" y="2" width="12" height="20" rx="3"></rect><path d="M11 18h2"></path></svg>Mobile</button>
<button style="height: 80px; border-radius: 24px; border: none; background: {{lime}}; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; font-family: Outfit, sans-serif; font-size: 13px; font-weight: 500; color: #141414">
<svg width="22" height="22" viewBox="0 0 24 24" fill="#141414" aria-hidden="true"><circle cx="7" cy="7" r="2"></circle><circle cx="17" cy="7" r="2"></circle><circle cx="7" cy="17" r="2"></circle><circle cx="17" cy="17" r="2"></circle></svg>More</button>
</div>
<div style="background: #FFFFFF; border-radius: 24px; padding: 14px 16px 12px; display: flex; flex-direction: column; gap: 12px">
<div style="display: flex; justify-content: space-between; align-items: center">
<span style="font-size: 15px; font-weight: 600">Quick Send</span>
<a href="#" style="font-size: 12px; text-decoration: none; display: flex; align-items: center; gap: 2px">See all <svg width="12" height="12" viewBox="0 0 12 12" fill="none" stroke="#141414" stroke-width="1.6" stroke-linecap="round" aria-hidden="true"><path d="M4.5 2.5L8 6l-3.5 3.5"></path></svg></a>
</div>
<div style="display: flex; justify-content: space-between">
<div style="display: flex; flex-direction: column; align-items: center; gap: 6px"><img src="https://developermill.com/app-designs/finance-app-ui-design/assets/a83189def8.jpg" alt="Azie" style="width: 46px; height: 46px; border-radius: 23px; object-fit: cover"><span style="font-size: 11px; color: #3F443A">Azie</span></div>
<div style="display: flex; flex-direction: column; align-items: center; gap: 6px"><img src="https://developermill.com/app-designs/finance-app-ui-design/assets/fea6aeff93.jpg" alt="Chaoir" style="width: 46px; height: 46px; border-radius: 23px; object-fit: cover"><span style="font-size: 11px; color: #3F443A">Chaoir</span></div>
<div style="display: flex; flex-direction: column; align-items: center; gap: 6px"><img src="https://developermill.com/app-designs/finance-app-ui-design/assets/1cb0912499.jpg" alt="Famdit" style="width: 46px; height: 46px; border-radius: 23px; object-fit: cover"><span style="font-size: 11px; color: #3F443A">Famdit</span></div>
<div style="display: flex; flex-direction: column; align-items: center; gap: 6px"><img src="https://developermill.com/app-designs/finance-app-ui-design/assets/ddb012f2c0.jpg" alt="Happy" style="width: 46px; height: 46px; border-radius: 23px; object-fit: cover"><span style="font-size: 11px; color: #3F443A">Happy</span></div>
<div style="display: flex; flex-direction: column; align-items: center; gap: 6px"><img src="https://developermill.com/app-designs/finance-app-ui-design/assets/04d09efc3a.jpg" alt="Nayu" style="width: 46px; height: 46px; border-radius: 23px; object-fit: cover"><span style="font-size: 11px; color: #3F443A">Nayu</span></div>
</div>
</div>
<div style="display: flex; justify-content: space-between; align-items: center">
<span style="font-size: 15px; font-weight: 600">Recent Activity</span>
<a href="#" style="font-size: 12px; text-decoration: none; display: flex; align-items: center; gap: 2px">See all <svg width="12" height="12" viewBox="0 0 12 12" fill="none" stroke="#141414" stroke-width="1.6" stroke-linecap="round" aria-hidden="true"><path d="M4.5 2.5L8 6l-3.5 3.5"></path></svg></a>
</div>
<div style="background: #FFFFFF; border-radius: 24px; padding: 4px 16px; display: flex; flex-direction: column">
<div style="display: flex; align-items: center; gap: 12px; padding: 12px 0; border-bottom: 1px solid #EEF2E4">
<span style="width: 40px; height: 40px; border-radius: 20px; background: #F3F8E6; display: flex; align-items: center; justify-content: center"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#141414" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 8h14l-1.5 12h-11z"></path><path d="M9 8V6a3 3 0 0 1 6 0v2"></path></svg></span>
<div style="flex: 1; display: flex; flex-direction: column; gap: 2px"><span style="font-size: 14px; font-weight: 600">Food Store</span><span style="font-size: 11px; color: #6B7062">Monday, 25 January</span></div>
<span style="font-family: 'Space Grotesk', sans-serif; font-size: 16px; font-weight: 600">-$15.00</span>
</div>
<div style="display: flex; align-items: center; gap: 12px; padding: 12px 0; border-bottom: 1px solid #EEF2E4">
<span style="width: 40px; height: 40px; border-radius: 20px; background: #F3F8E6; display: flex; align-items: center; justify-content: center"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#141414" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 11l9-7 9 7"></path><path d="M5 10v10h14V10"></path><path d="M10 20v-6h4v6"></path></svg></span>
<div style="flex: 1; display: flex; flex-direction: column; gap: 2px"><span style="font-size: 14px; font-weight: 600">House Rent</span><span style="font-size: 11px; color: #6B7062">Monday, 25 January</span></div>
<span style="font-family: 'Space Grotesk', sans-serif; font-size: 16px; font-weight: 600">-$290.00</span>
</div>
<div style="display: flex; align-items: center; gap: 12px; padding: 12px 0">
<span style="width: 40px; height: 40px; border-radius: 20px; background: #F3F8E6; display: flex; align-items: center; justify-content: center"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#141414" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="5" y="3" width="14" height="15" rx="3"></rect><path d="M5 11h14"></path><path d="M8 21l2-3M16 21l-2-3"></path></svg></span>
<div style="flex: 1; display: flex; flex-direction: column; gap: 2px"><span style="font-size: 14px; font-weight: 600">Metro Card</span><span style="font-size: 11px; color: #6B7062">Sunday, 24 January</span></div>
<span style="font-family: 'Space Grotesk', sans-serif; font-size: 16px; font-weight: 600">-$27.00</span>
</div>
</div>
</div></div>
</x-dc>
<script type="text/x-dc" data-dc-script data-props='{"lime":{"editor":"color","default":"#C7E369","options":["#C7E369","#A7E3C9","#F4D35E","#BFD7FF"]},"$preview":{"width":390,"height":844}}'>
class Component extends DCLogic {
renderVals() {
return { lime: this.props.lime ?? '#C7E369' };
}
}
</script>
</body>
</html>
```
### Statistics
```html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Statistics</title>
<script src="./support.js"></script>
</head>
<body>
<x-dc>
<helmet>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600&family=Outfit:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
body{margin:0}
a{color:#141414}a:hover{color:#000}
</style>
</helmet>
<div style="width: 390px; height: 844px; box-sizing: border-box; background: #F3F8E6; font-family: Outfit, system-ui, sans-serif; color: #141414; padding: 52px 20px 24px; display: flex; flex-direction: column; gap: 18px; overflow: hidden">
<div style="display: flex; align-items: center; justify-content: space-between">
<a href="Home.dc.html" aria-label="Back" style="width: 48px; height: 48px; border-radius: 24px; background: #FFFFFF; display: flex; align-items: center; justify-content: center"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#141414" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 12H4M10 6l-6 6 6 6"></path></svg></a>
<h1 style="margin: 0; font-size: 18px; font-weight: 600">Statistics</h1>
<button aria-label="More options" style="width: 48px; height: 48px; border-radius: 24px; border: none; background: #FFFFFF; display: flex; align-items: center; justify-content: center"><svg width="20" height="20" viewBox="0 0 24 24" fill="#141414" aria-hidden="true"><circle cx="5" cy="12" r="2"></circle><circle cx="12" cy="12" r="2"></circle><circle cx="19" cy="12" r="2"></circle></svg></button>
</div>
<div style="display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px">
<sc-for list="{{periods}}" as="p" hint-placeholder-count="4">
<button onClick="{{p.pick}}" style="{{p.style}}">{{p.label}}</button>
</sc-for>
</div>
<div style="display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px">
<div style="background: {{lime}}; border-radius: 24px; padding: 14px; display: flex; flex-direction: column; gap: 8px; height: 180px; box-sizing: border-box">
<div style="display: flex; justify-content: space-between; align-items: center">
<span style="display: flex; align-items: center; gap: 4px; font-size: 12px; font-weight: 500"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#141414" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 17l6-6 4 4 8-8M15 7h6v6"></path></svg>Earning</span>
<span style="width: 24px; height: 24px; border-radius: 12px; background: #141414; display: flex; align-items: center; justify-content: center"><svg width="12" height="12" viewBox="0 0 24 24" fill="#FFFFFF" aria-hidden="true"><circle cx="5" cy="12" r="2.4"></circle><circle cx="12" cy="12" r="2.4"></circle><circle cx="19" cy="12" r="2.4"></circle></svg></span>
</div>
<span style="font-family: 'Space Grotesk', sans-serif; font-size: 32px; font-weight: 600; line-height: 1">24%</span>
<span style="font-size: 10px; line-height: 1.35; color: #2E3A10">Your current month earning is increased by 24% compared to last month.</span>
<div style="margin-top: auto; display: flex; flex-direction: column; gap: 6px">
<div style="display: flex; justify-content: space-between; font-size: 10px"><span style="font-weight: 600">Goal</span><span><b>$2,567</b> / $5,000</span></div>
<div style="display: flex; gap: 3px">
<span style="flex: 1; height: 8px; border-radius: 4px; background: #141414"></span><span style="flex: 1; height: 8px; border-radius: 4px; background: #141414"></span><span style="flex: 1; height: 8px; border-radius: 4px; background: #141414"></span><span style="flex: 1; height: 8px; border-radius: 4px; background: #141414"></span><span style="flex: 1; height: 8px; border-radius: 4px; background: #141414"></span><span style="flex: 1; height: 8px; border-radius: 4px; background: #FFFFFF"></span><span style="flex: 1; height: 8px; border-radius: 4px; background: #FFFFFF"></span><span style="flex: 1; height: 8px; border-radius: 4px; background: #FFFFFF"></span><span style="flex: 1; height: 8px; border-radius: 4px; background: #FFFFFF"></span><span style="flex: 1; height: 8px; border-radius: 4px; background: #FFFFFF"></span>
</div>
</div>
</div>
<div style="background: #1B1C1A; color: #FFFFFF; border-radius: 24px; padding: 14px; display: flex; flex-direction: column; gap: 6px; height: 180px; box-sizing: border-box">
<div style="display: flex; justify-content: space-between; align-items: center">
<span style="display: flex; align-items: center; gap: 4px; font-size: 12px; font-weight: 500"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="{{lime}}" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 7l6 6 4-4 8 8M15 17h6v-6"></path></svg>Spending</span>
<span style="width: 24px; height: 24px; border-radius: 12px; background: #FFFFFF; display: flex; align-items: center; justify-content: center"><svg width="12" height="12" viewBox="0 0 24 24" fill="#141414" aria-hidden="true"><circle cx="5" cy="12" r="2.4"></circle><circle cx="12" cy="12" r="2.4"></circle><circle cx="19" cy="12" r="2.4"></circle></svg></span>
</div>
<span style="font-family: 'Space Grotesk', sans-serif; font-size: 20px; font-weight: 600">$3,250<span style="font-size: 11px; color: #A3A79A">.80</span></span>
<svg width="100%" height="90" viewBox="0 0 120 90" fill="none" role="img" aria-label="Radar chart comparing debit and credit card spending across six categories">
<polygon points="60,4 108,26 108,66 60,88 12,66 12,26" stroke="#3B3E37" stroke-width="1"></polygon>
<polygon points="60,20 92,34 92,58 60,72 28,58 28,34" stroke="#3B3E37" stroke-width="1"></polygon>
<path d="M60 4V88M12 26L108 66M108 26L12 66" stroke="#3B3E37" stroke-width="1"></path>
<polygon points="60,10 100,30 88,60 60,80 22,62 30,30" fill="rgba(46,196,182,0.25)" stroke="#2EC4B6" stroke-width="1.5"></polygon>
<polygon points="60,24 104,28 96,64 60,70 34,56 18,28" fill="rgba(199,227,105,0.25)" stroke="{{lime}}" stroke-width="1.5"></polygon>
</svg>
<div style="display: flex; justify-content: space-between; font-size: 9px; color: #C9CCC0">
<span style="display: flex; align-items: center; gap: 4px"><span style="width: 10px; height: 2px; background: {{lime}}"></span>Debit Card</span>
<span style="display: flex; align-items: center; gap: 4px"><span style="width: 10px; height: 2px; background: #2EC4B6"></span>Credit Card</span>
</div>
</div>
</div>
<div style="display: flex; justify-content: space-between; align-items: center">
<h2 style="margin: 0; font-size: 16px; font-weight: 600">Overview</h2>
<button aria-label="Filter" style="width: 44px; height: 36px; border-radius: 18px; border: none; background: #FFFFFF; display: flex; align-items: center; justify-content: center"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#141414" stroke-width="1.9" stroke-linecap="round" aria-hidden="true"><path d="M4 7h10M18 7h2M4 17h2M10 17h10"></path><circle cx="16" cy="7" r="2"></circle><circle cx="8" cy="17" r="2"></circle></svg></button>
</div>
<div style="background: #FFFFFF; border-radius: 24px; padding: 16px; display: flex; flex-direction: column; gap: 14px; flex: 1">
<div style="display: flex; justify-content: space-between; align-items: flex-start">
<div style="display: flex; flex-direction: column; gap: 4px">
<span style="font-size: 11px; color: #6B7062">Total Balance</span>
<span style="font-family: 'Space Grotesk', sans-serif; font-size: 20px; font-weight: 600">$25,453.00</span>
</div>
<div style="display: flex; flex-direction: column; gap: 6px; font-size: 10px; color: #3F443A; align-items: flex-end">
<span style="display: flex; align-items: center; gap: 6px">Debit Card Spending <span style="width: 10px; height: 10px; border-radius: 3px; background: {{lime}}"></span></span>
<span style="display: flex; align-items: center; gap: 6px">Credit Card Spending <span style="width: 10px; height: 10px; border-radius: 3px; background: #141414"></span></span>
</div>
</div>
<div style="display: flex; gap: 8px; flex: 1">
<div style="display: flex; flex-direction: column; justify-content: space-between; font-size: 9px; color: #6B7062; padding-bottom: 20px; height: 196px">
<span>$3000</span><span>$2500</span><span>$2000</span><span>$1500</span><span>$1000</span><span>$500</span><span>$0</span>
</div>
<div style="flex: 1; display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); align-items: end; height: 196px; position: relative">
<div style="display: flex; flex-direction: column; align-items: center; gap: 3px"><span style="width: 26px; height: 40px; border-radius: 6px; background: {{lime}}"></span><span style="width: 26px; height: 34px; border-radius: 6px; background: #141414"></span><span style="font-size: 9px; color: #6B7062; margin-top: 6px">JAN</span></div>
<div style="display: flex; flex-direction: column; align-items: center; gap: 3px"><span style="width: 26px; height: 28px; border-radius: 6px; background: {{lime}}"></span><span style="width: 26px; height: 23px; border-radius: 6px; background: #141414"></span><span style="font-size: 9px; color: #6B7062; margin-top: 6px">FEB</span></div>
<div style="display: flex; flex-direction: column; align-items: center; gap: 3px"><span style="width: 26px; height: 91px; border-radius: 6px; background: {{lime}}"></span><span style="width: 26px; height: 51px; border-radius: 6px; background: #141414"></span><span style="font-size: 9px; color: #6B7062; margin-top: 6px">MAR</span></div>
<div style="display: flex; flex-direction: column; align-items: center; gap: 3px; position: relative">
<span style="position: absolute; bottom: 160px; background: #141414; color: #FFFFFF; font-size: 10px; font-weight: 600; padding: 4px 8px; border-radius: 8px; white-space: nowrap">$2,410.00</span>
<span style="position: absolute; bottom: 141px; height: 18px; border-left: 1.5px dashed #141414"></span>
<span style="width: 26px; height: 80px; border-radius: 6px; background: {{lime}}"></span><span style="width: 26px; height: 57px; border-radius: 6px; background: #141414"></span><span style="font-size: 9px; color: #141414; font-weight: 600; margin-top: 6px">APR</span>
</div>
<div style="display: flex; flex-direction: column; align-items: center; gap: 3px"><span style="width: 26px; height: 108px; border-radius: 6px; background: {{lime}}"></span><span style="width: 26px; height: 57px; border-radius: 6px; background: #141414"></span><span style="font-size: 9px; color: #6B7062; margin-top: 6px">MAY</span></div>
<div style="display: flex; flex-direction: column; align-items: center; gap: 3px"><span style="width: 26px; height: 51px; border-radius: 6px; background: {{lime}}"></span><span style="width: 26px; height: 40px; border-radius: 6px; background: #141414"></span><span style="font-size: 9px; color: #6B7062; margin-top: 6px">JUN</span></div>
</div>
</div>
</div>
</div>
</x-dc>
<script type="text/x-dc" data-dc-script data-props='{"lime":{"editor":"color","default":"#C7E369","options":["#C7E369","#A7E3C9","#F4D35E","#BFD7FF"]},"$preview":{"width":390,"height":844}}'>
class Component extends DCLogic {
renderVals() {
const lime = this.props.lime ?? '#C7E369';
const picked = (this.state && this.state.picked) || 'Monthly';
const base = 'height: 48px; border-radius: 24px; font-family: Outfit, sans-serif; font-size: 13px; font-weight: 500; color: #141414; cursor: pointer; ';
const periods = ['Today', 'Weekly', 'Monthly', 'Yearly'].map((label) => ({
label,
pick: () => this.setState({ picked: label }),
style: base + (label === picked ? 'border: none; background: ' + lime + ';' : 'border: 1px solid #E3EAD3; background: #FFFFFF;'),
}));
return { lime, periods };
}
}
</script>
</body>
</html>
```SKILL.md
Save as .claude/skills/finance-app-ui/SKILL.md
--- name: finance-app-ui description: Build the Personal Finance mobile app UI in Expo React Native. Use when asked to create a personal finance app UI or a new screen in this visual style. --- # Personal Finance app UI Build this UI in an Expo SDK 58 app with Expo Router and strict TypeScript. Match the spec below rather than inventing a new look. The finished reference lives at https://developermill.com/app-designs/finance-app-ui-design ## Visual direction Fresh lime on pale green with black contrast cards, Space Grotesk figures and a hand-drawn onboarding illustration. Keep these signature details: - Notched debit card drawn in SVG - Radar and stacked bar charts with no chart library - Working period tabs on statistics - Illustrated onboarding with a skip path ## Set up ```bash npx expo install expo-image react-native-svg @expo-google-fonts/outfit @expo-google-fonts/space-grotesk expo-font ``` ## Tokens | Token | Hex | | --- | --- | | Lime | `#C7E369` | | Soft green | `#F3F8E6` | | Ink | `#141414` | | Card black | `#1B1C1A` | | Olive grey | `#6B7062` | | Teal | `#2EC4B6` | - Typefaces: Outfit, Space Grotesk - Common sizes (px): 9, 10, 11, 12, 13, 14, 15, 16 - Common corner radii (px): 4, 6, 20, 23, 24, 26 Define these once and reuse them. Do not add new colours. ## Screens Build one Expo Router route per screen, in this order: 1. **Onboarding**: A hand-drawn wallet illustration on lime, a headline with an inline arrow pill, and skip and start actions. 2. **Card home**: A notched black debit card with budget and tap controls, quick actions, quick send contacts and recent activity. 3. **Statistics**: Period tabs, earning and spending cards with a radar chart, and a monthly overview in stacked bars with a tooltip. ## Build rules - Design on a 390 × 844 artboard, then scale to the device width so layouts match on every phone. - Load each custom font weight by its own family name with expo-font. Do not rely on `fontWeight` with custom fonts. - Draw icons, charts and illustrations with react-native-svg rather than image files or chart libraries. - Use `Pressable` with an `accessibilityLabel` for every icon-only control, and keep touch targets at 44 px or larger. - Wire navigation with `router.navigate`, and keep sample data in constants at the top of each file so it is easy to replace. - Use expo-image for photos, with `contentFit` set explicitly. ## Done when - Every screen above exists as a route and they link together. - Colours, type and radii match the tokens exactly. - `npx tsc --noEmit` and `npx expo lint` both pass. - Layouts hold up on small and large phones.
Set up the project
npx create-expo-app@latest finance-app --template default cd finance-app rm -rf src npx expo install expo-image react-native-svg @expo-google-fonts/outfit @expo-google-fonts/space-grotesk expo-font
src/app/_layout.tsx
import {
Outfit_400Regular,
Outfit_500Medium,
Outfit_600SemiBold,
Outfit_700Bold,
} from '@expo-google-fonts/outfit';
import {
SpaceGrotesk_500Medium,
SpaceGrotesk_600SemiBold,
SpaceGrotesk_700Bold,
} from '@expo-google-fonts/space-grotesk';
import { useFonts } from 'expo-font';
import { Stack } from 'expo-router';
export default function RootLayout() {
const [fontsLoaded] = useFonts({
Outfit_400Regular,
Outfit_500Medium,
Outfit_600SemiBold,
Outfit_700Bold,
SpaceGrotesk_500Medium,
SpaceGrotesk_600SemiBold,
SpaceGrotesk_700Bold,
});
if (!fontsLoaded) return null;
return <Stack screenOptions={{ headerShown: false }} />;
}src/app/home.tsx
import { Image } from 'expo-image';
import { router } from 'expo-router';
import { Pressable, Text, View } from 'react-native';
import Svg, { Circle, Defs, Path, Pattern, RadialGradient, Rect, Stop } from 'react-native-svg';
import { Screen } from '@/components/screen';
import { asset } from '@/lib/assets';
const lime = '#C7E369';
export default function HomeScreen() {
return (
<Screen background="#F3F8E6" statusBar="dark">
<View style={{ flex: 1 }}>
<View
style={{
position: 'absolute',
left: '50%',
bottom: 24,
transform: [{ translateX: '-50%' }],
backgroundColor: '#1B1C1A',
borderRadius: 34,
padding: 8,
gap: 10,
boxShadow: '0 10px 30px rgba(20,20,20,0.25)',
zIndex: 1,
flexDirection: 'row',
}}>
<Pressable
accessibilityRole="link"
accessibilityLabel="Statistics"
onPress={() => router.navigate('/statistics')}
style={{
width: 52,
height: 52,
borderRadius: 26,
backgroundColor: '#2E302B',
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'row',
}}>
<Svg
width="22"
height="22"
viewBox="0 0 24 24"
fill="none"
stroke="#FFFFFF"
strokeWidth="1.9"
strokeLinecap="round"
strokeLinejoin="round">
<Rect x="3" y="3" width="18" height="18" rx="5" />
<Path d="M8 16v-4M12 16V8M16 16v-6" />
</Svg>
</Pressable>
<Pressable
accessibilityRole="link"
accessibilityLabel="Scan to pay"
style={{
width: 52,
height: 52,
borderRadius: 26,
backgroundColor: lime,
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'row',
}}>
<Svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="#141414"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round">
<Path d="M3 8V5a2 2 0 0 1 2-2h3M16 3h3a2 2 0 0 1 2 2v3M21 16v3a2 2 0 0 1-2 2h-3M8 21H5a2 2 0 0 1-2-2v-3" />
<Rect x="8" y="8" width="8" height="8" rx="1.5" />
</Svg>
</Pressable>
<Pressable
accessibilityRole="link"
accessibilityLabel="Menu"
style={{
width: 52,
height: 52,
borderRadius: 26,
backgroundColor: '#2E302B',
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'row',
}}>
<Svg width="22" height="22" viewBox="0 0 24 24" fill="#FFFFFF">
<Circle cx="8" cy="8" r="2" />
<Circle cx="16" cy="8" r="2" />
<Circle cx="8" cy="16" r="2" />
<Circle cx="16" cy="16" r="2" />
</Svg>
</Pressable>
</View>
<View style={{ paddingTop: 52, paddingBottom: 0, paddingHorizontal: 20, gap: 16 }}>
<View
style={{ alignItems: 'center', justifyContent: 'space-between', flexDirection: 'row' }}>
<View style={{ alignItems: 'center', gap: 12, flexShrink: 1, flexDirection: 'row' }}>
<Image
source={{ uri: asset('cbcc3a069b.jpg') }}
contentFit="cover"
accessibilityLabel="William Current"
style={{ width: 48, height: 48, borderRadius: 24 }}
/>
<View style={{ gap: 2, flexShrink: 1 }}>
<Text style={{ fontFamily: 'Outfit_400Regular', fontSize: 13, color: '#5B6150' }}>
William Current
</Text>
<Text style={{ fontFamily: 'Outfit_600SemiBold', fontSize: 20, color: '#141414' }}>
Welcome Back
</Text>
</View>
</View>
<Pressable
accessibilityRole="button"
accessibilityLabel="Notifications"
style={{
width: 48,
height: 48,
borderRadius: 24,
borderWidth: 0,
backgroundColor: '#FFFFFF',
alignItems: 'center',
justifyContent: 'center',
boxShadow: '0 2px 8px rgba(20,20,20,0.06)',
flexDirection: 'row',
}}>
<Svg
width="22"
height="22"
viewBox="0 0 24 24"
fill="none"
stroke="#141414"
strokeWidth="1.9"
strokeLinecap="round"
strokeLinejoin="round">
<Path d="M6 9a6 6 0 1 1 12 0c0 6 2.5 7.5 2.5 7.5h-17S6 15 6 9" />
<Path d="M10 20a2 2 0 0 0 4 0" />
</Svg>
<View
style={{
position: 'absolute',
top: 12,
right: 13,
width: 12,
height: 12,
borderRadius: 4,
backgroundColor: '#E5484D',
borderWidth: 2,
borderColor: '#FFFFFF',
}}
/>
</Pressable>
</View>
<View style={{ height: 207 }}>
<Svg
width="350"
height="207"
viewBox="0 0 350 207"
style={{ position: 'absolute', left: 0, top: 0 }}>
<Defs>
<RadialGradient id="cardGlow" cx="70%" cy="40%" r="75%">
<Stop offset="0%" stopColor="#262824" />
<Stop offset="100%" stopColor="#161715" />
</RadialGradient>
<Pattern
id="cardLines"
patternUnits="userSpaceOnUse"
width="11"
height="11"
patternTransform="rotate(35)">
<Rect x="10" width="1" height="11" fill="rgba(255,255,255,0.045)" />
</Pattern>
</Defs>
<Path
d="M22 0 H230 Q239 0 244 8 L260 30 Q265 37 274 37 H328 A22 22 0 0 1 350 59 V185 A22 22 0 0 1 328 207 H22 A22 22 0 0 1 0 185 V22 A22 22 0 0 1 22 0 Z"
fill="url(#cardGlow)"
/>
<Path
d="M22 0 H230 Q239 0 244 8 L260 30 Q265 37 274 37 H328 A22 22 0 0 1 350 59 V185 A22 22 0 0 1 328 207 H22 A22 22 0 0 1 0 185 V22 A22 22 0 0 1 22 0 Z"
fill="url(#cardLines)"
/>
</Svg>
<Text
style={{
position: 'absolute',
left: 20,
top: 20,
fontFamily: 'SpaceGrotesk_700Bold',
fontSize: 14,
color: '#FFFFFF',
letterSpacing: 0.5,
}}>
VISA
</Text>
<Svg
width="30"
height="30"
viewBox="0 0 24 24"
style={{ position: 'absolute', left: 186, top: 30 }}>
<Path
d="M12 0 C12.8 8.5 15.5 11.2 24 12 C15.5 12.8 12.8 15.5 12 24 C11.2 15.5 8.5 12.8 0 12 C8.5 11.2 11.2 8.5 12 0Z"
fill={lime}
/>
</Svg>
<Svg
width="9"
height="9"
viewBox="0 0 24 24"
style={{ position: 'absolute', left: 186, top: 121 }}>
<Path
d="M12 0 C12.8 8.5 15.5 11.2 24 12 C15.5 12.8 12.8 15.5 12 24 C11.2 15.5 8.5 12.8 0 12 C8.5 11.2 11.2 8.5 12 0Z"
fill="#8FA34A"
/>
</Svg>
<Svg
width="12"
height="12"
viewBox="0 0 24 24"
style={{ position: 'absolute', left: 250, top: 154 }}>
<Path
d="M12 0 C12.8 8.5 15.5 11.2 24 12 C15.5 12.8 12.8 15.5 12 24 C11.2 15.5 8.5 12.8 0 12 C8.5 11.2 11.2 8.5 12 0Z"
fill="#4A4D44"
/>
</Svg>
<Text
style={{
position: 'absolute',
left: 20,
top: 56,
fontFamily: 'Outfit_400Regular',
fontSize: 11,
color: '#9EA295',
}}>
Balance
</Text>
<Text
style={{
position: 'absolute',
left: 20,
top: 74,
fontFamily: 'SpaceGrotesk_500Medium',
fontSize: 30,
color: '#FFFFFF',
letterSpacing: -0.5,
lineHeight: 36,
}}>
$ 25,453.00
</Text>
<Text
style={{
position: 'absolute',
left: 20,
top: 136,
fontFamily: 'Outfit_400Regular',
fontSize: 12,
color: '#D6D9CE',
letterSpacing: 1,
}}>
**** **** **** 7281
</Text>
<View
style={{
position: 'absolute',
left: 20,
width: 253,
bottom: 16,
justifyContent: 'space-between',
flexDirection: 'row',
}}>
<Text
style={{
flexShrink: 1,
fontFamily: 'Outfit_400Regular',
fontSize: 11,
color: '#D6D9CE',
}}>
William Current
</Text>
<Text
style={{
flexShrink: 1,
fontFamily: 'Outfit_400Regular',
fontSize: 11,
color: '#D6D9CE',
}}>
Exp 07/26
</Text>
</View>
<View
style={{
position: 'absolute',
right: 9,
top: 49,
bottom: 9,
width: 52,
borderRadius: 20,
backgroundColor: lime,
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'row',
}}>
<Svg
width="22"
height="22"
viewBox="0 0 24 24"
fill="none"
stroke="#141414"
strokeWidth="2"
strokeLinecap="round">
<Path d="M8 7.5a6 6 0 0 1 0 9" />
<Path d="M12 5a10 10 0 0 1 0 14" />
<Path d="M16 3a13 13 0 0 1 0 18" />
</Svg>
</View>
<Pressable
accessibilityRole="button"
style={{
position: 'absolute',
right: 2,
top: -6,
width: 106,
borderWidth: 0,
backgroundColor: lime,
borderRadius: 17,
height: 34,
paddingVertical: 0,
paddingLeft: 5,
paddingRight: 0,
alignItems: 'center',
gap: 8,
flexDirection: 'row',
}}>
<View
style={{
width: 24,
height: 24,
borderRadius: 12,
backgroundColor: '#141414',
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'row',
}}>
<Svg width="10" height="10" viewBox="0 0 24 24">
<Path
d="M12 0 C12.8 8.5 15.5 11.2 24 12 C15.5 12.8 12.8 15.5 12 24 C11.2 15.5 8.5 12.8 0 12 C8.5 11.2 11.2 8.5 12 0Z"
fill="#FFFFFF"
/>
</Svg>
</View>
<Text
style={{
fontFamily: 'Outfit_600SemiBold',
fontSize: 11,
color: '#141414',
flexShrink: 1,
}}>
Set Budget
</Text>
</Pressable>
</View>
<View style={{ flexDirection: 'row', gap: 10 }}>
<Pressable
accessibilityRole="button"
style={{
height: 80,
borderRadius: 24,
borderWidth: 1,
borderColor: '#E3EAD3',
backgroundColor: '#FFFFFF',
alignItems: 'center',
justifyContent: 'center',
gap: 8,
flex: 1,
}}>
<Svg
width="22"
height="22"
viewBox="0 0 24 24"
fill="none"
stroke="#141414"
strokeWidth="1.9"
strokeLinecap="round"
strokeLinejoin="round">
<Path d="M3 21l3-3" />
<Circle cx="12" cy="12" r="5" />
<Path d="M17 7l4-4M17 3h4v4" />
</Svg>
<Text style={{ fontFamily: 'Outfit_500Medium', fontSize: 13, color: '#141414' }}>
Send
</Text>
</Pressable>
<Pressable
accessibilityRole="button"
style={{
height: 80,
borderRadius: 24,
borderWidth: 1,
borderColor: '#E3EAD3',
backgroundColor: '#FFFFFF',
alignItems: 'center',
justifyContent: 'center',
gap: 8,
flex: 1,
}}>
<Svg
width="22"
height="22"
viewBox="0 0 24 24"
fill="none"
stroke="#141414"
strokeWidth="1.9"
strokeLinecap="round"
strokeLinejoin="round">
<Path d="M6 2h12v20l-3-2-3 2-3-2-3 2z" />
<Path d="M9 7h6M9 11h6M9 15h3" />
</Svg>
<Text style={{ fontFamily: 'Outfit_500Medium', fontSize: 13, color: '#141414' }}>
Bill
</Text>
</Pressable>
<Pressable
accessibilityRole="button"
style={{
height: 80,
borderRadius: 24,
borderWidth: 1,
borderColor: '#E3EAD3',
backgroundColor: '#FFFFFF',
alignItems: 'center',
justifyContent: 'center',
gap: 8,
flex: 1,
}}>
<Svg
width="22"
height="22"
viewBox="0 0 24 24"
fill="none"
stroke="#141414"
strokeWidth="1.9"
strokeLinecap="round"
strokeLinejoin="round">
<Rect x="6" y="2" width="12" height="20" rx="3" />
<Path d="M11 18h2" />
</Svg>
<Text style={{ fontFamily: 'Outfit_500Medium', fontSize: 13, color: '#141414' }}>
Mobile
</Text>
</Pressable>
<Pressable
accessibilityRole="button"
style={{
height: 80,
borderRadius: 24,
borderWidth: 0,
backgroundColor: lime,
alignItems: 'center',
justifyContent: 'center',
gap: 8,
flex: 1,
}}>
<Svg width="22" height="22" viewBox="0 0 24 24" fill="#141414">
<Circle cx="7" cy="7" r="2" />
<Circle cx="17" cy="7" r="2" />
<Circle cx="7" cy="17" r="2" />
<Circle cx="17" cy="17" r="2" />
</Svg>
<Text style={{ fontFamily: 'Outfit_500Medium', fontSize: 13, color: '#141414' }}>
More
</Text>
</Pressable>
</View>
<View
style={{
backgroundColor: '#FFFFFF',
borderRadius: 24,
paddingTop: 14,
paddingBottom: 12,
paddingHorizontal: 16,
gap: 12,
}}>
<View
style={{
justifyContent: 'space-between',
alignItems: 'center',
flexDirection: 'row',
}}>
<Text
style={{
flexShrink: 1,
fontFamily: 'Outfit_600SemiBold',
fontSize: 15,
color: '#141414',
}}>
Quick Send
</Text>
<Pressable
accessibilityRole="link"
style={{ alignItems: 'center', gap: 2, flexShrink: 1, flexDirection: 'row' }}>
<Text
style={{
fontFamily: 'Outfit_400Regular',
fontSize: 12,
color: '#141414',
flexShrink: 1,
}}>
See all
</Text>
<Svg
width="12"
height="12"
viewBox="0 0 12 12"
fill="none"
stroke="#141414"
strokeWidth="1.6"
strokeLinecap="round">
<Path d="M4.5 2.5L8 6l-3.5 3.5" />
</Svg>
</Pressable>
</View>
<View style={{ justifyContent: 'space-between', flexDirection: 'row' }}>
<View style={{ alignItems: 'center', gap: 6, flexShrink: 1 }}>
<Image
source={{ uri: asset('a83189def8.jpg') }}
contentFit="cover"
accessibilityLabel="Azie"
style={{ width: 46, height: 46, borderRadius: 23 }}
/>
<Text style={{ fontFamily: 'Outfit_400Regular', fontSize: 11, color: '#3F443A' }}>
Azie
</Text>
</View>
<View style={{ alignItems: 'center', gap: 6, flexShrink: 1 }}>
<Image
source={{ uri: asset('fea6aeff93.jpg') }}
contentFit="cover"
accessibilityLabel="Chaoir"
style={{ width: 46, height: 46, borderRadius: 23 }}
/>
<Text style={{ fontFamily: 'Outfit_400Regular', fontSize: 11, color: '#3F443A' }}>
Chaoir
</Text>
</View>
<View style={{ alignItems: 'center', gap: 6, flexShrink: 1 }}>
<Image
source={{ uri: asset('1cb0912499.jpg') }}
contentFit="cover"
accessibilityLabel="Famdit"
style={{ width: 46, height: 46, borderRadius: 23 }}
/>
<Text style={{ fontFamily: 'Outfit_400Regular', fontSize: 11, color: '#3F443A' }}>
Famdit
</Text>
</View>
<View style={{ alignItems: 'center', gap: 6, flexShrink: 1 }}>
<Image
source={{ uri: asset('ddb012f2c0.jpg') }}
contentFit="cover"
accessibilityLabel="Happy"
style={{ width: 46, height: 46, borderRadius: 23 }}
/>
<Text style={{ fontFamily: 'Outfit_400Regular', fontSize: 11, color: '#3F443A' }}>
Happy
</Text>
</View>
<View style={{ alignItems: 'center', gap: 6, flexShrink: 1 }}>
<Image
source={{ uri: asset('04d09efc3a.jpg') }}
contentFit="cover"
accessibilityLabel="Nayu"
style={{ width: 46, height: 46, borderRadius: 23 }}
/>
<Text style={{ fontFamily: 'Outfit_400Regular', fontSize: 11, color: '#3F443A' }}>
Nayu
</Text>
</View>
</View>
</View>
<View
style={{ justifyContent: 'space-between', alignItems: 'center', flexDirection: 'row' }}>
<Text
style={{
flexShrink: 1,
fontFamily: 'Outfit_600SemiBold',
fontSize: 15,
color: '#141414',
}}>
Recent Activity
</Text>
<Pressable
accessibilityRole="link"
style={{ alignItems: 'center', gap: 2, flexShrink: 1, flexDirection: 'row' }}>
<Text
style={{
fontFamily: 'Outfit_400Regular',
fontSize: 12,
color: '#141414',
flexShrink: 1,
}}>
See all
</Text>
<Svg
width="12"
height="12"
viewBox="0 0 12 12"
fill="none"
stroke="#141414"
strokeWidth="1.6"
strokeLinecap="round">
<Path d="M4.5 2.5L8 6l-3.5 3.5" />
</Svg>
</Pressable>
</View>
<View
style={{
backgroundColor: '#FFFFFF',
borderRadius: 24,
paddingVertical: 4,
paddingHorizontal: 16,
}}>
<View
style={{
alignItems: 'center',
gap: 12,
paddingVertical: 12,
paddingHorizontal: 0,
borderBottomWidth: 1,
borderBottomColor: '#EEF2E4',
flexDirection: 'row',
}}>
<View
style={{
width: 40,
height: 40,
borderRadius: 20,
backgroundColor: '#F3F8E6',
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'row',
}}>
<Svg
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
stroke="#141414"
strokeWidth="1.8"
strokeLinecap="round"
strokeLinejoin="round">
<Path d="M5 8h14l-1.5 12h-11z" />
<Path d="M9 8V6a3 3 0 0 1 6 0v2" />
</Svg>
</View>
<View style={{ flex: 1, gap: 2 }}>
<Text style={{ fontFamily: 'Outfit_600SemiBold', fontSize: 14, color: '#141414' }}>
Food Store
</Text>
<Text style={{ fontFamily: 'Outfit_400Regular', fontSize: 11, color: '#6B7062' }}>
Monday, 25 January
</Text>
</View>
<Text
style={{
flexShrink: 1,
fontFamily: 'SpaceGrotesk_600SemiBold',
fontSize: 16,
color: '#141414',
}}>
-$15.00
</Text>
</View>
<View
style={{
alignItems: 'center',
gap: 12,
paddingVertical: 12,
paddingHorizontal: 0,
borderBottomWidth: 1,
borderBottomColor: '#EEF2E4',
flexDirection: 'row',
}}>
<View
style={{
width: 40,
height: 40,
borderRadius: 20,
backgroundColor: '#F3F8E6',
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'row',
}}>
<Svg
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
stroke="#141414"
strokeWidth="1.8"
strokeLinecap="round"
strokeLinejoin="round">
<Path d="M3 11l9-7 9 7" />
<Path d="M5 10v10h14V10" />
<Path d="M10 20v-6h4v6" />
</Svg>
</View>
<View style={{ flex: 1, gap: 2 }}>
<Text style={{ fontFamily: 'Outfit_600SemiBold', fontSize: 14, color: '#141414' }}>
House Rent
</Text>
<Text style={{ fontFamily: 'Outfit_400Regular', fontSize: 11, color: '#6B7062' }}>
Monday, 25 January
</Text>
</View>
<Text
style={{
flexShrink: 1,
fontFamily: 'SpaceGrotesk_600SemiBold',
fontSize: 16,
color: '#141414',
}}>
-$290.00
</Text>
</View>
<View
style={{
alignItems: 'center',
gap: 12,
paddingVertical: 12,
paddingHorizontal: 0,
flexDirection: 'row',
}}>
<View
style={{
width: 40,
height: 40,
borderRadius: 20,
backgroundColor: '#F3F8E6',
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'row',
}}>
<Svg
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
stroke="#141414"
strokeWidth="1.8"
strokeLinecap="round"
strokeLinejoin="round">
<Rect x="5" y="3" width="14" height="15" rx="3" />
<Path d="M5 11h14" />
<Path d="M8 21l2-3M16 21l-2-3" />
</Svg>
</View>
<View style={{ flex: 1, gap: 2 }}>
<Text style={{ fontFamily: 'Outfit_600SemiBold', fontSize: 14, color: '#141414' }}>
Metro Card
</Text>
<Text style={{ fontFamily: 'Outfit_400Regular', fontSize: 11, color: '#6B7062' }}>
Sunday, 24 January
</Text>
</View>
<Text
style={{
flexShrink: 1,
fontFamily: 'SpaceGrotesk_600SemiBold',
fontSize: 16,
color: '#141414',
}}>
-$27.00
</Text>
</View>
</View>
</View>
</View>
</Screen>
);
}src/app/index.tsx
import { Image } from 'expo-image';
import { router } from 'expo-router';
import { Pressable, Text, View } from 'react-native';
import Svg, { Path } from 'react-native-svg';
import { Screen } from '@/components/screen';
import { asset } from '@/lib/assets';
export default function MainScreen() {
return (
<Screen background="#C7E369" statusBar="dark">
<View style={{ paddingVertical: 40, paddingHorizontal: 28, flex: 1 }}>
<View
style={{
flex: 1,
minHeight: 0,
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'row',
}}>
<Image
source={{ uri: asset('b81c0d5bb9.jpg') }}
contentFit="contain"
accessibilityLabel="Smiling man popping out of a wallet, pointing up, with a QR code, card, coin and receipt floating around him"
style={{ width: '100%', height: '100%' }}
/>
</View>
<View style={{ marginTop: 8, marginBottom: 0, marginHorizontal: 0 }}>
<Text
style={{
margin: 0,
fontFamily: 'SpaceGrotesk_500Medium',
fontSize: 38,
color: '#141414',
letterSpacing: -0.5,
lineHeight: 46.36,
}}>
Digital Banking
</Text>
<View style={{ alignItems: 'center', gap: 12, flexDirection: 'row' }}>
<Text
style={{
margin: 0,
flexShrink: 1,
fontFamily: 'SpaceGrotesk_500Medium',
fontSize: 38,
color: '#141414',
letterSpacing: -0.5,
lineHeight: 46.36,
}}>
Made for
</Text>
<View
style={{
alignItems: 'center',
justifyContent: 'center',
width: 64,
height: 30,
borderRadius: 15,
backgroundColor: '#141414',
flexDirection: 'row',
}}>
<Svg
width="26"
height="14"
viewBox="0 0 26 14"
fill="none"
stroke="#C7E369"
strokeWidth="2.4"
strokeLinecap="round"
strokeLinejoin="round">
<Path d="M2 7h21M17 1l6 6-6 6" />
</Svg>
</View>
</View>
<Text
style={{
margin: 0,
fontFamily: 'SpaceGrotesk_500Medium',
fontSize: 38,
color: '#141414',
letterSpacing: -0.5,
lineHeight: 46.36,
}}>
Digital Users
</Text>
</View>
<Text
style={{
marginTop: 14,
marginBottom: 32,
marginHorizontal: 0,
fontFamily: 'Outfit_400Regular',
fontSize: 15,
color: '#2E3A10',
}}>
Spend, earn and track financial activity
</Text>
<View
style={{ alignItems: 'center', justifyContent: 'space-between', flexDirection: 'row' }}>
<Pressable
accessibilityRole="link"
onPress={() => router.navigate('/home')}
style={{ paddingVertical: 12, paddingHorizontal: 4, minHeight: 44, flexShrink: 1 }}>
<Text style={{ fontFamily: 'Outfit_600SemiBold', fontSize: 15, color: '#141414' }}>
Skip
</Text>
</Pressable>
<View style={{ alignItems: 'center', gap: 14, flexShrink: 1, flexDirection: 'row' }}>
<Text
style={{
flexShrink: 1,
fontFamily: 'Outfit_600SemiBold',
fontSize: 15,
color: '#141414',
}}>
{"Let's Start"}
</Text>
<Pressable
accessibilityRole="link"
accessibilityLabel="Let's start"
onPress={() => router.navigate('/home')}
style={{
width: 64,
height: 64,
borderRadius: 32,
backgroundColor: '#141414',
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'row',
}}>
<Svg
width="22"
height="22"
viewBox="0 0 22 22"
fill="none"
stroke="#FFFFFF"
strokeWidth="2.4"
strokeLinecap="round"
strokeLinejoin="round">
<Path d="M4 18L18 4M8 4h10v10" />
</Svg>
</Pressable>
</View>
</View>
</View>
</Screen>
);
}src/app/statistics.tsx
import { router } from 'expo-router';
import { useState } from 'react';
import { Pressable, Text, View } from 'react-native';
import Svg, { Circle, Path, Polygon } from 'react-native-svg';
import { Screen } from '@/components/screen';
const lime = '#C7E369';
export default function StatisticsScreen() {
const [picked, setPicked] = useState('Monthly');
const periods = ['Today', 'Weekly', 'Monthly', 'Yearly'].map((label) => ({
label,
pick: () => setPicked(label),
style: {
height: 48,
borderRadius: 24,
...(label === picked
? { backgroundColor: lime }
: { backgroundColor: '#FFFFFF', borderWidth: 1, borderColor: '#E3EAD3' }),
},
}));
return (
<Screen background="#F3F8E6" statusBar="dark">
<View style={{ paddingTop: 52, paddingBottom: 24, paddingHorizontal: 20, gap: 18, flex: 1 }}>
<View
style={{ alignItems: 'center', justifyContent: 'space-between', flexDirection: 'row' }}>
<Pressable
accessibilityRole="link"
accessibilityLabel="Back"
onPress={() => router.navigate('/home')}
style={{
width: 48,
height: 48,
borderRadius: 24,
backgroundColor: '#FFFFFF',
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'row',
}}>
<Svg
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
stroke="#141414"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round">
<Path d="M20 12H4M10 6l-6 6 6 6" />
</Svg>
</Pressable>
<Text
style={{
margin: 0,
flexShrink: 1,
fontFamily: 'Outfit_600SemiBold',
fontSize: 18,
color: '#141414',
}}>
Statistics
</Text>
<Pressable
accessibilityRole="button"
accessibilityLabel="More options"
style={{
width: 48,
height: 48,
borderRadius: 24,
borderWidth: 0,
backgroundColor: '#FFFFFF',
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'row',
}}>
<Svg width="20" height="20" viewBox="0 0 24 24" fill="#141414">
<Circle cx="5" cy="12" r="2" />
<Circle cx="12" cy="12" r="2" />
<Circle cx="19" cy="12" r="2" />
</Svg>
</Pressable>
</View>
<View style={{ flexDirection: 'row', gap: 8 }}>
{periods.map((p, index) => (
<Pressable
key={index}
accessibilityRole="button"
onPress={p.pick}
style={{ ...p.style, flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text
style={{
fontFamily: 'Outfit_500Medium',
fontSize: 13,
color: '#141414',
textAlign: 'center',
}}>
{p.label}
</Text>
</Pressable>
))}
</View>
<View style={{ flexDirection: 'row', gap: 12 }}>
<View
style={{
backgroundColor: lime,
borderRadius: 24,
padding: 14,
gap: 8,
height: 180,
flex: 1,
}}>
<View
style={{
justifyContent: 'space-between',
alignItems: 'center',
flexDirection: 'row',
}}>
<View style={{ alignItems: 'center', gap: 4, flexShrink: 1, flexDirection: 'row' }}>
<Svg
width="14"
height="14"
viewBox="0 0 24 24"
fill="none"
stroke="#141414"
strokeWidth="2.2"
strokeLinecap="round"
strokeLinejoin="round">
<Path d="M3 17l6-6 4 4 8-8M15 7h6v6" />
</Svg>
<Text
style={{
fontFamily: 'Outfit_500Medium',
fontSize: 12,
color: '#141414',
flexShrink: 1,
}}>
Earning
</Text>
</View>
<View
style={{
width: 24,
height: 24,
borderRadius: 12,
backgroundColor: '#141414',
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'row',
}}>
<Svg width="12" height="12" viewBox="0 0 24 24" fill="#FFFFFF">
<Circle cx="5" cy="12" r="2.4" />
<Circle cx="12" cy="12" r="2.4" />
<Circle cx="19" cy="12" r="2.4" />
</Svg>
</View>
</View>
<Text
style={{
fontFamily: 'SpaceGrotesk_600SemiBold',
fontSize: 32,
color: '#141414',
lineHeight: 32,
}}>
24%
</Text>
<Text
style={{
fontFamily: 'Outfit_400Regular',
fontSize: 10,
color: '#2E3A10',
lineHeight: 13.5,
}}>
Your current month earning is increased by 24% compared to last month.
</Text>
<View style={{ marginTop: 'auto', gap: 6 }}>
<View style={{ justifyContent: 'space-between', flexDirection: 'row' }}>
<Text
style={{
flexShrink: 1,
fontFamily: 'Outfit_600SemiBold',
fontSize: 10,
color: '#141414',
}}>
Goal
</Text>
<Text
style={{
flexShrink: 1,
fontFamily: 'Outfit_400Regular',
fontSize: 10,
color: '#141414',
}}>
<Text style={{ fontFamily: 'Outfit_700Bold' }}>$2,567</Text>
{' / $5,000'}
</Text>
</View>
<View style={{ gap: 3, flexDirection: 'row' }}>
<View style={{ flex: 1, height: 8, borderRadius: 4, backgroundColor: '#141414' }} />
<View style={{ flex: 1, height: 8, borderRadius: 4, backgroundColor: '#141414' }} />
<View style={{ flex: 1, height: 8, borderRadius: 4, backgroundColor: '#141414' }} />
<View style={{ flex: 1, height: 8, borderRadius: 4, backgroundColor: '#141414' }} />
<View style={{ flex: 1, height: 8, borderRadius: 4, backgroundColor: '#141414' }} />
<View style={{ flex: 1, height: 8, borderRadius: 4, backgroundColor: '#FFFFFF' }} />
<View style={{ flex: 1, height: 8, borderRadius: 4, backgroundColor: '#FFFFFF' }} />
<View style={{ flex: 1, height: 8, borderRadius: 4, backgroundColor: '#FFFFFF' }} />
<View style={{ flex: 1, height: 8, borderRadius: 4, backgroundColor: '#FFFFFF' }} />
<View style={{ flex: 1, height: 8, borderRadius: 4, backgroundColor: '#FFFFFF' }} />
</View>
</View>
</View>
<View
style={{
backgroundColor: '#1B1C1A',
borderRadius: 24,
padding: 14,
gap: 6,
height: 180,
flex: 1,
}}>
<View
style={{
justifyContent: 'space-between',
alignItems: 'center',
flexDirection: 'row',
}}>
<View style={{ alignItems: 'center', gap: 4, flexShrink: 1, flexDirection: 'row' }}>
<Svg
width="14"
height="14"
viewBox="0 0 24 24"
fill="none"
stroke={lime}
strokeWidth="2.2"
strokeLinecap="round"
strokeLinejoin="round">
<Path d="M3 7l6 6 4-4 8 8M15 17h6v-6" />
</Svg>
<Text
style={{
fontFamily: 'Outfit_500Medium',
fontSize: 12,
color: '#FFFFFF',
flexShrink: 1,
}}>
Spending
</Text>
</View>
<View
style={{
width: 24,
height: 24,
borderRadius: 12,
backgroundColor: '#FFFFFF',
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'row',
}}>
<Svg width="12" height="12" viewBox="0 0 24 24" fill="#141414">
<Circle cx="5" cy="12" r="2.4" />
<Circle cx="12" cy="12" r="2.4" />
<Circle cx="19" cy="12" r="2.4" />
</Svg>
</View>
</View>
<Text
style={{ fontFamily: 'SpaceGrotesk_600SemiBold', fontSize: 20, color: '#FFFFFF' }}>
$3,250<Text style={{ fontSize: 11, color: '#A3A79A' }}>.80</Text>
</Text>
<Svg
width="100%"
height="90"
viewBox="0 0 120 90"
fill="none"
accessibilityRole="image"
accessibilityLabel="Radar chart comparing debit and credit card spending across six categories">
<Polygon
points="60,4 108,26 108,66 60,88 12,66 12,26"
stroke="#3B3E37"
strokeWidth="1"
/>
<Polygon
points="60,20 92,34 92,58 60,72 28,58 28,34"
stroke="#3B3E37"
strokeWidth="1"
/>
<Path d="M60 4V88M12 26L108 66M108 26L12 66" stroke="#3B3E37" strokeWidth="1" />
<Polygon
points="60,10 100,30 88,60 60,80 22,62 30,30"
fill="rgba(46,196,182,0.25)"
stroke="#2EC4B6"
strokeWidth="1.5"
/>
<Polygon
points="60,24 104,28 96,64 60,70 34,56 18,28"
fill="rgba(199,227,105,0.25)"
stroke={lime}
strokeWidth="1.5"
/>
</Svg>
<View style={{ justifyContent: 'space-between', flexDirection: 'row' }}>
<View style={{ alignItems: 'center', gap: 4, flexShrink: 1, flexDirection: 'row' }}>
<View style={{ width: 10, height: 2, backgroundColor: lime }} />
<Text
style={{
fontFamily: 'Outfit_400Regular',
fontSize: 9,
color: '#C9CCC0',
flexShrink: 1,
}}>
Debit Card
</Text>
</View>
<View style={{ alignItems: 'center', gap: 4, flexShrink: 1, flexDirection: 'row' }}>
<View style={{ width: 10, height: 2, backgroundColor: '#2EC4B6' }} />
<Text
style={{
fontFamily: 'Outfit_400Regular',
fontSize: 9,
color: '#C9CCC0',
flexShrink: 1,
}}>
Credit Card
</Text>
</View>
</View>
</View>
</View>
<View
style={{ justifyContent: 'space-between', alignItems: 'center', flexDirection: 'row' }}>
<Text
style={{
margin: 0,
flexShrink: 1,
fontFamily: 'Outfit_600SemiBold',
fontSize: 16,
color: '#141414',
}}>
Overview
</Text>
<Pressable
accessibilityRole="button"
accessibilityLabel="Filter"
style={{
width: 44,
height: 36,
borderRadius: 18,
borderWidth: 0,
backgroundColor: '#FFFFFF',
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'row',
}}>
<Svg
width="18"
height="18"
viewBox="0 0 24 24"
fill="none"
stroke="#141414"
strokeWidth="1.9"
strokeLinecap="round">
<Path d="M4 7h10M18 7h2M4 17h2M10 17h10" />
<Circle cx="16" cy="7" r="2" />
<Circle cx="8" cy="17" r="2" />
</Svg>
</Pressable>
</View>
<View
style={{ backgroundColor: '#FFFFFF', borderRadius: 24, padding: 16, gap: 14, flex: 1 }}>
<View
style={{
justifyContent: 'space-between',
alignItems: 'flex-start',
flexDirection: 'row',
}}>
<View style={{ gap: 4, flexShrink: 1 }}>
<Text style={{ fontFamily: 'Outfit_400Regular', fontSize: 11, color: '#6B7062' }}>
Total Balance
</Text>
<Text
style={{ fontFamily: 'SpaceGrotesk_600SemiBold', fontSize: 20, color: '#141414' }}>
$25,453.00
</Text>
</View>
<View style={{ gap: 6, alignItems: 'flex-end', flexShrink: 1 }}>
<View style={{ alignItems: 'center', gap: 6, flexDirection: 'row' }}>
<Text
style={{
fontFamily: 'Outfit_400Regular',
fontSize: 10,
color: '#3F443A',
flexShrink: 1,
}}>
Debit Card Spending
</Text>
<View style={{ width: 10, height: 10, borderRadius: 3, backgroundColor: lime }} />
</View>
<View style={{ alignItems: 'center', gap: 6, flexDirection: 'row' }}>
<Text
style={{
fontFamily: 'Outfit_400Regular',
fontSize: 10,
color: '#3F443A',
flexShrink: 1,
}}>
Credit Card Spending
</Text>
<View
style={{ width: 10, height: 10, borderRadius: 3, backgroundColor: '#141414' }}
/>
</View>
</View>
</View>
<View style={{ gap: 8, flex: 1, flexDirection: 'row' }}>
<View
style={{
justifyContent: 'space-between',
paddingBottom: 20,
height: 216,
flexShrink: 1,
}}>
<Text style={{ fontFamily: 'Outfit_400Regular', fontSize: 9, color: '#6B7062' }}>
$3000
</Text>
<Text style={{ fontFamily: 'Outfit_400Regular', fontSize: 9, color: '#6B7062' }}>
$2500
</Text>
<Text style={{ fontFamily: 'Outfit_400Regular', fontSize: 9, color: '#6B7062' }}>
$2000
</Text>
<Text style={{ fontFamily: 'Outfit_400Regular', fontSize: 9, color: '#6B7062' }}>
$1500
</Text>
<Text style={{ fontFamily: 'Outfit_400Regular', fontSize: 9, color: '#6B7062' }}>
$1000
</Text>
<Text style={{ fontFamily: 'Outfit_400Regular', fontSize: 9, color: '#6B7062' }}>
$500
</Text>
<Text style={{ fontFamily: 'Outfit_400Regular', fontSize: 9, color: '#6B7062' }}>
$0
</Text>
</View>
<View style={{ flex: 1, height: 196, flexDirection: 'row', alignItems: 'flex-end' }}>
<View style={{ alignItems: 'center', gap: 3, flex: 1 }}>
<View style={{ width: 26, height: 40, borderRadius: 6, backgroundColor: lime }} />
<View
style={{ width: 26, height: 34, borderRadius: 6, backgroundColor: '#141414' }}
/>
<Text
style={{
marginTop: 6,
fontFamily: 'Outfit_400Regular',
fontSize: 9,
color: '#6B7062',
}}>
JAN
</Text>
</View>
<View style={{ alignItems: 'center', gap: 3, flex: 1 }}>
<View style={{ width: 26, height: 28, borderRadius: 6, backgroundColor: lime }} />
<View
style={{ width: 26, height: 23, borderRadius: 6, backgroundColor: '#141414' }}
/>
<Text
style={{
marginTop: 6,
fontFamily: 'Outfit_400Regular',
fontSize: 9,
color: '#6B7062',
}}>
FEB
</Text>
</View>
<View style={{ alignItems: 'center', gap: 3, flex: 1 }}>
<View style={{ width: 26, height: 91, borderRadius: 6, backgroundColor: lime }} />
<View
style={{ width: 26, height: 51, borderRadius: 6, backgroundColor: '#141414' }}
/>
<Text
style={{
marginTop: 6,
fontFamily: 'Outfit_400Regular',
fontSize: 9,
color: '#6B7062',
}}>
MAR
</Text>
</View>
<View style={{ alignItems: 'center', gap: 3, flex: 1 }}>
<Text
numberOfLines={1}
style={{
position: 'absolute',
bottom: 160,
backgroundColor: '#141414',
paddingVertical: 4,
paddingHorizontal: 8,
borderRadius: 8,
zIndex: 1,
fontFamily: 'Outfit_600SemiBold',
fontSize: 10,
color: '#FFFFFF',
}}>
$2,410.00
</Text>
<View
style={{
position: 'absolute',
bottom: 141,
height: 18,
borderLeftWidth: 1.5,
borderLeftColor: '#141414',
borderStyle: 'dashed',
zIndex: 1,
}}
/>
<View style={{ width: 26, height: 80, borderRadius: 6, backgroundColor: lime }} />
<View
style={{ width: 26, height: 57, borderRadius: 6, backgroundColor: '#141414' }}
/>
<Text
style={{
marginTop: 6,
fontFamily: 'Outfit_600SemiBold',
fontSize: 9,
color: '#141414',
}}>
APR
</Text>
</View>
<View style={{ alignItems: 'center', gap: 3, flex: 1 }}>
<View style={{ width: 26, height: 108, borderRadius: 6, backgroundColor: lime }} />
<View
style={{ width: 26, height: 57, borderRadius: 6, backgroundColor: '#141414' }}
/>
<Text
style={{
marginTop: 6,
fontFamily: 'Outfit_400Regular',
fontSize: 9,
color: '#6B7062',
}}>
MAY
</Text>
</View>
<View style={{ alignItems: 'center', gap: 3, flex: 1 }}>
<View style={{ width: 26, height: 51, borderRadius: 6, backgroundColor: lime }} />
<View
style={{ width: 26, height: 40, borderRadius: 6, backgroundColor: '#141414' }}
/>
<Text
style={{
marginTop: 6,
fontFamily: 'Outfit_400Regular',
fontSize: 9,
color: '#6B7062',
}}>
JUN
</Text>
</View>
</View>
</View>
</View>
</View>
</Screen>
);
}src/components/screen.tsx
import { StatusBar } from 'expo-status-bar';
import type { ReactNode } from 'react';
import { ScrollView, useWindowDimensions, View } from 'react-native';
// Every screen is drawn on a 390 x 844 artboard, then scaled to the device width.
const ARTBOARD_WIDTH = 390;
const ARTBOARD_HEIGHT = 844;
type Props = {
background: string;
statusBar: 'light' | 'dark';
children: ReactNode;
};
export function Screen({ background, statusBar, children }: Props) {
const { width, height } = useWindowDimensions();
const scale = width / ARTBOARD_WIDTH;
return (
<ScrollView
bounces={false}
showsVerticalScrollIndicator={false}
style={{ flex: 1, backgroundColor: background }}
contentContainerStyle={{ height: Math.max(ARTBOARD_HEIGHT * scale, height) }}>
<StatusBar style={statusBar} />
<View
style={{
width: ARTBOARD_WIDTH,
height: ARTBOARD_HEIGHT,
overflow: 'hidden',
transformOrigin: 'left top',
transform: [{ scale }],
}}>
{children}
</View>
</ScrollView>
);
}src/lib/assets.ts
// Demo images are hosted by DeveloperMill. Point this at your own CDN, or swap to require().
const ASSET_BASE = 'https://developermill.com/app-designs/finance-app-ui-design/assets';
export const asset = (name: string) => `${ASSET_BASE}/${name}`;About this design
The statistics screen combines an earnings goal, a radar chart of card spending and a monthly bar chart, with working period tabs.
Fresh lime on pale green with black contrast cards, Space Grotesk figures and a hand-drawn onboarding illustration.
- Notched debit card drawn in SVG
- Radar and stacked bar charts with no chart library
- Working period tabs on statistics
- Illustrated onboarding with a skip path
Colour palette
Lime
#C7E369
Soft green
#F3F8E6
Ink
#141414
Card black
#1B1C1A
Olive grey
#6B7062
Teal
#2EC4B6
How to use this design
- 01
Pick what to copy
Copy the Personal Finance artifact, skill or code from this page.
- 02
Run it or generate it
Paste the code into a new Expo app and start it, or give the skill to your AI coding agent.
- 03
Make it yours
Replace the demo images and sample content, then connect your own data.
Frequently asked questions
Which charts are included?
A radar chart, stacked monthly bars and a segmented goal bar. All of them are built with views and react-native-svg, so there is no chart dependency.
Is the Personal Finance design free to use?
Yes. The design, skill and Expo code are free and MIT licensed, including for commercial apps. Replace the demo images and sample content with your own before you ship.
What is the difference between the artifact, skill and code?
The artifact is the full design: tokens, screens and source. The skill is a SKILL.md that teaches an AI coding agent to build the UI. The code is the finished Expo app you can paste in and run.
Which Expo version does the code use?
It targets Expo SDK 58 with Expo Router and TypeScript. It uses packages installed through npx expo install, with no custom native code.



