All Taste components
Animated heroes
Hero with product (motion)
The invoice writes itself line by line, a Paid stamp lands on it, and the payment-received card springs up underneath.
copy rises · card settles · lines write in · Paid stamp · payment card spring · stacks on small screens
For freelancers and small studios
Send the invoice. Fernbill does the chasing.
Make an invoice in a minute, add a pay link, and let polite reminders go out until it's paid.
ARDOLM
Used by freelancers in 40 countriesimport { ArrowRight, Check } from "lucide-react";
/* Add once to globals.css:
@keyframes card-settle { from { opacity: 0; transform: translateY(28px) rotate(-1.5deg); } }
@keyframes write-in { from { opacity: .15; clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes stamp { from { opacity: 0; transform: scale(1.9) rotate(-12deg); } }
@keyframes toast-in { from { opacity: 0; translate: 0 22px; scale: .94; } }
*/
const lines = [
{ item: "Website design", amount: "$2,400.00" },
{ item: "Copywriting, 6 pages", amount: "$900.00" },
{ item: "Hosting set-up", amount: "$150.00" },
];
const customers = ["AR", "DO", "LM"];
// Each invoice row is "written" left to right, one after another.
const write = "animate-[write-in_.55s_cubic-bezier(.2,.7,.1,1)_both] motion-reduce:animate-fade";
const at = (i: number) => ({ animationDelay: 600 + i * 130 + "ms" });
export function HeroSplitMotion() {
return (
<section aria-labelledby="hero-title" className="bg-bg font-sans">
<div className="mx-auto grid max-w-6xl items-center gap-12 px-4 py-16 sm:px-6 sm:py-24 lg:grid-cols-[1.05fr_1fr] lg:gap-16">
<div className="flex flex-col items-start [&>*]:animate-rise motion-reduce:[&>*]:animate-fade">
<p className="text-[13px] font-medium text-primary">For freelancers and small studios</p>
<h1 id="hero-title" className="mt-4 text-balance text-4xl font-semibold leading-[1.08] tracking-tight text-fg [animation-delay:90ms] sm:text-5xl">
Send the invoice. Fernbill does the chasing.
</h1>
<p className="mt-5 max-w-lg text-pretty text-base leading-relaxed text-fg-muted [animation-delay:180ms] sm:text-lg">
Make an invoice in a minute, add a pay link, and let polite reminders go out until it’s paid.
</p>
<div className="mt-8 flex flex-wrap gap-3 [animation-delay:270ms]">
<a href="/signup" className="inline-flex h-11 items-center rounded bg-primary px-5 text-[15px] font-medium text-primary-fg transition hover:bg-primary-hover active:scale-[.97]">Start free</a>
<a href="/demo" className="inline-flex h-11 items-center gap-1.5 rounded px-5 text-[15px] font-medium text-fg transition hover:bg-surface-2">
Book a demo <ArrowRight className="size-4" aria-hidden />
</a>
</div>
<div className="mt-8 flex items-center gap-3 text-[13px] text-fg-subtle [animation-delay:360ms]">
<div className="flex [&>*]:-ml-2 [&>*:first-child]:ml-0">
{customers.map((c) => (
<span key={c} className="inline-grid size-7 place-items-center rounded-full border-2 border-bg bg-primary-soft text-[11px] font-medium text-primary-soft-fg">{c}</span>
))}
</div>
Used by freelancers in 40 countries
</div>
</div>
{/* Product picture, drawn with plain elements so it follows the theme */}
<div aria-hidden className="relative mb-5 rounded-xl border border-border bg-surface p-4 shadow-2xl shadow-fg/10 animate-[card-settle_1s_cubic-bezier(.2,.7,.1,1)_.25s_both] motion-reduce:animate-fade">
<div className="grid gap-3 rounded-lg border border-border bg-bg p-5 text-[13px]">
<div className="flex items-center justify-between gap-3 animate-fade [animation-delay:550ms]">
<p className="text-[15px] font-semibold text-fg">Invoice INV-1042</p>
<span className="inline-flex items-center gap-1.5 rounded-full bg-success-soft px-2 py-0.5 text-xs font-medium text-success-fg animate-[stamp_.6s_cubic-bezier(.34,1.56,.64,1)_1.6s_both] motion-reduce:animate-fade">
<span className="size-1.5 rounded-full bg-current" /> Paid
</span>
</div>
<div className={"flex justify-between text-fg-subtle " + write} style={at(0)}><span>Kaveri Foods</span><span>Due 30 Oct</span></div>
<hr className={"border-border " + write} style={at(1)} />
{lines.map((l, i) => (
<div key={l.item} className={"flex justify-between gap-3 text-fg " + write} style={at(2 + i)}>
<span className="truncate">{l.item}</span>
<span className="tabular-nums">{l.amount}</span>
</div>
))}
<div className={"flex justify-between border-t border-border pt-3 text-[15px] font-semibold text-fg " + write} style={at(5)}>
<span>Total</span><span className="tabular-nums">$3,450.00</span>
</div>
</div>
<div className="absolute -bottom-5 right-4 flex items-center gap-3 rounded-lg border border-border bg-bg px-3 py-2.5 text-[13px] shadow-lg animate-[toast-in_.7s_cubic-bezier(.34,1.56,.64,1)_2s_both] motion-reduce:animate-fade">
<span className="inline-grid size-7 place-items-center rounded-full bg-success-soft text-success-fg"><Check className="size-3.5" /></span>
<div>
<p className="font-medium text-fg">Payment received</p>
<p className="text-fg-subtle">$3,450 from Kaveri Foods</p>
</div>
</div>
</div>
</div>
</section>
);
}
The code uses the Taste Tailwind preset. Make yours on the Taste page with Export my system.