Utilities
A deliberately small, token-bound utility surface — a hand of cards, not a vocabulary; no arbitrary values, no responsive prefixes.
Display
.k-d-none·.k-d-block·.k-d-flex·.k-d-inline-flex·.k-d-grid- One display value each. That's the whole set — there is no utility for every display mode, only the ones a page actually switches between.
.k-mobile-only·.k-desktop-only- Show an element on only one side of keel's md
breakpoint (820px):
.k-mobile-onlyrenders below it and disappears above;.k-desktop-onlydoes the opposite. This is the only responsive behavior in the whole utilities layer. .k-visually-hidden- Hides an element visually while keeping it in the
accessibility tree — screen readers still announce it. Use it
for skip links, icon-button labels, and headings that structure
a page for assistive tech. Never use
display: none(or.k-d-none) for content you want announced; that removes it for everyone.
Markup
<a class="k-visually-hidden" href="#main">Skip to content</a>
<p class="k-mobile-only">Shown below 820px.</p>
<p class="k-desktop-only">Shown at 820px and up.</p>
Spacing
Five properties on the token scale, nothing else. No inline margins, no left/right margins, no negative values — if you need those, write CSS.
| Class pattern | Property | Scale |
|---|---|---|
.k-mt-* | margin-top | 0–8 |
.k-mb-* | margin-bottom | 0–8 |
.k-p-* | padding | 0–6 |
.k-px-* | padding-inline | 2–5 |
.k-py-* | padding-block | 2–5 |
.k-gap-* | gap | 1–6 |
.k-mx-auto | margin-inline: auto | — |
Each step is the matching --k-space-* token
(.k-mt-4 is margin-top: var(--k-space-4);
step 0 is a plain zero), so everything still scales with
--k-density.
baseline
.k-mt-2
.k-mt-5
.k-mt-8
Markup
<div>baseline</div>
<div class="k-mt-2">.k-mt-2</div>
<div class="k-mt-5">.k-mt-5</div>
<div class="k-mt-8">.k-mt-8</div>
Text
.k-text-xs·.k-text-s·.k-text-l·.k-text-xl- Font size from the type scale. There is deliberately no
.k-text-m— that's the body default — and no utility for the heading sizes; headings are headings. .k-text-soft·.k-text-faint·.k-text-accent·.k-text-accent-2·.k-text-accent-3- Text color from the tokens: softened, faint, or one of the three brand colors.
.k-text-center·.k-text-start·.k-text-end- Text alignment. Logical properties, so they follow the writing direction.
.k-bold- Font weight 650 — the same weight keel uses for strong text and display type.
.k-mono- The mono font stack, for inline figures and identifiers.
.k-uppercase- Uppercase with letter-spacing and a drop to the
xs size — an opinionated label style, not a bare
text-transform. .k-nowrap- Prevents wrapping. For dates, figures, and short phrases that read wrong when broken.
.k-truncate- One line, cut with an ellipsis. Needs a constrained width to have anything to truncate against.
.k-balancetext-wrap: balance— evens out line lengths. Headings already get this from the base layer; use it on the odd standfirst or card blurb.
.k-truncate — this line is longer than its box and gets cut with an ellipsis
Markup
<p class="k-truncate" style="max-width: 16rem">
A line longer than its box gets cut with an ellipsis…
</p>
Flex & size
.k-items-center·.k-items-start·.k-items-end·.k-items-baseline- Cross-axis alignment for a flex or grid parent.
.k-justify-between·.k-justify-center·.k-justify-start·.k-justify-end- Main-axis distribution.
.k-flex-col·.k-flex-wrap- Stack a flex row into a column, or let it wrap.
.k-growflex-grow: 1— the child that takes the leftover room..k-flex-noneflex: none— the child that must not shrink or grow: icons, avatars, buttons in a row..k-w-full- Full inline size.
.k-maxw-narrow·.k-maxw- Max inline size capped at the container-width tokens
(
--k-width-narrow,--k-width) — for capping an element without introducing a new container.
Markup
<div class="k-d-flex k-items-center k-justify-between k-gap-3">
<span class="k-grow k-truncate">A long filename that truncates</span>
<button class="k-btn k-btn--small k-flex-none">Open</button>
</div>
Surface
.k-rounded-s·.k-rounded·.k-rounded-l·.k-rounded-full- Corner radius from the shape tokens;
-fullis a pill or circle. .k-border- The standard one-pixel border in the border color.
.k-shadow·.k-shadow-l- The token shadows — the same ones cards and dialogs use.
.k-bg-surface·.k-bg-surface-2·.k-bg-soft·.k-bg-accent-2-soft·.k-bg-accent-3-soft- Background from the tokens: surface, raised surface, and a soft wash of each brand color. Every color utility here points at a token, never a raw color.
surface · border · rounded
surface-2 · rounded-l
soft · rounded-full
shadow
shadow-l
Markup
<div class="k-bg-surface k-border k-rounded k-p-3">…</div>
<div class="k-bg-surface-2 k-rounded-l k-p-3">…</div>
<div class="k-bg-soft k-rounded-full k-px-4 k-py-2">…</div>
<div class="k-bg-surface k-shadow k-rounded k-p-3">…</div>
When not to use utilities
- If the same cluster of utilities keeps appearing across pages, that's a component asking to exist — name it once instead of repeating it.
- If a whole page feels too tight or too airy, don't sprinkle
spacing utilities everywhere — change
--k-densityonce and let every space scale with it. - If the brand changes, change the tokens. Never reach for color utilities to repaint pieces of a page — that's how a design system stops being one.