Color

Our color system uses OKLCH — a perceptually uniform color space that ensures consistent lightness across hues. Colors are defined as CSS custom properties and mapped to Tailwind utility classes via shadcn's token layer.

Brand Palette

Three signature hues embody our duality. Green for Life, violet/pink for Virtual, and blue as the Bridge between them. These appear in our gradient title, wavy background, and accent moments.

Life
oklch(0.65 0.20 145)
Life Soft
oklch(0.80 0.12 145)
Life Muted
oklch(0.45 0.10 145)
Virtual
oklch(0.60 0.22 300)
Virtual Soft
oklch(0.75 0.14 300)
Virtual Muted
oklch(0.40 0.12 300)
Bridge
oklch(0.60 0.20 220)
Bridge Soft
oklch(0.75 0.12 220)
Accent Warm
oklch(0.70 0.19 340)
Gradient Signature. The brand gradient flows Blue → Pink → Green at 120°. It appears on the app title, the "Generate" button aura, and the wavy background SVG. This gradient is the single most recognizable visual element of VirtualLife AI Imagine.
Brand Gradient — 120° · Blue → Pink → Green

Semantic Tokens (Dark Mode)

Semantic tokens are the bridge between brand colors and component usage. They are defined as CSS custom properties and consumed through shadcn's Tailwind mapping. Every component references semantics, never raw values.

Token Preview OKLCH Value Tailwind Class Usage
--background oklch(0.21 0.04 266) bg-background App canvas, main content area
--foreground oklch(0.93 0.013 256) text-foreground Primary body text
--card oklch(0.28 0.04 260) bg-card Card surfaces (used at /10 opacity)
--primary oklch(0.68 0.158 277) bg-primary Primary buttons, active states, links
--secondary oklch(0.34 0.033 261) bg-secondary Secondary buttons, less prominent actions
--muted oklch(0.24 0.038 260) bg-muted Subdued backgrounds, disabled fields
--muted-foreground oklch(0.71 0.019 261) text-muted-foreground Secondary text, placeholders, captions
--accent oklch(0.37 0.031 260) bg-accent Hover highlights, sidebar active bg
--destructive oklch(0.64 0.208 25) bg-destructive Delete actions, error states
--border oklch(0.45 0.026 257) border-border Card edges, dividers, input borders
--ring oklch(0.68 0.158 277) ring-ring Focus rings on interactive elements
--sidebar oklch(0.21 0.04 266) bg-sidebar Navigation sidebar, title bar, status bar

Semantic Tokens (Light Mode)

Light mode tokens are applied via the html.light class. They maintain the same semantic names but shift values for readability on light backgrounds. Primary colors become darker; surfaces become lighter.

Token Preview OKLCH Value Tailwind Class Usage
--background oklch(0.97 0.005 265) bg-background App canvas, main content area
--foreground oklch(0.18 0.04 265) text-foreground Primary body text
--card oklch(0.95 0.005 265) bg-card Card surfaces
--primary oklch(0.52 0.20 277) bg-primary Primary buttons, active states, links
--secondary oklch(0.90 0.010 260) bg-secondary Secondary buttons, less prominent actions
--muted oklch(0.94 0.008 260) bg-muted Subdued backgrounds, disabled fields
--muted-foreground oklch(0.40 0.04 257) text-muted-foreground Secondary text, placeholders, captions
--accent oklch(0.92 0.008 260) bg-accent Hover highlights, sidebar active bg
--destructive oklch(0.55 0.22 25) bg-destructive Delete actions, error states
--border oklch(0.78 0.015 257) border-border Card edges, dividers, input borders
--ring oklch(0.52 0.20 277) ring-ring Focus rings on interactive elements
--sidebar oklch(0.94 0.018 272) bg-sidebar Navigation sidebar, title bar, status bar

Status Colors

Status colors are consistent across modes — they're designed to be accessible on both dark and light backgrounds. In light mode, darker variants (--success, --warning) are used for better contrast against white surfaces.

StatusDarkDark OKLCHLightLight OKLCH
Success oklch(0.723 0.219 150) oklch(0.45 0.18 150)
Error oklch(0.64 0.208 25) oklch(0.55 0.22 25)
Warning oklch(0.828 0.189 84) oklch(0.65 0.18 84)
Info oklch(0.68 0.158 277) oklch(0.52 0.20 277)

Surface Scale

Surfaces layer from darkest (canvas) to lightest (elevated card) in dark mode, and from lightest to elevated in light mode. Each step is subtle — about 7% lightness change — creating depth without hard edges.

SurfaceDarkDark OKLCHLightLight OKLCHUsage
Surface 0 oklch(0.13 0.04 265) oklch(0.97 0.005 265) Canvas
Surface 1 oklch(0.21 0.04 266) oklch(0.94 0.018 272) Background / Sidebar
Surface 2 oklch(0.28 0.04 260) oklch(0.90 0.010 260) Card
Surface 3 oklch(0.34 0.03 261) oklch(0.86 0.012 261) Elevated

Typography

Our type system uses TT Rounds Neue — a geometric rounded sans-serif by TypeType Foundry — as the primary typeface. It pairs with a monospaced face for technical precision and a serif for rare prose moments. The system supports theme-level font overrides.

Primary · Sans-Serif
The quick brown fox jumps over the lazy dog
ABCDEFGHIJKLMNOPQRSTUVWXYZ · abcdefghijklmnopqrstuvwxyz · 0123456789
Light 300 Regular 400 Medium 500 Semibold 600 Bold 700 ExtraBold 800
TT Rounds Neue is the primary typeface. It's a geometric rounded sans-serif with a warm, friendly character that matches VirtualLife's personality — playful yet professional. Variable font loaded locally (100–900 weight axis). Fallback chain: Plus Jakarta Sans → system-ui → sans-serif.

Licensing: TT Rounds Neue is free for personal/trial use. Commercial deployment requires a license from TypeType Foundry.
Theme overrides. Each theme can specify its own font stack. Solar Dusk uses Oxanium (a futuristic geometric face). Caffeine uses the system UI stack. The DLS tokens remain the same — only the values change per theme. The CSS variable --font-sans is the single source of truth. The default VirtualLife theme uses TT Rounds Neue; other themes fall back to Plus Jakarta Sans.
Monospace
const imagine = (prompt) => ai.generate(prompt);
ABCDEFGHIJKLMNOPQRSTUVWXYZ · abcdefghijklmnopqrstuvwxyz · 0123456789 · {} [] () <> = + - * / | \ _ @ # $ %
JetBrains Mono is used for code snippets, technical values, token names, and the version number badge. Fallback: Cascadia Code → Fira Code → ui-monospace → monospace.
Serif (Display / Prose)
Where human creativity meets artificial imagination
ABCDEFGHIJKLMNOPQRSTUVWXYZ · abcdefghijklmnopqrstuvwxyz · 0123456789
Source Serif 4 is reserved for long-form prose content and special display moments. It is rarely used in the app UI but available for rich content areas. Fallback: Georgia → Times New Roman → serif.

Type Scale

Base size is 0.825rem (~13.2px) — slightly smaller than the browser default to increase information density without sacrificing readability. The scale uses --text-scaling for user preferences and Tailwind's built-in classes.

Page Title
text-lg · 600 · tight
Generate Images
Section Title
text-base · 600
Model Settings
Body
text-sm · 400
Enter a detailed description of the image you want to create.
Caption
text-xs · 400 · muted
Generated 2 minutes ago · Flux1.dev
Label
text-sm · 500
Prompt
Badge / Pill
text-xs · 600
READY
Token / Code
mono · text-xs
--primary: oklch(0.68 0.16 277)

Prose Headings (Rich Content)

ElementSizeWeightMargin
h11.5em700 (Bold)0.67em top/bottom
h21.3em600 (Semibold)0.83em
h31.17em6001em
h41em6001.33em
pinherit4000.5em

Spacing

Spacing follows Tailwind's 4px base grid. We favor a constrained set of values for consistency: the 4-8-12-16-24-32-48 scale handles virtually all layout needs.

1 · 4px
0.25rem
2 · 8px
0.5rem
3 · 12px
0.75rem
4 · 16px
1rem
6 · 24px
1.5rem
8 · 32px
2rem
12 · 48px
3rem

Spacing Usage Guidelines

ContextTailwindValueWhen to Use
Inline element gap gap-2 8px Icon + text, badge contents, tight groups
Form field gap gap-2 8px Label to input, switch to label
Card internal padding p-4 16px Standard card content padding
Section vertical gap gap-4 16px Between cards, between form groups
Page padding px-4 pt-4 16px Section wrapper padding
Grid image gap gap-4 16px Gallery grid, catalog grid
Dialog padding p-6 24px Modal dialogs and popovers
Toolbar compact px-3 py-1 12px × 4px Status bar, compact toolbar rows
Consistency rule: Within a single container, use one gap value. Mixed spacing inside the same flex/grid creates visual noise. The 4px grid ensures everything aligns, even when nested.

Border Radius

Rounded corners are fundamental to VirtualLife's soft, approachable feel. The base radius (--radius: 0.625rem) ripples through the system via calc() expressions. Themes can override the base to shift the entire system's roundness.

sm
0.375rem · 6px
md
0.5rem · 8px
lg (base)
0.625rem · 10px
xl
0.875rem · 14px
2xl
1rem · 16px
full
9999px · pill

Radius Assignment

ElementRadiusTailwind
Buttons (default)mdrounded-md
Input fieldsmdrounded-md
Cardsxlrounded-xl
Dialogslgrounded-lg
Badges / Pillsfullrounded-full
Images (generated)lg or xlrounded-lg
Main content inset2xl (top-left only)border-top-left-radius: 16px
Radial menu buttonsfullrounded-full
Status dotsfullrounded-full
Tab listlgrounded-lg
Scrollbar thumb4pxCustom CSS

Elevation

Elevation is communicated through shadow depth and backdrop blur. In dark mode, shadows are more subtle and surface lightness shifts do most of the layering work. The glass effect replaces heavy drop shadows for most surfaces.

Level 0
No shadow
Level 1
shadow-sm
Level 2
shadow-md
Level 3
shadow-lg
Level 4
shadow-xl
LevelUsed ForShadow
0Flat surfaces, inline elementsnone
1 (sm)Buttons, cards at rest, inputs0 1px 2px oklch(0 0 0/0.15)
2 (md)Toasts, popovers, dropdowns0 4px 12px oklch(0 0 0/0.15)
3 (lg)Image tiles on hover, dialogs0 15px 40px -10px oklch(0 0 0/0.50)
4 (xl)Image tile active hover, fullscreen overlayMulti-layer composite

Glass & Transparency

Glass morphism is VirtualLife's signature surface treatment. Translucent backgrounds combined with backdrop blur create depth and visual interest while letting the wavy background pattern breathe through the interface.

Glass Light

The standard card surface. Most of the background shows through, with just enough blur to maintain text legibility.

bg-card/10 backdrop-blur-sm
Glass Medium

For interactive panels, filter bars, overlays on images. More opacity means more contrast for denser content.

bg-card/40 backdrop-blur-md
Glass Heavy

For sticky headers, group labels, badges on images. Nearly opaque but still part of the glass family.

bg-card/80 backdrop-blur-sm

Glass Recipes

RecipeOpacityBlurBorderUsed For
Glass Light bg-card/10 backdrop-blur-sm border-border/50 Standard cards (VLCard)
Glass Medium bg-card/40 backdrop-blur-md border-border Image overlays, filter panels, edit panels
Glass Heavy bg-card/80 backdrop-blur-sm border-border/50 Sticky headers, group labels
Glass Scrim bg-black/50 none none Image status overlays (loading/error)
Glass Overlay bg-black/80 none none Dialog backdrop, fullscreen overlay
Performance note: backdrop-filter: blur() is GPU-accelerated in Chromium (Electron's renderer) but can cause compositing overhead on dense grids. Use backdrop-blur-sm (4px blur) as the default; reserve backdrop-blur-md (12px blur) for surfaces that overlay rich content like images.

Wavy Background

The wave pattern is VirtualLife's most distinctive visual element. It represents the flowing connection between human and AI creativity — organic curves rendered with digital precision.

Anatomy

PropertyValuePurpose
Curves11 cubic Bézier pathsFan from edges, converge tightly at center
Gradient directionVertical (top → bottom)Blue → Pink → Green
Stroke width3pxThin enough to be texture, not distraction
Opacity ramp0.11 → 1.00Builds density toward center of fan
SVG opacity0.3 (base) × 0.6 (img layer)Subtle background presence
Dark mode blendmix-blend-mode: lightenWaves glow against dark surface
Light mode blendmix-blend-mode: darkenWaves deepen against light surface
Positioningbackground-size: coverAlways fills the content area fully
Design intent: The waves should always be perceived as ambient texture — felt more than seen. If they compete with content for attention, the opacity is too high. Glass card surfaces float above the waves, and the blur softens them further beneath interactive elements.

Theming

VirtualLife supports swappable themes that override the semantic token layer without changing component structure. Each theme is a JSON file with light/dark CSS variable overrides plus optional font and radius changes.

Theme Architecture

// theme.json structure
{
  "name": "Clean Slate",
  "cssVars": {
    "theme": { // Shared (fonts, radius)
      "--font-sans": "TT Rounds Neue, sans-serif",
      "--radius": "0.5rem"
    },
    "light": { // Light mode overrides
      "--background": "oklch(0.98 0.003 248)",
      "--primary": "oklch(0.59 0.204 277)"
    },
    "dark": { // Dark mode overrides
      "--background": "oklch(0.21 0.04 266)",
      "--primary": "oklch(0.68 0.158 277)"
    }
  }
}

Available Themes

Clean Slate
Default · TT Rounds Neue
Northern Lights
Aurora · Plus Jakarta Sans
Solar Dusk
Warm · Oxanium
Caffeine
Monochrome · System UI
Modern Minimal
Cool · Inter
Amber Minimal
Warm · Inter
Theme rules: Themes change values, never structure. A theme must provide all semantic tokens for both light and dark modes. Components never reference theme-specific values directly — they only consume semantic tokens like bg-primary. This guarantees every theme works with every component.

Light & Dark Mode

Dark mode is the primary design surface — optimized for immersive creative work where generated images pop against deep backgrounds. Light mode is a first-class alternative, not an afterthought. The .dark class on <html> toggles the active variable set. Each theme provides both dictionaries.