Koala logo Design
No matches for “
↑↓ navigate open Esc close
Foundations UI usage guide

UI usage guide

When to reach for each element — so the Portal reads as one considered product, not a pile of similar-looking parts. Every example below is built from the real koala-* helpers, so this guide can't drift from the components it documents.

Type roles

Six jobs, one typeface (Plus Jakarta Sans) plus system mono. Each role is one helper class — apply it, get the whole role. Size and weight signal hierarchy, never colour alone.

Page title

Page title
<koala-page-title> · 28px / 600
The one h1 per screen: the page name or the object you're looking at. Exactly one.
Card title
Section title
.koala-section-title · 16px / 600
Names a card or a section within the page. Sentence case, always — never caps.
Section label
<koala-section-label> · 11px / 600 / UPPERCASE
A quiet label grouping rows inside a panel, or a nav-group header. The only sanctioned uppercase.
Body copy carries the actual sentences a user reads.
Body
.koala-body · 16px / 400 / on-surface-variant
Descriptions, help text, paragraph content. Never shrink below 14px.
Issued 23 hours ago
Caption
.koala-caption · 14px / on-surface-muted
Timestamps, secondary detail, field labels above a value. Muted, not coloured.
KQ-001234
Mono ID
.koala-mono-id · system mono / 600 / plum
References, postcodes, money in tables. Refs take plum; postcodes/money stay ink.

When a heading gets a divider

A divider marks a structural seam between a header band and a body. Use it only when the card genuinely has those two zones — that's what koala-card-header-label renders.

The test
Is the body a separate, structured zone the title introduces (fields, a table, key/value rows)? → divider. Is the title just the top line of one continuous idea (a metric + its chart)? → no divider.
Purchase price
£250,000
Tenure
Freehold
Divider. The header band (label + icon) sits over a structured key/value body.
Quotes97
No divider. Plain koala-card — title, figure and sparkline are one composition.

Caps vs sentence case

Two different things, not two styles of the same thing. Caps (koala-section-label) is a label for a region; sentence case (koala-section-title) is an actual title.

The test
Does it name a whole card or page? → sentence-case title. Is it a quiet caption grouping rows inside a surface, or a nav-group header? → ALL-CAPS section label.
ReferenceP-FPIJTI
TypePurchase
CAPS section label. "Transaction" only groups the rows beneath it — it's a label, not a title.

Card body…

Sentence-case title names the whole card; the CAPS section label carries the region label.

Cards

Every card is a koala-card — a surface-container with a 1px outline and a 5px corner. They differ by how the title relates to the body.

Header band + divider + structured body.

Form sections, detail panels.
Metric card
£1,150
Dashboard stats. No divider.
£1,740
Koala Admin
Sidebar panel — CAPS-labelled sub-sections split by hairlines.

Tabs

Tabs switch between sections of one object (a case: General, Enquiries, Docs, Tasks…). They never navigate the whole app — that's the sidebar's job. The active tab is a plum pill; the row is flush so the active pill's left edge lines up with the content below.

Active state is the plum pill; counts ride as a small recessed badge.
On mobile it becomes a dropdown that always shows where you are and reaches every tab — nothing hidden, no scroll.
Don't scroll the tab strip, push tabs into a "More" menu, or use tabs for top-level app nav.

Buttons

One primary action per view. Everything else is secondary or quieter. Destructive actions are outlined, never filled, until the moment of confirmation.

Primary — the single main action.
Secondary — supporting actions.
Danger (outlined) — destructive, pre-confirm.
Icon button — repeated row actions.
Never two filled-plum buttons side by side — the eye can't pick the real action.

Status badges

Six warm-aligned families, each carrying a fixed meaning. Pick by meaning, not by colour you fancy — and keep one status vocabulary per object type.

Active
Healthy / in progress
Accepted
Informational state
Expired
Needs attention
Cancelled
Failed / stopped
Draft
Inactive / not started
Complete
Gold — terminal success only
Gold is reserved for the single "Complete" end-state (with its shimmer). Using it elsewhere steals that signal.
No alpha/transparency on status colours — full-opacity container + on-container only.

Avatars

Initials on a coloured chip — never gradient fills or AI faces. koala-avatar derives a stable colour from the name, so a person keeps the same colour across the app.

Nina West
sm (rows, lists)
Haris Khan
md (sidebar)
Amy King
lg (header / profile)
Avatars are the one genuinely round element — rounded-full is correct here.

Form controls

koala-field generates the label, the surface-recessed input and its validation in one tag. koala-toggle is for instant on/off. Focus is a 2px plum ring, no offset.

Text input
On — plum
Off — recessed
Toggle for instant on/off settings; a checkbox only inside a form that's saved with a button.

Surfaces & nesting

Depth is built from surface roles and borders, not shadows. Adjacent surfaces always differ by one role, and nesting caps at two levels: page → container → recessed.

Surface
--color-surface
The page itself.
Container-low
…-container-low
Chrome, hover, header bands.
Container
…-container
Cards, modals, dropdowns.
Recessed
…-recessed
Inputs/controls inside a card.
Dim
…-dim
Empty states, skeletons.
Shadows only for things that float (dropdowns, modals, toasts). Static cards never get a shadow.

Colour

Plum is the only brand accent. There is no secondary brand colour. Everything non-plum is either neutral ink/surface or a semantic status colour.

Primary (plum)
CTAs, active nav/tabs, focus, selected, links.
Primary-container
Active pill backgrounds, admin chips.
On-surface
Headings, key figures.
Status
Only with semantic meaning.
No gradients, no second accent, no decorative colour. If it's not plum, neutral, or a status — it's wrong.

Spacing & shape

A 4px spacing base, and a single 5px corner on every UI surface — buttons, inputs, cards, badges, dropdowns. The full circle is reserved for genuinely round things.

5px — all UI surfaces
Full — avatars, dots, spinners, toggles
4 / 8 / 12 / 16 / 24 — the spacing rhythm
No pill-shaped buttons, badges or inputs — those keep the 5px corner. Toggles are the one rounded control.

Icons

Lucide, outlined, 1.5 stroke-width, round caps, drawn in currentColor via <koala-icon>. Set colour on the element, never an icon-colour prop. See the full set on the Icons page.

ExtraSmall
Small
Default
Large / plum

Empty states

A muted icon, a one-line headline, a sentence of warm guidance, and (if there's an action) a single button. koala-empty-state centres and sizes it for you.

No notes yet

Add a note to keep the team in the loop on this quote.

Pages in context

The rules above, composed into real screens from the same helpers. Numbered markers map every part back to its rule.

1 — List page

A collection you scan and filter. Page title + one primary action, a toolbar, then a single table card.

koala.legal / transactions

Transactions1

44 active
Search transactions
Client3ReferenceStatusFeeCompletion
Susan BatchelorSusan BatchelorP-YCJFQH4Active5£1,740.0014 Aug 20266
Matthew DaughtreyMatthew DaughtreyS-KOISYZActive£2,257.0022 Jul 2026
Gillian KinnearGillian KinnearS-HGXISIComplete£1,492.802 Jun 2026
1Page title — the one h1, with a quiet count caption beneath. Never a section label here.
2One primary action, top-right. Everything else is secondary or quieter.
3Table = one flush card. Column headers are koala-th (uppercase label role); rows are koala-tr.
4Mono reference in plum — koala-mono-id.
5Status badge chosen by meaning; gold only for the terminal "Complete".
6Money is mono ink; dates are the muted caption role.

2 — Detail / view page

A single object opened up. Object title with a descriptor and status, object tabs, then a main column of section cards beside a sidebar panel of meta.

koala.legal / transactions / P-YCJFQH

Susan Batchelor1

Active2
Purchase
Purchase price5
£250,000
Tenure
Freehold
Buyers
2 buyers
Mortgage
Yes
5 of 10
Answering enquiries
Exchange of contracts
  • £1,740.004
  • Susan BatchelorSusan Batchelor
  • P-YCJFQH
1Object title is the page h1; the descriptor ("Purchase") rides beneath as caption.
2Status badge sits with the title, so state is the first thing read.
3Object tabs (koala-tabs) switch sections of this one record — never app-level nav.
4Sidebar panel — one flush card split into CAPS-labelled sub-sections by hairlines.
5Key/value — muted caption label above an ink value. The repeating unit of every detail card.

3 — Settings page

Configuration grouped into stacked section cards, with a nav rail. Each card states what it does, then the controls, then one save.

koala.legal / settings

Settings1

Manage your workspace.
Account email3
Where Koala sends quote and transaction updates.
4
Notifications
Email me when a quote is accepted.
Quote accepted
5
1Page title + body description — the one place a short body sentence sits directly under the h1.
2Nav group headers are the section-label role; the active link is a filled-plum item.
3Section card per setting: title, a caption description, divider, then controls.
4Form control (koala-field) in a recessed surface, label above.
5Toggle for an instant on/off setting — no save needed.
6One primary "Save" per card, bottom-right, when the change needs committing.

Voice

Copy is part of the brand: warm, plain, human — like a helpful colleague, not a system notice. UK English, sentence case, action verbs.

"✅ All confirmed — mail to … lands where it should" — lead with the human outcome; emoji at the start, sparingly.
"Receipt confirmed. Provider dispatch successful. ✅" — jargon, system-speak, emoji after a full stop.
On errors: no emoji, hide the technical detail, and say what to do next — kindly.
Buttons are action verbs: "Save changes", "Accept quote", "Add branch".