Welcome to Vanilla Breeze
This bell pulls live notifications from /go/notify/messages — the same contract documented at /docs/concepts/service-contracts/. Static articles like this one are the no-JS / no-backend fallback.
This bell pulls live notifications from /go/notify/messages — the same contract documented at /docs/concepts/service-contracts/. Static articles like this one are the no-JS / no-backend fallback.
A minimal set of design tokens for new projects. Copy this file as your foundation and customize the values to match your brand.
Design tokens are CSS custom properties that define your visual design language. This starter includes everything you need for a consistent design system:
See the tokens in action with color swatches, spacing samples, and typography examples.
Copy this CSS to your project's tokens.css file.
/** * Vanilla Breeze Starter Tokens * * A minimal set of custom properties for new pages. * Import this or copy the relevant tokens to your project. */ :root { /* Enable automatic light/dark switching */ color-scheme: light dark; /* ==================== SIZE SCALE ==================== */ --size-unit: 0.25rem; --size-3xs: calc(var(--size-unit) * 0.5); /* 2px */ --size-2xs: calc(var(--size-unit) * 1); /* 4px */ --size-xs: calc(var(--size-unit) * 2); /* 8px */ --size-s: calc(var(--size-unit) * 3); /* 12px */ --size-m: calc(var(--size-unit) * 4); /* 16px */ --size-l: calc(var(--size-unit) * 6); /* 24px */ --size-xl: calc(var(--size-unit) * 8); /* 32px */ --size-2xl: calc(var(--size-unit) * 12); /* 48px */ --size-3xl: calc(var(--size-unit) * 16); /* 64px */ /* ==================== COLORS ==================== */ /* Grays (achromatic) */ --color-gray-50: oklch(98% 0 0); --color-gray-100: oklch(96% 0 0); --color-gray-200: oklch(90% 0 0); --color-gray-300: oklch(80% 0 0); --color-gray-400: oklch(70% 0 0); --color-gray-500: oklch(55% 0 0); --color-gray-600: oklch(45% 0 0); --color-gray-700: oklch(35% 0 0); --color-gray-800: oklch(25% 0 0); --color-gray-900: oklch(15% 0 0); --color-gray-950: oklch(10% 0 0); --color-white: oklch(100% 0 0); --color-black: oklch(0% 0 0); /* Brand hues - override these for custom themes */ --hue-primary: 260; --hue-secondary: 200; --hue-accent: 30; /* Primary color */ --color-primary: oklch(50% 0.2 var(--hue-primary)); --color-primary-hover: oklch(from var(--color-primary) calc(l - 0.08) calc(c + 0.02) h); /* Semantic colors (auto light/dark) */ --color-background: light-dark(var(--color-white), var(--color-gray-950)); --color-surface: light-dark(var(--color-white), var(--color-gray-900)); --color-surface-raised: light-dark(var(--color-gray-50), var(--color-gray-800)); --color-text: light-dark(var(--color-gray-900), var(--color-gray-100)); --color-text-muted: light-dark(var(--color-gray-600), var(--color-gray-400)); --color-border: light-dark(var(--color-gray-200), var(--color-gray-700)); /* Status colors */ --color-success: oklch(55% 0.2 145); --color-warning: oklch(70% 0.18 70); --color-error: oklch(55% 0.22 25); --color-info: oklch(55% 0.15 240); /* ==================== TYPOGRAPHY ==================== */ --font-sans: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; --font-serif: Charter, "Bitstream Charter", Cambria, serif; --font-mono: ui-monospace, "Cascadia Code", "Source Code Pro", Menlo, monospace; --font-size-xs: 0.75rem; --font-size-sm: 0.875rem; --font-size-md: 1rem; --font-size-lg: 1.125rem; --font-size-xl: 1.25rem; --font-size-2xl: 1.5rem; --font-size-3xl: 1.875rem; --line-height-tight: 1.25; --line-height-normal: 1.5; --line-height-relaxed: 1.625; /* Reading measure */ --measure-narrow: 45ch; --measure-normal: 65ch; --measure-wide: 80ch; /* ==================== BORDERS ==================== */ --border-width-thin: 1px; --border-width-medium: 2px; --radius-s: 0.25rem; --radius-m: 0.5rem; --radius-l: 0.75rem; --radius-full: 9999px; /* ==================== SHADOWS ==================== */ --shadow-sm: 0 1px 2px oklch(0% 0 0 / 0.05); --shadow-md: 0 4px 6px oklch(0% 0 0 / 0.1); --shadow-lg: 0 10px 15px oklch(0% 0 0 / 0.15); /* ==================== MOTION ==================== */ --duration-fast: 150ms; --duration-normal: 250ms; --duration-slow: 400ms; --ease-out: cubic-bezier(0, 0, 0.2, 1); --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);}
The size scale uses a base unit of 0.25rem (4px at default font size) with named stops from 3xs to 3xl. Use these for all spacing, gaps, and sizing:
.card { padding: var(--size-m); /* 16px */ gap: var(--size-s); /* 12px */ margin-block: var(--size-l); /* 24px */}
Colors use the OKLCH color space for perceptually uniform values. The light-dark() function automatically switches between light and dark mode values based on color-scheme:
.card { background: var(--color-surface); color: var(--color-text); border: 1px solid var(--color-border);} .button-primary { background: var(--color-primary);} .alert-error { background: var(--color-error);}
Three font stacks are provided: sans-serif for UI, serif for content, and monospace for code. Combine with size and line-height tokens:
.prose { font-family: var(--font-serif); font-size: var(--font-size-lg); line-height: var(--line-height-relaxed); max-width: var(--measure-normal);} code { font-family: var(--font-mono); font-size: var(--font-size-sm);}
Use border-radius tokens for consistent rounding and shadow tokens for elevation:
.card { border-radius: var(--radius-m); box-shadow: var(--shadow-md);} .button { border-radius: var(--radius-s);} .avatar { border-radius: var(--radius-full);}
Duration and easing tokens ensure consistent animation timing:
.button { transition: background-color var(--duration-fast) var(--ease-out);} .modal { transition: opacity var(--duration-normal) var(--ease-in-out);}
To customize for your brand, override the hue variables:
:root { /* Change brand colors by adjusting hue values */ --hue-primary: 220; /* Blue instead of purple */ --hue-secondary: 150; /* Teal */ --hue-accent: 45; /* Gold */}
For more extensive customization, override the specific color tokens directly.
Full documentation of all design tokens
CSS @layer configuration for cascade control
Theme switching with data-mode attribute