Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Progress Urgency CTA Block for React

A centred scarcity statement: a headline over a framed seat map of 200 dots, one per founding seat, with the claimed ones solid and the next open ones pulsing, then the price with its list price struck and a Shine Button.

Framework
UI library

Preview

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Overview

Make scarcity something visitors can count, in this call to action for React with Base UI. The block sits on the page's spine: two side rails at the page column and one top rule with a + mark on each crossing, so it joins the blocks above and below it. A centred headline and one sentence introduce Marrow's founding seats; under them a wide frame with + marks on its corners holds a seat map of two hundred dots, forty to a row on desktop and twenty-five on phones. The 153 already claimed are solid in the theme's foreground tone, the next few open ones pulse softly, and the rest wait, dim. A legend and the seats left sit inside the frame; below it are the price with its list price struck through, the saving worked out, and one Shine Button to claim a seat. It's built from Badge and Shine Button, with CSS animation only. The block follows the theme and fits one screen on desktop, with the button on the first screen of a phone. For founding-member offers, limited cohorts, early-access programmes and launch pricing with a hard cap.

FAQ

How do I change the number of seats and how many are taken?

Edit TOTAL_SEATS and CLAIMED_SEATS at the top of the file. The map is drawn from a list with one entry per seat, the seats left, the headline and the screen-reader summary are all worked out from those two numbers, and PULSING sets how many open seats pulse. The map is forty columns wide on desktop and twenty-five on phones, so use 200 (a multiple of both) or adjust grid-cols-* to match, or the last row will be short.

Is the count live?

No: it's a typed number, and the block never calls a server. To make it live, pass the claimed count in from your server or build (a prop, or a fetch in the page) in place of the constant; every figure and the dots follow from it.

What does a screen reader hear for the dots?

The map is a single image with a label built from the numbers ("153 of 200 founding seats claimed, 47 left"); the two hundred dots themselves are hidden from assistive technology, since two hundred empty elements would say nothing. The seats left are also written out as text under the map.

What moves, and what happens with reduced motion?

The map is drawn row by row from the top when the section loads, and the next six open seats pulse in turn with Tailwind's animate-pulse and a staggered delay. With reduced motion the map is simply there and nothing pulses. The pulse is a soft decoration that carries no information; the legend and the numbers say everything it does.

How is the saving worked out?

LIST_PRICE and FOUNDER_PRICE are the two numbers you type; the percentage in the badge is worked out from them with whole-number arithmetic, rounded down ($20 off $49 is 40%). The old price is read by screen readers as "Was $49" and the new one as ", now $29 per month".

Where does the button go?

Claim your spot is a real link (href="#"): point it at your sign-up or checkout. It is a ShineButton with render set to an a element and nativeButton={false}.

  • Pro

    Ribbon Urgency CTA

    Urgency and limits

    A reverse split sale call to action: the discount at display size under a corner sash reading Limited time, a hairline divider, then an Ends in 3 days badge, the headline and a Shine Button. Urgency comes from type and structure, not a red fill.

  • Pro

    Savings Badge CTA

    Prices and offers

    A card-in-card price call to action: a big monthly price over its struck list price, with a twelve-point starburst sticker in foreground tones reading the percent saved, then a Shine Button and an outline link.

  • Pro

    Price Savings CTA

    Prices and offers

    A card-in-card bundle call to action: the three products as pills and two bars, what they cost bought separately at full width and a shorter bundle bar with the gap labelled You save, then a Shine Button.

  • Pro

    A light waitlist CTA as a split between solid rails: the headline, a sentence and the email form with the Shine Button at the start, and a capacity panel at the end whose bar gets a You pin and a count that rolls up by one when you join.

  • Pro

    Early Bird Pricing

    Discounts and offers

    Founder seats that run out: '163 of 200 claimed' at display size over a bar of forty segments, with the one founder plan, its struck regular price and its lifetime price beside the features.

  • Pro

    Centered Progress Bar Hero

    Updates and timelines

    A compact centered launch hero with a full-width progress bar that fills on load, four milestone cells divided at the quarter marks, the Shine Button and a second action.