Skip to content
All Taste components

Animated sections

Feature checklist

A list of what’s included where each check draws itself in turn, with the copy sliding in beside it.

5 items · sequential check draw · heading beside or above · hover rows

Every plan includes

The boring parts, handled.

No add-ons to unlock the basics. These come with the free plan and stay when you grow.

Compare plans
  • Unlimited clientsAdd every client you work with, no per-contact pricing.
  • Automatic remindersPolite follow-ups on the schedule you pick.
  • Card and bank paymentsClients pay from the invoice link, no account needed.
  • Tax-ready exportsOne click gives your accountant what they ask for.
  • Two-step sign-inYour books stay yours, on every device.
import { ArrowRight } from "lucide-react";

/* Add once to globals.css:
@keyframes slide-in { from { opacity: 0; transform: translateX(-8px); } }
*/

const features = [
  { title: "Unlimited clients", text: "Add every client you work with, no per-contact pricing." },
  { title: "Automatic reminders", text: "Polite follow-ups on the schedule you pick." },
  { title: "Card and bank payments", text: "Clients pay from the invoice link, no account needed." },
  { title: "Tax-ready exports", text: "One click gives your accountant what they ask for." },
  { title: "Two-step sign-in", text: "Your books stay yours, on every device." },
];
const STEP = 260; // ms between items

export function FeatureChecklist() {
  return (
    <section aria-labelledby="ck-title" className="bg-bg py-20 font-sans">
      <div className="mx-auto grid max-w-5xl items-center gap-10 px-4 sm:px-6 lg:grid-cols-[.9fr_1.1fr] lg:gap-14">
        <div className="flex flex-col items-start gap-4">
          <p className="text-xs font-medium text-fg-subtle">Every plan includes</p>
          <h2 id="ck-title" className="text-3xl font-medium tracking-tight text-fg">The boring parts, handled.</h2>
          <p className="max-w-md text-base leading-relaxed text-fg-muted">No add-ons to unlock the basics. These come with the free plan and stay when you grow.</p>
          <a href="/pricing" className="inline-flex h-9 items-center gap-1.5 rounded border border-border-strong bg-bg px-3.5 text-sm font-medium text-fg transition hover:bg-surface active:scale-[.97]">
            Compare plans <ArrowRight className="size-4" aria-hidden />
          </a>
        </div>
        <ul className="grid gap-0.5">
          {features.map((f, i) => (
            <li key={f.title} className="flex gap-3.5 rounded p-3 transition-colors hover:bg-surface">
              <svg viewBox="0 0 26 26" className="size-[26px] shrink-0" aria-hidden>
                <circle cx="13" cy="13" r="12" className="origin-center fill-primary-soft [transform-box:fill-box] animate-pop motion-reduce:animate-none" style={{ animationDelay: i * STEP + 200 + "ms" }} />
                <circle cx="13" cy="13" r="12" pathLength={1} transform="rotate(-90 13 13)" className="fill-none stroke-primary [stroke-dasharray:1] [stroke-width:1.5] animate-[draw_.55s_cubic-bezier(.2,.7,.1,1)_both] motion-reduce:animate-none" style={{ animationDelay: i * STEP + 200 + "ms" }} />
                <path d="m8 13.5 3.2 3.2L18.5 9.5" pathLength={1} className="fill-none stroke-primary [stroke-dasharray:1] [stroke-linecap:round] [stroke-linejoin:round] [stroke-width:2.2] animate-[draw_.35s_cubic-bezier(.2,.7,.1,1)_both] motion-reduce:animate-none" style={{ animationDelay: i * STEP + 520 + "ms" }} />
              </svg>
              <div className="animate-[slide-in_.5s_cubic-bezier(.2,.7,.1,1)_both] motion-reduce:animate-none" style={{ animationDelay: i * STEP + 300 + "ms" }}>
                <p className="text-[15px] font-medium text-fg">{f.title}</p>
                <p className="text-[13.5px] leading-relaxed text-fg-muted">{f.text}</p>
              </div>
            </li>
          ))}
        </ul>
      </div>
    </section>
  );
}

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