Skip to content

Features Checklist

Interactive split section: copy and a mint progress bar on the left, a white card of four round-checkbox steps on the right that turn mint with a bouncy tick when clicked; celebration at 100%.

soft-flat/section/features-checklist
Open ↗

Source

"use client";

import { useState } from "react";
import { Check } from "lucide-react";
import { cn } from "@/lib/utils";

export interface FeaturesChecklistProps {
  eyebrow?: string;
  title?: string;
  description?: string;
  items?: { title: string; text: string }[];
  className?: string;
}

const DEFAULT_ITEMS = [
  { title: "Create a board in one click", text: "Start from 60+ templates for launches, hiring, content and more." },
  { title: "Invite your team", text: "Everyone gets their own weekly view of shared work." },
  { title: "Set gentle reminders", text: "One nudge before the deadline — never a notification storm." },
  { title: "Celebrate the done column", text: "Weekly recaps show what the team finished, not just what’s left." },
];

/** Split feature section: an interactive round-checkbox checklist on one side (click to tick items), explanatory copy and progress on the other. */
export function FeaturesChecklist({
  eyebrow = "How it works",
  title = "Four steps to a calmer week",
  description = "Planta is set up in minutes. Tick the steps to see how it feels.",
  items = DEFAULT_ITEMS,
  className,
}: FeaturesChecklistProps) {
  const [done, setDone] = useState<boolean[]>(() => items.map((_, i) => i === 0));
  const count = done.filter(Boolean).length;

  return (
    <section aria-labelledby="sf-check-title" className={cn("da-section bg-da-bg text-da-fg", className)}>
      <div className="da-container grid items-center gap-12 lg:grid-cols-2">
        <div>
          <p className="text-sm font-semibold text-da-primary">{eyebrow}</p>
          <h2
            id="sf-check-title"
            className="mt-3 font-da-display text-[clamp(2rem,4.5vw,3.25rem)] leading-[1.08] font-extrabold tracking-da-display text-balance"
          >
            {title}
          </h2>
          <p className="mt-4 text-lg text-da-muted-fg">{description}</p>
          <div className="mt-8 max-w-sm">
            <p className="flex justify-between text-sm font-semibold">
              <span>Your progress</span>
              <span aria-live="polite">
                {count}/{items.length}
              </span>
            </p>
            <div className="mt-2 h-3 overflow-hidden rounded-da-pill bg-da-muted">
              <div
                className="h-full rounded-da-pill bg-da-secondary-fg transition-[width] duration-(--da-duration-slow) ease-da-emphasized"
                style={{ width: `${(count / items.length) * 100}%` }}
              />
            </div>
            {count === items.length && <p className="mt-3 font-da-display text-lg font-extrabold">All done — nice! 🎉</p>}
          </div>
        </div>
        <ul className="space-y-3 rounded-da-lg bg-da-surface p-4 shadow-da-md sm:p-6">
          {items.map((it, i) => (
            <li key={it.title}>
              <label
                className={cn(
                  "da-transition flex cursor-pointer items-start gap-4 rounded-da-md p-4 has-focus-visible:ring-(length:--da-ring-width) has-focus-visible:ring-da-ring",
                  done[i] ? "bg-da-secondary" : "hover:bg-da-surface-2",
                )}
              >
                <input type="checkbox" checked={done[i]} onChange={() => setDone((d) => d.map((v, k) => (k === i ? !v : v)))} className="sr-only" />
                <span
                  aria-hidden
                  className={cn(
                    "mt-0.5 grid size-7 shrink-0 place-items-center rounded-full border-2 transition-all duration-(--da-duration) ease-da-emphasized",
                    done[i] ? "scale-110 border-da-secondary-fg bg-da-secondary-fg text-da-secondary" : "border-da-border-strong",
                  )}
                >
                  {done[i] && <Check className="size-4" strokeWidth={3} />}
                </span>
                <span>
                  <span className={cn("block font-da-display text-lg font-extrabold", done[i] && "text-da-secondary-fg")}>{it.title}</span>
                  <span className={cn("mt-0.5 block text-sm", done[i] ? "text-da-secondary-fg/85" : "text-da-muted-fg")}>{it.text}</span>
                </span>
              </label>
            </li>
          ))}
        </ul>
      </div>
    </section>
  );
}

export default FeaturesChecklist;

modules/soft-flat/section/features-checklist/index.tsx

Props

PropTypeDefaultDescription
eyebrow / title / descriptionstring—Header copy.
items{ title, text }[]—Steps.
classNamestring—Classes.

Other features variants in Soft Flat

Features in other art directions

Features Grid

Six features in a single ruled box (1/2/3 columns) with numbered tiles, color-cycling icon blocks that press on hover, and a two-column section header.

BrutalistFeatures

Features Numbered

Full-width ruled rows with giant faded step numbers, uppercase titles, descriptions and a stat chip; each row floods with a different primary color on hover and the number turns solid.

BrutalistFeatures

Features Tabs

Tabbed feature explorer: ruled mono tab bar (ink active tab), then a big split panel with title, description and square-bullet list on the left and a stacked mock preview of the channel on the right.

BrutalistFeatures

Features Versus

Before/after comparison: two slightly tilted cards side by side — the old way in paper with red crosses, the new way in solid yellow with ink checks — row by row on the same topics.

BrutalistFeatures

Features Bento

Glass bento grid on 6 columns: a large AI-recap tile with a mock summary and owner chips, plus five smaller frosted tiles with gradient squircle icons.

GlassFeatures

Features Glass Grid

Centered header and six frosted feature cards with gradient squircle icons; cards lift with an overshoot and reveal a soft corner glow on hover.

GlassFeatures

Features Orbit

Integrations section: copy with a chip list on one side, and a central gradient orb with integration bubbles orbiting on two counter-rotating glass rings (bubbles stay upright). Pure CSS.

GlassFeatures

Features Tabs

Glass pill tab bar (Radix Tabs) with gradient active tab switching a large frosted panel: title, copy and bullets on the left, a layered glass preview on the right.

GlassFeatures

Features Alternating

Three zig-zag rows, each pairing a numbered kicker, title, copy and link with an HTML product mock-up (routing rules, on-call week, AI postmortem) on a soft tinted plate.

MinimalFeatures

Features Bento

Bento grid of five hairline tiles on a 6-column layout, each with a small token-themed HTML illustration (routing lines, uptime bars, MTTR metric, on-call week) above an icon, title and description.

MinimalFeatures

Features List

Dense four-column feature list: each item has a small indigo line icon, a title and a one-sentence description under a hairline top rule. Eight defaults, left-aligned header.

MinimalFeatures

Features Steps

Five-step workflow (detect, page, coordinate, resolve, learn) laid out horizontally on desktop and vertically on mobile, joined by a hairline, with numbered nodes and timing labels.

MinimalFeatures

Features Index

Features as a numbered index: a label + headline in the left columns, and a two-column ruled list on the right where each item is “01 — Title” with a short description.

Mono CleanFeatures

Features Numbered

Three large numbered steps: giant outlined-looking numerals in muted ink above a hairline, step title and text; columns on desktop, stacked on mobile.

Mono CleanFeatures

Features Showcase

Work showcase as the feature: an asymmetric grid (fixed row heights; wide, tall, square and full-width spans) of neutral gray image frames with mono captions (studio — project, template used); captions underline on hover.

Mono CleanFeatures

Features Specs

Technical spec sheet: grouped key/value definition lists in a 4-column grid, each group under a full-ink rule with a mono heading — reads like a product data sheet.

Mono CleanFeatures

Features Bento

Data-driven bento grid of bordered cards: cash-flow line chart, DSO metric, approval flow, currency list and integrations — each a small realistic mock.

Neo CorporateFeatures

Features Grid

Classic 3×2 bordered feature grid sharing hairline borders (one outer frame), each cell with a blue icon square, title, text and a “Learn more” link.

Neo CorporateFeatures

Features Tabs

Underline tabs (Radix Tabs) switching between product areas: copy + check points on the left, a bordered data card (status rows) on the right.

Neo CorporateFeatures

Features Versus

Before/after comparison: a muted “spreadsheets and email” column with red crosses next to a blue-bordered “with Ledgerly” column with green checks.

Neo CorporateFeatures

Features Alternating

Alternating zig-zag rows: copy with check points on one side, a soft blob-shaped tinted panel holding a small product vignette (suppliers, actions, report) on the other.

Organic SoftFeatures

Features Bento

Soft bento: rounded tinted tiles of mixed sizes — a monthly emissions bar chart, a human equivalence (“= 42 flights”), supplier avatars, a certifications tile and a leaf quote.

Organic SoftFeatures

Features Cards

Three tall rounded cards in sage, clay and paper tints; each has an icon sitting in an organic blob, a serif title and calm copy.

Organic SoftFeatures

Features Journey

Horizontal journey: numbered circles connected by a hand-drawn wavy dashed path (vertical list on mobile), each step with a serif title, text and a mono time estimate.

Organic SoftFeatures