Every bank, one view
Link savings and credit cards from 40+ Indian banks.
Templates
A launch page for a budgeting app with phone mock-ups, store buttons, feature highlights, store reviews and a QR code to install.
Nav · hero with phones and store buttons · stats · feature spotlight · feature cards · how it works · reviews · FAQ · download CTA with QR · footer
Gullak splits your pay into rent, bills, savings and fun the day it lands, so you always know what is safe to spend.
Why people stay
Payments are tagged as food, travel or bills the moment they happen. Fix one and it learns.
A gentle nudge when a jar is running low, with how many days are left until payday.
Rent, EMIs and subscriptions are found from your history and reminded three days early.
Features
Link savings and credit cards from 40+ Indian banks.
Share a trip jar and settle up with one UPI request.
A two-minute summary on the 1st, with one thing to try.
We can see transactions, never move money. Your data is never sold.
How it works
With your mobile number. No forms, no documents.
Pick your bank and approve access once. Six months of history comes in.
Start from our suggestions or set your own amounts. Done before your tea.
Reviews
First app that made me save without making me feel bad. Goa trip jar is at 54%!
My rent is set aside the day salary comes. No more panic on the 30th.
No ads, no loan offers, no clutter. Just my money, sorted.
FAQ
Yes. Jars, insights and reminders are free. Gullak Plus at ₹99 a month adds shared jars and exports.
No. Bank access is read-only. Money only moves when you pay from your own UPI app.
Over 40 Indian banks, including all large public and private banks, and most credit cards.
Delete your account from settings and your data is erased within 30 days.
Free on Android and iPhone. Takes three minutes to set up.
import { Bell, CalendarClock, ChartColumn, Check, CreditCard, Lock, Play, Smartphone, Star, TrendingUp, Users } from "lucide-react";
import { cn } from "@/lib/utils";
const jars = [
{ name: "Rent", saved: "₹18,000", goal: "18,000", pct: 100 },
{ name: "Groceries", saved: "₹6,240", goal: "9,000", pct: 69 },
{ name: "Goa trip", saved: "₹21,500", goal: "40,000", pct: 54 },
];
const stats = [
{ value: "20 lakh+", label: "downloads" },
{ value: "₹1,400 Cr", label: "sorted into jars" },
{ value: "4.8 ★", label: "average rating" },
{ value: "₹3,100", label: "saved a month, on average" },
];
const highlights = [
{ icon: TrendingUp, title: "Sorts every rupee by itself", body: "Payments are tagged as food, travel or bills the moment they happen." },
{ icon: Bell, title: "Warns you, not scolds you", body: "A gentle nudge when a jar is running low, with days left until payday." },
{ icon: CalendarClock, title: "Bills never sneak up", body: "Rent, EMIs and subscriptions reminded three days early." },
];
const features = [
{ icon: CreditCard, title: "Every bank, one view", body: "Link savings and credit cards from 40+ Indian banks." },
{ icon: Users, title: "Split with friends", body: "Share a trip jar and settle up with one UPI request." },
{ icon: ChartColumn, title: "Month in review", body: "A two-minute summary on the 1st, with one thing to try." },
{ icon: Lock, title: "Read-only and private", body: "We can see transactions, never move money." },
];
const steps = [
{ title: "Download and sign in", body: "With your mobile number. No forms, no documents." },
{ title: "Link your bank, read-only", body: "Approve access once. Six months of history comes in." },
{ title: "Make your jars", body: "Start from our suggestions or set your own amounts." },
];
const reviews = [
{ title: "Finally saving every month", body: "First app that made me save without making me feel bad.", name: "Aditi P.", meta: "Android · Sept 2026" },
{ title: "The rent jar alone is worth it", body: "My rent is set aside the day salary comes.", name: "Rohan M.", meta: "iPhone · Aug 2026" },
{ title: "Clean and calm", body: "No ads, no loan offers, no clutter. Just my money, sorted.", name: "Shreya N.", meta: "Android · Oct 2026" },
];
const faqs = [
{ q: "Is Gullak free?", a: "Yes. Jars, insights and reminders are free. Gullak Plus adds shared jars and exports." },
{ q: "Can Gullak move my money?", a: "No. Bank access is read-only." },
{ q: "Which banks work?", a: "Over 40 Indian banks and most credit cards." },
{ q: "What if I delete the app?", a: "Your data is erased within 30 days." },
];
function Container({ className, children }: { className?: string; children: React.ReactNode }) {
return <div className={cn("mx-auto w-full max-w-6xl px-5 sm:px-8", className)}>{children}</div>;
}
function Heading({ eyebrow, title, left }: { eyebrow: string; title: string; left?: boolean }) {
return (
<div className={cn("mb-12 grid max-w-2xl gap-3", !left && "mx-auto text-center")}>
<p className="text-sm font-medium text-primary">{eyebrow}</p>
<h2 className="text-balance text-3xl font-semibold tracking-tight sm:text-4xl">{title}</h2>
</div>
);
}
function StoreButtons({ inverted }: { inverted?: boolean }) {
const base = cn("inline-flex h-[52px] items-center gap-2.5 rounded-lg px-4 leading-tight", inverted ? "bg-bg text-fg" : "bg-fg text-bg");
return (
<div className="flex flex-wrap gap-2.5">
<a href="#" className={base}><Smartphone className="size-6" /><span><span className="block text-[11px]">Download on the</span><b className="font-semibold">App Store</b></span></a>
<a href="#" className={base}><Play className="size-6" /><span><span className="block text-[11px]">Get it on</span><b className="font-semibold">Google Play</b></span></a>
</div>
);
}
function Phone({ className }: { className?: string }) {
return (
<div className={cn("w-[270px] rounded-[46px] bg-neutral-900 p-2.5 shadow-2xl", className)}>
<div className="grid h-[540px] grid-rows-[auto_1fr] overflow-hidden rounded-[36px] bg-bg text-xs text-fg">
<div className="flex justify-between px-6 pt-3 text-[11px] font-semibold"><span>9:41</span><span>5G</span></div>
<div className="grid content-start gap-2.5 px-3.5 pt-5">
<p className="text-[15px] font-semibold">Hi, Aditi</p>
<div className="rounded-lg bg-primary p-3.5 text-primary-fg">
<p className="text-[11px]">Left to spend in October</p>
<p className="text-2xl font-semibold tabular-nums">₹23,480</p>
</div>
{jars.map((j) => (
<div key={j.name} className="grid gap-1.5 rounded bg-surface p-2.5">
<div className="flex justify-between"><b className="font-medium">{j.name}</b><span className="tabular-nums text-fg-muted">{j.saved} / {j.goal}</span></div>
<div className="h-1.5 rounded-full bg-surface-2"><div className="h-full rounded-full bg-primary" style={{ width: j.pct + "%" }} /></div>
</div>
))}
</div>
</div>
</div>
);
}
function Header() {
return (
<header>
<Container className="flex h-16 items-center gap-8">
<a href="/" className="flex items-center gap-2 font-semibold"><span className="size-6 rounded-sm bg-primary" aria-hidden />Gullak</a>
<nav aria-label="Main" className="hidden gap-6 text-sm text-fg-muted md:flex">
{["Features", "Security", "Reviews", "FAQ"].map((l) => <a key={l} href={"#" + l.toLowerCase()} className="hover:text-fg">{l}</a>)}
</nav>
<a href="#download" className="ml-auto inline-flex items-center gap-2 rounded bg-primary px-4 py-2 text-sm font-medium text-primary-fg hover:bg-primary-hover"><Smartphone className="size-4" />Get the app</a>
</Container>
</header>
);
}
function Hero() {
return (
<section className="overflow-hidden pt-10 sm:pt-14">
<Container className="grid items-center gap-10 lg:grid-cols-2">
<div className="grid justify-items-start gap-5 pb-4 lg:pb-16">
<span className="rounded-full bg-primary-soft px-2.5 py-0.5 text-xs font-medium text-primary-soft-fg">Free · Android and iPhone</span>
<h1 className="text-balance text-4xl font-semibold tracking-tight sm:text-6xl">Your salary, sorted into jars.</h1>
<p className="max-w-lg text-lg text-fg-muted">Gullak splits your pay into rent, bills, savings and fun the day it lands.</p>
<StoreButtons />
<p className="text-sm text-fg-muted"><b className="text-fg">4.8</b> from 1.2 lakh ratings</p>
</div>
<div role="img" aria-label="Gullak app showing money left to spend and three savings jars" className="flex justify-center">
<Phone className="translate-y-6" />
</div>
</Container>
</section>
);
}
function Stats() {
return (
<section aria-label="Gullak in numbers">
<Container>
<dl className="grid grid-cols-2 gap-6 border-y border-border py-9 text-center lg:grid-cols-4">
{stats.map((s) => <div key={s.label} className="flex flex-col"><dt className="text-sm text-fg-muted">{s.label}</dt><dd className="order-first text-3xl font-semibold tracking-tight">{s.value}</dd></div>)}
</dl>
</Container>
</section>
);
}
function Spotlight() {
return (
<section id="features" className="py-20 sm:py-24">
<Container className="grid items-center gap-12 lg:grid-cols-2">
<Phone className="mx-auto" />
<div>
<Heading left eyebrow="Why people stay" title="Know where it went, before it goes" />
<ul className="grid gap-7">
{highlights.map(({ icon: Icon, title, body }) => (
<li key={title} className="flex gap-4">
<span className="grid size-11 shrink-0 place-items-center rounded bg-primary-soft text-primary-soft-fg"><Icon className="size-5" /></span>
<div><h3 className="font-semibold">{title}</h3><p className="mt-1 text-sm text-fg-muted">{body}</p></div>
</li>
))}
</ul>
</div>
</Container>
</section>
);
}
function Features() {
return (
<section className="bg-surface py-20 sm:py-24">
<Container>
<Heading eyebrow="Features" title="Small tools for a calmer month" />
<div className="grid gap-5 sm:grid-cols-2 lg:grid-cols-4">
{features.map(({ icon: Icon, title, body }) => (
<article key={title} className="grid content-start gap-3 rounded-lg border border-border bg-bg p-6">
<span className="grid size-10 place-items-center rounded bg-primary-soft text-primary-soft-fg"><Icon className="size-5" /></span>
<h3 className="font-semibold">{title}</h3>
<p className="text-sm text-fg-muted">{body}</p>
</article>
))}
</div>
</Container>
</section>
);
}
function HowItWorks() {
return (
<section className="py-20 sm:py-24">
<Container>
<Heading eyebrow="How it works" title="Set up in three minutes" />
<ol className="grid gap-8 md:grid-cols-3">
{steps.map((s, i) => (
<li key={s.title} className="flex gap-4">
<span className="grid size-11 shrink-0 place-items-center rounded-full bg-primary-soft font-semibold text-primary-soft-fg">{i + 1}</span>
<div><h3 className="font-semibold">{s.title}</h3><p className="mt-1 text-sm text-fg-muted">{s.body}</p></div>
</li>
))}
</ol>
</Container>
</section>
);
}
function Reviews() {
return (
<section id="reviews" className="bg-surface py-20 sm:py-24">
<Container>
<Heading eyebrow="Reviews" title="Loved in the stores" />
<div className="grid gap-5 md:grid-cols-3">
{reviews.map((r) => (
<figure key={r.name} className="grid content-start gap-3 rounded-lg border border-border bg-bg p-6">
<div className="flex gap-0.5 text-primary" aria-label="5 out of 5 stars">{[0, 1, 2, 3, 4].map((i) => <Star key={i} className="size-4 fill-current" />)}</div>
<h3 className="font-semibold">{r.title}</h3>
<blockquote className="text-sm text-fg-muted">{r.body}</blockquote>
<figcaption className="text-sm text-fg-subtle">{r.name} · {r.meta}</figcaption>
</figure>
))}
</div>
</Container>
</section>
);
}
function Faq() {
return (
<section id="faq" className="py-20 sm:py-24">
<Container className="max-w-3xl">
<Heading eyebrow="FAQ" title="Good questions" />
<div className="border-t border-border">
{faqs.map((f, i) => (
<details key={f.q} open={i === 0} className="border-b border-border">
<summary className="cursor-pointer list-none py-4 font-medium">{f.q}</summary>
<p className="pb-5 text-sm text-fg-muted">{f.a}</p>
</details>
))}
</div>
</Container>
</section>
);
}
function Download() {
return (
<section id="download" className="pb-20 sm:pb-24">
<Container>
<div className="grid items-center gap-8 rounded-xl bg-fg p-6 text-bg sm:p-14 lg:grid-cols-[1fr_auto]">
<div className="grid justify-items-start gap-4">
<h2 className="text-3xl font-semibold tracking-tight sm:text-4xl">Next payday, try it with jars.</h2>
<p className="text-lg">Free on Android and iPhone. Takes three minutes to set up.</p>
<StoreButtons inverted />
</div>
<figure className="hidden justify-items-center gap-2 sm:grid">
<div role="img" aria-label="QR code to download Gullak" className="grid size-40 place-items-center rounded-lg bg-neutral-50 text-neutral-950"><Check className="size-8" /></div>
<figcaption className="text-sm">Scan with your phone camera</figcaption>
</figure>
</div>
</Container>
</section>
);
}
function Footer() {
return (
<footer className="border-t border-border py-10">
<Container className="flex flex-wrap justify-between gap-4 text-sm text-fg-muted">
<span className="font-semibold text-fg">Gullak</span>
<nav aria-label="Footer" className="flex flex-wrap gap-6">{["Security", "Privacy", "Careers", "Help centre"].map((l) => <a key={l} href="#" className="hover:text-fg">{l}</a>)}</nav>
<span>© 2026 Gullak Money Technologies Pvt. Ltd.</span>
</Container>
</footer>
);
}
export default function Page() {
return (
<div className="bg-bg font-sans text-fg">
<Header />
<main>
<Hero />
<Stats />
<Spotlight />
<Features />
<HowItWorks />
<Reviews />
<Faq />
<Download />
</main>
<Footer />
</div>
);
}
The code uses the Taste Tailwind preset. Make yours on the Taste page with Export my system.