Changelog Azalea Kit UI 101 Usage Customizing Utilities Form controls Laravel Vue FHIR Types Accessibility Icons Actions Button Button group Layout and structure Card Card section Care summary Care timeline Divider Empty state Footer Header Layout Stack Table Selection and input Calendar Checkbox Checkbox group Color picker Combobox Combobox option Input Input mask Memorable date Number input Option Phone input Radio Radio button Radio group Range Select SSN input Tag Textarea Toggle ZIP code input Images and icons Avatar Icon Icon button Logo Feedback indicators Badge Banner Progress bar Skeleton Skeleton body text Skeleton display text Skeleton thumbnail Spinner Typography Text Navigation Breadcrumb Breadcrumb item Dropdown Menu Menu item Menu label Navigation Nav group Nav item Nav toggle Pagination Tab Tab group Tab panel Top bar Tree Tree item User menu Overlays Dialog Popover Tooltip Utilities Collapsible FHIR address FHIR human name FHIR quantity FHIR questionnaire Format bytes Format date Format number Relative time Resize observer Split panel Tooltip Border Color Shadow Spacing Transition Typography Z-index Contributing Visual Tests Light Dark System

Utility Classes

Azalea Kit UI ships an optional set of framework-agnostic utility classes for common layout, spacing, typography, and accessibility needs — so app teams don’t hand-roll flex/grid/spacing CSS that drifts from the design tokens.

Every utility on this page ships inside the theme. Load one and you have them all:

<link rel="stylesheet" href="/dist/themes/light.css" />

There is no second stylesheet to add. (utility.css used to be one; it was merged into the themes and removed.)

All classes are prefixed ahi- and reference --ahi-* design tokens, so they track the active theme. Everything lives in the ahi-utilities cascade layer, which means any unlayered CSS in your app overrides these utilities regardless of stylesheet load order — treat them as low-priority defaults you can always override.

:::tip The type and accessibility utilities need no second stylesheet. They ship inside every theme, so ahi-text-body, ahi-text-truncate, ahi-visually-hidden and the rest are available as soon as light.css or dark.css is on the page.

That is deliberate. Some apps embed AKU components and a theme and nothing else — for them, <ahi-text> works today only because its styles ride inside its own shadow root. Its replacement had to reach them the same way. So does everything else on this page. :::

There is no .ahi-stack utility. <div class="ahi-column"> is deprecated — use .ahi-column for a vertical stack or .ahi-row for a horizontal one, with .ahi-gap-* and the alignment classes. Both ship inside the theme, so no extra stylesheet is needed.

Layout primitives

Class What it does
ahi-cluster Inline row that wraps; vertically centered. Buttons, tags, chips, nav links.
ahi-grid Responsive columns with no media queries. Tune the wrap threshold with --ahi-min-column-size (default 20ch).
ahi-flank A fixed-size item beside a flexible one (media object). Set the fixed width with --ahi-flank-size. Add ahi-flank-end to flank the last child instead.
ahi-split Pushes children to opposite ends (toolbars, headers with a trailing action). Add ahi-split-column to stack vertically.
ahi-frame Fixed aspect-ratio box; children cover it. Add ahi-frame-landscape (16:9) or ahi-frame-portrait (9:16); default is square.
<div class="ahi-cluster ahi-gap-2">
  <ahi-button>Save</ahi-button>
  <ahi-button variant="default">Cancel</ahi-button>
</div>

<div class="ahi-grid" style="--ahi-min-column-size: 16rem;">
  <ahi-card>…</ahi-card>
  <ahi-card>…</ahi-card>
  <ahi-card>…</ahi-card>
</div>

<div class="ahi-flank ahi-gap-3" style="--ahi-flank-size: 3rem;">
  <ahi-avatar></ahi-avatar>
  <div>Name and supporting text that fills the remaining space.</div>
</div>

Use ahi-span-grid on a child to make it span the full width of an ahi-grid row.

Spacing

ahi-gap-* sets the gap on any flex or grid container, from the spacing scale (--ahi-space-*): ahi-gap-0, -1, -2, -3, -4, -5, -6, -8, -10, -12, -16.

Alignment

  • Cross-axis: ahi-align-items-start / -end / -center / -stretch / -baseline
  • Main-axis: ahi-justify-content-start / -end / -center / -space-between / -space-around / -space-evenly
  • Wrapping: ahi-flex-wrap / ahi-flex-nowrap

Typography

Available from the theme alone — no second stylesheet. See type roles for what the roles mean and how a density tier moves them.

Roles

A role sets a size and its matching line height together. Pick what the text is, not how big it should be.

Class What it is Example
ahi-text-display Page-level titles. Aa
ahi-text-heading Section titles. Aa
ahi-text-subheading Card and group titles. Aa
ahi-text-body Running text, and most of the UI. Aa
ahi-text-body-emphasis Body, weight-shifted. Same metrics, heavier. Aa
ahi-text-label Form labels, table headers. Aa
ahi-text-caption Help text, timestamps, metadata. Aa
ahi-text-code Monospace, inline and block. Aa

Modifiers

Combine any of these with a role. Each is a single class, so order in the class attribute does not matter.

Group Classes
Color ahi-text-subdued, -critical, -warning, -success, -inherit
Weight ahi-text-regular, -medium, -semibold, -bold
Alignment ahi-text-start, -center, -end, -justify
Transform ahi-text-uppercase, -capitalize
Wrapping ahi-text-truncate (single-line ellipsis), -nowrap, -break-word (breaks long URLs and identifiers), -clamp-2, -clamp-3
Other ahi-text-numeric (tabular figures, so columns of numbers line up), ahi-text-line-through
<p class="ahi-text-body ahi-text-subdued">Last updated 12 minutes ago</p>
<p class="ahi-text-caption ahi-text-critical">This field is required</p>
<p class="ahi-text-body ahi-text-clamp-2">A long note that stops after two lines…</p>

ahi-text-truncate needs a definite width to clip against, and the clamps need the element to be a block — neither forces display, so they keep working on a flex or grid child.

If your app styles h1–h6 globally, those rules win. The utilities live in the ahi-utilities cascade layer, and unlayered CSS beats a layer — which is deliberate, so your app can always override AKU. But it means a rule like h1 { font-size: 2.5rem } overrides .ahi-text-heading on an <h1 class="ahi-text-heading">.

The failure is worse than it sounds, because it is partial: your rule sets font-size but probably not line-height, so the element takes your size and the role’s leading — a mismatched pair, which is the one thing the roles exist to prevent. AKU’s own documentation site hit exactly this.

Exclude elements that opt into a role:

h1:not([class*='ahi-text-']),
h2:not([class*='ahi-text-']) {
  font-size: 2.5rem;
}

Migrating from <ahi-text>

<ahi-text> is being retired. Every one of its properties is plain CSS, so each maps to a class:

<ahi-text> Utility class
variant="heading-3xl" / "heading-2xl" ahi-text-display
variant="heading-xl" / "heading-lg" ahi-text-heading
variant="heading-md" / "heading-sm" ahi-text-subheading or ahi-text-body-emphasis
variant="heading-xs" ahi-text-caption
variant="body-lg" / "body-md" (default) ahi-text-body
variant="body-sm" / "body-xs" ahi-text-caption
color="subdued" | "critical" | "warning" | "success" ahi-text-subdued | -critical | -warning | -success
font-weight="regular" | "medium" | "semibold" | "bold" ahi-text-regular | -medium | -semibold | -bold
alignment="start" | "center" | "end" | "justify" ahi-text-start | -center | -end | -justify
truncate ahi-text-truncate
break-word ahi-text-break-word
numeric ahi-text-numeric
text-decoration="line-through" ahi-text-line-through
visually-hidden ahi-visually-hidden
as="h2" Write the element you want: <h2 class="…">

The variant sizes and the roles are not the same scale, so a few mappings change the rendered size by a pixel or two. body-md — the default when no variant is set — is 13px and becomes 14px as ahi-text-body. Check anywhere the exact size matters.

Accessibility

Available from the theme alone — no second stylesheet.

  • ahi-visually-hidden — hide content visually while keeping it available to assistive technology (revealed when it or a descendant receives focus, so it works for skip links)
  • ahi-visually-hidden-label — applied to a form control, visually hides just its label part while keeping it announced

Preventing flash of undefined elements (FOUCE)

Add ahi-cloak to a container to keep it hidden until it and all of its custom-element descendants are defined — no loader required:

<div class="ahi-cloak">
  <ahi-card>…</ahi-card>
</div>