CTA
The clinia.com call to action: a mono uppercase label beside a square arrow tile.
When to use
- Send a visitor to the next step on a marketing page: book a demo, read a case study, start building.
- The main action of a hero, a feature section or a closing band.
When not to use
- A product (
base-luma) surface: use Button. - A form submit or an action inside a dialog or a menu on a marketing site: use Button, which the Sera style already shapes for marketing.
- A link inside a sentence: use a text link.
Install
npx shadcn@latest add @clinia/ctaUsage
import Link from "next/link";
import { Cta } from "@/components/ui/cta";
<Cta variant="primary" render={<Link href="/demo" />}>
Book a demo
</Cta>Clinia rules
- One
primaryCTA per section. Pair it with aghostordefaultCTA, never with a secondprimary. - On a dark band, add the
darkclass to the band. The tokens switch inside it, soprimarybecomes a Serene fill with an Infinite tile. - Labels are short and name the result:
Book a demo,Read the case study. Write them in sentence case: the component sets the capitals. - Keep the forward arrow for a CTA that moves the visitor on. Use
iconPosition="start"with a back arrow or a person icon for Back and Log in. - No Vital tile. The clinia.com styleguide has one (
--cta-icon-vital), but Vital never colours a control. - The tile is always the inverse of the CTA's fill, so the arrow reads in both themes. Don't recolor it.
Do and don't
States
Focus cells apply the component's focus-visible classes statically. Toggle the site theme to review both themes.
Sizes
| Size | Height | Gap | Radius | Type |
|---|---|---|---|---|
| default | h-9 · 36px, xl:h-[38px] · 38px | gap-2.5 · 10px, xl:gap-4 · 16px | --radius-lg | text-xs · 12px, xl:text-sm · 14px |
| sm | h-9 · 36px | gap-2.5 · 10px | --radius-lg | text-xs · 12px |
Accessibility
Built in
- Focus-visible shows a solid Trust ring with an offset, so it reads on the frosted
defaultfill and on a photo. - The label is real text, so it names the CTA. The rolling copy and the arrow tile are hidden from assistive tech.
- Reduced motion keeps the colour change and drops the label roll and the arrow slide.
Your responsibility
- Give a CTA that navigates an
href, orrender={<Link href="…" />}for a router link. It then renders a plain link: Enter follows it and Space scrolls the page, as on any link. - Give an icon-only use a visible label instead. A CTA always has text.
- On a photo, check the ground behind
defaultandghost: the frosted tint can't promise contrast over every image. Useprimarythere.
How to test
- Press Tab until the CTA has focus: the Trust ring appears and, without reduced motion, the label rolls.
- With a screen reader, it's announced once, as its label, then as a link when it has an
hrefand as a button when it doesn't. - Turn on reduced motion and hover: only the fill changes.
API
| Prop | Values | Default | Description |
|---|---|---|---|
| variant | defaultprimaryghost | default |
|
| size | defaultsm | default | Height 36px. |
| href | string | – | Renders a native link to this URL. For a router link, pass |
| icon | React.ReactNode | <ArrowForwardIcon /> | The icon beside the label. Defaults to the forward arrow; pass |
| iconPosition | startend | end |
|
| iconTile | boolean | true | Set the icon in its square tile. Turn off for a bare 16px icon, as in a ghost Back link. |
All other props come from Base UI Button.