Design system

The AkurAI design system is the set of UI primitives the framework ships so that any app built on it — and the built-in admin — looks coherent without a single line of bespoke CSS. It is no-build, like the rest of the framework: plain semantic HTML classes, design tokens as CSS custom properties, and (soon) an atomic CSS engine in crates/css that emits only the classes a project actually uses. No Tailwind dependency, no PostCSS, no bundler — the same win-by-subtraction philosophy as the runtime.

This section is the specification for that system. It documents the components we want to create, what each must do, and how we tell when one is done. Treat it the way the crate map in AGENTS.md is treated: the source of truth, updated in the same commit as the work.

How it works

live as CSS custom properties on :root. Components reference tokens; they never hard-code a value. Change a token, reload, everything updates — and a theme (or a per-tenant brand) is just an alternate token set. See Foundations.

classes to match the existing CSS — btn btn-primary, alert alert-danger, badge badge-ok. The planned atomic engine generates these from source scans and ships only what's used.

<details> for disclosure and menus, <dialog> for modals, :focus-within and :focus-visible for state, real <button>/<label>/<table> for semantics. JavaScript is an enhancement, never the only path.

contract (labels, roles, keyboard, focus management). A component is not done until that contract holds under keyboard-only and screen-reader use.

Visual direction

The house style is liquid glass: refractive, tinted, dimensional surfaces over a dark canvas. It is the visual counterpart of the framework's engineering stance — quiet on the surface, serious depth underneath. Light and refraction do the decorating, so the system stays restrained: one material, many tints, almost no ornament. The look sits deliberately next to the liquid-glass treatment in the Búi Pi desktop app, so the whole AkurAI fleet reads as one family.

Three rules keep it coherent:

An app or agent is told apart by a single signature colour (its attenuation tint) and, for icons, its silhouette — never by a different material. This is why the fleet looks unified even as it grows: adding an app is choosing a hue, not designing a style.

a faint bloom, and a dark-first canvas are the brand signal. Flat fills and drop-shadows are not part of the language.

like colour and spacing. Change a token, reload, the whole fleet shifts. A per-tenant brand is an alternate tint set, nothing more.

The glass tokens

The canonical defaults (reference implementation below). Treat these the way :root custom properties are treated — the values components read, never hard-code.

| Token | Default | What it controls | |-------|---------|------------------| | ior | 1.5 | Index of refraction — how hard light bends through the glass | | thickness | 1.15 | Volume the light travels through (drives tint depth) | | roughness | 0.05 | Surface frost; near-0 is wet/clear, higher is satin | | dispersion | 1.6 | Chromatic split at the edges — the "expensive" rainbow rim | | attenuationColor | per-app | The signature tint carried by the volume | | attenuationDistance | 0.85 | How fast the tint deepens with thickness | | clearcoat | 1.0 | Glossy lacquer layer for sharp highlights | | envMapIntensity | 1.25 | Strength of studio reflections on the surface | | exposure | 1.08 | ACES tone-mapping exposure of the scene | | bloomStrength / bloomRadius / bloomThreshold | 0.55 / 0.45 / 0.82 | The highlight glow | | spin / bob | 0.25 / 0.05 | Idle rotation + float (motion tokens) |

Iconography (3D)

Every app and customer-facing agent gets one icon: a single extruded glyph rendered in the shared glass material, set apart only by silhouette and tint.

ExtrudeGeometry with a bevel — so icons are source, diffable and retintable. No PNGs to re-export when the brand moves.

importmap, native ES modules, no bundler — the same contract as the rest of the frontend. WebGL path uses WebGLRenderer + EffectComposer (bloom), MeshPhysicalMaterial with transmission + dispersion, a RoomEnvironment PMREM for reflections, and a dim coloured aurora behind the grid so each tint bleeds through the glass.

runnable gallery of all 14 icons with a live tuning panel (drag to orbit, open the panel to dial ior / dispersion / bloom). It is the canonical source for the token defaults above and the registry below.

App → identity registry

| App / agent | Role | Tint | Glyph | |-------------|------|------|-------| | Console | runtime | #38e1ff | terminal prompt >_ | | Drive | storage | #4f8cff | cloud | | Router | gateway | #8b5cff | hub + nodes | | VPN | mesh | #2ee6a6 | shield | | Mail | póstur | #5ad1ff | envelope | | IDP | auðkenni | #ffb44d | key | | Fulltrúinn | réttindi | #ffd24d | scales of justice | | Framework | kerfi | #ff5cf0 | stacked blocks | | Customer Service | þjónusta | #2ee6c9 | speech bubble | | Reports | skýrslur | #5a8cff | bar chart | | Accounting | bókhald | #6fe05a | coin stack | | Knowledge Base | þekking | #6f7bff | open book | | Automation | sjálfvirkni | #ff8a4d | gear | | Content | efni | #ff5c9a | pencil |

Fallback & accessibility

3D is the hero treatment, never a dependency. Where it is wrong — dense lists, favicons, low-power devices, no WebGL — icons fall back to flat marks that inherit the same tint token plus a glassy CSS treatment (frosted backdrop-filter surface, tint as accent). Every 3D icon ships with a static poster frame; content must never block on WebGL. prefers-reduced-motion freezes spin/bob to that poster pose.

Surfaces

The glass language extends to UI chrome: frosted panels (backdrop-filter: blur), soft elevation, a dark-first canvas, and the per-app tint as the accent token. The default AkurAI theme is the canonical glass canvas; the other named themes (see Themes) restyle the flat token layer but keep this structure.

Status: 🟡 partial — direction set and the reference icon set built (14 apps). The CSS frosted-surface utilities and the production <glass-icon> component are ⬜ planned.

The pages

colour, typography, spacing, radius, elevation, motion, z-index, and breakpoints. Everything else is built on these.

themes (Nord, Claude Code, Catppuccin, Solarized, Gruvbox, Tokyo Night, Rosé Pine, Dracula, AkurAI) in dark and light variants. How they are generated, how the switcher works, and how to add a new theme.

grouped by job (actions, forms, data display, feedback, navigation, overlays, layout, and the admin shell), each with variants, states, markup, accessibility, and the tokens it consumes.

Status model

Components and tokens carry one of three marks, kept current in the catalog:

/components page.

no a11y pass).

is the work ahead.

Where things stand today: a hand-written CSS layer already ships buttons, form controls, cards, alerts, badges, tables, and disclosure, plus the layout primitives behind this very site (nav, hero, features, stats, split, sidebar, prose). The catalog promotes those to a documented, tokenised system and lays out the full target set — including the toasts, overlays, navigation, and admin shell that turn the framework into a complete PocketBase-style product.

Relationship to the roadmap

This system is roadmap step 9 (CSS engine + frontend + admin UI). The catalog is what step 9 builds against: the crates/css engine produces the classes, the frontend layer assembles primitives into the admin shell, and each component's spec here is its acceptance check. Building the design system before (or alongside) the auto-API means the day the API generates routes, there is already a UI ready to render them.