Skip to content

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-only renders below it and disappears above; .k-desktop-only does 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 patternPropertyScale
.k-mt-*margin-top0–8
.k-mb-*margin-bottom0–8
.k-p-*padding0–6
.k-px-*padding-inline2–5
.k-py-*padding-block2–5
.k-gap-*gap1–6
.k-mx-automargin-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-balance
text-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-grow
flex-grow: 1 — the child that takes the leftover room.
.k-flex-none
flex: 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; -full is 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-density once 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.