Screens in this system are assembled from a deliberately small set of semantic building blocks. Three carry the weight:
<section>- The semantic grouping block. It thematically unites primarily textual content and sets the vertical rhythm between page parts.
.card- A narrative surface — authorial, human, story-like content that wants to stand slightly apart from the page.
.panel- The data surface — the stricter sibling for system-facing, structured, metric-heavy content. (Ships in a later release; the distinction is described below so you know which one a given block wants.)
The important idea is what is not here. There is no grid component, no deck component, no positioning component. Those jobs belong to the utility layers — layout & grid, alignment, spacing, and positioning. A handful of surfaces plus the utilities compose any screen, so reaching for a brand-new class should be rare and deliberate.
Card vs Panel
Both are surfaces, but they answer different questions, and keeping them separate keeps the intent of a screen legible.
.card — narrative
Authorial, human, story-like. An article preview, a person, a project, a pricing block, a visual fragment.
Soft surface, no rigid internal frame. Holds whatever the author needs.
.panel — data
System-facing, structured, scannable. A KPI, a status block, settings, a log, a metrics readout.
Explicit internal structure (header / body / footer) for content that benefits from a predictable frame.
The rule. If a human authored it and it reads as content, it is a .card. If a system produced it and it reads as data, it is a .panel. When unsure, ask whether the block would feel at home in an article (card) or on a dashboard (panel).
Section
The section is the basic semantic block, thematically uniting primarily text elements. Think of it as the foundation piece in your construction set. It is visually separated with margin-bottom: var(--space-lg):
Wide Background
Sometimes a section needs more canvas than the normal reading column allows: a full-bleed image, a contextual band, or a wide visual insert. .wide-background breaks the outer section to the viewport edge, while .wide-background-text-content-wrapper brings inner prose back to the normal line.
A full-bleed band with a disciplined inner text line
The outer surface can carry color, imagery, or other wide media. The inner wrapper returns content to the same reading track the rest of the page uses, so a dramatic section does not force the prose to become chaotic.
Feature Row
When a set of features, offerings, or highlights reads better as a scannable horizontal strip than as a wrapping grid, .feature-row lays its .feature-row__item children out in a single row that scrolls sideways instead of squashing. Each item is a flex column — media on top, copy below — pinned to a fixed responsive width (clamp(280px, 30vw, 420px)), so the cards keep a comfortable size and the row simply runs past the edge when there are more than fit.
Read the table
Surface the one number that changes the next move — not the whole hand.
Stay flexible
Match it to your brand without bending the underlying presentation logic.
Cut the noise
Every tile earns its place, or it doesn't get one.
Use it for a small, deliberate set of features — not as a generic carousel. If the items want a uniform, wrapping arrangement instead of a horizontal scroll, reach for .card-grid instead.
Card
Cards provide distinct content separation, letting you build complex hierarchies and group related elements. By default they stand out through background color, and they lay out as a flex column.
A card is a versatile connector piece — it takes on any visual style through utilities: sizes, colors, margins, paddings, alignment, borders. Content-wise it can be a simple container or develop its own hierarchy, holding any content type, blocks, or interactive elements.
Cards come in two default styles: .card and .card-inverted.
Card Grid
When one card is not enough and the cards form a regular, repeated set, .card-grid is the special case that arranges .card-grid__item tiles into a responsive grid. It is the one place where the card surface owns its own layout, because the tiles are uniform by design. Column count defaults to five via the --cols-2 / --cols-3 / --cols-4 modifiers (or the --card-grid-cols custom property); below desktop every variant collapses to two so tiles stay legible.
The grid ships two tile treatments. .card-grid--cards turns items into square card surfaces:
.card-grid--gallery turns items into image tiles — set the image with an inline background-image — with a title overlaid at the bottom:
The card grid is for uniform, repeated tiles. For a freeform arrangement of full .card surfaces, do not reach for a component — use the grid utilities directly, as shown next.
Composing cards — no new class required
There is no .card-deck selector, and there never needs to be. A "card deck" is not a thing the library ships; it is just several cards arranged together, and arrangement is already a solved problem. Any block-level element — a <div>, a <section>, or another .card — can serve as the wrapper, and the alignment, positioning, spacing, and grid utilities do the placement.
A "deck" is just composition
This block is a .card-inverted wrapping an image, a header, prose, and a nested card — no special deck class involved.
Cards are standard block elements capable of holding any content type: text, images, charts, tables, or interactive elements.
The takeaway: any positioning a card layout needs is reachable through the existing utilities. Before adding a new class, check whether alignment and positioning already cover it — they almost always do.
Helper Selectors
The same principle, pushed further. Everything below is built from cards plus decoration, color, spacing, and positioning utilities — no bespoke classes. Combine them freely to satisfy virtually any design requirement.
.rounded
.circle
.shadow
.card-hover
.square