All Taste components
Pricing
Pricing — monthly/yearly toggle, plan rows
Plans as full-width rows you can scan top to bottom, with a monthly or yearly switch beside the heading.
monthly / yearly toggle · plan rows · recommended marker · stacks on mobile
Plans for every stage
Switch to yearly billing and keep two months for free.
Solo
One person, a handful of clients
- Unlimited invoices
- Reminders
- 1 user
$9$7per monthper month, billed yearlyChoose SoloTeam
Most chosenA studio or small agency
- Everything in Solo
- Recurring billing
- Client portal
- 5 users
$24$19per monthper month, billed yearlyChoose TeamCompany
Finance team plus approvals
- Everything in Team
- Approvals
- Accounting sync
- SSO
$59$47per monthper month, billed yearlyChoose Company
Prices exclude sales tax. Need more than 50 users? Talk to us.
"use client";
import { useState } from "react";
import { Check } from "lucide-react";
import { cn } from "@/lib/utils";
type Period = "monthly" | "yearly";
const plans = [
{ name: "Solo", note: "One person, a handful of clients", price: { monthly: "$9", yearly: "$7" }, cta: "Choose Solo", href: "/signup?plan=solo",
features: ["Unlimited invoices", "Reminders", "1 user"] },
{ name: "Team", note: "A studio or small agency", price: { monthly: "$24", yearly: "$19" }, cta: "Choose Team", href: "/signup?plan=team", recommended: true,
features: ["Everything in Solo", "Recurring billing", "Client portal", "5 users"] },
{ name: "Company", note: "Finance team plus approvals", price: { monthly: "$59", yearly: "$47" }, cta: "Choose Company", href: "/signup?plan=company",
features: ["Everything in Team", "Approvals", "Accounting sync", "SSO"] },
];
export function PricingToggleRows() {
const [period, setPeriod] = useState<Period>("monthly");
return (
<section aria-labelledby="pricing-rows-title" className="bg-bg px-5 py-16 font-sans sm:px-10 sm:py-20">
<div className="mx-auto max-w-6xl">
<div className="flex flex-wrap items-end justify-between gap-x-8 gap-y-5">
<div className="max-w-xl">
<h2 id="pricing-rows-title" className="text-3xl font-semibold tracking-tight text-fg sm:text-4xl">Plans for every stage</h2>
<p className="mt-4 text-base text-fg-muted sm:text-lg">Switch to yearly billing and keep two months for free.</p>
</div>
<div role="group" aria-label="Billing period" className="flex gap-0.5 rounded-lg bg-surface-2 p-[3px]">
{(["monthly", "yearly"] as const).map((p) => (
<button
key={p}
type="button"
aria-pressed={period === p}
onClick={() => setPeriod(p)}
className="inline-flex h-8 items-center gap-1.5 rounded px-3.5 text-[13px] font-medium capitalize text-fg-muted transition aria-pressed:bg-bg aria-pressed:text-fg aria-pressed:shadow-sm"
>
{p}
{p === "yearly" && <span className="rounded-full bg-primary-soft px-1.5 text-[11px] text-primary-soft-fg">−20%</span>}
</button>
))}
</div>
</div>
<ul className="mt-10 border-t border-border-strong">
{plans.map((plan) => (
<li
key={plan.name}
className={cn(
"relative grid gap-4 border-b border-border py-7 lg:grid-cols-[1fr_1.5fr_0.8fr_168px] lg:items-center lg:gap-8",
plan.recommended && "before:absolute before:-top-px before:left-0 before:h-0.5 before:w-16 before:bg-primary",
)}
>
<div>
<div className="flex items-center gap-2">
<h3 className="text-lg font-semibold text-fg">{plan.name}</h3>
{plan.recommended && <span className="rounded-full bg-primary-soft px-2 py-0.5 text-xs font-medium text-primary-soft-fg">Most chosen</span>}
</div>
<p className="mt-1 text-[13px] text-fg-subtle">{plan.note}</p>
</div>
<ul className="flex flex-wrap gap-x-4 gap-y-2 text-[13.5px] text-fg-muted">
{plan.features.map((f) => (
<li key={f} className="inline-flex items-center gap-1.5"><Check className="size-3.5 text-primary" aria-hidden />{f}</li>
))}
</ul>
<p className="flex flex-wrap items-baseline gap-x-2">
<span className="text-4xl font-semibold tracking-tight tabular-nums text-fg">{plan.price[period]}</span>
<span className="text-[13px] text-fg-subtle">{period === "yearly" ? "per month, billed yearly" : "per month"}</span>
</p>
<a
href={plan.href}
className={cn(
"inline-flex h-9 items-center justify-center rounded px-4 text-sm font-medium transition",
plan.recommended ? "bg-primary text-primary-fg hover:bg-primary-hover" : "border border-border-strong text-fg hover:bg-surface",
)}
>
{plan.cta}
</a>
</li>
))}
</ul>
<p className="mt-5 text-[13px] text-fg-subtle">
Prices exclude sales tax. Need more than 50 users? <a href="/contact" className="text-primary underline underline-offset-4">Talk to us</a>.
</p>
</div>
</section>
);
}
The code uses the Taste Tailwind preset. Make yours on the Taste page with Export my system.