Skip to contentVibraUI
Palette

Graphite theme

Cool graphite greys with a low-chroma blue. Built for the dark mode, with a slate light mode beside it.

background
card
primary
chart-2
success
danger

Install

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

npx shadcn@latest add @vibra/theme-graphite

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

The stylesheet

app/vibra-graphite.css
/* Graphite — the default's cool hue-260 ladder, kept whole, with a low-chroma
 * blue where the default puts the ink.
 *
 * Same neutrals, same steps, same chart palette as vibra.css; the one change
 * is the accent, so a page picking this preset gets one colour in six roles
 * rather than a near-ink fill. Every line weight is an opaque token rather
 * than a white alpha (a white/10% hairline composites to 1.32:1 on a dark
 * card, and a white/14% field boundary to 1.53:1, under WCAG 1.4.11's 3:1),
 * and the dark popover sits a step above the card.
 *
 * Both scopes carry every token vibra.css defines, so `data-preset="graphite"`
 * repaints a page completely — on <html> or on any wrapper, which is what the
 * second scope's three selectors are for (a .dark ancestor, .dark on the
 * element itself, a .dark subtree beneath it).
 */
[data-preset="graphite"] {
  --radius: 0.5rem;
  --background: oklch(0.99 0.002 260);
  --surface: oklch(0.97 0.003 260);
  --card: oklch(1 0 0);
  --popover: oklch(1 0 0);
  --muted: oklch(0.96 0.004 260);
  --secondary: oklch(0.955 0.005 260);
  --accent: oklch(0.955 0.005 260);
  --foreground: oklch(0.17 0.012 260);
  --card-foreground: oklch(0.17 0.012 260);
  --popover-foreground: oklch(0.17 0.012 260);
  --muted-foreground: oklch(0.5 0.014 260);
  --faint-foreground: oklch(0.51 0.014 260);
  --secondary-foreground: oklch(0.21 0.014 260);
  --accent-foreground: oklch(0.21 0.014 260);
  --brand: oklch(0.45 0.09 260);
  --brand-foreground: oklch(0.985 0.002 260);
  --brand-muted: oklch(0.935 0.028 260);
  --primary: var(--brand);
  --primary-foreground: var(--brand-foreground);
  --ring: var(--brand);
  --border: oklch(0.9 0.006 260);
  --rule: oklch(0.79 0.01 260);
  --input: oklch(0.64 0.012 260);
  --chart-grid: oklch(0.9 0.005 260);
  --success: oklch(0.52 0.14 150);
  --success-foreground: oklch(0.99 0 0);
  --success-muted: oklch(0.95 0.04 150);
  --warning: oklch(0.54 0.11 75);
  --warning-foreground: oklch(0.99 0 0);
  --warning-muted: oklch(0.96 0.05 85);
  --danger: oklch(0.52 0.22 25);
  --danger-foreground: oklch(0.99 0 0);
  --danger-muted: oklch(0.95 0.03 25);
  --info: oklch(0.53 0.15 250);
  --info-foreground: oklch(0.99 0 0);
  --info-muted: oklch(0.95 0.03 250);
  --destructive: var(--danger);
  --chart-1: var(--brand);
  --chart-2: oklch(0.62 0.14 190);
  --chart-3: oklch(0.64 0.16 75);
  --chart-4: oklch(0.62 0.2 15);
  --chart-5: oklch(0.58 0.2 300);
  --chart-6: oklch(0.62 0.15 145);
  --chart-7: oklch(0.66 0.2 40);
  --chart-8: oklch(0.55 0.11 260);
  --chart-positive: var(--success);
  --chart-negative: var(--danger);
  --chart-neutral: var(--muted-foreground);
  --chart-axis: var(--muted-foreground);
  --sidebar: oklch(0.975 0.003 260);
  --sidebar-foreground: oklch(0.17 0.012 260);
  --sidebar-primary: var(--brand);
  --sidebar-primary-foreground: var(--brand-foreground);
  --sidebar-accent: oklch(0.94 0.005 260);
  --sidebar-accent-foreground: oklch(0.21 0.014 260);
  --sidebar-border: oklch(0.91 0.006 260);
  --sidebar-ring: var(--brand);
  --shadow-sheet: 0 1px 2px oklch(0.2 0.03 260 / 6%), 0 2px 6px -2px oklch(0.2 0.03 260 / 5%);
  --shadow-float: 0 8px 24px -8px oklch(0.2 0.03 260 / 22%), 0 1px 2px oklch(0.2 0.03 260 / 8%);
  --shadow-modal: 0 24px 48px -16px oklch(0.2 0.03 260 / 30%);
  --overlay: oklch(0.2 0.03 260 / 24%);
}

.dark [data-preset="graphite"],
[data-preset="graphite"].dark,
[data-preset="graphite"] .dark {
  --background: oklch(0.15 0.01 260);
  --surface: oklch(0.17 0.01 260);
  --card: oklch(0.2 0.01 260);
  --popover: oklch(0.235 0.01 260);
  --muted: oklch(0.26 0.01 260);
  --secondary: oklch(0.26 0.01 260);
  --accent: oklch(0.26 0.01 260);
  --foreground: oklch(0.96 0.004 260);
  --card-foreground: oklch(0.96 0.004 260);
  --popover-foreground: oklch(0.96 0.004 260);
  --muted-foreground: oklch(0.68 0.012 260);
  --faint-foreground: oklch(0.69 0.012 260);
  --secondary-foreground: oklch(0.96 0.004 260);
  --accent-foreground: oklch(0.96 0.004 260);
  --brand: oklch(0.78 0.08 260);
  --brand-foreground: oklch(0.18 0.02 260);
  --brand-muted: oklch(0.27 0.035 260);
  --primary: var(--brand);
  --primary-foreground: var(--brand-foreground);
  --ring: var(--brand);
  --border: oklch(0.31 0.01 260);
  --rule: oklch(0.4 0.012 260);
  --input: oklch(0.55 0.01 260);
  --chart-grid: oklch(0.32 0.01 260);
  --success: oklch(0.72 0.17 150);
  --success-foreground: oklch(0.15 0.03 150);
  --success-muted: oklch(0.3 0.04 152);
  --warning: oklch(0.82 0.16 80);
  --warning-foreground: oklch(0.2 0.05 80);
  --warning-muted: oklch(0.31 0.04 82);
  --danger: oklch(0.78 0.14 27);
  --danger-foreground: oklch(0.15 0.03 25);
  --danger-muted: oklch(0.295 0.035 27);
  --info: oklch(0.7 0.15 250);
  --info-foreground: oklch(0.15 0.03 250);
  --info-muted: oklch(0.3 0.04 250);
  --destructive: var(--danger);
  --chart-1: var(--brand);
  --chart-2: oklch(0.64 0.13 190);
  --chart-3: oklch(0.66 0.15 80);
  --chart-4: oklch(0.62 0.18 15);
  --chart-5: oklch(0.6 0.18 300);
  --chart-6: oklch(0.59 0.12 145);
  --chart-7: oklch(0.62 0.18 45);
  --chart-8: oklch(0.55 0.11 260);
  --chart-positive: var(--success);
  --chart-negative: var(--danger);
  --chart-neutral: var(--muted-foreground);
  --chart-axis: var(--muted-foreground);
  --sidebar: oklch(0.17 0.01 260);
  --sidebar-foreground: oklch(0.96 0.004 260);
  --sidebar-primary: var(--brand);
  --sidebar-primary-foreground: var(--brand-foreground);
  --sidebar-accent: oklch(0.24 0.01 260);
  --sidebar-accent-foreground: oklch(0.96 0.004 260);
  --sidebar-border: oklch(1 0 0 / 10%);
  --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%);
}