Block
Hero
The opening section of a page, with a title, a short lead, actions and optional media.
3 layoutsOne structure; add one layout modifier to pick the arrangement.
Centered layout
ca-hero--centered: One column with text and actions centered. For short messages and launch pages.
Launch
Eyebrow, title, lead and two actions, the main action first.
New in version 2
Plan a week of lessons in minutes
Drag lessons into the week. Every student gets the new times on their phone, and nobody has to call.
<section class="ca-hero ca-hero--centered" aria-labelledby="launch-title">
<div class="ca-hero__content">
<p class="ca-hero__eyebrow">New in version 2</p>
<h2 class="ca-hero__title" id="launch-title">Plan a week of lessons in minutes</h2>
<p class="ca-hero__lead">Drag lessons into the week. Every student gets the new times on their phone, and nobody has to call.</p>
<div class="ca-hero__actions">
<a class="ca-button ca-button--primary ca-button--lg" href="#start">Start a free trial</a>
<a class="ca-button ca-button--outline ca-button--lg" href="#tour">Take the tour</a>
</div>
</div>
</section>Title and one action
Every part apart from ca-hero__content and the title is optional.
Your driving test, booked
<section class="ca-hero ca-hero--centered" aria-labelledby="minimal-title">
<div class="ca-hero__content">
<h2 class="ca-hero__title" id="minimal-title">Your driving test, booked</h2>
<div class="ca-hero__actions">
<a class="ca-button ca-button--primary ca-button--lg" href="#booking">View your booking</a>
</div>
</div>
</section>Split layout
ca-hero--split: Content and media side by side, one column when the hero is narrow. For a product shown next to its pitch.
Product
The media part holds any markup; here a card shows the product itself.
For driving schools
One place for students, cars and lessons
See who drives when, which car is free and who is ready for the test.
Tuesday, 09:00
ConfirmedHighway practice with Sam in the blue car. Pick-up at the station.
<section class="ca-hero ca-hero--split" aria-labelledby="product-title">
<div class="ca-hero__content">
<p class="ca-hero__eyebrow">For driving schools</p>
<h2 class="ca-hero__title" id="product-title">One place for students, cars and lessons</h2>
<p class="ca-hero__lead">See who drives when, which car is free and who is ready for the test.</p>
<div class="ca-hero__actions">
<a class="ca-button ca-button--primary ca-button--lg" href="#start">Start a free trial</a>
<a class="ca-button ca-button--ghost ca-button--lg" href="#pricing">See pricing</a>
</div>
</div>
<div class="ca-hero__media">
<article class="ca-card" aria-labelledby="product-lesson">
<div class="flex items-start justify-between gap-3">
<h3 class="ca-card__title" id="product-lesson">Tuesday, 09:00</h3>
<span class="ca-badge ca-badge--success">Confirmed</span>
</div>
<p class="ca-card__description">Highway practice with Sam in the blue car. Pick-up at the station.</p>
<div class="ca-card__footer">
<button class="ca-button ca-button--secondary ca-button--sm" type="button">Move lesson</button>
</div>
</article>
</div>
</section>Stacked layout
ca-hero--stacked: The title runs across the full width, lead and actions share the row below it, media spans last. For stories and long titles.
Story
Inline SVG, images and video fill ca-hero__media and keep their aspect ratio.
Our story
We started with one car and a paper diary
Twelve years later we plan four thousand lessons a week, and the diary is still on the shelf.
<section class="ca-hero ca-hero--stacked" aria-labelledby="story-title">
<div class="ca-hero__content">
<p class="ca-hero__eyebrow">Our story</p>
<h2 class="ca-hero__title" id="story-title">We started with one car and a paper diary</h2>
<p class="ca-hero__lead">Twelve years later we plan four thousand lessons a week, and the diary is still on the shelf.</p>
<div class="ca-hero__actions">
<a class="ca-button ca-button--outline ca-button--lg" href="#team">Meet the team</a>
</div>
</div>
<div class="ca-hero__media">
<svg role="img" aria-labelledby="story-chart" viewBox="0 0 600 200" fill="currentColor">
<title id="story-chart">Lessons per week grew every year, from 40 in the first year to 4,000 now</title>
<rect x="20" y="180" width="40" height="10" opacity="0.35" />
<rect x="80" y="170" width="40" height="20" opacity="0.4" />
<rect x="140" y="160" width="40" height="30" opacity="0.45" />
<rect x="200" y="145" width="40" height="45" opacity="0.5" />
<rect x="260" y="130" width="40" height="60" opacity="0.55" />
<rect x="320" y="110" width="40" height="80" opacity="0.6" />
<rect x="380" y="90" width="40" height="100" opacity="0.7" />
<rect x="440" y="60" width="40" height="130" opacity="0.8" />
<rect x="500" y="30" width="40" height="160" opacity="0.9" />
<rect x="560" y="10" width="20" height="180" />
</svg>
</div>
</section>Guidance and accessibility
When to use
- Use one hero at the top of a page, to say what the page is for and what to do next.
- Pick the layout for the arrangement you need. Changes in content, such as leaving out the eyebrow or the media, need no other class.
- Keep one main action. A second action uses a quieter variant, such as outline or ghost.
Accessibility
- When the hero opens the page, its title is the page’s
<h1>. The examples here use<h2>because they sit inside this documentation page. - Label the section with
aria-labelledbypointing to the title, so screen reader users can find it in the list of regions. - Every layout keeps the markup order as the reading order. Put the content before the media in the markup.
- Media that carries meaning needs a text alternative:
alton images, orrole="img"with a<title>on inline SVG. Decorative media getsalt=""oraria-hidden="true". - Actions that go to another page are links (
<a>withca-button); actions that do something on the page are buttons.
Classes
Generated from the block contract. Layouts are part of the core, so every skin gets all of them.
| Class | Kind | Use it for |
|---|---|---|
ca-hero | Block | Section with the hero's grid and spacing. Add exactly one layout. |
ca-hero__content | Part | Wrapper for the eyebrow, title, lead and actions. |
ca-hero__eyebrow | Part | Short label above the title, such as a category or release. |
ca-hero__title | Part | The page's main heading. Use <h1> when the hero opens the page. |
ca-hero__lead | Part | One or two sentences below the title, kept to a readable line length. |
ca-hero__actions | Part | Row of links or buttons that wraps on narrow screens. |
ca-hero__media | Part | Image, video, illustration or product preview. |
ca-hero--centered | Layout | One centered column. |
ca-hero--split | Layout | Content and media side by side. |
ca-hero--stacked | Layout | Full-width title, then lead and actions side by side, then media. |
Skins
The same markup, dressed by each skin. The arrangement stays; spacing, type and color change.
Base skin
Neutral grayscale starting point; product skins extend it and change what differs.
New in version 2
Plan a week of lessons in minutes
Drag lessons into the week. Every student gets the new times on their phone, and nobody has to call.
Calaca skin
The Calaca UI brand: hueso paper and tinta ink, cempasúchil marigold, rosa and jade.
New in version 2
Plan a week of lessons in minutes
Drag lessons into the week. Every student gets the new times on their phone, and nobody has to call.
Proof skin
Pilot skin pushed far from base: square, heavy, offset shadows, larger targets.
New in version 2
Plan a week of lessons in minutes
Drag lessons into the week. Every student gets the new times on their phone, and nobody has to call.
Crossview skin
The CrossView proofing table: cool ground, bond-paper sheets, rule-grey hairlines, one red mark.
New in version 2
Plan a week of lessons in minutes
Drag lessons into the week. Every student gets the new times on their phone, and nobody has to call.
Framework notes
Link the prebuilt stylesheet of your skin next to your brand theme. No build step.
<link rel="stylesheet" href="theme.css" />
<link rel="stylesheet" href="ca-base.css" />In Astro, Vite and other Tailwind projects, import Calaca after Tailwind and your theme in your main stylesheet.
@import "tailwindcss";
@import "./theme.css";
@import "@calaca/ui/core.css";
@import "@calaca/ui/skins/base.css";Same stylesheet as above; write the classes in className.
<button className="ca-button ca-button--primary ca-button--md" type="button">Save changes</button>