Invoices that look like your business
Your logo, your colours, your terms. Line items, discounts and GST worked out as you type.
Templates
A complete landing page for an invoicing app, with a product screenshot hero, bento features and three-tier pricing.
Nav · hero with app screenshot · logos · bento features · how it works · pricing with monthly/yearly · testimonials · FAQ · CTA · footer
Ledgerleaf makes GST-ready invoices in a minute, lets clients pay by UPI or card, and follows up until the money is in.
Free for 5 invoices a month · No card needed
| Client | Amount | Status |
|---|---|---|
| Bloom & Co | ₹48,500 | Paid |
| Haldi Studio | ₹1,12,000 | Due in 6 days |
| Northpoint Tea | ₹36,250 | Overdue |
| Kite & Kin | ₹74,800 | Paid |
Used by 3,200 studios, agencies and consultants
Features
Your logo, your colours, your terms. Line items, discounts and GST worked out as you type.
Polite emails on a schedule you set.
The split is picked from the place of supply.
What came in, what is owed and what lands next month.
One link on every invoice, every method behind it.
Bill in 14 currencies and see the rupee value the day it is paid.
How it works
Your GSTIN, logo and bank details. We fill the rest from your GSTIN.
Pick a template, add line items and send it by email or a link.
Payments match their invoices on their own, ready for your accountant.
Pricing
For freelancers sending a few invoices a month.
For small teams that bill every week.
For agencies with many clients and currencies.
Prices exclude 18% GST. Cancel any time.
Customers
“We used to spend Friday afternoons chasing payments. Now the reminders do it and we hear about it when the money lands.”
“Our accountant stopped asking for spreadsheets. The GST report is just there at the end of the month.”
“Clients pay from the invoice link by UPI. Our average wait went from 34 days to 9.”
FAQ
Something else? Write to help@ledgerleaf.in and a person replies within a working day.
Yes. Invoices carry your GSTIN, HSN or SAC codes and the right CGST, SGST or IGST split, and the monthly report matches the GSTR-1 layout.
Every invoice has a payment link. Clients pay by UPI, card, net banking or bank transfer, and the invoice is marked paid on its own.
Import a CSV from your spreadsheet or accounting tool. Numbering carries on from your last invoice.
You move to the free Solo plan unless you pick a paid one. Nothing is deleted.
Start free, send five invoices this month, and upgrade only when you need more.
"use client";
import { useState } from "react";
import { ArrowRight, Check, Menu, Star } from "lucide-react";
import { cn } from "@/lib/utils";
const invoices = [
{ client: "Bloom & Co", number: "INV-2041", amount: "₹48,500", status: "Paid" },
{ client: "Haldi Studio", number: "INV-2040", amount: "₹1,12,000", status: "Due in 6 days" },
{ client: "Northpoint Tea", number: "INV-2039", amount: "₹36,250", status: "Overdue" },
{ client: "Kite & Kin", number: "INV-2038", amount: "₹74,800", status: "Paid" },
];
const steps = [
{ title: "Add your business", body: "Your GSTIN, logo and bank details. We fill the rest from your GSTIN." },
{ title: "Send the first invoice", body: "Pick a template, add line items and send it by email or a link." },
{ title: "Get paid and reconciled", body: "Payments match their invoices on their own, ready for your accountant." },
];
const plans = [
{ name: "Solo", monthly: "₹0", yearly: "₹0", blurb: "For freelancers sending a few invoices a month.", cta: "Start free", features: ["5 invoices a month", "UPI and card payments", "GST-ready templates"] },
{ name: "Studio", monthly: "₹799", yearly: "₹666", blurb: "For small teams that bill every week.", cta: "Try Studio free", popular: true, features: ["Unlimited invoices", "Automatic reminders", "Recurring billing", "3 team members"] },
{ name: "Agency", monthly: "₹2,199", yearly: "₹1,833", blurb: "For agencies with many clients and currencies.", cta: "Talk to us", features: ["Everything in Studio", "14 currencies", "Approvals and roles", "Priority support"] },
];
const quotes = [
{ quote: "We used to spend Friday afternoons chasing payments. Now the reminders do it.", name: "Ritika Menon", role: "Founder, Haldi Studio" },
{ quote: "Our accountant stopped asking for spreadsheets. The GST report is just there.", name: "Arjun Bhat", role: "Partner, Kite & Kin" },
{ quote: "Clients pay from the invoice link by UPI. Our average wait went from 34 days to 9.", name: "Leah Fernandes", role: "Operations, Bloom & Co" },
];
const faqs = [
{ q: "Is Ledgerleaf GST compliant?", a: "Yes. Invoices carry your GSTIN, HSN or SAC codes and the right CGST, SGST or IGST split." },
{ q: "How do my clients pay?", a: "Every invoice has a payment link: UPI, card, net banking or bank transfer." },
{ q: "Can I bring my old invoices?", a: "Import a CSV from your spreadsheet or accounting tool. Numbering carries on." },
{ q: "What happens when my trial ends?", a: "You move to the free Solo plan unless you pick a paid one. Nothing is deleted." },
];
const footer = [
{ title: "Product", links: ["Invoices", "Payments", "Reminders", "Reports"] },
{ title: "Company", links: ["About", "Careers", "Blog", "Contact"] },
{ title: "Help", links: ["Guides", "GST basics", "Status", "Security"] },
];
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 SectionHead({ eyebrow, title, align = "center" }: { eyebrow: string; title: string; align?: "center" | "left" }) {
return (
<div className={cn("mb-12 grid gap-3", align === "center" ? "mx-auto max-w-2xl text-center" : "max-w-2xl")}>
<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 Logo() {
return (
<a href="/" className="flex items-center gap-2 font-semibold tracking-tight">
<span className="size-6 rounded-sm bg-primary" aria-hidden /> Ledgerleaf
</a>
);
}
function Header() {
return (
<header className="border-b border-border">
<Container className="flex h-16 items-center gap-8">
<Logo />
<nav aria-label="Main" className="hidden gap-6 text-sm text-fg-muted md:flex">
{["Product", "Pricing", "Customers", "Help"].map((l) => <a key={l} href="#" className="hover:text-fg">{l}</a>)}
</nav>
<div className="ml-auto flex items-center gap-2">
<a href="#" className="hidden rounded px-3 py-2 text-sm hover:bg-surface-2 sm:block">Sign in</a>
<a href="#" className="rounded bg-primary px-4 py-2 text-sm font-medium text-primary-fg hover:bg-primary-hover">Start free</a>
<button type="button" aria-label="Open menu" className="rounded p-2 hover:bg-surface-2 md:hidden"><Menu className="size-5" /></button>
</div>
</Container>
</header>
);
}
function Hero() {
return (
<section className="relative overflow-hidden pt-16 text-center sm:pt-20">
<Container>
<h1 className="mx-auto max-w-3xl text-balance text-4xl font-semibold tracking-tight sm:text-6xl">
Send the invoice. We’ll chase the payment.
</h1>
<p className="mx-auto mt-5 max-w-xl text-lg text-fg-muted">
GST-ready invoices in a minute, paid by UPI or card, followed up until the money is in.
</p>
<div className="mt-8 flex flex-wrap justify-center gap-3">
<a href="#" className="inline-flex h-11 items-center gap-2 rounded bg-primary px-5 font-medium text-primary-fg hover:bg-primary-hover">Start free <ArrowRight className="size-4" /></a>
<a href="#" className="inline-flex h-11 items-center rounded border border-border-strong px-5 font-medium hover:bg-surface">Book a demo</a>
</div>
<p className="mt-3 text-sm text-fg-subtle">Free for 5 invoices a month · No card needed</p>
<div className="mx-auto mt-14 max-w-5xl rounded-t-xl border border-b-0 border-border bg-surface-2 p-2 pb-0">
<div className="rounded-t-lg border border-b-0 border-border bg-bg p-4 text-left sm:p-6">
<div className="mb-4 flex items-center justify-between">
<p className="text-lg font-semibold">Invoices</p>
<span className="rounded bg-primary px-3 py-1.5 text-sm text-primary-fg">New invoice</span>
</div>
<table className="w-full text-sm">
<thead className="text-left text-xs text-fg-subtle">
<tr><th className="py-2 font-medium">Client</th><th className="hidden py-2 font-medium sm:table-cell">Number</th><th className="py-2 text-right font-medium">Amount</th><th className="py-2 pl-4 font-medium">Status</th></tr>
</thead>
<tbody>
{invoices.map((i) => (
<tr key={i.number} className="border-t border-border">
<td className="py-2.5">{i.client}</td>
<td className="hidden py-2.5 text-fg-muted sm:table-cell">{i.number}</td>
<td className="py-2.5 text-right tabular-nums">{i.amount}</td>
<td className="py-2.5 pl-4"><span className={cn("rounded-full px-2 py-0.5 text-xs font-medium", i.status === "Paid" ? "bg-success-soft text-success-fg" : i.status === "Overdue" ? "bg-danger-soft text-danger-fg" : "bg-warning-soft text-warning-fg")}>{i.status}</span></td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</Container>
</section>
);
}
function Logos() {
return (
<section aria-label="Customers" className="bg-surface py-12 text-center">
<Container>
<p className="text-sm text-fg-subtle">Used by 3,200 studios, agencies and consultants</p>
<ul className="mt-6 flex flex-wrap justify-center gap-x-12 gap-y-4 text-lg font-semibold tracking-tight text-fg-subtle">
{["Halcyon Labs", "Tinkerbox", "Moonrise", "Arcadia Print", "Kiln & Co", "Parallel"].map((l) => <li key={l}>{l}</li>)}
</ul>
</Container>
</section>
);
}
function Features() {
return (
<section className="py-20 sm:py-24">
<Container>
<SectionHead eyebrow="Features" title="Everything between “work done” and “money in”" />
<div className="grid gap-4 md:grid-cols-6">
<article className="rounded-xl border border-border bg-primary-soft p-6 md:col-span-4">
<h3 className="font-semibold">Invoices that look like your business</h3>
<p className="mt-1.5 text-sm text-fg-muted">Your logo, colours and terms. GST worked out as you type.</p>
</article>
<article className="rounded-xl border border-border p-6 md:col-span-2">
<h3 className="font-semibold">Reminders that chase for you</h3>
<p className="mt-1.5 text-sm text-fg-muted">Polite emails on a schedule you set.</p>
</article>
<article className="rounded-xl border border-border p-6 md:col-span-2">
<h3 className="font-semibold">GST, done right</h3>
<p className="mt-1.5 text-sm text-fg-muted">CGST, SGST or IGST from the place of supply.</p>
</article>
<article className="rounded-xl border border-border p-6 md:col-span-4">
<h3 className="font-semibold">Know your cash flow</h3>
<p className="mt-1.5 text-sm text-fg-muted">What came in, what is owed and what lands next month.</p>
</article>
<article className="rounded-xl border border-border p-6 md:col-span-3">
<h3 className="font-semibold">Paid the way clients like</h3>
<p className="mt-1.5 text-sm text-fg-muted">UPI, cards, net banking and bank transfer behind one link.</p>
</article>
<article className="rounded-xl border border-border p-6 md:col-span-3">
<h3 className="font-semibold">Clients abroad, rupees at home</h3>
<p className="mt-1.5 text-sm text-fg-muted">Bill in 14 currencies and see the rupee value when paid.</p>
</article>
</div>
</Container>
</section>
);
}
function HowItWorks() {
return (
<section className="bg-surface py-20 sm:py-24">
<Container>
<SectionHead eyebrow="How it works" title="Set up before your coffee cools" align="left" />
<ol className="grid gap-8 md:grid-cols-3">
{steps.map((s, i) => (
<li key={s.title} className="grid gap-2">
<span className="grid size-9 place-items-center rounded-full bg-fg text-sm font-semibold text-bg">{i + 1}</span>
<h3 className="mt-3 font-semibold">{s.title}</h3>
<p className="text-sm text-fg-muted">{s.body}</p>
</li>
))}
</ol>
</Container>
</section>
);
}
function Pricing() {
const [yearly, setYearly] = useState(true);
return (
<section className="py-20 sm:py-24">
<Container>
<SectionHead eyebrow="Pricing" title="Simple plans, priced in rupees" />
<div role="tablist" aria-label="Billing period" className="mx-auto -mt-4 mb-10 flex w-fit gap-0.5 rounded-lg bg-surface-2 p-1">
{[false, true].map((y) => (
<button key={String(y)} type="button" role="tab" aria-selected={yearly === y} onClick={() => setYearly(y)}
className="rounded px-3 py-1.5 text-sm font-medium text-fg-muted aria-selected:bg-bg aria-selected:text-fg aria-selected:shadow-sm">
{y ? "Yearly · 2 months free" : "Monthly"}
</button>
))}
</div>
<div className="mx-auto grid max-w-md gap-4 lg:max-w-none lg:grid-cols-3">
{plans.map((p) => (
<article key={p.name} className={cn("grid gap-5 rounded-xl border p-7", p.popular ? "border-fg bg-fg text-bg shadow-xl" : "border-border bg-bg")}>
<div className="flex items-center justify-between">
<h3 className="font-semibold">{p.name}</h3>
{p.popular && <span className="rounded-full bg-primary-soft px-2 py-0.5 text-xs font-medium text-primary-soft-fg">Most popular</span>}
</div>
<p className="flex items-baseline gap-1.5">
<span className="text-5xl font-semibold tracking-tight tabular-nums">{yearly ? p.yearly : p.monthly}</span>
<span className={cn("text-sm", p.popular ? "text-bg" : "text-fg-subtle")}>/ month</span>
</p>
<p className={cn("text-sm", p.popular ? "text-bg" : "text-fg-muted")}>{p.blurb}</p>
<a href="#" className={cn("flex h-11 items-center justify-center rounded font-medium", p.popular ? "bg-primary text-primary-fg hover:bg-primary-hover" : "border border-border-strong hover:bg-surface")}>{p.cta}</a>
<ul className="grid gap-2.5 border-t border-border pt-5 text-sm">
{p.features.map((f) => <li key={f} className="flex gap-2.5"><Check className="mt-0.5 size-4 shrink-0 text-primary" />{f}</li>)}
</ul>
</article>
))}
</div>
<p className="mt-5 text-center text-sm text-fg-subtle">Prices exclude 18% GST. Cancel any time.</p>
</Container>
</section>
);
}
function Testimonials() {
return (
<section className="bg-surface py-20 sm:py-24">
<Container>
<SectionHead eyebrow="Customers" title="Fewer reminders, faster payments" />
<div className="grid gap-4 md:grid-cols-3">
{quotes.map((t) => (
<figure key={t.name} className="grid content-between gap-5 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>
<blockquote>“{t.quote}”</blockquote>
<figcaption className="text-sm"><p className="font-medium">{t.name}</p><p className="text-fg-subtle">{t.role}</p></figcaption>
</figure>
))}
</div>
</Container>
</section>
);
}
function Faq() {
return (
<section className="py-20 sm:py-24">
<Container className="grid gap-10 lg:grid-cols-[2fr_3fr] lg:gap-16">
<div className="grid content-start gap-3">
<p className="text-sm font-medium text-primary">FAQ</p>
<h2 className="text-3xl font-semibold tracking-tight sm:text-4xl">Questions, answered</h2>
<p className="text-fg-muted">Something else? Write to help@ledgerleaf.in.</p>
</div>
<div className="border-t border-border">
{faqs.map((f, i) => (
<details key={f.q} open={i === 0} className="group border-b border-border">
<summary className="flex cursor-pointer list-none items-center justify-between gap-4 py-4 font-medium">{f.q}<span className="text-fg-subtle group-open:rotate-180" aria-hidden>⌄</span></summary>
<p className="pb-5 pr-8 text-sm text-fg-muted">{f.a}</p>
</details>
))}
</div>
</Container>
</section>
);
}
function Cta() {
return (
<section className="pb-20 sm:pb-24">
<Container>
<div className="grid justify-items-center gap-4 rounded-xl bg-primary px-6 py-16 text-center text-primary-fg">
<h2 className="text-balance text-3xl font-semibold tracking-tight sm:text-4xl">Your next invoice could be paid by Friday</h2>
<p className="max-w-lg">Start free, send five invoices this month, and upgrade only when you need more.</p>
<a href="#" className="mt-2 inline-flex h-11 items-center gap-2 rounded bg-bg px-5 font-medium text-fg">Start free <ArrowRight className="size-4" /></a>
</div>
</Container>
</section>
);
}
function Footer() {
return (
<footer className="border-t border-border pb-8 pt-16">
<Container>
<div className="grid grid-cols-2 gap-8 md:grid-cols-[1.6fr_1fr_1fr_1fr]">
<div className="col-span-2 grid content-start gap-3 md:col-span-1"><Logo /><p className="max-w-xs text-sm text-fg-muted">Invoicing and payments for small studios, made in Bengaluru.</p></div>
{footer.map((c) => (
<nav key={c.title} aria-label={c.title}>
<h2 className="mb-3 text-sm font-medium text-fg-subtle">{c.title}</h2>
<ul className="grid gap-2.5 text-sm text-fg-muted">{c.links.map((l) => <li key={l}><a href="#" className="hover:text-fg">{l}</a></li>)}</ul>
</nav>
))}
</div>
<p className="mt-14 border-t border-border pt-6 text-sm text-fg-subtle">© 2026 Ledgerleaf Software Pvt. Ltd.</p>
</Container>
</footer>
);
}
export default function Page() {
return (
<div className="bg-bg font-sans text-fg">
<Header />
<main>
<Hero />
<Logos />
<Features />
<HowItWorks />
<Pricing />
<Testimonials />
<Faq />
<Cta />
</main>
<Footer />
</div>
);
}
The code uses the Taste Tailwind preset. Make yours on the Taste page with Export my system.