Skip to content
All Taste components

Features

Feature bento

Features shown as a mosaic of different-sized cards, each with a small picture of the product.

4 tiles · chart · timeline · chips · progress · wide/narrow spans

One tidy place for money coming in

From the first invoice to the last reminder, you can see where every payment stands.

Know what's coming in

Paid and expected income by month, so a quiet month never surprises you.

Reminders on autopilot

Friendly first, firm later.

  1. On the due dateA friendly note
  2. 3 days lateA gentle nudge
  3. 10 days lateA firm reminder

Bill in 24 currencies

Your client pays in theirs.

Know when it's been opened

See the moment a client views the invoice, and when they pay.

const months = [
  { m: "May", value: 46, paid: true }, { m: "Jun", value: 62, paid: true }, { m: "Jul", value: 38, paid: true },
  { m: "Aug", value: 74, paid: true }, { m: "Sep", value: 58, paid: true }, { m: "Oct", value: 82, paid: false },
  { m: "Nov", value: 50, paid: false },
];
const reminders = [
  { when: "On the due date", what: "A friendly note" },
  { when: "3 days late", what: "A gentle nudge" },
  { when: "10 days late", what: "A firm reminder" },
];
const currencies = ["USD", "EUR", "GBP", "INR", "AUD", "SGD", "+18"];
const stages = [
  { label: "Sent · 2 Oct", done: true },
  { label: "Viewed · 3 Oct", done: true },
  { label: "Paid", done: false },
];

function Tile({ title, body, className = "", children }:
  { title: string; body: string; className?: string; children: React.ReactNode }) {
  return (
    <article className={"flex flex-col justify-between gap-6 overflow-hidden rounded-xl border border-border bg-surface p-6 " + className}>
      <div>
        <h3 className="text-base font-semibold tracking-tight text-fg">{title}</h3>
        <p className="mt-1 text-sm leading-relaxed text-fg-muted">{body}</p>
      </div>
      {children}
    </article>
  );
}

export function FeatureBento() {
  return (
    <section aria-labelledby="bento-title" className="bg-bg font-sans">
      <div className="mx-auto max-w-6xl px-4 py-20 sm:px-6">
        <div className="max-w-xl">
          <h2 id="bento-title" className="text-balance text-3xl font-semibold tracking-tight text-fg sm:text-4xl">One tidy place for money coming in</h2>
          <p className="mt-4 text-base leading-relaxed text-fg-muted sm:text-lg">From the first invoice to the last reminder, you can see where every payment stands.</p>
        </div>

        <div className="mt-12 grid gap-3 md:grid-cols-6">
          <Tile className="md:col-span-4" title="Know what’s coming in" body="Paid and expected income by month, so a quiet month never surprises you.">
            <div aria-hidden className="flex h-32 items-end gap-2">
              {months.map((x) => (
                <div key={x.m} className="flex h-full flex-1 flex-col justify-end gap-1.5 text-center text-[11px] text-fg-subtle">
                  <span className={(x.paid ? "bg-primary" : "bg-primary-soft") + " block rounded-t-sm"} style={{ height: x.value + "%" }} />
                  {x.m}
                </div>
              ))}
            </div>
          </Tile>

          <Tile className="bg-primary-soft md:col-span-2" title="Reminders on autopilot" body="Friendly first, firm later.">
            <ol className="grid gap-3 border-l border-border-strong pl-4 text-[13px]">
              {reminders.map((r) => (
                <li key={r.when} className="relative">
                  <span className="absolute -left-[21px] top-1 size-2.5 rounded-full border-2 border-primary bg-bg" />
                  <p className="font-medium text-fg">{r.when}</p>
                  <p className="text-fg-subtle">{r.what}</p>
                </li>
              ))}
            </ol>
          </Tile>

          <Tile className="md:col-span-2" title="Bill in 24 currencies" body="Your client pays in theirs.">
            <div className="flex flex-wrap gap-1.5">
              {currencies.map((c) => (
                <span key={c} className="rounded border border-border bg-bg px-2 py-1 text-xs font-medium tabular-nums text-fg">{c}</span>
              ))}
            </div>
          </Tile>

          <Tile className="md:col-span-4" title="Know when it’s been opened" body="See the moment a client views the invoice, and when they pay.">
            <div className="grid grid-cols-3 gap-2 text-xs text-fg-muted">
              {stages.map((s) => (
                <div key={s.label} className="grid gap-2">
                  <span className={(s.done ? "bg-primary" : "bg-surface-2") + " h-1.5 rounded-full"} />
                  {s.label}
                </div>
              ))}
            </div>
          </Tile>
        </div>
      </div>
    </section>
  );
}

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