All designs

Supabase

Postgres platform. Dark developer canvas with a single jade-green accent.

extracted from https://supabase.com/ on 2026-07-03

Supabase | The Open Source Firebase Alternative

light-leaning · 3 stylesheets · 120 native variables

fonts Inter · Source Code Pro · Manrope · Ubuntu · Courier New · Office Code Pro · Manrope Fallback · Inter Fallback
---
name: supabase-com-design-system
source: https://supabase.com/
extracted: 2026-07-03
theme: light  # measured from neutral usage weight
colors:  # roles inferred from usage frequency + luminance; names verified against values
  canvas: "#ffffff"
  ink: "#2e2e2e"
  text-muted: "#7e7e7e"
  surface: "#ededed"
  hairline: "#cccccc"
  accent: "#dffff1"  # pale-green
  accent-2: "#3ecf8e"  # green
  accent-3: "#061517"  # deep-teal
fonts:
  primary: "Inter"  # low-confidence: usage counts are low and close
  mono: "Source Code Pro"
---

# Supabase | The Open Source Firebase Alternative — Design System

Extracted from **https://supabase.com/** on 2026-07-03.

> Build production-grade applications with a Postgres database, Authentication, instant APIs, Realtime, Functions, Storage and Vector embeddings. Start for free.

Every value below is mined from the site's live CSS (120 native custom properties, ranked usage counts). Role assignments are inferred from usage and luminance and marked as such — treat them as a strong starting point, not gospel.

## Overview

The system reads as light: measured neutral usage weighs 161 light against 172 dark. The palette is chromatic: 12 saturated values against 11 neutrals, led by pale-green (`#dffff1`). Font usage counts are low and close together (Inter: 8, Source Code Pro: 8, Manrope: 7) — the extractor can't confidently call a primary face from CSS alone. Geometry mixes sharp corners (2px) with full pills.

## Usage rules

Derived from the measured usage below — each rule cites its evidence.

- Chromatic color is only 22% of measured color usage. Reserve `accent` (`#dffff1`) for primary actions, links, and emphasis — spreading it into body text or large surfaces breaks the ratio that defines this look.
- The theme is light (measured neutral weight 161:172). Don't flip individual sections to the opposite mode.
- `.25rem` is the workhorse radius (x8); treat the other radii as exceptions, not options.
- Shadows stay tight (max 5px blur) — keep elevation subtle if you extend the scale.
- `Source Code Pro` is the monospace — keep it for code, data, and metadata roles.

## Colors

### Neutrals (light → dark)

| Token | Value | Usage | Inferred role |
| --- | --- | --- | --- |
| `neutral-50` | `#ffffff` | 98 | **canvas** — lightest neutral, matches the measured light-leaning theme |
| `neutral-100` | `#ededed` | 58 | **surface** — neutral closest to canvas luminance |
| `neutral-200` | `#cccccc` | 5 | **hairline** — next neutral near canvas, hairline-border weight |
| `neutral-300` | `#b0b0b0` | 2 | — |
| `neutral-400` | `#a0a0a0` | 9 | — |
| `neutral-500` | `#8b9092` | 11 | — |
| `neutral-600` | `#7e7e7e` | 13 | **text-muted** — most-used mid-luminance neutral |
| `neutral-700` | `#707070` | 9 | — |
| `neutral-800` | `#525252` | 10 | — |
| `neutral-900` | `#464444` | 22 | — |
| `neutral-950` | `#2e2e2e` | 29 | **ink** — darkest neutral, highest contrast against canvas |

### Accents

| Token | Value | Usage | Inferred role |
| --- | --- | --- | --- |
| `pale-green` | `#dffff1` | 10 | **accent** — most-used chromatic color |
| `green` | `#3ecf8e` | 10 | **accent-2** — supporting chromatic color |
| `deep-teal` | `#061517` | 7 | **accent-3** — supporting chromatic color |
| `deep-teal-2` | `#163837` | 7 | — |
| `orange` | `#ffcda1` | 6 | — |
| `indigo` | `#bda4ff` | 5 | — |
| `orange-2` | `#f1a10d` | 5 | — |
| `cyan` | `#0070f3` | 5 | — |
| `green-2` | `#1a7a4c` | 5 | — |
| `blue` | `#6453c5` | 5 | — |
| `indigo-2` | `#6b35dc` | 4 | — |
| `blue-2` | `#32325d` | 4 | — |

### Modern color values (kept verbatim)

- `oklch(97.9% .021 166.113)`
- `oklch(90.5% .093 164.15)`
- `oklch(84.5% .143 164.978)`
- `oklch(76.5% .177 163.223)`
- `oklch(69.6% .17 162.48)`
- `oklch(59.6% .145 163.225)`
- `oklch(50.8% .118 165.612)`
- `oklch(37.8% .077 168.94)`
- `oklch(26.2% .051 172.552)`
- `oklch(70.4% .14 182.503)`
- `oklch(71.5% .143 215.221)`
- `oklch(98.5% 0 0)`

### Dark mode

The source defines 60 dark-mode variants (via dark selector). Both halves of the system, first 30:

| Token | Light | Dark |
| --- | --- | --- |
| `--ch-0` | — | `dark` |
| `--ch-1` | — | `#8b949e` |
| `--ch-2` | — | `#79c0ff` |
| `--ch-3` | — | `#ffcda1` |
| `--ch-4` | — | `#f8f8f2` |
| `--ch-5` | — | `#bda4ff` |
| `--ch-6` | — | `hsl(var(--brand-600))` |
| `--ch-7` | — | `#569cd6` |
| `--ch-8` | — | `hsl(var(--brand-default))` |
| `--ch-9` | — | `#ffa198` |
| `--ch-10` | — | `#f0f6fc` |
| `--ch-11` | — | `#490202` |
| `--ch-12` | — | `#04260f` |
| `--ch-13` | — | `#5a1e02` |
| `--ch-14` | — | `#161b22` |
| `--ch-15` | — | `#8b949e` |
| `--ch-16` | — | `#2a2929` |
| `--ch-17` | — | `#264f78` |
| `--ch-18` | — | `#3794ff` |
| `--ch-19` | — | `#ffffff0b` |
| `--ch-20` | — | `#6e7681` |
| `--ch-21` | — | `#010409` |
| `--ch-22` | — | `#30363d` |
| `--ch-23` | — | `#f78166` |
| `--ch-24` | — | `#6e768166` |
| `--ch-25` | — | `#6e76811a` |
| `--tw-brightness` | — | `brightness(200%)` |
| `--tw-contrast` | — | `contrast(0%)` |
| `--tw-gradient-position` | — | `to bottom` |
| `--tw-gradient-to` | — | `hsl(var(--background-surface-100))` |

`variables.css` ships these as a `prefers-color-scheme: dark` override block.

## Typography

Usage counts here are low and close together, so no family can be confidently called primary from CSS declarations alone — sites that set fonts via shorthand or JS under-count. Verify visually. Full list by usage:

| Family | Usage |
| --- | --- |
| Inter | 8 |
| Source Code Pro | 8 |
| Manrope | 7 |
| Ubuntu | 4 |
| Courier New | 1 |
| Office Code Pro | 1 |
| Manrope Fallback | 1 |
| Inter Fallback | 1 |

**Size scale (px):** `10`, `11`, `12`, `12.8`, `14`, `14.4`, `16`, `19.2`, `20`, `28`, `32`, `36`

**Weights in use:** `100` (x7), `200` (x15), `400` (x10), `500` (x3), `600` (x4), `700` (x5)

**Line-heights (unitless):** `1`, `1.11`, `1.33`, `1.43`, `1.5`, `1.6`, `1.71`, `1.75`

**Letter-spacing values:** `-1.5px`, `-1.1px`, `-.5px`, `-.025em`, `-.01rem`, `-.15px`

## Spacing

Most-used values (px): `1`, `2`, `3`, `4`, `5`, `6`, `8`, `10`, `12`, `15`, `16`, `48`

## Border radius

| Token | Value | Usage |
| --- | --- | --- |
| `radius-sm` | `2px` | 1 |
| `radius-md` | `.25rem` | 8 |
| `radius-lg` | `6px` | 5 |
| `radius-xl` | `8px` | 2 |
| `radius-2xl` | `14px` | 1 |
| `radius-3xl` | `20px` | 1 |
| `radius-4xl` | `100%` | 1 |
| `radius-full` | `50%` | 1 |

## Shadows (ordered by blur radius)

- `shadow-sm` — `0 13px 27px -5px rgba(50,50,93,.25),0 8px 16px -8px rgba(0,0,0,.3),0 -6px 16px -6px rgba(0,0,0,.025)` (x2)

## Breakpoints

`480px`, `520px`, `600px`, `640px`, `720px`, `768px`, `769px`, `960px`

## Starter recipes

Tokens composed into components. The source site's real components were **not** inspected — these are starting points built from the extracted values, with contrast ratios computed rather than assumed.

```css
.button-primary {
  background: var(--color-accent); /* #dffff1 */
  color: var(--color-ink); /* #2e2e2e — contrast 12.7:1 */
  border-radius: 9999px; /* pill — mined as 50% */
  font-weight: 500;
}

.card {
  background: var(--color-surface); /* #ededed */
  border: 1px solid var(--color-hairline); /* #cccccc */
  border-radius: .25rem; /* most-used finite radius */
  box-shadow: var(--shadow-sm);
}

.input {
  background: var(--color-canvas); /* #ffffff */
  color: var(--color-ink); /* #2e2e2e — contrast 13.6:1 */
  border: 1px solid var(--color-hairline); /* #cccccc */
  border-radius: 2px;
  /* placeholder color: var(--color-text-muted) #7e7e7e */
}

.nav {
  background: var(--color-canvas); /* #ffffff */
  border-bottom: 1px solid var(--color-hairline); /* #cccccc */
  color: var(--color-ink); /* #2e2e2e */
  /* inactive links: var(--color-text-muted) #7e7e7e */
  /* active link: var(--color-accent) #dffff1 — contrast vs canvas 1.1:1 */
}

.modal {
  background: var(--color-surface); /* #ededed */
  border-radius: .25rem;
  box-shadow: var(--shadow-sm); /* largest mined shadow */
}

.modal-backdrop {
  background: color-mix(in srgb, var(--color-ink) 55%, transparent); /* scrim from #2e2e2e */
}

.input-success {
  border-color: #dffff1; /* mined token: pale-green */
}

.input-error {
  /* no red exists in the mined palette — this site does not expose an error color in its CSS. */
  /* Introduce one deliberately rather than borrowing a random red; keep saturation near the accent's. */
}
```

## Observations

- 11 of 23 extracted colors are neutrals.
- 1 distinct shadow; the softest reaches 5px blur.
- 8 breakpoints, from 480px to 960px.
- The site ships a large native token system (120+ custom properties) — prefer those names when extending it.

## Native CSS custom properties

First 40 of 120:

```css
:root {
  --font-sans: var(--font-inter),Inter,Helvetica Neue,Helvetica,ui-sans-serif,system-ui,sans-serif;
  --color-emerald-50: oklch(97.9% .021 166.113);
  --color-emerald-200: oklch(90.5% .093 164.15);
  --color-emerald-300: oklch(84.5% .143 164.978);
  --color-emerald-400: oklch(76.5% .177 163.223);
  --color-emerald-500: oklch(69.6% .17 162.48);
  --color-emerald-600: oklch(59.6% .145 163.225);
  --color-emerald-700: oklch(50.8% .118 165.612);
  --color-emerald-900: oklch(37.8% .077 168.94);
  --color-emerald-950: oklch(26.2% .051 172.552);
  --color-teal-500: oklch(70.4% .14 182.503);
  --color-cyan-500: oklch(71.5% .143 215.221);
  --color-neutral-50: oklch(98.5% 0 0);
  --color-neutral-100: oklch(97% 0 0);
  --color-neutral-200: oklch(92.2% 0 0);
  --color-neutral-300: oklch(87% 0 0);
  --color-neutral-400: oklch(70.8% 0 0);
  --color-neutral-500: oklch(55.6% 0 0);
  --color-neutral-600: oklch(43.9% 0 0);
  --color-neutral-700: oklch(37.1% 0 0);
  --color-neutral-800: oklch(26.9% 0 0);
  --color-neutral-900: oklch(20.5% 0 0);
  --color-stone-500: oklch(55.3% .013 58.071);
  --color-black: #000;
  --color-white: #fff;
  --spacing: .25rem;
  --breakpoint-lg: 64rem;
  --breakpoint-2xl: 96rem;
  --container-xs: 20rem;
  --container-sm: 24rem;
  --container-md: 28rem;
  --container-lg: 32rem;
  --container-xl: 36rem;
  --container-2xl: 42rem;
  --container-3xl: 48rem;
  --container-4xl: 56rem;
  --container-5xl: 64rem;
  --container-6xl: 72rem;
  --container-7xl: 80rem;
  --text-xs: .75rem;
}
```

## Files

- `tailwind.css` — Tailwind v4 `@theme` block; tokens become utilities (e.g. `bg-neutral-900`, `text-pale-green`).
- `variables.css` — framework-agnostic `:root` variables, same values.
- `tokens.json` — W3C Design Tokens format for Figma plugins, Style Dictionary, etc.