Upset for shadcn/ui

Upset is a shadcn/ui theme built around a green primary color (#56a022) with muted light green accents (#dbe0d7). The light mode uses a neutral background (#f9fdf7). Dark mode keeps the green primary (#56a022) on a neutral background (#050802).

Color palette

TokenLightDark
Background
#f9fdf7mintcream
#050802black
Foreground
#070c03black
#f7f9f6whitesmoke
Card
#f7fcf3whitesmoke
#070c04black
Card foreground
#050802black
#fafbf9snow
Popover
#f9fdf7mintcream
#050802black
Popover foreground
#070c03black
#f7f9f6whitesmoke
Primary
#56a022olivedrab
#56a022olivedrab
Primary foreground
#ffffffwhite
#ffffffwhite
Secondary
#dbe0d7gainsboro
#252d20darkslategray
Secondary foreground
#414b3adarkslategray
#bdcab4silver
Muted
#dbdfd7gainsboro
#232820black
Muted foreground
#55644adarkolivegreen
#a6b59bdarkgray
Accent
#dbe0d7gainsboro
#252d20darkslategray
Accent foreground
#414b3adarkslategray
#bdcab4silver
Destructive
#9c2611brown
#e13719orangered
Destructive foreground
#fce7e3mistyrose
#ffffffwhite
Border
#e5e7eblavender
#1f2937darkslategray
Input
#e5e7eblavender
#1f2937darkslategray
Ring
#56a022olivedrab
#56a022olivedrab

Contrast

WCAG 2 contrast ratios between each background and its foreground color.

Light mode
Text on background19.23:1AAA
Text on card19.35:1AAA
Primary button3.25:1AA Large
Secondary button6.81:1AA
Muted text4.70:1AA
Accent6.81:1AA
Destructive6.54:1AA
Dark mode
Text on background19.05:1AAA
Text on card19.06:1AAA
Primary button3.25:1AA Large
Secondary button8.33:1AAA
Muted text6.97:1AA
Accent8.33:1AAA
Destructive4.41:1AA Large

CSS variables

Paste this into your globals.css to use Upset in your shadcn/ui project.

:root {
  --radius: 0.5rem;
  --background: oklch(0.99 0.009 131.801);
  --foreground: oklch(0.146 0.025 130.439);
  --muted: oklch(0.899 0.012 131.83);
  --muted-foreground: oklch(0.482 0.044 132.529);
  --popover: oklch(0.99 0.009 131.801);
  --popover-foreground: oklch(0.146 0.025 130.439);
  --card: oklch(0.985 0.014 131.841);
  --card-foreground: oklch(0.127 0.022 130.212);
  --border: oklch(0.928 0.006 264.531);
  --input: oklch(0.928 0.006 264.531);
  --primary: oklch(0.633 0.172 135.606);
  --primary-foreground: oklch(1 0 180);
  --secondary: oklch(0.9 0.014 131.85);
  --secondary-foreground: oklch(0.398 0.031 132.393);
  --accent: oklch(0.9 0.014 131.85);
  --accent-foreground: oklch(0.398 0.031 132.393);
  --destructive: oklch(0.458 0.157 32.292);
  --destructive-foreground: oklch(0.944 0.023 29.571);
  --ring: oklch(0.633 0.172 135.606);
  --chart-1: oklch(0.633 0.172 135.606);
  --chart-2: oklch(0.9 0.014 131.85);
  --chart-3: oklch(0.9 0.014 131.85);
  --chart-4: oklch(0.921 0.011 131.82);
  --chart-5: oklch(0.641 0.177 135.81);
}

.dark {
  --radius: 0.5rem;
  --background: oklch(0.125 0.019 130.416);
  --foreground: oklch(0.98 0.005 131.763);
  --muted: oklch(0.268 0.016 132.217);
  --muted-foreground: oklch(0.755 0.04 132.17);
  --popover: oklch(0.125 0.019 130.416);
  --popover-foreground: oklch(0.98 0.005 131.763);
  --card: oklch(0.144 0.022 130.547);
  --card-foreground: oklch(0.986 0.003 131.75);
  --border: oklch(0.278 0.03 256.848);
  --input: oklch(0.278 0.03 256.848);
  --primary: oklch(0.633 0.172 135.606);
  --primary-foreground: oklch(1 0 180);
  --secondary: oklch(0.284 0.025 132.5);
  --secondary-foreground: oklch(0.824 0.033 132.055);
  --accent: oklch(0.284 0.025 132.5);
  --accent-foreground: oklch(0.824 0.033 132.055);
  --destructive: oklch(0.597 0.21 32.195);
  --destructive-foreground: oklch(1 0 180);
  --ring: oklch(0.633 0.172 135.606);
  --chart-1: oklch(0.633 0.172 135.606);
  --chart-2: oklch(0.284 0.025 132.5);
  --chart-3: oklch(0.284 0.025 132.5);
  --chart-4: oklch(0.318 0.03 132.536);
  --chart-5: oklch(0.641 0.177 135.81);
}