Skip to content

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-soft/section/features-alternating
Open ↗

Source

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

export interface FeaturesAlternatingItem {
  eyebrow: string;
  title: string;
  text: string;
  points: string[];
  visual: "suppliers" | "actions" | "report";
}

export interface FeaturesAlternatingProps {
  items?: FeaturesAlternatingItem[];
  className?: string;
}

const DEFAULT_ITEMS: FeaturesAlternatingItem[] = [
  {
    eyebrow: "Suppliers",
    title: "Bring your supply chain along",
    text: "Invite suppliers to share their own data in a friendly two-minute form. Grove replaces estimates with real numbers as they come in.",
    points: ["Supplier portal in 12 languages", "Automatic reminders, no chasing"],
    visual: "suppliers",
  },
  {
    eyebrow: "Reduction",
    title: "A plan you can actually follow",
    text: "Every action is sized by tonnes saved, cost and effort — and tracked month by month so you see progress, not just promises.",
    points: ["120+ vetted actions", "Targets aligned with SBTi"],
    visual: "actions",
  },
  {
    eyebrow: "Reporting",
    title: "Reports that write themselves",
    text: "Export CSRD, CDP or GHG Protocol reports with every figure traceable back to its invoice.",
    points: ["Audit trail on every number", "Public climate page"],
    visual: "report",
  },
];

function Visual({ kind }: { kind: FeaturesAlternatingItem["visual"] }) {
  if (kind === "suppliers")
    return (
      <ul className="grid gap-3">
        {[
          ["Moulin Paper Co.", "Data shared", "bg-da-accent text-da-accent-fg"],
          ["Rhône Freight", "Invited 2 days ago", "bg-da-secondary text-da-secondary-fg"],
          ["Kiln & Clay", "Data shared", "bg-da-accent text-da-accent-fg"],
        ].map(([n, s, c]) => (
          <li key={n} className="flex items-center justify-between gap-3 rounded-da-md bg-da-surface px-4 py-3 shadow-da-sm">
            <span className="font-medium">{n}</span>
            <span className={cn("rounded-da-pill px-2.5 py-0.5 text-xs", c)}>{s}</span>
          </li>
        ))}
      </ul>
    );
  if (kind === "actions")
    return (
      <ul className="grid gap-3">
        {[
          ["Switch to green electricity", 42],
          ["Rail instead of short flights", 27],
          ["Consolidate freight lanes", 38],
        ].map(([n, v]) => (
          <li key={n} className="rounded-da-md bg-da-surface px-4 py-3 shadow-da-sm">
            <div className="flex justify-between text-sm">
              <span className="font-medium">{n}</span>
              <span className="font-da-mono text-da-primary">−{v} t</span>
            </div>
            <div className="mt-2 h-2 rounded-full bg-da-surface-2">
              <div className="h-full rounded-full bg-da-primary" style={{ width: `${Number(v) * 2}%` }} />
            </div>
          </li>
        ))}
      </ul>
    );
  return (
    <div className="rounded-da-md bg-da-surface p-5 shadow-da-sm">
      <p className="font-da-display text-xl">Climate report 2026</p>
      <p className="font-da-mono text-xs text-da-muted-fg">GHG Protocol · CSRD E1</p>
      <div className="mt-4 space-y-2">
        {[90, 75, 82, 60].map((w, i) => (
          <div key={i} className="h-2 rounded-full bg-da-surface-2" style={{ width: `${w}%` }} />
        ))}
      </div>
      <div className="mt-5 grid grid-cols-3 gap-2 text-center text-xs">
        {["Scope 1", "Scope 2", "Scope 3"].map((s) => (
          <span key={s} className="rounded-da-sm bg-da-accent py-2 text-da-accent-fg">
            {s}
          </span>
        ))}
      </div>
    </div>
  );
}

/** 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. */
export function FeaturesAlternating({ items = DEFAULT_ITEMS, className }: FeaturesAlternatingProps) {
  const blobs = ["rounded-[60%_40%_55%_45%/50%_60%_40%_50%]", "rounded-[45%_55%_40%_60%/55%_45%_60%_40%]", "rounded-[55%_45%_60%_40%/40%_55%_45%_60%]"];
  const tints = ["bg-da-accent", "bg-da-secondary", "bg-da-muted"];
  return (
    <section aria-label="Features" className={cn("da-section bg-da-bg text-da-fg", className)}>
      <div className="da-container grid gap-24">
        {items.map((it, i) => (
          <article key={it.title} className="grid items-center gap-10 lg:grid-cols-2 lg:gap-20">
            <div className={cn(i % 2 && "lg:order-2")}>
              <p className="text-sm font-medium text-da-primary">{it.eyebrow}</p>
              <h2 className="mt-3 font-da-display text-[clamp(2rem,4.5vw,3rem)] leading-[1.08] tracking-da-display">{it.title}</h2>
              <p className="mt-4 text-lg text-da-muted-fg">{it.text}</p>
              <ul className="mt-6 space-y-2.5">
                {it.points.map((p) => (
                  <li key={p} className="flex items-center gap-3">
                    <span aria-hidden className="grid size-6 place-items-center rounded-full bg-da-accent text-da-accent-fg">
                      <Check className="size-3.5" strokeWidth={2.5} />
                    </span>
                    {p}
                  </li>
                ))}
              </ul>
            </div>
            <div className={cn("px-8 py-14 sm:px-14", blobs[i % 3], tints[i % 3])}>
              <div className="mx-auto max-w-sm text-da-surface-fg">
                <Visual kind={it.visual} />
              </div>
            </div>
          </article>
        ))}
      </div>
    </section>
  );
}

export default FeaturesAlternating;

modules/organic-soft/section/features-alternating/index.tsx

Props

PropTypeDefaultDescription
itemsFeaturesAlternatingItem[]—Content items (see the exported types).
classNamestring—Extra classes on the root.

Other features variants in Organic Soft

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 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 FlatFeatures

Features Icons

Centered 4-column grid of eight small features, each with a large round pastel icon badge (colors rotate), rounded title and one-liner.

Soft FlatFeatures

Features Pastel

2×2 grid of large pastel feature cards (peach, mint, lavender, butter), each with icon, rounded title, copy and a tiny flat illustration (mini board, bar week, reminder toast, chat bubbles).

Soft FlatFeatures

Features Steps

Three numbered step cards in peach, lavender and mint joined by a dashed path on desktop, each with a white emoji medallion, mono step label, title and text.

Soft FlatFeatures