Skip to content

Cta Pledge

Interactive pledge CTA: pick the commitments your team is ready for (round check cards), a counter of companies who pledged, and a CTA that reflects how many you chose.

organic-soft/section/cta-pledge
Open ↗

Source

"use client";

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

export interface CtaPledgeProps {
  title?: string;
  pledges?: string[];
  count?: number;
  cta?: { label: string; href: string };
  className?: string;
}

/** Interactive pledge CTA: pick the commitments your team is ready for (round check cards), a counter of companies who pledged, and a CTA that reflects how many you chose. */
export function CtaPledge({
  title = "What is your team ready to commit to?",
  pledges = [
    "Measure our full footprint this year",
    "Switch to renewable electricity",
    "Replace short flights with trains",
    "Ask our top 10 suppliers for data",
  ],
  count = 1284,
  cta = { label: "Make it official", href: "#pledge" },
  className,
}: CtaPledgeProps) {
  const [picked, setPicked] = useState<string[]>([pledges[0] ?? ""]);
  const toggle = (p: string) => setPicked((x) => (x.includes(p) ? x.filter((y) => y !== p) : [...x, p]));
  return (
    <section aria-labelledby="os-cp-title" className={cn("da-section bg-da-surface-2 text-da-fg", className)}>
      <div className="da-container grid items-center gap-12 lg:grid-cols-2">
        <div>
          <h2 id="os-cp-title" className="font-da-display text-[clamp(2.25rem,5vw,3.5rem)] leading-[1.05] tracking-da-display text-balance">
            {title}
          </h2>
          <p className="mt-5 text-lg text-da-muted-fg">
            <span className="font-da-display text-3xl text-da-primary">{count.toLocaleString("en-US")}</span> companies have pledged this year.
          </p>
        </div>
        <div>
          <fieldset>
            <legend className="sr-only">Commitments</legend>
            <div className="grid gap-3">
              {pledges.map((p) => {
                const on = picked.includes(p);
                return (
                  <label
                    key={p}
                    className={cn(
                      "da-transition flex cursor-pointer items-center gap-4 rounded-da-lg p-5 has-focus-visible:ring-3 has-focus-visible:ring-da-ring",
                      on ? "bg-da-accent text-da-accent-fg" : "bg-da-surface text-da-surface-fg shadow-da-sm hover:shadow-da-md",
                    )}
                  >
                    <input type="checkbox" checked={on} onChange={() => toggle(p)} className="sr-only" />
                    <span
                      aria-hidden
                      className={cn(
                        "grid size-7 shrink-0 place-items-center rounded-full border-2 transition-colors duration-(--da-duration)",
                        on ? "border-da-primary bg-da-primary text-da-primary-fg" : "border-da-border-strong",
                      )}
                    >
                      {on && <Check className="size-4" strokeWidth={3} />}
                    </span>
                    <span className="text-lg">{p}</span>
                  </label>
                );
              })}
            </div>
          </fieldset>
          <a
            href={cta.href}
            aria-disabled={picked.length === 0}
            className={cn(
              "da-focus da-transition mt-6 inline-flex h-12 w-full items-center justify-center rounded-da-pill bg-da-primary font-medium text-da-primary-fg hover:bg-da-primary/90",
              picked.length === 0 && "pointer-events-none opacity-50",
            )}
          >
            {cta.label} · {picked.length} {picked.length === 1 ? "pledge" : "pledges"}
          </a>
        </div>
      </div>
    </section>
  );
}

export default CtaPledge;

modules/organic-soft/section/cta-pledge/index.tsx

Props

PropTypeDefaultDescription
titlestring—Heading.
pledgesstring[]—Pledges.
countnumber—Count.
cta{ label: string; href: string }—Cta.
classNamestring—Extra classes on the root.

Other cta variants in Organic Soft

CTA in other art directions

CTA Banner

Full-bleed yellow slab with a giant uppercase headline and an inline email capture form (pending + success states), ruled pattern in the corner.

BrutalistCTA

CTA Countdown

Limited-offer CTA in an ink slab: uppercase offer headline, yellow claim button, dashed promo code, and a four-cell live countdown (days/hours/min/sec) with the first cell in yellow.

BrutalistCTA

CTA Split

Two-audience CTA: a big headline over two fully clickable cards (yellow for engineers, blue for product teams) with audience label, title, pitch and a button chip; cards slam into their shadow on hover.

BrutalistCTA

CTA Sticker

Full-bleed pink CTA with a giant centered uppercase headline, an oversized ink button that slams into its shadow on hover, and a yellow circular text-path sticker ticking around in steps.

BrutalistCTA

Cta App

App download CTA in a glass panel: headline, ink store buttons and rating on the left; an HTML phone mock-up recording an in-person meeting (mic orb, waveform, AI chip) rising from the bottom on the right.

GlassCTA

Cta Gradient

Bold full-gradient CTA card with a masked grid overlay and top glow, white primary button, translucent secondary button and three frosted stat chips.

GlassCTA

CTA Orb

Large frosted panel with a slowly spinning, heavily blurred conic-gradient orb glowing through the glass, centered headline, ink + frosted CTAs and a reassurance line.

GlassCTA

Cta Waitlist

Frosted CTA panel haloed by a blurred gradient ring: headline, copy, pill email form with gradient button (success state) and three check perks.

GlassCTA

Cta Banner

Compact inverted ink banner on a single row: title and one-liner on the left, solid and outline actions on the right, with a faint grid fading in from the right edge.

MinimalCTA

CTA Glow

Closing call-to-action card: centered headline and copy, ink button with keyboard hint, ghost secondary link, an indigo glow rising from the bottom edge and a gradient hairline on top.

MinimalCTA

Cta Newsletter

Centered email capture card with an indigo hairline on top: headline, copy, email field and ink button, with client validation plus pending, success and error states.

MinimalCTA

Cta Split

Wide two-column CTA card: headline, copy and two buttons on the left; a tinted panel on the right with a numbered ‘first 10 minutes’ onboarding checklist and time estimates.

MinimalCTA

Cta Contact

Studio-style contact CTA: mono label, headline, the email address set huge as a link, and a row of contact channels (studio, press, careers) in mono under a hairline.

Mono CleanCTA

Cta Email

Underline-input signup: large headline, then an email field drawn as a single bottom rule with an inline “Get started →” button; confirmation replaces the form.

Mono CleanCTA

Cta Giant

Full-width CTA as a giant link: the whole headline is the link, an arrow slides in on hover and an ink underline wipes across; a mono note sits below.

Mono CleanCTA

Cta Split

Two-door CTA: the section is split into two equal halves (white | ink) with a mono label and a large title each; hovering a half inverts it and nudges the arrow.

Mono CleanCTA

Cta Band

Full-width primary-blue band with a faint grid pattern, headline + subline on the left and inverted white + outlined buttons on the right.

Neo CorporateCTA

Cta Demo

Book-a-demo CTA: benefits list on the left, bordered form card (work email, company, team size select) on the right with an inline success state.

Neo CorporateCTA

Cta Stats

Split CTA on a dark (fg-colored) panel: copy + buttons on the left, a 2×2 grid of large outcome stats divided by hairlines on the right.

Neo CorporateCTA

Cta Trust

Centered CTA inside a bordered panel: headline, two buttons, a line of compliance assurances with shield icons, and a strip of customer wordmarks below a hairline.

Neo CorporateCTA

Cta App

App-download CTA on a peach block: headline and ink store buttons on the left, a flat white phone mock-up with a “Today” checklist (mint done items) rising from the bottom on the right.

Soft FlatCTA

Cta Block

Big periwinkle rounded block with pastel circles peeking from the corners, a centered white headline and two pill buttons (solid white and translucent).

Soft FlatCTA

Cta Illustrated

Split CTA in a white rounded card: headline, ink pill button and note on the left; a composition of pastel circle, pill, rotated square and a ✅ tile on the right.

Soft FlatCTA

Cta Newsletter

Newsletter CTA on a mint block: a flat envelope made of shapes with a notification badge, headline, pill email form and a cheerful success state.

Soft FlatCTA