Skip to contentVibraUI
Palette

Paper theme

Warm off-white, ink text and an ochre accent. Built for the light mode; after dark the neutrals stay warm charcoal.

background
card
primary
chart-2
success
danger

Install

The file lands as app/vibra-paper.css. Import it after your globals and set data-preset="paper" on <html>, or on any wrapper.

npx shadcn@latest add @vibra/theme-paper

Needs the @vibra registry in your components.json — set it up once.

The stylesheet

app/vibra-paper.css
/* Paper — the warm ground with an ochre accent.
 *
 * The warm paper ladder is the default palette now, so what makes this preset
 * itself is the accent: a deep ochre in place of the iris, deep enough to be
 * text (`text-brand` is a link, a badge and a selected chip's label) rather
 * than the mustard that reads as mustard and measures 2.1:1 on paper. The
 * mustard lives on in the chart palette, and the iris takes the chart slot the
 * ochre vacated so no two series land on one hue.
 *
 * Both scopes carry every token vibra.css defines, so `data-preset="paper"`
 * repaints a page completely — on <html> or on any wrapper, which is what the
 * second scope's three selectors are for.
 */
[data-preset="paper"] {
  --radius: 0.625rem;
  --background: oklch(0.962 0.008 80);
  --surface: oklch(0.978 0.006 82);
  --card: oklch(0.995 0.003 85);
  --popover: oklch(1 0 0);
  --muted: oklch(0.955 0.007 80);
  --secondary: oklch(0.945 0.008 80);
  --accent: oklch(0.945 0.008 80);
  --foreground: oklch(0.22 0.018 55);
  --card-foreground: var(--foreground);
  --popover-foreground: var(--foreground);
  --muted-foreground: oklch(0.47 0.02 65);
  --faint-foreground: oklch(0.505 0.018 65);
  --secondary-foreground: var(--foreground);
  --accent-foreground: var(--foreground);
  --brand: oklch(0.46 0.11 72);
  --brand-foreground: oklch(0.985 0.004 85);
  --brand-muted: oklch(0.93 0.045 82);
  --primary: var(--brand);
  --primary-foreground: var(--brand-foreground);
  --ring: var(--brand);
  --border: oklch(0.885 0.012 78);
  --rule: oklch(0.78 0.015 72);
  --input: oklch(0.64 0.015 72);
  --chart-grid: oklch(0.9 0.008 80);
  --success: oklch(0.48 0.13 150);
  --success-foreground: oklch(0.99 0.003 85);
  --success-muted: oklch(0.94 0.045 150);
  --warning: oklch(0.5 0.1 75);
  --warning-foreground: oklch(0.99 0.003 85);
  --warning-muted: oklch(0.95 0.04 85);
  --danger: oklch(0.52 0.21 25);
  --danger-foreground: oklch(0.99 0.003 85);
  --danger-muted: oklch(0.945 0.025 25);
  --info: oklch(0.5 0.13 250);
  --info-foreground: oklch(0.99 0.003 85);
  --info-muted: oklch(0.945 0.025 250);
  --destructive: var(--danger);
  --chart-1: var(--brand);
  --chart-2: oklch(0.52 0.09 200);
  --chart-3: oklch(0.52 0.12 340);
  --chart-4: oklch(0.4 0.015 60);
  --chart-5: oklch(0.46 0.13 290);
  --chart-6: oklch(0.55 0.09 150);
  --chart-7: oklch(0.56 0.16 30);
  --chart-8: oklch(0.6 0.02 75);
  --chart-positive: var(--success);
  --chart-negative: var(--danger);
  --chart-neutral: var(--muted-foreground);
  --chart-axis: var(--muted-foreground);
  --sidebar: var(--background);
  --sidebar-foreground: var(--foreground);
  --sidebar-primary: var(--brand);
  --sidebar-primary-foreground: var(--brand-foreground);
  --sidebar-accent: oklch(0.925 0.01 80);
  --sidebar-accent-foreground: var(--foreground);
  --sidebar-border: var(--border);
  --sidebar-ring: var(--brand);
  --shadow-sheet: 0 1px 2px oklch(0.25 0.03 60 / 6%), 0 2px 6px -2px oklch(0.25 0.03 60 / 5%);
  --shadow-float: 0 8px 24px -8px oklch(0.25 0.03 60 / 22%), 0 1px 2px oklch(0.25 0.03 60 / 8%);
  --shadow-modal: 0 24px 48px -16px oklch(0.25 0.03 60 / 30%);
  --overlay: oklch(0.25 0.03 60 / 24%);
}

.dark [data-preset="paper"],
[data-preset="paper"].dark,
[data-preset="paper"] .dark {
  --background: oklch(0.165 0.01 60);
  --surface: oklch(0.19 0.01 60);
  --card: oklch(0.225 0.011 62);
  --popover: oklch(0.27 0.011 62);
  --muted: oklch(0.26 0.011 62);
  --secondary: oklch(0.285 0.012 62);
  --accent: oklch(0.285 0.012 62);
  --foreground: oklch(0.95 0.008 80);
  --card-foreground: var(--foreground);
  --popover-foreground: var(--foreground);
  --muted-foreground: oklch(0.7 0.012 70);
  --faint-foreground: oklch(0.695 0.012 70);
  --secondary-foreground: var(--foreground);
  --accent-foreground: var(--foreground);
  --brand: oklch(0.8 0.12 82);
  --brand-foreground: oklch(0.19 0.03 70);
  --brand-muted: oklch(0.28 0.04 82);
  --primary: var(--brand);
  --primary-foreground: var(--brand-foreground);
  --ring: var(--brand);
  --border: oklch(0.315 0.012 62);
  --rule: oklch(0.4 0.014 65);
  --input: oklch(0.55 0.012 62);
  --chart-grid: oklch(0.335 0.012 62);
  --success: oklch(0.8 0.15 150);
  --success-foreground: oklch(0.16 0.03 150);
  --success-muted: oklch(0.3 0.04 150);
  --warning: oklch(0.84 0.14 85);
  --warning-foreground: oklch(0.16 0.03 85);
  --warning-muted: oklch(0.31 0.04 85);
  --danger: oklch(0.78 0.12 25);
  --danger-foreground: oklch(0.16 0.03 25);
  --danger-muted: oklch(0.31 0.035 25);
  --info: oklch(0.79 0.1 250);
  --info-foreground: oklch(0.16 0.03 250);
  --info-muted: oklch(0.3 0.04 250);
  --destructive: var(--danger);
  --chart-1: var(--brand);
  --chart-2: oklch(0.76 0.09 200);
  --chart-3: oklch(0.76 0.1 340);
  --chart-4: oklch(0.82 0.012 75);
  --chart-5: oklch(0.78 0.11 290);
  --chart-6: oklch(0.76 0.1 150);
  --chart-7: oklch(0.74 0.14 30);
  --chart-8: oklch(0.57 0.015 70);
  --chart-positive: var(--success);
  --chart-negative: var(--danger);
  --chart-neutral: var(--muted-foreground);
  --chart-axis: var(--muted-foreground);
  --sidebar: var(--background);
  --sidebar-foreground: var(--foreground);
  --sidebar-primary: var(--brand);
  --sidebar-primary-foreground: var(--brand-foreground);
  --sidebar-accent: oklch(0.245 0.012 62);
  --sidebar-accent-foreground: var(--foreground);
  --sidebar-border: var(--border);
  --sidebar-ring: var(--brand);
  --shadow-sheet: inset 0 1px 0 oklch(1 0 0 / 5%);
  --shadow-float: 0 12px 32px -8px oklch(0 0 0 / 60%), inset 0 1px 0 oklch(1 0 0 / 6%);
  --shadow-modal: 0 24px 64px -12px oklch(0 0 0 / 70%);
  --overlay: oklch(0 0 0 / 60%);
}