AkurAI Build
Menu

Public repository / 439f0dcabf5cdf2b120c7724be895cf1df30507f

AkurAI-Framework / site/content/docs/design-system.md

Latest change df4f95a443de36bf428c6881f8cb50ca82b24136 - OLI-159: liquid-glass CSS kit (glass.css) + docs + changelog by Ólafur Búi Ólafsson

# 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

- **Tokens, not literals.** Colour, radius, type, spacing, motion, and elevation
  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](/docs/design-system/foundations).
- **Semantic classes.** A component is `block` + modifiers, written as separate
  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.
- **Native first.** Interactivity uses platform elements before script:
  `<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.
- **Accessibility is a requirement, not a pass.** Every component lists its a11y
  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:

- **One material, identity by tint.** Every glass surface is the *same* shader.
  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.
- **Depth as brand, not decoration.** Refraction, dispersion (chromatic edges),
  a faint bloom, and a dark-first canvas are the brand signal. Flat fills and
  drop-shadows are not part of the language.
- **Tokens all the way down — even in 3D.** The glass is a token set, exactly
  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.

- **Code, not binary assets.** Geometry is built procedurally — `THREE.Shape` →
  `ExtrudeGeometry` with a bevel — so icons are source, diffable and retintable.
  No PNGs to re-export when the brand moves.
- **No-build, like everything else.** Vanilla **three.js r185** via an
  `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.
- **Reference implementation:** `/home/olafurbui/Projects/SMARTAGENT/workspaces/akurai-icon-theme/index.html` — a
  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](/docs/design-system/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

- **[Foundations](/docs/design-system/foundations)** — the design tokens:
  colour, typography, spacing, radius, elevation, motion, z-index, and
  breakpoints. Everything else is built on these.
- **[Themes](/docs/design-system/themes)** — the named multi-theme system: 17
  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.
- **[Component catalog](/docs/design-system/components)** — every component,
  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:

- **✅ shipped** — implemented, all states reachable, a11y verified, on the live
  `/components` page.
- **🟡 partial** — exists but incomplete (missing states, not yet tokenised, or
  no a11y pass).
- **⬜ planned** — specified here, not yet built. The bulk of the catalog: this
  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.

## Glass kit (`glass.css`)

`frontend/glass.css` ships the liquid-glass material. Link it after
`styles.css`/`themes.css`; apps vendor the file. One material, identity by
tint: set `--tint` (default aurora `#4fe3c1`) on `:root` or any container.

- `.glass` (+ `.glass-card`, `.glass-nav`) — blurred, tinted surface with a refractive edge; falls back to a flat tinted panel without `backdrop-filter`, and to an opaque bordered panel under `prefers-contrast: more`.
- `.glass-aurora` — drifting tinted canvas glow (frozen under `prefers-reduced-motion`).
- `.btn-glass`, `.btn-glass-primary` — 44px-min pill buttons.
- `.glass-field` (+ `.glass-input`, `.is-invalid`, `.field-error`) — form controls pairing with `[[forms]]`.
- `--focus-ring`, `.glass-display` (`--font-display`: a system serif stack that renders þ ð æ ö natively), `.glass-tint`.

Surfaces status: ✅ shipped (CSS kit). The 3D `<glass-icon>` remains planned.

## Locales in the head

The layout header sets `<html lang="{{ __locale }}">` and emits `{{{ hreflang_links }}}` when path-prefix locales are enabled (see [i18n](/docs/i18n)).

## Forms

Form controls (`field`, inputs, `textarea`, `field-error`, `form-section`, `form-actions`) pair with server-side declarative forms: see [Forms](/docs/forms) for `[[forms]]` and the `form.errors` / `form.values` template context.