Skip to content
Protocore Design Systemv1.6.9

/// Cards

DualCTA

The split page-closer — two hover-inverting CTA halves (mono eyebrow + headline + outbound arrow) in one bordered surface, divided by a hairline.

import { DualCTA } from "@protocore/pds";
View as Markdown

Basics

Pass two columns, each with an eyebrow and title. When a column has an href, the whole half renders as an <a> (with optional target/rel) and shows the outbound ↗︎. Each half inverts on hover.

Button halves

Without an href, a half renders as a <div> and fires onClick — use it for in-app actions rather than navigation. Set arrow={false} to drop the outbound indicator when the action isn't a link.

RegionDeploy to eu-central-1
RegionDeploy to us-east-1
Pick a region above.

When to use it

DualCTA is a page-level closer: the recurring "talk to us / start building" split that sits above the footer. It's a *layout* component for exactly two balanced choices, not a general button group. For a *toolbar* of several actions use ButtonGroup; for a *single* call to action a plain Button is right. For a *tinted note* with an action, use Callout. Reserve DualCTA for the two-way fork at the end of a page or section — one path per half, no more than two halves.

Usage

Do

  • Give each half a parallel `eyebrow` + `title` so the two choices read as peers.
  • Use `href` for navigation halves and `onClick` for in-app halves.
  • Keep it to two columns — the layout is a balanced split, not an n-up grid.
  • Drop the arrow (`arrow={false}`) on non-link halves so the `↗︎` doesn't imply navigation.

Don't

  • Don't pass three or more columns; the halves stop being balanced.
  • Don't mix a giant headline in one half with a terse one in the other — keep them symmetric.
  • Don't use DualCTA as a generic button container; that's ButtonGroup.
  • Don't set `target="_blank"` without a matching `rel` for external links.

Accessibility

KeysAction
TabMoves focus to each CTA half in order.
EnterActivates the focused half — follows the link, or fires onClick.
SpaceActivates a link half (native anchor behavior).
  • Halves with an `href` are real anchors and are keyboard-focusable by default. Halves that only take `onClick` render as a `<div>` — add `role="button"` and `tabIndex={0}` via the column's props if the action must be keyboard-reachable, or prefer an `href` where one exists.
  • The `↗︎` arrow is `aria-hidden`; the accessible name comes from the `title` (and `eyebrow`) text.
  • The inversion on hover is mirrored by `:focus-visible`, so keyboard users see the same active-state feedback.

DualCTA props

PropTypeDefaultDescription
classNamestring
columns *DualCTAColumn[]The CTA halves — typically two — laid into equal columns.
styleCSSProperties

Related

  • CardA surface block with a hairline border and sharp corners — flat title/subtitle/action props or compound Card.Header/Body/Footer.
  • CalloutA tone-tinted note with a 2px left rule — the one place a note earns color, over an optional mono uppercase title.
  • ProductCardAn illustrated product card — art panel, eyebrow, title, one-line body, a mono tag row, and an outbound footer link, with a [ 0N ] index.
  • StatStripA hairline-bounded band of figures over mono captions, with the one-green-figure rule — signalIndex marks at most one accent figure.