Lerbb Design System
A unified visual language for every Lerbb product — Docs, Account, Notes, and beyond. Built on CSS custom properties (design tokens), the Inter typeface, and a four-colour brand palette. Designed for consistency, accessibility, and dark-first aesthetics.
AI / Vibe-coding guide: Every design decision in Lerbb UI is encoded as a CSS custom property. Start any component by pasting the :root token block (see CSS Variables). All colours, spacing, radius, shadow and motion values are referenced by token — never hardcode #4C8DFF, always write var(--accent). The sidebar shows every available section. Ask your AI assistant to "implement a Lerbb-style button using the design tokens from this doc" and it will produce consistent output.
data-theme="light"Brand Principles
Everything we build expresses four core values. These aren't aspirational — they are constraints that shape every design decision.
Private by default
Encryption indicators are visible, not buried. Security isn't a feature — it's the foundation.
Effortless speed
Every interaction should feel immediate. Optimistic UI, instant feedback, no perceived latency.
Honest clarity
No dark patterns. Copy is direct. Destructive actions require confirmation. Storage limits are visible.
Accessible for all
WCAG AA minimum contrast everywhere. Keyboard navigable. Touch targets ≥ 44×44px.
LLM / Vibe-Coding Guide
This design system is structured so AI assistants can build consistent Lerbb UI with a single context paste. Here's how to get the best results.
Quick start: Copy the entire :root { … } CSS token block from this page and paste it at the top of your prompt. Then describe the component you want: "Build a Lerbb-style sign-in card using these design tokens, dark theme, Inter font."
Prompting patterns that work
What this doc provides for LLMs
| Section | What AI gets from it |
|---|---|
| Design Tokens | Machine-readable CSS variable names, values, and purpose |
| Component demos | HTML structure + class naming conventions to replicate |
| Code snippets | Copy-pasteable CSS + React component stubs |
| Do/Don't examples | Guardrails that prevent common mistakes |
| Content style | Voice, tone, and copy patterns for microcopy generation |
Colour Palette
Four brand colours, each with a full range of tints and semantics. All colours are defined as CSS custom properties and automatically adapt between dark and light themes.
Brand colours
Colour ramps (hover for hex)
Semantic colours
| Token | Dark value | Light value | Usage |
|---|---|---|---|
--danger | #f28b82 | #c5221f | Errors, destructive actions |
--success | #38B27B | #2a8a5e | Confirmations, verified states |
--warning | #DFA62A | #B07D10 | Warnings, storage usage alerts |
--accent | #4C8DFF | #4C8DFF | Primary interactive colour |
Dark Mode Colours
Dark is the default theme for all Lerbb apps. Apply data-theme="light" on the root element to switch. Never use hardcoded colour values — always use tokens.
Use var(--bg), var(--surface), var(--text)
Hardcode #1a1c1e or #e3e5e8 — they won't adapt to light mode
| Token | Dark | Light | Purpose |
|---|---|---|---|
--bg | #1a1c1e | #eef2f8 | Page / outermost background |
--bg-alt | #1f2124 | #e6ecf5 | Alternate background for stripes |
--surface | #26292d | #ffffff | Card, modal, panel background |
--surface2 | #2e3135 | #eef2f8 | Input fields, inner card areas |
--surface3 | #363a3e | #e3e8f0 | Hover states, active pills |
--border | rgba(255,255,255,.08) | rgba(0,0,0,.08) | Default border |
--text | #e3e5e8 | #1a1c1e | Primary body text |
--text-muted | #8f9399 | #5f6368 | Secondary / helper text |
--text-dim | #b5b9bf | #3c4043 | Labels, metadata |
Typography Scale
Lerbb uses Inter exclusively. It is loaded from rsms.me/inter/inter.css which enables variable font features. One family, full weight axis, zero cognitive overhead.
Letter-spacing rules
| Style | letter-spacing | Notes |
|---|---|---|
| Display / H1 | -0.04em | Tight — creates weight at large sizes |
| H2 / H3 | -0.02em to -0.03em | Slightly tight |
| Body | normal (0) | Never touch body letter-spacing |
| ALL CAPS labels | +0.06em to +0.1em | Always add tracking to uppercase text |
| Monospace | normal | Never adjust mono tracking |
Spacing Scale
A 4px base grid. All spacing values are multiples of 4. Use the token names in CSS — never magic pixel values.
--space-14pxIcon gap, micro insets--space-28pxTight row gap, badge padding--space-312pxInner card padding (compact)--space-416pxStandard row gap--space-520pxCard padding (default)--space-624pxSection padding, modal body gap--space-832pxPage gutter, section margin--space-1040pxSection separator--space-1248pxPage top padding--space-1664pxMajor section gapBorder Radius Scale
Shadows
Lerbb uses shadows sparingly. In dark mode, depth is achieved via surface layering, not heavy shadows. Shadows are most visible in light mode.
--shadow-sm
Cards, nav
--shadow-md
Hovered cards, modals
--shadow-lg
Popovers, dropdowns
--shadow-focus
Focus ring on inputs
| Token | Value |
|---|---|
--shadow-sm | 0 1px 4px rgba(0,0,0,.25) |
--shadow-md | 0 4px 16px rgba(0,0,0,.35) |
--shadow-lg | 0 8px 32px rgba(0,0,0,.45) |
--shadow-focus | 0 0 0 3px rgba(76,141,255,.35) |
Gradients & Glass Effects
Brand spinner gradient
The four-quadrant conic spinner is a core Lerbb brand element. It appears on loading screens and async states across all apps.
Glass / Blur effect (use sparingly)
Motion & Animation
Lerbb animations are fast, purposeful, and non-distracting. Every transition serves feedback or orientation — never decoration.
| Token | Value | Use |
|---|---|---|
--dur-fast | .12s | Hover states, button active |
--dur-base | .18s | Most UI transitions (default) |
--dur-slow | .3s | Page transitions, modal open/close |
--ease | cubic-bezier(.4,0,.2,1) | Standard easing (Material-style) |
--ease-out | cubic-bezier(0,0,.2,1) | Enter / reveal |
--ease-in | cubic-bezier(.4,0,1,1) | Exit / dismiss |
Standard animation keyframes
Respect reduced motion: Wrap all animations in @media (prefers-reduced-motion: no-preference) { … } so users who've opted out of motion don't experience them.
Icons
Lerbb uses Font Awesome 6 solid and brand icons. All icons must be the same weight (solid or brand) within a context. Never mix outlined and filled styles.
| Context | Size | Notes |
|---|---|---|
| Nav / sidebar | 0.9rem | Used in .ni span, 20px wide slot |
| Button icon (leading) | 0.75rem | Set at font-size:.75rem |
| Inline / badge icon | 0.7–0.8rem | Vertically centred with text |
| Feature icon (card) | 1rem | In 44×44px coloured rounded container |
| Empty state icon | 2–2.5rem | Opacity 0.4 |
Complete Token Reference
The full :root block. Copy this into any project to immediately access all Lerbb design tokens.
Z-Index Tokens
| Token | Value | Usage |
|---|---|---|
--z-base | 0 | Default document flow |
--z-raised | 10 | Sticky table headers, raised cards |
--z-overlay | 100 | Topnav, sidebar, fixed UI |
--z-modal | 200 | Modals, drawers, sheets |
--z-toast | 300 | Toast notifications |
--z-max | 400 | Critical alerts, onboarding overlays |
Buttons
All interactive affordances. Buttons communicate priority through visual weight. Use primary sparingly — one per screen section.
Variants
Sizes
With icons
Disabled state
Use "Save" for committing a form. Use "Delete" for removal. Keep button text under 3 words.
Don't use "Click here", "Submit", or "OK". Don't place two primary buttons side by side.
Text Fields
Always pair an input with a <label>. Labels use uppercase micro-text style: font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em.
Checkboxes, Radios & Toggles
Tabs
Tab content goes here…
The tab strip uses background: var(--surface2) as the track, with the active tab using background: var(--surface3). Use a 3px internal padding and gap.
Cards
Documents
Create and edit documents
Security
Manage login methods
Password
Change your password
Section card pattern
Used extensively in the Account portal. A card with a header row and data rows.
Modals
Delete document?
This permanently deletes "Project Brief Q3" and cannot be undone.
Destructive modal rules: Always show what is being deleted by name. Use a red danger button. Require a text confirmation for irreversible account-level actions (e.g. type "DELETE").
Toasts
Toasts auto-dismiss after 2200ms. Never use toasts for errors that require user action — use inline validation instead. Max 1 visible at a time.
Tooltips
Badges & Chips
Avatars
Lerbb uses generated avatars from avatars.lerbb.services/{style}/{seed}. Two styles: shapes and thumbs. Avatars are always round.
Progress Bars
Skeleton Loaders
Use skeletons when content will load within 2–3 seconds. Mirror the shape of the content that will appear — this reduces layout shift.
Empty States
No documents yet
Create your first document to get started. Documents are saved automatically.
Empty state must include: An icon at ~40% opacity, a clear heading, 1–2 sentences of context, and a single primary action button.
File Cards
Used in Lerbb Docs home view. The preview area renders document content at reduced scale. A hover menu reveals the 3-dot action button.
The objective of this document is to outline the key goals and deliverables for Q3 including product launch timeline and resource allocation.
Attendees: Alex, Sam, Jordan. Discussed sprint velocity, blocking issues, and roadmap prioritisation for next quarter.
Storage Usage Bar
| Usage % | Bar colour | Warning shown |
|---|---|---|
| 0–69% | --success (green) | None |
| 70–89% | --warning (amber) | Inline warning text |
| 90–100% | --danger (red) | Inline warning + top banner |
Upload Dropzone
Drop files here or click to browse
.html, .docx, .txt, .md — up to 10 MB
Auth Sign-in Box
Plan / Pricing Cards
Tier Badges
Loading, Error & Success States
Loading states
| Duration | Pattern |
|---|---|
| < 300ms | No indicator — too fast to notice |
| 300ms – 2s | Spinner on the button / element itself (inline spinner) |
| 2s – 5s | Skeleton loader in the content area |
| > 5s | Full-page spinner + progress text |
Error states
Inline errors appear below the specific field (never as a toast). Page-level errors use a banner above content. Network errors use a toast with a retry option. Always explain what went wrong and what the user can do next.
Offline state
Form Validation
| Rule | Detail |
|---|---|
| Validate on blur | Validate when the user leaves a field, not while typing |
| Re-validate on input | Once a field has an error, clear it as the user types |
| Error placement | Below the input, in --danger colour, font-size .75rem |
| Required fields | Mark with * in the label, explain above the form |
| Button state | Disable save button while form has active errors |
| Success confirmation | Show inline success text below the field, then auto-collapse after 3s |
Destructive Action Confirmation
| Action level | Confirmation pattern |
|---|---|
| Low-risk delete (e.g. remove a document) | Modal with item name shown, single "Delete" button |
| Medium-risk (e.g. sign out all devices) | Modal + password confirmation |
| High-risk (e.g. delete account) | Modal + type "DELETE" + password confirmation |
Name the thing being deleted. "Delete 'Project Brief Q3'?" not "Delete document?".
Never auto-delete without a confirmation. Never make destructive buttons the default/focused element.
Accessibility
| Rule | Detail |
|---|---|
| Colour contrast | WCAG AA: 4.5:1 for body, 3:1 for large text. All brand colours pass. |
| Focus ring | Always visible. Use box-shadow: var(--shadow-focus) — never remove outline without a replacement |
| Skip links | Add <a href="#main">Skip to content</a> as first focusable element |
| Labels | Every input must have an associated <label for=…> |
| ARIA | Use semantic HTML first. Add ARIA only where semantics are insufficient |
| Keyboard nav | Tab order follows visual order. Escape closes modals. Enter submits forms |
| Screen readers | Icons that carry meaning get aria-label. Decorative icons get aria-hidden="true" |
| Reduced motion | Wrap animations in @media (prefers-reduced-motion: no-preference) |
Mobile & Touch
| Rule | Detail |
|---|---|
| Touch targets | Minimum 44×44px for any interactive element |
| Mobile nav | Sidebar hidden on <768px. Fixed bottom nav with 4 icons replaces it |
| Tap highlight | -webkit-tap-highlight-color: transparent on all interactive elements |
| Text select | Disable user-select on UI chrome, enable on content (inputs, document text) |
| Overscroll | overscroll-behavior: none on body to prevent pull-to-refresh in PWA |
| Safe areas | Use env(safe-area-inset-*) for PWA padding on notched devices |
| Viewport lock | user-scalable=no in meta viewport for app-like PWA feel |
Voice & Tone
Button & Error Copy
Button wording
| Context | Use | Avoid |
|---|---|---|
| Save form data | Save | Submit, OK, Confirm |
| Create new | New document, Add member | Create, Make |
| Delete | Delete | Remove, Erase |
| Cancel action | Cancel | No, Never mind, Close |
| Navigate away | Go back, Return | Back |
| Authentication | Sign in, Sign out | Login, Logout, Log in |
| Subscription | Upgrade to Pro | Buy, Purchase |
Error message patterns
| Error type | Pattern | Example |
|---|---|---|
| Wrong password | State the problem + hint | "Incorrect password. Try again or reset it." |
| Network failure | What happened + what to do | "Couldn't save — check your connection and try again." |
| Validation | Specific, not generic | "Password must be at least 6 characters." not "Invalid input" |
| Permission denied | Explain the restriction | "You don't have permission to edit this document." |
| Not found | Name the thing + offer help | "Document not found. It may have been deleted." |
Capitalisation Rules
| Element | Rule | Example |
|---|---|---|
| Page titles | Title case | Personal Info, Security & Login |
| Section headers | Title case | Login Methods, Account Details |
| Field labels | Title case (ALL CAPS in CSS) | DISPLAY NAME, EMAIL ADDRESS |
| Button text | Title case for 1–2 words, sentence case for 3+ | Save / Sign in / Upgrade to Pro |
| Body / help text | Sentence case | We'll send a verification email. |
| Error messages | Sentence case | Incorrect password. Try again. |
| Toast messages | Sentence case | Email address updated! |
| Product names | Lerbb, Lerbb Docs, Lerbb Account | Always capitalised as shown |
CSS Variables — Quick Reference
A compact cheatsheet of the most frequently used tokens. Perfect for pasting into an AI prompt.
For AI prompting: Paste this entire block at the top of your request: "Use these Lerbb CSS variables for all styling: [paste block]. Do not hardcode any colours, spacing, or radius values."
Tailwind Config
For projects using Tailwind CSS v3/v4 — map Lerbb tokens into the theme config.
React Component Stubs
Copy-ready component shells. These expect the :root token block to be defined globally.
Button
Toast hook
Changelog
| Version | Date | Changes |
|---|---|---|
| v1.0 | May 2026 | Initial release. Full token system, core components, Lerbb-specific components, UX rules, content guide, React stubs, Tailwind config. |
Updating tokens: All design tokens live in the single :root { … } block. Bumping a token value propagates instantly across every component without touching component code. This is intentional — the design system is managed at the token layer.