Skip to content
All Taste components

Hero

Hero — product screenshot

A centered headline with a large picture of the app underneath that fades into the page.

centered copy · app window with sidebar, 3 figures and a table · glow · bottom fade

Now with bank feeds

See every invoice, every client, every payment — on one screen.

Fernbill is the calm dashboard for the money side of freelancing. Know what's due, what's late and what's landed.

import { BarChart3, ChevronRight, CreditCard, FileText, Repeat, Users } from "lucide-react";
import { cn } from "@/lib/utils";

const nav = [
  { icon: FileText, label: "Invoices", active: true },
  { icon: Users, label: "Clients" },
  { icon: Repeat, label: "Retainers" },
  { icon: BarChart3, label: "Reports" },
  { icon: CreditCard, label: "Payouts" },
];
const figures = [
  { label: "Outstanding", value: "$8,420" },
  { label: "Overdue", value: "$1,150" },
  { label: "Paid this month", value: "$14,900" },
];
const status = {
  paid: "bg-success-soft text-success-fg",
  due: "bg-warning-soft text-warning-fg",
  late: "bg-danger-soft text-danger-fg",
};
const invoices: { client: string; number: string; due: string; state: keyof typeof status }[] = [
  { client: "Kaveri Foods", number: "INV-1042", due: "30 Oct", state: "paid" },
  { client: "Blue Pine Studio", number: "INV-1041", due: "28 Oct", state: "due" },
  { client: "Lumen Health", number: "INV-1040", due: "21 Oct", state: "late" },
  { client: "Orbit Coffee", number: "INV-1039", due: "18 Oct", state: "paid" },
];

export function HeroProductShot() {
  return (
    <section aria-labelledby="hero-title" className="overflow-hidden bg-bg pt-16 font-sans sm:pt-24">
      <div className="mx-auto flex max-w-3xl flex-col items-center gap-5 px-4 text-center sm:px-6">
        <a href="/changelog/bank-feeds" className="inline-flex items-center gap-1 rounded-full border border-border-strong px-2.5 py-0.5 text-xs font-medium text-fg-muted hover:text-fg">
          Now with bank feeds <ChevronRight className="size-3" aria-hidden />
        </a>
        <h1 id="hero-title" className="text-balance text-4xl font-semibold leading-[1.04] tracking-tight text-fg sm:text-5xl lg:text-6xl">
          See every invoice, every client, every payment — on one screen.
        </h1>
        <p className="max-w-xl text-pretty text-base leading-relaxed text-fg-muted sm:text-lg">
          Fernbill is the calm dashboard for the money side of freelancing. Know what’s due, what’s late and what’s landed.
        </p>
        <div className="flex flex-wrap justify-center gap-3">
          <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">Start free</a>
          <a href="/demo" className="inline-flex h-11 items-center rounded border border-border-strong bg-bg px-5 text-[15px] font-medium text-fg transition hover:bg-surface">Book a demo</a>
        </div>
      </div>

      {/* App picture: plain elements, so it follows the theme. Fades into the page at the bottom. */}
      <div aria-hidden className="mx-auto mt-14 max-w-5xl px-4 [mask-image:linear-gradient(to_bottom,black_62%,transparent)] sm:px-6">
        <div className="overflow-hidden rounded-t-xl border border-b-0 border-border bg-bg shadow-[0_-20px_80px_-30px_var(--tst-primary)]">
          <div className="flex h-9 items-center gap-1.5 border-b border-border bg-surface px-3.5">
            <span className="size-2.5 rounded-full bg-border-strong" /><span className="size-2.5 rounded-full bg-border-strong" /><span className="size-2.5 rounded-full bg-border-strong" />
            <span className="ml-2.5 h-[18px] w-60 max-w-[40%] rounded-sm bg-surface-2" />
          </div>
          <div className="grid min-h-[380px] text-[12.5px] md:grid-cols-[184px_1fr]">
            <div className="hidden content-start gap-0.5 border-r border-border bg-surface p-2.5 md:grid">
              {nav.map(({ icon: Icon, label, active }) => (
                <span key={label} className={cn("flex items-center gap-2 rounded px-2.5 py-2 text-fg-muted", active && "bg-bg font-medium text-fg shadow-sm")}>
                  <Icon className="size-3.5" /> {label}
                </span>
              ))}
            </div>
            <div className="grid content-start gap-4 p-5">
              <div className="flex items-center justify-between">
                <p className="text-[15px] font-semibold text-fg">Invoices</p>
                <span className="rounded bg-primary px-2.5 py-1.5 text-xs font-medium text-primary-fg">New invoice</span>
              </div>
              <div className="grid gap-2.5 sm:grid-cols-3">
                {figures.map((f) => (
                  <div key={f.label} className="rounded-lg border border-border p-3">
                    <p className="text-fg-subtle">{f.label}</p>
                    <p className="text-lg font-semibold tabular-nums text-fg">{f.value}</p>
                  </div>
                ))}
              </div>
              <div className="overflow-hidden rounded-lg border border-border">
                {invoices.map((inv) => (
                  <div key={inv.number} className="grid grid-cols-[1fr_72px] items-center gap-3 border-t border-border px-3 py-2.5 first:border-t-0 sm:grid-cols-[1.6fr_1fr_0.8fr_72px]">
                    <span className="truncate text-fg">{inv.client}</span>
                    <span className="hidden text-fg-muted sm:block">{inv.number}</span>
                    <span className="hidden text-fg-muted sm:block">{inv.due}</span>
                    <span className={cn("w-fit rounded-full px-2 py-0.5 text-xs font-medium capitalize", status[inv.state])}>{inv.state}</span>
                  </div>
                ))}
              </div>
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

The code uses the Taste Tailwind preset. Make yours on the Taste page with Export my system.