Block
Features
A set of features, each with an icon, a title and one line of text.
2 layoutsOne structure; add one layout modifier to pick the arrangement.
Grid layout
ca-features--grid: Features in as many columns as fit, icon above the text. For three to six features of equal weight.
Driving school
A header, then three features with an icon each.
Everything a driving school runs on
Lessons, students and payments in one place, on every device.
-
Planning
Drag lessons into the week; students get the new times on their phone.
-
Progress
Mark skills after each drive and see who is ready for the test.
-
Payments
Send invoices and see what is paid, without a spreadsheet.
<section class="ca-features ca-features--grid w-full" aria-labelledby="features-grid-title">
<div class="ca-features__header">
<h2 class="ca-features__title" id="features-grid-title">Everything a driving school runs on</h2>
<p class="ca-features__lead">Lessons, students and payments in one place, on every device.</p>
</div>
<ul class="ca-features__list">
<li class="ca-features__item">
<span class="ca-features__icon" aria-hidden="true"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="17" rx="2" /><path d="M3 9h18M8 2v4M16 2v4" /></svg></span>
<h3 class="ca-features__item-title">Planning</h3>
<p class="ca-features__item-text">Drag lessons into the week; students get the new times on their phone.</p>
</li>
<li class="ca-features__item">
<span class="ca-features__icon" aria-hidden="true"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="8" r="4" /><path d="M4 21a8 8 0 0 1 16 0" /></svg></span>
<h3 class="ca-features__item-title">Progress</h3>
<p class="ca-features__item-text">Mark skills after each drive and see who is ready for the test.</p>
</li>
<li class="ca-features__item">
<span class="ca-features__icon" aria-hidden="true"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="5" width="20" height="14" rx="2" /><path d="M2 10h20" /></svg></span>
<h3 class="ca-features__item-title">Payments</h3>
<p class="ca-features__item-text">Send invoices and see what is paid, without a spreadsheet.</p>
</li>
</ul>
</section>List layout
ca-features--list: One feature per row, icon beside the text. For fewer features with more to say, or a narrow column.
Driving school, as a list
The same markup; only the layout class differs.
Everything a driving school runs on
Lessons, students and payments in one place, on every device.
-
Planning
Drag lessons into the week; students get the new times on their phone.
-
Progress
Mark skills after each drive and see who is ready for the test.
-
Payments
Send invoices and see what is paid, without a spreadsheet.
<section class="ca-features ca-features--list w-full" aria-labelledby="features-list-title">
<div class="ca-features__header">
<h2 class="ca-features__title" id="features-list-title">Everything a driving school runs on</h2>
<p class="ca-features__lead">Lessons, students and payments in one place, on every device.</p>
</div>
<ul class="ca-features__list">
<li class="ca-features__item">
<span class="ca-features__icon" aria-hidden="true"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="17" rx="2" /><path d="M3 9h18M8 2v4M16 2v4" /></svg></span>
<h3 class="ca-features__item-title">Planning</h3>
<p class="ca-features__item-text">Drag lessons into the week; students get the new times on their phone.</p>
</li>
<li class="ca-features__item">
<span class="ca-features__icon" aria-hidden="true"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="8" r="4" /><path d="M4 21a8 8 0 0 1 16 0" /></svg></span>
<h3 class="ca-features__item-title">Progress</h3>
<p class="ca-features__item-text">Mark skills after each drive and see who is ready for the test.</p>
</li>
<li class="ca-features__item">
<span class="ca-features__icon" aria-hidden="true"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="5" width="20" height="14" rx="2" /><path d="M2 10h20" /></svg></span>
<h3 class="ca-features__item-title">Payments</h3>
<p class="ca-features__item-text">Send invoices and see what is paid, without a spreadsheet.</p>
</li>
</ul>
</section>Guidance and accessibility
When to use
- Use features to show what a product does, in a few short points.
- Lead each point with what it does for people, not with the name of a module.
Accessibility
- The features are a list, so screen readers announce how many there are.
- Each title is a heading one level below the block title.
- Icons are decoration: hide them with
aria-hidden="true".
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-features | Block | Section with the header and the list of features. Add one layout. |
ca-features__header | Part | Optional title and lead above the features. |
ca-features__title | Part | Heading of the block. |
ca-features__lead | Part | One or two sentences below the title. |
ca-features__list | Part | The <ul> of features. |
ca-features__item | Part | One feature. |
ca-features__icon | Part | Optional icon or illustration; decoration. |
ca-features__item-title | Part | Name of the feature, as a heading. |
ca-features__item-text | Part | One line on what it does for people. |
ca-features--grid | Layout | Columns as room allows, icon above. |
ca-features--list | Layout | One column, icon beside the text. |
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.
Everything a driving school runs on
Lessons, students and payments in one place, on every device.
-
Planning
Drag lessons into the week; students get the new times on their phone.
-
Progress
Mark skills after each drive and see who is ready for the test.
-
Payments
Send invoices and see what is paid, without a spreadsheet.
Calaca skin
The Calaca UI brand: hueso paper and tinta ink, cempasúchil marigold, rosa and jade.
Everything a driving school runs on
Lessons, students and payments in one place, on every device.
-
Planning
Drag lessons into the week; students get the new times on their phone.
-
Progress
Mark skills after each drive and see who is ready for the test.
-
Payments
Send invoices and see what is paid, without a spreadsheet.
Proof skin
Pilot skin pushed far from base: square, heavy, offset shadows, larger targets.
Everything a driving school runs on
Lessons, students and payments in one place, on every device.
-
Planning
Drag lessons into the week; students get the new times on their phone.
-
Progress
Mark skills after each drive and see who is ready for the test.
-
Payments
Send invoices and see what is paid, without a spreadsheet.
Crossview skin
The CrossView proofing table: cool ground, bond-paper sheets, rule-grey hairlines, one red mark.
Everything a driving school runs on
Lessons, students and payments in one place, on every device.
-
Planning
Drag lessons into the week; students get the new times on their phone.
-
Progress
Mark skills after each drive and see who is ready for the test.
-
Payments
Send invoices and see what is paid, without a spreadsheet.
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>