Skip to content

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.

glass/section/cta-waitlist
Open ↗

Source

"use client";

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

export interface CtaWaitlistProps {
  title?: string;
  description?: string;
  buttonLabel?: string;
  onSubmit?: (email: string) => void | Promise<void>;
  perks?: string[];
  className?: string;
}

const GLASS = "da-stroke bg-da-surface backdrop-blur-da backdrop-saturate-150";

/** Frosted CTA panel with a gradient ring glow, email pill form (success state) and three perks with checks. */
export function CtaWaitlist({
  title = "Get your first recap in 5 minutes",
  description = "Connect your calendar, and Halo joins your next call. Free for your first 10 meetings.",
  buttonLabel = "Get started",
  onSubmit,
  perks = ["No credit card", "Works with Zoom, Meet, Teams", "Cancel any time"],
  className,
}: CtaWaitlistProps) {
  const id = useId();
  const [done, setDone] = useState(false);

  const submit = async (e: FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    await onSubmit?.(String(new FormData(e.currentTarget).get("email")));
    setDone(true);
  };

  return (
    <section className={cn("da-section text-da-fg", className)}>
      <div className="da-container">
        <div className="relative mx-auto max-w-3xl">
          <div
            aria-hidden
            className="absolute -inset-1 rounded-[calc(var(--da-radius-lg)+4px)] bg-gradient-to-r from-da-primary via-da-accent to-da-primary opacity-40 blur-xl"
          />
          <div className={cn("relative rounded-da-lg px-6 py-12 text-center shadow-da-lg sm:px-12", GLASS)}>
            <h2 className="font-da-display text-[clamp(1.75rem,4vw,2.75rem)] leading-[1.1] font-semibold tracking-da-display text-balance">{title}</h2>
            <p className="mx-auto mt-4 max-w-lg text-lg text-da-muted-fg">{description}</p>
            {done ? (
              <p role="status" className="mt-8 inline-flex items-center gap-2 rounded-da-pill bg-da-success px-5 py-3 font-semibold text-da-success-fg">
                <Check aria-hidden className="size-4" /> Check your inbox to connect your calendar.
              </p>
            ) : (
              <form onSubmit={submit} className="mx-auto mt-8 flex max-w-md flex-col gap-2 sm:flex-row">
                <label htmlFor={id} className="sr-only">
                  Work email
                </label>
                <input
                  id={id}
                  name="email"
                  type="email"
                  required
                  autoComplete="email"
                  placeholder="you@company.com"
                  className="da-focus da-stroke h-12 min-w-0 sm:flex-1 rounded-da-pill bg-da-input px-5 placeholder:text-da-muted-fg"
                />
                <button
                  type="submit"
                  className="da-focus da-transition h-12 rounded-da-pill bg-gradient-to-r from-da-primary to-da-accent px-6 font-semibold text-da-primary-fg shadow-da-md hover:-translate-y-0.5"
                >
                  {buttonLabel}
                </button>
              </form>
            )}
            <ul className="mt-6 flex flex-wrap justify-center gap-x-6 gap-y-2 text-sm text-da-muted-fg">
              {perks.map((p) => (
                <li key={p} className="inline-flex items-center gap-1.5">
                  <Check aria-hidden className="size-4 text-da-success" />
                  {p}
                </li>
              ))}
            </ul>
          </div>
        </div>
      </div>
    </section>
  );
}

export default CtaWaitlist;

modules/glass/section/cta-waitlist/index.tsx

Props

PropTypeDefaultDescription
title / description / buttonLabelstring—Texts.
onSubmit(email: string) => void | Promise<void>—Handler.
perksstring[]—Reassurance list.
classNamestring—Classes.

Other cta variants in Glass

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

Closing CTA inside a large sage organic blob (SVG shape scaled to the content) with a clay pebble and two leaves around it; serif headline and cream pill buttons.

Organic SoftCTA

Cta Journal

Newsletter CTA styled like a paper journal: clay-tinted card with serif title, recent issue list with mono numbers, and a rounded email + button form with a warm thank-you state.

Organic SoftCTA

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 SoftCTA

Cta Wave

Full-width sage band with soft wavy top and bottom edges (SVG), centered serif headline with an italic word, and two pill buttons; flows naturally between cream sections.

Organic SoftCTA

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