Colour and tokens
Every value in the system, generated from tokens.json. Components read these as CSS variables (var(--surface-100)) and never use a literal. Swatches show each theme side by side; the page theme does not change them.
Colour
Section titled “Colour”| Token | Light | Dark | High contrast | Usage |
|---|---|---|---|---|
surface-000 |
#f2f0ea |
#141a17 |
#ffffff |
Page ground. Bone in light, Ink in dark. Everything else sits on this. |
surface-100 |
#ffffff |
#1c2320 |
#ffffff |
Raised: cards, inputs, modals, menus, table rows. |
surface-200 |
#eceae3 |
#0f1412 |
#ededed |
Sunken: sidebar, code blocks, skeleton base, table header. |
surface-hover |
#e6e4dc |
#26302a |
#e2e2e2 |
Hover on rows, nav items, subtle buttons. |
surface-selected |
#e4f1ea |
#1c3328 |
#d6efe2 |
Selected nav item, selected row, active chip. Pair with emerald-deep text. |
surface-inverse |
#141a17 |
#f2f0ea |
#000000 |
Tooltips and the inverted hero band. Text on it is ink-inverse. |
ink |
#141a17 |
#f2f0ea |
#000000 |
Headings, labels, primary text on every surface. 15:1 on surface-000 in both themes. |
ink-secondary |
#2b332e |
#d4d8d2 |
#000000 |
Running prose and chat replies on surface-000 and surface-100. |
ink-muted |
#4f5752 |
#a3aca6 |
#2f3532 |
Descriptions, metadata, placeholders, timestamps on surface-000, surface-100, surface-200. 6.5:1 light, 7.6:1 dark. |
ink-disabled |
#8e968f |
#5e6762 |
#545a57 |
Disabled control text and icons only. Exempt from contrast rules; never use for live content. |
ink-inverse |
#f2f0ea |
#141a17 |
#ffffff |
Text and icons on surface-inverse. |
ink-on-brand |
#f2f0ea |
#141a17 |
#ffffff |
Text and icons on emerald-deep fills (primary buttons, progress fill). 5.7:1 light, 6.5:1 dark. |
emerald |
#1f8a5b |
#2f9a68 |
#0d593a |
The brand green: caret mark, the up in the wordmark, status icons, large text 24px+. 3.9:1 on surface-000 light, so never for body-size text; use emerald-deep. |
emerald-deep |
#176b47 |
#4fae7f |
#0a4a30 |
Interactive green: primary button fill, links, selected text, focus ring, progress. 5.7:1 on surface-000 and 6.5:1 on surface-100 in light; 6.5:1 on surface-000 dark. |
emerald-hover |
#125a3b |
#7cc29c |
#083d27 |
Hover fill of primary buttons and hovered links. |
emerald-active |
#0d452d |
#a8d5bc |
#062d1d |
Pressed fill of primary buttons. |
emerald-soft |
#e4f1ea |
#1c3328 |
#d6efe2 |
Light button fill, success alert ground, done badge ground. Text on it is emerald-deep. |
mist |
#d4d8d2 |
#3a423d |
#5e6662 |
Inactive progress track, skeleton shimmer high. |
caret-idle |
#7c847e |
#6f7873 |
#5e6662 |
Undrawn caret stroke: both strokes of Queued, the right stroke of Preparing and Planning. 3.4:1 on surface-000 light, 3.9:1 dark, so the caret keeps its shape. In high contrast it stays apart from ink. |
border |
#dddbd3 |
#2a322e |
#6e6e6e |
Decorative hairlines: card edges, dividers, table rules. Carries no meaning, so may sit under 3:1. |
border-strong |
#7c847e |
#6f7873 |
#000000 |
Control borders: inputs, checkboxes, radios, outline buttons. 3.4:1 on surface-000 light, 3.9:1 dark, as WCAG asks of a control edge. |
focus |
#176b47 |
#4fae7f |
#000000 |
The one focus ring: 2px solid, 2px offset, on every focusable element. 5.7:1 on surface-000 light, 6.5:1 dark. |
success = emerald-deep |
#176b47 |
#4fae7f |
#0a4a30 |
Success text and icon, always next to a word or the done caret, never colour alone. |
success-soft = emerald-soft |
#e4f1ea |
#1c3328 |
#d6efe2 |
Success alert and badge ground. |
warning |
#8a5a14 |
#e8b45a |
#5c3a00 |
Needs-approval and waiting states: text and icon on warning-soft (5.0:1 light, 7.5:1 dark) and on surface-000. |
warning-soft |
#f7ebd3 |
#413d2a |
#fff0d1 |
Warning alert, badge and banner ground. |
danger |
#9a3a2a |
#f09080 |
#7d1d0e |
Failed states, destructive buttons, field errors: text and icon on danger-soft (5.6:1 light, 6.4:1 dark) and on surface-000. Always paired with an X icon or the word. |
danger-soft |
#f6e3de |
#423731 |
#fde3dd |
Error alert, badge and field-error ground. |
info |
#2f5f8f |
#7fb3e6 |
#173f6e |
Informational notices: text and icon on info-soft (5.5:1 light, 6.8:1 dark). Blue, so it is never confused with success. |
info-soft |
#e1eaf4 |
#2e3d44 |
#dbe8f7 |
Info alert and badge ground. |
overlay |
#141a177a |
#000000a6 |
#000000cc |
Scrim behind modals and drawers. |
chart-1 |
#1f8a5b |
#2f9a68 |
#0a4a30 |
Categorical series 1 (emerald). Fixed order, never cycled. Validated: adjacent CVD ΔE ≥ 10 both themes, ≥ 3:1 on surface-100. |
chart-2 |
#2e6fd8 |
#5b93ea |
#1a4fa8 |
Categorical series 2 (blue). |
chart-3 |
#b8780f |
#bf7f18 |
#7a4d00 |
Categorical series 3 (amber). Last slot safe for scatter and maps; beyond three series fold to Other or facet. |
chart-4 |
#d3588e |
#d2659c |
#a52a6b |
Categorical series 4 (magenta). Bars, lines and stacks only. |
chart-5 |
#7a5bd6 |
#8676de |
#4b2fa6 |
Categorical series 5 (violet). |
chart-6 |
#c8562e |
#d06a48 |
#8f3414 |
Categorical series 6 (clay). Also the warm pole of the diverging scale. Never for danger; that is danger. |
chart-ord-1 |
#6ab98f |
#a8d5bc |
#6ab98f |
Ordinal and sequential ramp, lightest step (near zero). Validated: monotone, ΔL ≥ 0.06, ≥ 2:1 on the surface. |
chart-ord-2 |
#2f9a68 |
#7cc29c |
#2f9a68 |
Ramp step 2. |
chart-ord-3 |
#176b47 |
#4fae7f |
#176b47 |
Ramp step 3. |
chart-ord-4 |
#0d452d |
#2f9a68 |
#0d452d |
Ramp step 4, darkest in light, mid in dark; dark adds chart-ord-5. |
chart-ord-5 |
#0d452d |
#176b47 |
#0d452d |
Ramp step 5 (dark theme only; equals step 4 in light). |
chart-mid = mist |
#d4d8d2 |
#3a423d |
#5e6662 |
Neutral midpoint of the diverging scale (emerald ↔ clay) and the empty track of charts. |
emerald-0 |
#e8f3ed |
#e8f3ed |
#e8f3ed |
Mantine colors.emerald[0]. Softest tint. |
emerald-1 |
#cde6d8 |
#cde6d8 |
#cde6d8 |
Mantine colors.emerald[1]. |
emerald-2 |
#a8d5bc |
#a8d5bc |
#a8d5bc |
Mantine colors.emerald[2]. Dark theme pressed fill. |
emerald-3 |
#7cc29c |
#7cc29c |
#7cc29c |
Mantine colors.emerald[3]. Dark theme hover fill. |
emerald-4 |
#4fae7f |
#4fae7f |
#4fae7f |
Mantine colors.emerald[4]. Dark theme primary shade. |
emerald-5 |
#2f9a68 |
#2f9a68 |
#2f9a68 |
Mantine colors.emerald[5]. Dark theme brand green. |
emerald-6 |
#1f8a5b |
#1f8a5b |
#1f8a5b |
Mantine colors.emerald[6]. The brand green. |
emerald-7 |
#176b47 |
#176b47 |
#176b47 |
Mantine colors.emerald[7]. Light theme primary shade. |
emerald-8 |
#125a3b |
#125a3b |
#125a3b |
Mantine colors.emerald[8]. Light theme hover. |
emerald-9 |
#0d452d |
#0d452d |
#0d452d |
Mantine colors.emerald[9]. Light theme pressed. |
Shadow
Section titled “Shadow”Borders carry structure; shadows only lift floating layers. Never shadow a card at rest.
| Token | Light | Dark | High contrast | Usage |
|---|---|---|---|---|
shadow-sm |
Dropdown menus, popovers, tooltips. | |||
shadow-md |
Notifications, the composer when focused, dragged items. | |||
shadow-lg |
Modals and drawers over overlay. |
Typography
Section titled “Typography”| Style | Sample | Size / line | Weight | Usage |
|---|---|---|---|---|
hero |
Always up. | 56px / 60px | 700 | Marketing hero only. Familjen Grotesk never appears inside the app UI; the wordmark ships as SVG. |
hero-sm |
Your data. Your control. | 40px / 44px | 700 | Marketing section titles and the hero at phone width. |
h1 |
Tasks | 28px / 36px | 700 | Page title. One per page. |
h2 |
Four phases. One caret. | 24px / 32px | 600 | Section title, modal title. |
h3 |
Connect a provider | 20px / 28px | 600 | Card title, stepper step title. |
h4 |
Daily finance digest | 17px / 24px | 600 | List item title, task card title. |
body-lg |
Always-on AI agents, on infrastructure you own. | 17px / 26px | 400 | Lead paragraphs, onboarding copy. |
body |
Long-running tasks that plan, execute, and review their own work. | 15px / 22px | 400 | Default text: chat, descriptions, table cells, inputs. |
body-sm |
Worked for 4.2 s | 13px / 18px | 400 | Metadata, helper text, timestamps, nav items. |
label |
Provider | 13px / 16px | 600 | Form labels, button text at size sm, badge text. |
caption |
Enter to send · Shift+Enter for a new line | 12px / 16px | 500 | Hints under composers, footnotes. Never below 12px. |
overline |
TODAY | 11px / 16px | 600 | Uppercase group headers in lists and sidebars. |
code |
docker compose up -d | 13px / 20px | 400 | Code blocks, tool call arguments, version strings. |
code-sm |
0.1.0-alpha.122 | 12px / 18px | 400 | Inline code inside body-sm, keyboard shortcuts. |
Spacing
Section titled “Spacing”4px base. Use steps, never odd values. Component padding is on the step; layout gaps use the larger steps.
| Token | Value | Usage |
|---|---|---|
space-1 |
4px |
Icon to text inside a badge; gap between stacked helper lines. |
space-2 |
8px |
Icon to label in buttons; gap between chips; inside padding of small controls. |
space-3 |
12px |
Horizontal padding of inputs and medium buttons; gap between form fields in a row. |
space-4 |
16px |
Card padding at phone width; gap between fields; the minimum side gutter. |
space-5 |
20px |
Card padding on desktop; gap between cards. |
space-6 |
24px |
Modal padding; gap between form sections; page side padding on tablet. |
space-8 |
32px |
Page side padding on desktop; gap between page sections. |
space-10 |
40px |
Gap between major page regions; stepper content top margin. |
space-12 |
48px |
Top bar height; empty state padding. |
space-16 |
64px |
Marketing section padding. |
Radius
Section titled “Radius”Soft, 8px base. Radius signals an object: controls md, containers lg, overlays xl, pills full.
| Token | Value | Usage |
|---|---|---|
radius-xs |
4px |
Checkbox box, kbd, inline code, skeleton lines. |
radius-sm |
6px |
Small buttons, chips at size sm, menu items. |
radius-md |
8px |
Buttons, inputs, selects, tabs, table container, tooltips. |
radius-lg |
12px |
Cards, tiles, alerts, chat bubbles, popovers. |
radius-xl |
16px |
Modals, drawers, the composer. |
radius-full |
9999px |
Badges, pills, avatars, switch, progress bar. |
Control heights and icon sizes. Touch targets are 40px minimum on pointer-coarse devices, 32px minimum with a mouse.
| Token | Value | Usage |
|---|---|---|
control-sm |
32px |
Small buttons, inline inputs in tables, action icons. |
control-md |
40px |
Default buttons, inputs, selects, nav items. The touch minimum. |
control-lg |
48px |
Primary call to action on marketing pages and onboarding. |
icon-sm |
16px |
Icons inside badges, inputs and body-sm text. |
icon-md |
20px |
Default icon: buttons, nav, table actions. |
icon-lg |
24px |
Empty states, feature tiles, page headers. |
sidebar |
248px |
App sidebar width on desktop. Collapses to an icon rail of 56px below md, a drawer below sm. |
topbar |
48px |
App top bar height. |
measure |
68ch |
Maximum width of running prose, chat replies and documentation. |
Breakpoints
Section titled “Breakpoints”Mantine’s defaults, in em so they follow the user’s font size. Mobile first: write the phone layout, then add from sm up.
| Token | Value | Usage |
|---|---|---|
bp-xs |
36em |
576px. Two-column form rows start here. |
bp-sm |
48em |
768px. Sidebar becomes an icon rail; cards go two across. |
bp-md |
62em |
992px. Full sidebar; three-card grids. |
bp-lg |
75em |
1200px. Chat gets the side panel; tables show every column. |
bp-xl |
88em |
1408px. Content stops growing; margins absorb the rest. |
Z-index
Section titled “Z-index”| Token | Value | Usage |
|---|---|---|
z-sticky |
100 |
Top bar, table header, stepper header. |
z-dropdown |
200 |
Menus, selects, popovers, tooltips. |
z-overlay |
300 |
Modal and drawer scrim. |
z-modal |
400 |
Modal and drawer panel. |
z-toast |
500 |
Notifications stack, always above modals. |
Motion
Section titled “Motion”Durations and easings. Hover and colour 120ms, state 200ms, overlays 240ms in and 160ms out. The caret is the only thing that animates for longer. Everything stops under prefers-reduced-motion.
| Token | Value | Usage |
|---|---|---|
duration-fast |
120ms |
Hover, colour and border changes, press scale, tooltip fade. |
duration-base |
200ms |
State changes: checked, expanded, selected, caret stroke, progress width, chevron rotate. |
duration-enter |
240ms |
Overlays entering: modal, drawer, menu, toast, popover. |
duration-leave |
160ms |
Overlays leaving. Always shorter than entering. |
duration-loader |
1600ms |
One loop of the drawing caret loader. |
duration-lift |
4000ms |
Period of the working-task lift (2px up and back). |
duration-shimmer |
1800ms |
One pass of the skeleton shimmer. |
ease-standard |
cubic-bezier(.4, 0, .2, 1) |
Everything that moves or changes state. |
ease-leave |
cubic-bezier(.4, 0, 1, 1) |
Overlays leaving: starts fast, no settle. |
ease-caret |
cubic-bezier(.2, 0, 0, 1) |
The caret draw: quick start, long settle so the stroke looks drawn, not slid. |
press-scale |
0.98 |
Scale of a button or tile while pressed. |
tooltip-delay |
400ms |
Hover delay before a tooltip shows; 0 when another tooltip was open in the last second. |