design
Design System
design (previously styles) lives under core.assets/assets/design/ and provides versioned CSS assets organised into three categories: standards, ui, and layouts. Each category is versioned independently (e.g. v1.css).Directory structure
core.assets/assets/design/
├── standards/
│ ├── v1.css ← Design tokens, reset, utilities
│ └── info.md (optional: stable/latest pointers)
├── ui/
│ ├── v1.css ← Component styles (buttons, cards, forms, etc.)
│ └── info.md
└── layouts/
├── v1.css ← Page layouts (sidebar, holy grail, stacks, etc.)
└── info.mdUsage
Include one, two, or all three files in your
<head>. standards must always come first since ui and layouts depend on its design tokens.<link rel="stylesheet" href="/design/standards/v1.css">
<link rel="stylesheet" href="/design/ui/v1.css">
<link rel="stylesheet" href="/design/layouts/v1.css">Via the asset service:
GET /design/standards/v1.css
GET /design/ui/v1.css
GET /design/layouts/v1.cssStandards (standards/v1.css)
The foundational stylesheet. It contains no component styles, only tokens, resets, and utilities.
1. Color system
Each project picks a hue by overriding
--brand-hue. Six presets are provided:| Variable | Hue | Result |
--brand-hue-blue | 210° | Blue (default) |
--brand-hue-green | 150° | Green |
--brand-hue-purple | 270° | Purple |
--brand-hue-red | 0° | Red |
--brand-hue-orange | 30° | Orange |
--brand-hue-teal | 180° | Teal |
Set the active brand:
:root {
--brand-hue: var(--brand-hue-green);
}From
--brand-hue, the system derives a full color scale:| Token | Description |
--brand | Base brand color |
--brand-strong | 18% darker |
--brand-soft | 72% lighter |
--brand-faint | 92% lighter |
--complement | Opposite hue |
--bg | Page background |
--surface | Card/section background |
--surface-2, --surface-3 | Deeper layers |
--text | Body text |
--text-muted, --text-faint | Lower emphasis |
--border, --border-strong, --border-faint | Borders |
--focus-ring | Focus outline |
--success, --warning, --danger, --info | Semantic colors |
Dark mode is handled automatically via
prefers-color-scheme: dark — no class toggling needed. All surfaces, text, and borders invert cleanly while keeping the same brand hue.2. Size scale
xxs 0.125rem ( 2px)
xs 0.25rem ( 4px)
s 0.5rem ( 8px)
m 1rem (16px)
l 1.5rem (24px)
xl 2rem (32px)
xxl 3rem (48px)
xxxl 4rem (64px)Applied as
--space-{key}, --text-{key} (font sizes), --radius-{key} (border radii), --shadow-{key} (box shadows).3. Z-index system
Use these custom properties instead of raw numbers:
| Token | Value | Used for |
--z-base | 0 | Normal content |
--z-below | -1 | Behind everything |
--z-dropdown | 100 | Dropdown menus |
--z-sticky | 200 | Sticky headers |
--z-nav | 300 | Fixed nav bars |
--z-overlay | 400 | Page overlays |
--z-modal | 500 | Modal dialogs |
--z-popover | 600 | Popovers |
--z-tooltip | 700 | Tooltips |
--z-toast | 800 | Toast messages |
--z-notification | 900 | Notifications |
--z-banner | 950 | Emergency banners |
--z-emergency | 1000 | Critical alerts |
4. Reset & base
box-sizing: border-boxeverywherebodygetsmin-height: 100dvh, system font stack, smooth text rendering- Typography: balanced heading wrapping,
text-wrap: prettyfor body text - Links inherit brand color with fast hover transition
- Images, media, form elements are reset to behave predictably
::selectionmatches the brand- Custom scrollbar styling (webkit)
5. Utility classes
| Category | Examples |
| Spacing | .gap-xs, .p-m, .m-xl etc. |
| Flex | .flex, .flex-col, .items-center, .justify-between |
| Grid | .grid, .grid-cols-2, .grid-cols-3 |
| Text | .text-muted, .text-xs, .text-xxxl, .weight-bold |
| Surface | .surface, .surface-2, .inset |
| Borders | .border, .radius-m, .radius-full |
| Shadows | .shadow-sm, .shadow-md, .shadow-lg |
| Layout | .container (1200px max-width, responsive padding) |
| Accessibility | .sr-only (screen-reader only) |
UI components (ui/v1.css)
Requires
standards/v1.css. Provides styled components using the design tokens.Buttons
<button class="btn btn--primary">Primary</button>
<button class="btn btn--secondary">Secondary</button>
<button class="btn btn--ghost">Ghost</button>
<button class="btn btn--danger">Danger</button>Sizes:
btn--s, default, btn--l, btn--xl.Cards
<div class="card">
<div class="card__header"><h3>Title</h3></div>
<p>Content</p>
<div class="card__footer">Footer</div>
</div>Add
card--interactive for hover effect.Forms
<div class="form-group">
<label class="form-label" for="email">Email</label>
<input class="form-input" id="email" type="email" placeholder="you@example.com">
<span class="form-hint">We'll never share your email.</span>
</div>Available:
.form-input, .form-textarea, .form-select, .form-check, .form-error, .form-hint.Badges
<span class="badge badge--brand">New</span>
<span class="badge badge--success">Active</span>
<span class="badge badge--danger">Expired</span>Tables, progress bars, spinners
<table class="table">...</table>
<div class="progress"><div class="progress__bar" style="width: 60%"></div></div>
<div class="spinner"></div>Layouts (layouts/v1.css)
Requires
standards/v1.css. Provides reusable layout patterns.| Class | Description |
.page | Full page shell with sticky header |
.layout-sidebar | 260px sidebar + main content (collapses on mobile) |
.stack | Vertical flex with gap (--xs to --xxl variants) |
.inline | Horizontal flex row |
.split | Two-column grid (collapses on mobile) |
.holy-grail | header + nav + main + aside + footer grid |
.grid-auto | Auto-fit responsive grid (min 280px per item) |
.hero | Centered hero section |
.section | Vertical section spacing |
.full-bleed | Full viewport width breakout |
Versioning
Each file follows the same version resolution rules as other versioned assets in
core.assets:| Request | Behavior |
?version=stable | Read info.md in the folder → serve that file |
?version=latest | Serve newest file by modification time |
?version=v1.css | Serve exact file |
| (no param) | Serve latest |
Development workflow
- Edit the relevant
v1.cssfile incore.assets/assets/design/. - Commit and push to
origin/main. - The VPS pulls via webhook automatically.
- Update consuming projects'
<link>or asset request paths if needed.