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.

Status Dark Dark OKLCH Light Light 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.

Surface Dark Dark OKLCH Light Light OKLCH Usage
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)

Element Size Weight Margin
h1 1.5em 700 (Bold) 0.67em top/bottom
h2 1.3em 600 (Semibold) 0.83em
h3 1.17em 600 1em
h4 1em 600 1.33em
p inherit 400 0.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

Context Tailwind Value When 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

Element Radius Tailwind
Buttons (default) md rounded-md
Input fields md rounded-md
Cards xl rounded-xl
Dialogs lg rounded-lg
Badges / Pills full rounded-full
Images (generated) lg or xl rounded-lg
Main content inset 2xl (top-left only) border-top-left-radius: 16px
Radial menu buttons full rounded-full
Status dots full rounded-full
Tab list lg rounded-lg
Scrollbar thumb 4px Custom 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
Level Used For Shadow
0 Flat surfaces, inline elements none
1 (sm) Buttons, cards at rest, inputs 0 1px 2px oklch(0 0 0/0.15)
2 (md) Toasts, popovers, dropdowns 0 4px 12px oklch(0 0 0/0.15)
3 (lg) Image tiles on hover, dialogs 0 15px 40px -10px oklch(0 0 0/0.50)
4 (xl) Image tile active hover, fullscreen overlay Multi-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

Recipe Opacity Blur Border Used 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

Property Value Purpose
Curves 11 cubic Bézier paths Fan from edges, converge tightly at center
Gradient direction Vertical (top → bottom) Blue → Pink → Green
Stroke width 3px Thin enough to be texture, not distraction
Opacity ramp 0.11 → 1.00 Builds density toward center of fan
SVG opacity 0.3 (base) × 0.6 (img layer) Subtle background presence
Dark mode blend mix-blend-mode: lighten Waves glow against dark surface
Light mode blend mix-blend-mode: darken Waves deepen against light surface
Positioning background-size: cover Always 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.