Layout cookbook.
Rows, columns and the variations of the small things — cards above all — written in UCM utility classes. Each one is live on this page, shows its block structure, and copies straight into the editor.
Rows and columns
How to put things side by side. Every one of these starts as a single column on a phone and widens from there. For whole sections — a hero, pricing, a footer — use the components; this is what goes inside them, and between them.
Two equal columns
One column on a phone, two from md. The most common row there is.
<UCM WRAPPER::DIV classes="ucm-grid ucm-grid-cols-1 ucm-grid-cols-2--md ucm-gap-4"> <UCM HTML::DIV classes="lib-cell">Half</> <UCM HTML::DIV classes="lib-cell lib-cell-alt">Half</> </>
Wide and narrow
A three-track grid where one cell takes two tracks. Swap which one is wide per row for a staggered look.
<UCM WRAPPER::DIV classes="ucm-grid ucm-grid-cols-1 ucm-grid-cols-3--md ucm-gap-4"> <UCM HTML::DIV classes="lib-cell ucm-col-span-2--md">Two thirds</> <UCM HTML::DIV classes="lib-cell lib-cell-alt">One third</> <UCM HTML::DIV classes="lib-cell lib-cell-alt">One third</> <UCM HTML::DIV classes="lib-cell ucm-col-span-2--md">Two thirds</> </>
A fixed column beside a fluid one
A side column that stays 16rem wide however big the screen gets, and a main column that takes the rest. ucm-min-w-0 lets long words and tables inside the main column shrink rather than push it wider.
<UCM WRAPPER::DIV classes="ucm-flex ucm-flex-col ucm-flex-row--md ucm-gap-4"> <UCM HTML::DIV classes="lib-cell lib-cell-alt ucm-w-64--md ucm-shrink-0">Fixed 16rem</> <UCM HTML::DIV classes="lib-cell ucm-grow ucm-min-w-0">Takes the rest</> </>
One, two, three across
The listing grid: one column on a phone, two on a tablet, three on a laptop. Change one number to change a whole breakpoint.
<UCM WRAPPER::DIV classes="ucm-grid ucm-grid-cols-1 ucm-grid-cols-2--md ucm-grid-cols-3--lg ucm-gap-4"> <UCM HTML::DIV classes="lib-cell">One</> <UCM HTML::DIV classes="lib-cell lib-cell-alt">Two</> <UCM HTML::DIV classes="lib-cell">Three</> <UCM HTML::DIV classes="lib-cell lib-cell-alt">Four</> <UCM HTML::DIV classes="lib-cell">Five</> <UCM HTML::DIV classes="lib-cell lib-cell-alt">Six</> </>
Twelve columns with spans
When columns are not equal. The parent declares twelve tracks; each child says how many it takes, and can say something different per breakpoint.
<UCM WRAPPER::DIV classes="ucm-grid ucm-grid-cols-12 ucm-gap-4"> <UCM HTML::DIV classes="lib-cell ucm-col-span-12 ucm-col-span-8--md">8 / 12</> <UCM HTML::DIV classes="lib-cell lib-cell-alt ucm-col-span-12 ucm-col-span-4--md">4 / 12</> <UCM HTML::DIV classes="lib-cell ucm-col-span-6 ucm-col-span-4--md">4 / 12</> <UCM HTML::DIV classes="lib-cell lib-cell-alt ucm-col-span-6 ucm-col-span-4--md">4 / 12</> <UCM HTML::DIV classes="lib-cell ucm-col-span-12 ucm-col-span-4--md">4 / 12</> </>
Starting further in
ucm-col-start-3 starts a cell at the third track, which centres an eight-wide column in twelve without an empty cell on either side.
<UCM WRAPPER::DIV classes="ucm-grid ucm-grid-cols-12 ucm-gap-4"> <UCM HTML::DIV classes="lib-cell ucm-col-span-12 ucm-col-start-3--md ucm-col-span-8--md">Starts at column 3, spans 8</> <UCM HTML::DIV classes="lib-cell lib-cell-alt ucm-col-span-12 ucm-col-start-5--md ucm-col-span-4--md">Column 5, spans 4</> </>
A row that wraps by itself
Grid gives fixed tracks; flex lets items wrap when they run out of room, and ucm-grow lets the last one fill what is left.
<UCM WRAPPER::DIV classes="ucm-flex ucm-flex-wrap ucm-gap-4"> <UCM HTML::DIV classes="lib-cell ucm-basis-full ucm-basis-1-2--sm ucm-basis-1-3--lg ucm-grow">full → ½ → ⅓</> <UCM HTML::DIV classes="lib-cell lib-cell-alt ucm-basis-full ucm-basis-1-2--sm ucm-basis-1-3--lg ucm-grow">full → ½ → ⅓</> <UCM HTML::DIV classes="lib-cell ucm-basis-full ucm-basis-1-2--sm ucm-basis-1-3--lg ucm-grow">full → ½ → ⅓</> <UCM HTML::DIV classes="lib-cell lib-cell-alt ucm-basis-full ucm-basis-1-2--sm ucm-basis-1-3--lg ucm-grow">the last one grows to fill</> </>
A bento grid
Cells of different sizes packed together. ucm-row-span-2 makes a cell two rows tall, and ucm-grid-flow-dense fills the holes that leaves.
<UCM WRAPPER::DIV classes="ucm-grid ucm-grid-cols-2 ucm-grid-cols-4--md ucm-auto-rows-fr ucm-grid-flow-dense ucm-gap-4"> <UCM HTML::DIV classes="lib-cell ucm-col-span-2 ucm-row-span-2">Big — 2 × 2</> <UCM HTML::DIV classes="lib-cell lib-cell-alt ucm-col-span-2">Wide — 2 × 1</> <UCM HTML::DIV classes="lib-cell">Small</> <UCM HTML::DIV classes="lib-cell lib-cell-alt">Small</> <UCM HTML::DIV classes="lib-cell lib-cell-alt ucm-row-span-2">Tall — 1 × 2</> <UCM HTML::DIV classes="lib-cell ucm-col-span-2">Wide — 2 × 1</> <UCM HTML::DIV classes="lib-cell lib-cell-alt">Small</> </>
Alternating rows
Picture and text, then text and picture. The markup keeps the same order in every row — what a screen reader reads — and ucm-order-*--md swaps them from md.
<UCM WRAPPER::DIV classes="ucm-flex ucm-flex-col ucm-gap-6">
<UCM WRAPPER::DIV classes="ucm-grid ucm-grid-cols-1 ucm-grid-cols-2--md ucm-gap-4 ucm-items-center">
<UCM HTML::DIV classes="lib-cell ucm-aspect-video">Picture</>
<UCM HTML::DIV classes="lib-cell lib-cell-alt">Text beside it</>
</>
<UCM WRAPPER::DIV classes="ucm-grid ucm-grid-cols-1 ucm-grid-cols-2--md ucm-gap-4 ucm-items-center">
<UCM HTML::DIV classes="lib-cell ucm-aspect-video ucm-order-2--md">Picture — on the right from md</>
<UCM HTML::DIV classes="lib-cell lib-cell-alt ucm-order-1--md">Text, first from md</>
</>
</>
Masonry
Items of different heights in columns that pack up tightly, with CSS columns rather than a grid: ucm-columns-3 on the parent, and each item a full-width inline block so it does not split between columns.
with more
lines in it
height
tall
tall
tall
height
<UCM WRAPPER::DIV classes="ucm-columns-1 ucm-columns-2--sm ucm-columns-3--lg ucm-gap-4"> <UCM HTML::DIV classes="lib-cell ucm-inline-block ucm-w-full ucm-mb-4">Short</> <UCM HTML::DIV classes="lib-cell lib-cell-alt ucm-inline-block ucm-w-full ucm-mb-4">A taller one with more lines in it</> <UCM HTML::DIV classes="lib-cell ucm-inline-block ucm-w-full ucm-mb-4">Medium height</> <UCM HTML::DIV classes="lib-cell lib-cell-alt ucm-inline-block ucm-w-full ucm-mb-4">Short</> <UCM HTML::DIV classes="lib-cell ucm-inline-block ucm-w-full ucm-mb-4">Tall tall tall tall</> <UCM HTML::DIV classes="lib-cell lib-cell-alt ucm-inline-block ucm-w-full ucm-mb-4">Medium height</> </>
A row that scrolls sideways
Cards in one row that scrolls rather than wraps — a gallery, a carousel without the dots. Each card keeps its width with ucm-shrink-0.
<UCM WRAPPER::DIV classes="ucm-flex ucm-gap-4 ucm-overflow-x-auto ucm-pb-2"> <UCM HTML::DIV classes="lib-cell ucm-shrink-0 ucm-w-56">Card</> <UCM HTML::DIV classes="lib-cell lib-cell-alt ucm-shrink-0 ucm-w-56">Card</> <UCM HTML::DIV classes="lib-cell ucm-shrink-0 ucm-w-56">Card</> <UCM HTML::DIV classes="lib-cell lib-cell-alt ucm-shrink-0 ucm-w-56">Card</> <UCM HTML::DIV classes="lib-cell ucm-shrink-0 ucm-w-56">Card</> <UCM HTML::DIV classes="lib-cell lib-cell-alt ucm-shrink-0 ucm-w-56">Card</> </>
A column that stays in view
The narrow column stays put while the wide one scrolls past it, from md. ucm-items-start matters: a stretched column has no room to move in.
of content
that keeps
going
and going
<UCM WRAPPER::DIV classes="ucm-grid ucm-grid-cols-1 ucm-grid-cols-3--md ucm-gap-4 ucm-items-start"> <UCM HTML::DIV classes="lib-cell lib-cell-alt ucm-sticky--md ucm-top-4">Sticks while the column beside i…</> <UCM HTML::DIV classes="lib-cell ucm-col-span-2--md">A long column of content that ke…</> </>
Centred both ways
ucm-grid ucm-place-items-center on a box with a height — the shortest way to put something in the middle.
<UCM WRAPPER::DIV classes="ucm-grid ucm-place-items-center ucm-h-48 ucm-rounded-lg ucm-bg-white-08"> <UCM HTML::DIV classes="lib-cell">In the middle, both ways</> </>
Pushing one item to the end
ucm-ml-auto on one item takes all the spare space before it, so it and everything after it move to the end of the row.
<UCM WRAPPER::DIV classes="ucm-flex ucm-items-center ucm-gap-2 ucm-p-3 ucm-rounded-lg ucm-bg-white-08"> <UCM HTML::DIV classes="lib-cell">Logo</> <UCM HTML::DIV classes="lib-cell lib-cell-alt">Link</> <UCM HTML::DIV classes="lib-cell lib-cell-alt">Link</> <UCM HTML::DIV classes="lib-cell ucm-ml-auto">Pushed to the end</> </>
Alignment inside a row
Where items sit across the row, and how spare space is shared along it. items-* takes start / center / end / stretch / baseline; justify-* adds between / around / evenly.
cell
<UCM WRAPPER::DIV classes="ucm-flex ucm-items-center ucm-justify-between ucm-gap-4 ucm-p-4 ucm-rounded-lg ucm-bg-white-08"> <UCM HTML::DIV classes="lib-cell lib-cell-alt">left</> <UCM HTML::DIV classes="lib-cell">centre — taller cell</> <UCM HTML::DIV classes="lib-cell lib-cell-alt">right</> </>
A different order per breakpoint
The markup keeps a sensible reading order and only the painted order changes. ucm-order-first and ucm-order-last also exist, plus 1–12.
<UCM WRAPPER::DIV classes="ucm-grid ucm-grid-cols-1 ucm-grid-cols-3--md ucm-gap-4"> <UCM HTML::DIV classes="lib-cell lib-cell-alt ucm-order-2 ucm-order-1--md">Side — 2nd on a phone, 1st from md</> <UCM HTML::DIV classes="lib-cell ucm-order-1 ucm-order-2--md ucm-col-span-2--md">Main — 1st on a phone, 2nd from md</> </>
Showing and hiding per breakpoint
Variants are min-width, so hiding something below a breakpoint takes two classes: one to hide it, one to show it again further up. The editor’s Hide on control writes exactly these.
<UCM WRAPPER::DIV classes="ucm-grid ucm-grid-cols-1 ucm-grid-cols-3--md ucm-gap-4"> <UCM HTML::DIV classes="lib-cell">Always visible</> <UCM HTML::DIV classes="lib-cell lib-cell-alt ucm-hidden ucm-block--md">Hidden below md</> <UCM HTML::DIV classes="lib-cell lib-cell-alt ucm-hidden--lg">Hidden from lg up</> </>
Card variations
The component library has a card; a site needs a dozen. These use only Starter Library classes, so a copied one arrives styled on any install — change the text, the tints and the sizes from there.
Picture on top, link at the bottom
Three cards with different amounts of text, and links that still line up: each card is a column filling its row, and ucm-mt-auto gives the link whatever space is left.
Card title
A little more text again, which is exactly when a link at the bottom of each card would otherwise sit at three different heights.
Read more →<UCM WRAPPER::DIV classes="ucm-grid ucm-grid-cols-1 ucm-grid-cols-3--md ucm-gap-4">
<UCM WRAPPER::ARTICLE classes="ucm-rounded-xl ucm-border ucm-border-solid ucm-border-white-10 ucm-bg-white-08 ucm-flex ucm-flex-col ucm-overflow-hidden">
<UCM HTML::DIV classes="ucm-bg-white-25 ucm-aspect-video"></>
<UCM WRAPPER::DIV classes="ucm-flex ucm-flex-col ucm-grow ucm-gap-2 ucm-p-4">
<UCM HTML::H3 classes="ucm-m-0 ucm-text-base ucm-font-bold ucm-text-white ucm-leading-tight">Card title</>
<UCM HTML::P classes="ucm-m-0 ucm-text-sm ucm-text-white-60 ucm-leading-relaxed">One line.</>
<UCM HTML::A classes="ucm-mt-auto ucm-pt-2 ucm-text-sm ucm-font-semibold ucm-text-white" href="#">Read more →</>
</>
</>
<UCM WRAPPER::ARTICLE classes="ucm-rounded-xl ucm-border ucm-border-solid ucm-border-white-10 ucm-bg-white-08 ucm-flex ucm-flex-col ucm-overflow-hidden">
<UCM HTML::DIV classes="ucm-bg-white-25 ucm-aspect-video"></>
<UCM WRAPPER::DIV classes="ucm-flex ucm-flex-col ucm-grow ucm-gap-2 ucm-p-4">
<UCM HTML::H3 classes="ucm-m-0 ucm-text-base ucm-font-bold ucm-text-white ucm-leading-tight">Card title</>
<UCM HTML::P classes="ucm-m-0 ucm-text-sm ucm-text-white-60 ucm-leading-relaxed">Two lines of text, so this card …</>
<UCM HTML::A classes="ucm-mt-auto ucm-pt-2 ucm-text-sm ucm-font-semibold ucm-text-white" href="#">Read more →</>
</>
</>
<UCM WRAPPER::ARTICLE classes="ucm-rounded-xl ucm-border ucm-border-solid ucm-border-white-10 ucm-bg-white-08 ucm-flex ucm-flex-col ucm-overflow-hidden">
<UCM HTML::DIV classes="ucm-bg-white-25 ucm-aspect-video"></>
<UCM WRAPPER::DIV classes="ucm-flex ucm-flex-col ucm-grow ucm-gap-2 ucm-p-4">
<UCM HTML::H3 classes="ucm-m-0 ucm-text-base ucm-font-bold ucm-text-white ucm-leading-tight">Card title</>
<UCM HTML::P classes="ucm-m-0 ucm-text-sm ucm-text-white-60 ucm-leading-relaxed">A little more text again, which …</>
<UCM HTML::A classes="ucm-mt-auto ucm-pt-2 ucm-text-sm ucm-font-semibold ucm-text-white" href="#">Read more →</>
</>
</>
</>
Picture beside the words
Stacked on a phone; from sm the picture is a fixed square on the left. ucm-line-clamp-3 stops a long text making the card taller than the picture.
Picture beside the words
Stacked on a phone; from sm the picture keeps a square on the left and the text takes the rest.
<UCM WRAPPER::ARTICLE classes="ucm-rounded-xl ucm-border ucm-border-solid ucm-border-white-10 ucm-bg-white-08 ucm-flex ucm-flex-col ucm-flex-row--sm ucm-overflow-hidden">
<UCM HTML::DIV classes="ucm-bg-white-25 ucm-aspect-video ucm-aspect-square--sm ucm-w-full ucm-w-48--sm ucm-shrink-0"></>
<UCM WRAPPER::DIV classes="ucm-flex ucm-flex-col ucm-gap-2 ucm-p-4 ucm-min-w-0">
<UCM HTML::SPAN classes="ucm-text-xs ucm-uppercase ucm-tracking-wide ucm-text-white-50">Category</>
<UCM HTML::H3 classes="ucm-m-0 ucm-text-base ucm-font-bold ucm-text-white ucm-leading-tight">Picture beside the words</>
<UCM HTML::P classes="ucm-m-0 ucm-text-sm ucm-text-white-60 ucm-leading-relaxed ucm-line-clamp-3">Stacked on a phone; from sm the …</>
</>
</>
Words over the picture
The card is the picture — relative, with an aspect ratio — and the words sit in a darkened band across the bottom, absolute.
Words over the picture
A band across the bottom keeps them readable on any image.
<UCM WRAPPER::ARTICLE classes="ucm-relative ucm-overflow-hidden ucm-rounded-xl ucm-aspect-video ucm-bg-white-25">
<UCM WRAPPER::DIV classes="ucm-absolute ucm-inset-x-0 ucm-bottom-0 ucm-p-4 ucm-bg-black-60">
<UCM HTML::H3 classes="ucm-m-0 ucm-text-base ucm-font-bold ucm-text-white ucm-leading-tight">Words over the picture</>
<UCM HTML::P classes="ucm-m-0 ucm-text-sm ucm-text-white-60 ucm-leading-relaxed ucm-text-white-70">A band across the bottom keeps t…</>
</>
</>
A badge on the card
In the corner, placed absolutely; or in the title row, where a long title pushes it along instead of running under it.
A badge in the corner
The card is relative; the badge is absolute, three steps in from the top and the right.
A badge beside the title
PopularIn the row with the title instead, so a long title pushes it along rather than running under it.
<UCM WRAPPER::DIV classes="ucm-grid ucm-grid-cols-1 ucm-grid-cols-2--md ucm-gap-4">
<UCM WRAPPER::ARTICLE classes="ucm-rounded-xl ucm-border ucm-border-solid ucm-border-white-10 ucm-bg-white-08 ucm-relative ucm-p-4 ucm-flex ucm-flex-col ucm-gap-2">
<UCM HTML::SPAN classes="ucm-absolute ucm-top-3 ucm-right-3 ucm-px-2 ucm-py-1 ucm-rounded-full ucm-text-xs ucm-font-bold ucm-bg-white-20 ucm-text-white">New</>
<UCM HTML::H3 classes="ucm-m-0 ucm-text-base ucm-font-bold ucm-text-white ucm-leading-tight">A badge in the corner</>
<UCM HTML::P classes="ucm-m-0 ucm-text-sm ucm-text-white-60 ucm-leading-relaxed">The card is relative; the badge …</>
</>
<UCM WRAPPER::ARTICLE classes="ucm-rounded-xl ucm-border ucm-border-solid ucm-border-white-10 ucm-bg-white-08 ucm-p-4 ucm-flex ucm-flex-col ucm-gap-2 ucm-border-white-30">
<UCM WRAPPER::DIV classes="ucm-flex ucm-items-center ucm-justify-between ucm-gap-2">
<UCM HTML::H3 classes="ucm-m-0 ucm-text-base ucm-font-bold ucm-text-white ucm-leading-tight">A badge beside the title</>
<UCM HTML::SPAN classes="ucm-shrink-0 ucm-px-2 ucm-py-1 ucm-rounded-full ucm-text-xs ucm-font-bold ucm-bg-white-20 ucm-text-white">Popular</>
</>
<UCM HTML::P classes="ucm-m-0 ucm-text-sm ucm-text-white-60 ucm-leading-relaxed">In the row with the title instea…</>
</>
</>
An icon, a title, a line
The feature card, without the section around it: a tile for the icon, the title, a sentence.
Fast
A tile for an icon, then the words. Put an icon from the HTML block’s picker in the tile.
Private
A tile for an icon, then the words. Put an icon from the HTML block’s picker in the tile.
Yours
A tile for an icon, then the words. Put an icon from the HTML block’s picker in the tile.
<UCM WRAPPER::DIV classes="ucm-grid ucm-grid-cols-1 ucm-grid-cols-3--md ucm-gap-4">
<UCM WRAPPER::ARTICLE classes="ucm-rounded-xl ucm-border ucm-border-solid ucm-border-white-10 ucm-bg-white-08 ucm-p-5 ucm-flex ucm-flex-col ucm-gap-3">
<UCM HTML::DIV classes="ucm-size-10 ucm-rounded-lg ucm-bg-white-15 ucm-grid ucm-place-items-center ucm-text-white ucm-font-bold">✦</>
<UCM HTML::H3 classes="ucm-m-0 ucm-text-base ucm-font-bold ucm-text-white ucm-leading-tight">Fast</>
<UCM HTML::P classes="ucm-m-0 ucm-text-sm ucm-text-white-60 ucm-leading-relaxed">A tile for an icon, then the wor…</>
</>
<UCM WRAPPER::ARTICLE classes="ucm-rounded-xl ucm-border ucm-border-solid ucm-border-white-10 ucm-bg-white-08 ucm-p-5 ucm-flex ucm-flex-col ucm-gap-3">
<UCM HTML::DIV classes="ucm-size-10 ucm-rounded-lg ucm-bg-white-15 ucm-grid ucm-place-items-center ucm-text-white ucm-font-bold">✦</>
<UCM HTML::H3 classes="ucm-m-0 ucm-text-base ucm-font-bold ucm-text-white ucm-leading-tight">Private</>
<UCM HTML::P classes="ucm-m-0 ucm-text-sm ucm-text-white-60 ucm-leading-relaxed">A tile for an icon, then the wor…</>
</>
<UCM WRAPPER::ARTICLE classes="ucm-rounded-xl ucm-border ucm-border-solid ucm-border-white-10 ucm-bg-white-08 ucm-p-5 ucm-flex ucm-flex-col ucm-gap-3">
<UCM HTML::DIV classes="ucm-size-10 ucm-rounded-lg ucm-bg-white-15 ucm-grid ucm-place-items-center ucm-text-white ucm-font-bold">✦</>
<UCM HTML::H3 classes="ucm-m-0 ucm-text-base ucm-font-bold ucm-text-white ucm-leading-tight">Yours</>
<UCM HTML::P classes="ucm-m-0 ucm-text-sm ucm-text-white-60 ucm-leading-relaxed">A tile for an icon, then the wor…</>
</>
</>
A number with its label
Two across on a phone, four from md. The label is small and quiet so the number carries the card.
<UCM WRAPPER::DIV classes="ucm-grid ucm-grid-cols-2 ucm-grid-cols-4--md ucm-gap-4">
<UCM WRAPPER::DIV classes="ucm-rounded-xl ucm-border ucm-border-solid ucm-border-white-10 ucm-bg-white-08 ucm-p-4 ucm-flex ucm-flex-col ucm-gap-1">
<UCM HTML::SPAN classes="ucm-text-xs ucm-uppercase ucm-tracking-wide ucm-text-white-50">Visitors</>
<UCM HTML::STRONG classes="ucm-text-2xl ucm-font-bold ucm-text-white ucm-leading-tight">12,480</>
<UCM HTML::SPAN classes="ucm-text-xs ucm-text-white-60">+8% on last week</>
</>
<UCM WRAPPER::DIV classes="ucm-rounded-xl ucm-border ucm-border-solid ucm-border-white-10 ucm-bg-white-08 ucm-p-4 ucm-flex ucm-flex-col ucm-gap-1">
<UCM HTML::SPAN classes="ucm-text-xs ucm-uppercase ucm-tracking-wide ucm-text-white-50">Orders</>
<UCM HTML::STRONG classes="ucm-text-2xl ucm-font-bold ucm-text-white ucm-leading-tight">342</>
<UCM HTML::SPAN classes="ucm-text-xs ucm-text-white-60">+3%</>
</>
<UCM WRAPPER::DIV classes="ucm-rounded-xl ucm-border ucm-border-solid ucm-border-white-10 ucm-bg-white-08 ucm-p-4 ucm-flex ucm-flex-col ucm-gap-1">
<UCM HTML::SPAN classes="ucm-text-xs ucm-uppercase ucm-tracking-wide ucm-text-white-50">Revenue</>
<UCM HTML::STRONG classes="ucm-text-2xl ucm-font-bold ucm-text-white ucm-leading-tight">€18.2k</>
<UCM HTML::SPAN classes="ucm-text-xs ucm-text-white-60">−1%</>
</>
<UCM WRAPPER::DIV classes="ucm-rounded-xl ucm-border ucm-border-solid ucm-border-white-10 ucm-bg-white-08 ucm-p-4 ucm-flex ucm-flex-col ucm-gap-1">
<UCM HTML::SPAN classes="ucm-text-xs ucm-uppercase ucm-tracking-wide ucm-text-white-50">Returns</>
<UCM HTML::STRONG classes="ucm-text-2xl ucm-font-bold ucm-text-white ucm-leading-tight">4</>
<UCM HTML::SPAN classes="ucm-text-xs ucm-text-white-60">none pending</>
</>
</>
A person
A round picture, a name, what they do — centred, four across from md.
Anna
DesignBen
EngineeringCleo
SupportDan
Sales<UCM WRAPPER::DIV classes="ucm-grid ucm-grid-cols-2 ucm-grid-cols-4--md ucm-gap-4">
<UCM WRAPPER::ARTICLE classes="ucm-rounded-xl ucm-border ucm-border-solid ucm-border-white-10 ucm-bg-white-08 ucm-p-5 ucm-flex ucm-flex-col ucm-items-center ucm-text-center ucm-gap-2">
<UCM HTML::DIV classes="ucm-size-16 ucm-rounded-full ucm-bg-white-20 ucm-grid ucm-place-items-center ucm-text-white ucm-font-bold">A</>
<UCM HTML::H3 classes="ucm-m-0 ucm-text-base ucm-font-bold ucm-text-white ucm-leading-tight">Anna</>
<UCM HTML::SPAN classes="ucm-text-sm ucm-text-white-60">Design</>
</>
<UCM WRAPPER::ARTICLE classes="ucm-rounded-xl ucm-border ucm-border-solid ucm-border-white-10 ucm-bg-white-08 ucm-p-5 ucm-flex ucm-flex-col ucm-items-center ucm-text-center ucm-gap-2">
<UCM HTML::DIV classes="ucm-size-16 ucm-rounded-full ucm-bg-white-20 ucm-grid ucm-place-items-center ucm-text-white ucm-font-bold">B</>
<UCM HTML::H3 classes="ucm-m-0 ucm-text-base ucm-font-bold ucm-text-white ucm-leading-tight">Ben</>
<UCM HTML::SPAN classes="ucm-text-sm ucm-text-white-60">Engineering</>
</>
<UCM WRAPPER::ARTICLE classes="ucm-rounded-xl ucm-border ucm-border-solid ucm-border-white-10 ucm-bg-white-08 ucm-p-5 ucm-flex ucm-flex-col ucm-items-center ucm-text-center ucm-gap-2">
<UCM HTML::DIV classes="ucm-size-16 ucm-rounded-full ucm-bg-white-20 ucm-grid ucm-place-items-center ucm-text-white ucm-font-bold">C</>
<UCM HTML::H3 classes="ucm-m-0 ucm-text-base ucm-font-bold ucm-text-white ucm-leading-tight">Cleo</>
<UCM HTML::SPAN classes="ucm-text-sm ucm-text-white-60">Support</>
</>
<UCM WRAPPER::ARTICLE classes="ucm-rounded-xl ucm-border ucm-border-solid ucm-border-white-10 ucm-bg-white-08 ucm-p-5 ucm-flex ucm-flex-col ucm-items-center ucm-text-center ucm-gap-2">
<UCM HTML::DIV classes="ucm-size-16 ucm-rounded-full ucm-bg-white-20 ucm-grid ucm-place-items-center ucm-text-white ucm-font-bold">D</>
<UCM HTML::H3 classes="ucm-m-0 ucm-text-base ucm-font-bold ucm-text-white ucm-leading-tight">Dan</>
<UCM HTML::SPAN classes="ucm-text-sm ucm-text-white-60">Sales</>
</>
</>
A card that is a row
For lists: a picture, two lines that shorten with “…” rather than wrapping, and an action at the end. The middle takes ucm-min-w-0 ucm-grow, without which ucm-truncate cannot shorten anything.
<UCM WRAPPER::DIV classes="ucm-flex ucm-flex-col ucm-gap-2">
<UCM WRAPPER::DIV classes="ucm-rounded-xl ucm-border ucm-border-solid ucm-border-white-10 ucm-bg-white-08 ucm-p-3 ucm-flex ucm-items-center ucm-gap-3">
<UCM HTML::DIV classes="ucm-size-10 ucm-shrink-0 ucm-rounded-full ucm-bg-white-20 ucm-grid ucm-place-items-center ucm-text-white ucm-font-bold">A</>
<UCM WRAPPER::DIV classes="ucm-min-w-0 ucm-grow">
<UCM HTML::P classes="ucm-m-0 ucm-text-sm ucm-font-semibold ucm-text-white ucm-truncate">A row that is a card</>
<UCM HTML::P classes="ucm-m-0 ucm-text-xs ucm-text-white-60 ucm-truncate">Picture, two lines that shorten …</>
</>
<UCM HTML::A classes="ucm-shrink-0 ucm-text-sm ucm-font-semibold ucm-text-white" href="#">Open</>
</>
<UCM WRAPPER::DIV classes="ucm-rounded-xl ucm-border ucm-border-solid ucm-border-white-10 ucm-bg-white-08 ucm-p-3 ucm-flex ucm-items-center ucm-gap-3">
<UCM HTML::DIV classes="ucm-size-10 ucm-shrink-0 ucm-rounded-full ucm-bg-white-20 ucm-grid ucm-place-items-center ucm-text-white ucm-font-bold">B</>
<UCM WRAPPER::DIV classes="ucm-min-w-0 ucm-grow">
<UCM HTML::P classes="ucm-m-0 ucm-text-sm ucm-font-semibold ucm-text-white ucm-truncate">Ben Carter</>
<UCM HTML::P classes="ucm-m-0 ucm-text-xs ucm-text-white-60 ucm-truncate">ben@example.com — a long address…</>
</>
<UCM HTML::A classes="ucm-shrink-0 ucm-text-sm ucm-font-semibold ucm-text-white" href="#">Open</>
</>
</>
Small patterns
The bits in between that every site builds, the same way each time.
A field and its button
The field grows, the button keeps its size, and ucm-min-w-0 lets the field shrink on a narrow phone rather than push the button off the row.
<UCM WRAPPER::DIV classes="ucm-flex ucm-gap-2 ucm-max-w-md"> <UCM HTML::INPUT classes="ucm-grow ucm-min-w-0 ucm-px-3 ucm-py-2 ucm-rounded-lg ucm-border ucm-border-solid ucm-border-white-20 ucm-bg-white-08 ucm-text-white" type="email" placeholder="you@example.com" aria-label="Email"></> <UCM HTML::BUTTON classes="ucm-shrink-0 ucm-px-4 ucm-py-2 ucm-rounded-lg ucm-bg-white ucm-font-semibold" type="button">Subscribe</> </>
A toolbar that wraps
Filters on the left and actions on the right, which drop onto a line of their own when there is no room, rather than squashing.
<UCM WRAPPER::DIV classes="ucm-flex ucm-flex-wrap ucm-items-center ucm-justify-between ucm-gap-3 ucm-p-3 ucm-rounded-lg ucm-bg-white-08">
<UCM WRAPPER::DIV classes="ucm-flex ucm-flex-wrap ucm-gap-2">
<UCM HTML::DIV classes="lib-cell">Search</>
<UCM HTML::DIV classes="lib-cell lib-cell-alt">Filter</>
<UCM HTML::DIV classes="lib-cell lib-cell-alt">Filter</>
</>
<UCM WRAPPER::DIV classes="ucm-flex ucm-gap-2">
<UCM HTML::DIV classes="lib-cell lib-cell-alt">Export</>
<UCM HTML::DIV classes="lib-cell">New</>
</>
</>
Labels and values
A three-track grid: the label takes one, the value two. The values line up however long the labels are.
- Status
- Active
- Owner
- Anna
- Due
- 12 Oct
- Budget
- €4,800
<UCM WRAPPER::DL classes="ucm-grid ucm-grid-cols-3 ucm-gap-x-4 ucm-gap-y-2 ucm-max-w-md"> <UCM HTML::DT classes="ucm-text-sm ucm-text-white-50">Status</> <UCM HTML::DD classes="ucm-col-span-2 ucm-text-sm ucm-text-white ucm-m-0">Active</> <UCM HTML::DT classes="ucm-text-sm ucm-text-white-50">Owner</> <UCM HTML::DD classes="ucm-col-span-2 ucm-text-sm ucm-text-white ucm-m-0">Anna</> <UCM HTML::DT classes="ucm-text-sm ucm-text-white-50">Due</> <UCM HTML::DD classes="ucm-col-span-2 ucm-text-sm ucm-text-white ucm-m-0">12 Oct</> <UCM HTML::DT classes="ucm-text-sm ucm-text-white-50">Budget</> <UCM HTML::DD classes="ucm-col-span-2 ucm-text-sm ucm-text-white ucm-m-0">€4,800</> </>
Tags that wrap
A row of tags that wraps onto as many lines as it needs, with the same gap across and down.
<UCM WRAPPER::DIV classes="ucm-flex ucm-flex-wrap ucm-gap-2"> <UCM HTML::SPAN classes="ucm-px-3 ucm-py-1 ucm-rounded-full ucm-text-xs ucm-font-semibold ucm-border ucm-border-solid ucm-border-white-20 ucm-text-white-80">Design</> <UCM HTML::SPAN classes="ucm-px-3 ucm-py-1 ucm-rounded-full ucm-text-xs ucm-font-semibold ucm-border ucm-border-solid ucm-border-white-20 ucm-text-white-80">Branding</> <UCM HTML::SPAN classes="ucm-px-3 ucm-py-1 ucm-rounded-full ucm-text-xs ucm-font-semibold ucm-border ucm-border-solid ucm-border-white-20 ucm-text-white-80">Web</> <UCM HTML::SPAN classes="ucm-px-3 ucm-py-1 ucm-rounded-full ucm-text-xs ucm-font-semibold ucm-border ucm-border-solid ucm-border-white-20 ucm-text-white-80">E-commerce</> <UCM HTML::SPAN classes="ucm-px-3 ucm-py-1 ucm-rounded-full ucm-text-xs ucm-font-semibold ucm-border ucm-border-solid ucm-border-white-20 ucm-text-white-80">Photography</> <UCM HTML::SPAN classes="ucm-px-3 ucm-py-1 ucm-rounded-full ucm-text-xs ucm-font-semibold ucm-border ucm-border-solid ucm-border-white-20 ucm-text-white-80">Copywriting</> <UCM HTML::SPAN classes="ucm-px-3 ucm-py-1 ucm-rounded-full ucm-text-xs ucm-font-semibold ucm-border ucm-border-solid ucm-border-white-20 ucm-text-white-80">Strategy</> <UCM HTML::SPAN classes="ucm-px-3 ucm-py-1 ucm-rounded-full ucm-text-xs ucm-font-semibold ucm-border ucm-border-solid ucm-border-white-20 ucm-text-white-80">Print</> </>
Reference
Every class takes a suffix. ucm-grid-cols-3--md means “three columns from md upward”. All variants are min-width, so you write the phone layout first and widen from there. These values come from your own settings.
Only what you use is shipped
UCM scans your content for class names and generates a stylesheet containing those rules and no others. The starter library holds 1,855 groups, each with responsive and pseudo-state variants — a page that uses six of them ships six.