Skip to content
All Taste components

Features

Features — 2 × 2 large cards

Four big feature cards, each with its own small picture of the feature above the words.

centered heading · 4 cards · illustrated tops (messages, pay card, currencies, chart) · 1 column below 640px

Getting paid

From “sent” to “paid” without the awkward bit

Reminders in your voice

Write the nudge once. Fernbill sends it on time and stops the second they pay.

A pay button on every invoice

Clients pay by card, bank or UPI in a few taps. No account, no login.

Bill in 24 currencies

Invoice clients in their own money and see what lands in yours before you send.

Cash flow at a glance

What's due this week, what's late and what's landed — in one honest chart.

import type { ReactNode } from "react";
import { cn } from "@/lib/utils";

/* Each card has a small picture drawn with plain elements, so it follows the theme. */
const Messages = () => (
  <div className="grid w-full max-w-[300px] gap-2 text-[12.5px]">
    <span className="max-w-[85%] justify-self-start rounded-lg rounded-bl-sm border border-border bg-bg px-3 py-2 text-fg shadow-sm">Hi Ravi — a friendly note that INV-1042 is due Friday.</span>
    <span className="max-w-[85%] justify-self-end rounded-lg rounded-br-sm bg-primary px-3 py-2 text-primary-fg">Paid just now, thanks!</span>
  </div>
);
const PayCard = () => (
  <div className="grid w-full max-w-[260px] gap-3 rounded-lg border border-border bg-bg p-4 text-[12.5px] shadow-lg">
    <div className="flex justify-between text-fg-subtle"><span>Amount due</span><span className="rounded-full bg-surface-2 px-2 text-xs text-fg-muted">INV-1042</span></div>
    <p className="text-[22px] font-semibold tracking-tight tabular-nums text-fg">$3,450.00</p>
    <div className="flex gap-1.5 text-center text-[11px]">
      {["Card", "Bank", "UPI"].map((m, i) => (
        <span key={m} className={cn("flex-1 rounded-sm border border-border py-1.5 text-fg-muted", i === 0 && "border-primary text-fg ring-1 ring-primary")}>{m}</span>
      ))}
    </div>
    <span className="rounded bg-primary py-1.5 text-center text-[13px] font-medium text-primary-fg">Pay now</span>
  </div>
);
const Currencies = () => (
  <div className="grid grid-cols-4 gap-2.5">
    {["$", "€", "£", "₹", "¥", "A$", "R", "kr"].map((c, i) => (
      <span key={c} className={cn("grid size-11 place-items-center rounded-full border border-border bg-bg text-base font-semibold text-fg-muted shadow-sm sm:size-[52px] sm:text-lg", i === 1 && "border-transparent bg-primary text-primary-fg")}>{c}</span>
    ))}
  </div>
);
const Chart = () => (
  <svg viewBox="0 0 320 130" fill="none" preserveAspectRatio="none" className="h-[130px] w-full max-w-[320px] text-primary">
    <path d="M0 110 L40 96 L80 100 L120 72 L160 80 L200 52 L240 58 L280 30 L320 18 L320 130 L0 130 Z" fill="currentColor" opacity=".12" />
    <path d="M0 110 L40 96 L80 100 L120 72 L160 80 L200 52 L240 58 L280 30 L320 18" stroke="currentColor" strokeWidth="2.5" strokeLinejoin="round" />
    <circle cx="280" cy="30" r="5" fill="currentColor" />
  </svg>
);

const cards: { title: string; text: string; picture: ReactNode }[] = [
  { title: "Reminders in your voice", text: "Write the nudge once. Fernbill sends it on time and stops the second they pay.", picture: <Messages /> },
  { title: "A pay button on every invoice", text: "Clients pay by card, bank or UPI in a few taps. No account, no login.", picture: <PayCard /> },
  { title: "Bill in 24 currencies", text: "Invoice clients in their own money and see what lands in yours before you send.", picture: <Currencies /> },
  { title: "Cash flow at a glance", text: "What’s due this week, what’s late and what’s landed — in one honest chart.", picture: <Chart /> },
];

export function FeaturesCards2x2() {
  return (
    <section aria-labelledby="features-title" className="bg-surface font-sans">
      <div className="mx-auto max-w-6xl px-4 py-16 sm:px-6 lg:py-24">
        <div className="mx-auto mb-12 max-w-2xl text-center">
          <p className="text-[13px] font-medium text-primary">Getting paid</p>
          <h2 id="features-title" className="mt-3.5 text-balance text-3xl font-semibold tracking-tight text-fg sm:text-4xl">
            From “sent” to “paid” without the awkward bit
          </h2>
        </div>
        <div className="grid gap-4 sm:grid-cols-2">
          {cards.map((c) => (
            <article key={c.title} className="overflow-hidden rounded-xl border border-border bg-bg">
              <div aria-hidden className="grid h-[200px] place-items-center overflow-hidden border-b border-border bg-surface bg-[radial-gradient(90%_80%_at_50%_0%,color-mix(in_srgb,var(--tst-primary)_14%,transparent),transparent_70%)] p-6">
                {c.picture}
              </div>
              <div className="grid gap-2 px-6 pb-6 pt-5">
                <h3 className="text-base font-semibold tracking-tight text-fg">{c.title}</h3>
                <p className="text-pretty text-[14.5px] leading-relaxed text-fg-muted">{c.text}</p>
              </div>
            </article>
          ))}
        </div>
      </div>
    </section>
  );
}

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