Let one green carry all the brand signal; if you add a second accent color, you've already broken the system.
The pitch
I built this around one chromatic anchor — Supabase green #3fcf8e — and otherwise stayed in a neutral grayscale because Postgres developers don't need to be sold to with color, they need to read documentation. I went with regular 400 weight headlines instead of 600/700 bold because at 72px the type already has presence; piling on weight would push it into marketing-deck territory and we're a developer tool. The page sits on near-white #fcfcfc with cards on pure #ffffff and 1px #ededed borders doing all the elevation work — I rejected drop shadows because shadows imply a UI metaphor (paper, depth) that competes with the actual product screenshots we want to feature. Buttons are 6px radius, cards step up to 12-16px, and that ladder is consistent from pricing to docs. The trade-off: this language reads as quiet to a first-time visitor expecting marketing pyrotechnics, and the green CTA is doing a lot of work alone to signal where to click.
Signature move
A single saturated green (#3fcf8e) used only for the CTA and brand logo, with everything else — surfaces, type, borders — held in strict grayscale.
When to use it
Building a developer-facing product where the audience evaluates you on docs quality and API surface, not on hero animation or visual storytelling.
Building a consumer or prosumer marketing site that needs to convert cold traffic — the grayscale restraint reads as indifference to non-technical visitors.
What gets written
The files dropped into your repo
---
name: supabase.com
description: "I built this around one chromatic anchor — Supabase green #3fcf8e — and otherwise stayed in a neutral grayscale because Postgres developers don't need to be sold to with color, they need to read documentation. I went with regular 400 weight headlines instead of 600/700 bold because at 72px the type already has presence; piling on weight would push it into marketing-deck territory and we're a developer tool. The page sits on near-white #fcfcfc with cards on pure #ffffff and 1px #ededed borders doing all the elevation work — I rejected drop shadows because shadows imply a UI metaphor (paper, depth) that competes with the actual product screenshots we want to feature. Buttons are 6px radius, cards step up to 12-16px, and that ladder is consistent from pricing to docs. The trade-off: this language reads as quiet to a first-time visitor expecting marketing pyrotechnics, and the green CTA is doing a lot of work alone to signal where to click."
colors:
primary: "#3fcf8e"
surface-2: "#72e3ad"
background: "#fcfcfc"
surface: "#ffffff"
fg: "#171717"
fg-muted: "#525252"
border: "#ededed"
fg-subtle: "#8f8f8f"
typography:
sans: Circular
weights: [400, 500, 600]
scale:
page-hero:
size: 72px
lineHeight: 72px
classes: text-7xl tracking-tight
page-hero-2:
size: 48px
lineHeight: 48px
classes: text-5xl font-semibold tracking-tight
section-header:
size: 36px
lineHeight: 43px
classes: text-4xl tracking-tight
subsection-header:
size: 24px
lineHeight: 32px
classes: text-2xl
body:
size: 18px
lineHeight: 28px
classes: text-lg
body-2:
size: 16px
lineHeight: 24px
classes: text-base
rounded:
button: 6px
card: 12px
spacing:
container: max-w-6xl mx-auto px-6
section: py-24
components:
button-primary:
background: "{colors.primary}"
text: "{colors.background}"
rounded: "{rounded.button}"
padding: 8px 12px
button-secondary:
background: "{colors.surface}"
text: "{colors.fg}"
border: "1px solid {colors.border}"
rounded: "{rounded.button}"
padding: 8px 12px
card:
background: "{colors.surface}"
border: "1px solid {colors.border}"
rounded: "{rounded.card}"
padding: 24px
input:
background: "{colors.surface}"
text: "{colors.fg}"
placeholder: "{colors.fg-muted}"
border: "1px solid {colors.border}"
rounded: "{rounded.input}"
padding: 8px 10px
---
# Design System — inspired by supabase.com
> **Let one green carry all the brand signal; if you add a second accent color, you've already broken the system.**
I built this around one chromatic anchor — Supabase green #3fcf8e — and otherwise stayed in a neutral grayscale because Postgres developers don't need to be sold to with color, they need to read documentation. I went with regular 400 weight headlines instead of 600/700 bold because at 72px the type already has presence; piling on weight would push it into marketing-deck territory and we're a developer tool. The page sits on near-white #fcfcfc with cards on pure #ffffff and 1px #ededed borders doing all the elevation work — I rejected drop shadows because shadows imply a UI metaphor (paper, depth) that competes with the actual product screenshots we want to feature. Buttons are 6px radius, cards step up to 12-16px, and that ladder is consistent from pricing to docs. The trade-off: this language reads as quiet to a first-time visitor expecting marketing pyrotechnics, and the green CTA is doing a lot of work alone to signal where to click.
**Signature move.** A single saturated green (#3fcf8e) used only for the CTA and brand logo, with everything else — surfaces, type, borders — held in strict grayscale.
**Use this when.** Building a developer-facing product where the audience evaluates you on docs quality and API surface, not on hero animation or visual storytelling.
**Avoid when.** Building a consumer or prosumer marketing site that needs to convert cold traffic — the grayscale restraint reads as indifference to non-technical visitors.
When in doubt: less. Restraint reads as confidence.
## Rules
- **Color**: Use only tokens from `tailwind.config.ts` theme.colors. Never hardcode hex values, hsl(), or arbitrary `bg-[#...]` classes.
- **Spacing**: Use Tailwind's default scale. Avoid arbitrary values like `p-[18px]` unless matching a fixed asset.
- **Type weights**: Only `font-normal`, `font-medium`, `font-semibold`. Do not introduce other weights.
- **Radius**: Buttons and inputs use `rounded-md`. Cards use `rounded-xl`. Avatars use `rounded-full`. Nothing else.
- **Borders before shadows**: Use `border border-border` for elevation. Reserve `shadow-sm` for floating menus only.
- **Motion**: Hover transitions are `transition-colors duration-150`. Never animate layout. Never use `duration-500` or longer for UI feedback.
- **Container**: Page content sits in `max-w-6xl mx-auto px-6`. Sections use `py-24`.
- **Icons**: Use `lucide-react` at `size-4` (default) or `size-5` (emphasis). No emoji in UI.
## Tokens
### Color (defined in `tailwind.config.ts`)
| Token | Value | Use for |
|---|---|---|
| `bg-primary` | `#3fcf8e` | CTA button background |
| `bg-surface-2` | `#72e3ad` | Elevated hover state |
| `bg-background` | `#fcfcfc` | Page background |
| `bg-surface` | `#ffffff` | Surface background, elevated above page |
| `text-fg` | `#171717` | Primary text, headings |
| `text-fg-muted` | `#525252` | Secondary text, muted content |
| `border-border` | `#ededed` | Borders, dividers |
| `text-fg-subtle` | `#8f8f8f` | Tertiary text, placeholders |
### Type scale
| Class | Size / line-height | Use for |
|---|---|---|
| `text-7xl tracking-tight` | 72px / 72px | Page hero |
| `text-5xl font-semibold tracking-tight` | 48px / 48px | Page hero |
| `text-4xl tracking-tight` | 36px / 43px | Section header |
| `text-2xl` | 24px / 32px | Subsection header |
| `text-lg` | 18px / 28px | Body |
| `text-base` | 16px / 24px | Body |
### Font families
- **Sans**: Circular. Class: `font-sans`.
## Components
### Button
- **Primary**: `bg-primary text-background px-3 h-8 rounded-md text-sm font-medium hover:opacity-90 transition-colors`
- **Secondary**: `bg-surface text-fg border border-border px-3 h-8 rounded-md text-sm font-medium hover:bg-opacity-80`
- **Ghost**: `text-fg-muted px-3 h-8 rounded-md text-sm hover:bg-surface hover:text-fg`
- **Sizes**: only `h-8` (default) and `h-7 text-xs` (compact).
### Card
`bg-surface border border-border rounded-xl p-6`
Cards never have shadows in this design. Hover state: slightly lighter border.
### Input
`bg-surface border border-border rounded-md h-8 px-2.5 text-sm text-fg placeholder:text-fg-muted focus:outline-none focus:border-primary`
### Section
```html
<section class="py-24">
<div class="max-w-6xl mx-auto px-6">
...
</div>
</section>
```
## Anti-patterns — this design does NOT use
- **Drop shadows.** Depth comes from borders and surface tints. Never `shadow-md`, `shadow-lg`, etc.
- **Gradients.** All fills are solid. No `bg-gradient-*`.
- **Multiple accent colors.** There is one accent (`primary`). No success-green, warning-yellow, etc., unless explicitly building a status indicator.
- **Heavy font weights.** The maximum weight in this design is `font-semibold` (600).
- **Light font weights.** This design does not use `font-light` or `font-thin` for UI text.
- **Pill-shaped buttons (rounded-full).** Buttons use `rounded-md`. `rounded-full` is reserved for avatars and badges.
- **Decorative animations.** No fade-in-on-scroll, parallax, or entrance animations on page load. Motion is reserved for hover/focus feedback.
- **Emoji in UI.** Use `lucide-react` icons. Never emoji in buttons, headings, or interface chrome.
- **Centered body text.** Long-form content is left-aligned. Centering is reserved for hero headlines and short CTA blocks.
- **Multiple type families on one screen.** Sans for everything except code blocks (mono).
- **Arbitrary Tailwind values.** Avoid `text-[15px]`, `p-[13px]`, `bg-[#abc]` — these break the system. If a value is missing from the theme, add it to `tailwind.config.ts` first.
## Slop to avoid
Patterns AI coding agents reach for that produce visibly AI-generated UI. Avoid all of these. Items marked **avoided here** are choices the source design explicitly makes — preserve them when generating new screens.
- **Purple-to-pink gradient hero**
The default LLM hero — every AI starter looks like this. Reads as 'made by ChatGPT' on sight.
- ✗ `bg-gradient-to-br from-purple-600 to-pink-500`
- ✓ Solid brand color with one accent. Reserve gradients for illustration, not chrome.
- **Glassmorphism card (frosted blur)**
backdrop-blur + low-opacity white was a 2021 trend. AI agents pile it on every modal and card.
- ✗ `bg-white/10 backdrop-blur-md border border-white/20`
- ✓ Solid surface color with a 1px border. If you need elevation, raise the surface.
- **Stacked drop shadows on every surface** — _avoided here_
shadow-md on cards, shadow-lg on modals, shadow-xl on hover — depth performed instead of designed.
- ✗ `shadow-md hover:shadow-xl`
- ✓ Pick one: borders OR shadows for elevation, never both. Reserve shadow for floating menus.
- **Gradient text on headlines**
bg-clip-text on every H1 — distracts from the message and ages instantly.
- ✗ `bg-gradient-to-r from-blue-500 to-purple-500 bg-clip-text text-transparent`
- ✓ Solid foreground color. If the headline needs emphasis, use weight or size.
- **Pill-shaped buttons everywhere** — _avoided here_
rounded-full is the consumer-app default. On a B2B/dev tool it reads as derivative.
- ✗ `rounded-full px-6 py-3`
- ✓ Match the radius vocabulary of the design — usually 4-8px on dev tools, 12-16px on consumer.
- **Inter or Geist as the default 'modern' font**
Every AI-generated UI uses Inter. It's not wrong, it's just the same answer everyone gets.
- ✗ `font-family: "Inter", sans-serif;`
- ✓ If you don't have a brand font, use the system stack. If you do, use it. Don't reach for Inter as a 'safe' default.
- **Decorative emoji in headings and buttons**
"🚀 Launch your app" — emoji as decoration is the visual equivalent of comic sans for AI output.
- ✗ `<button>🚀 Get started</button>`
- ✓ Use icon components (lucide, heroicons). Reserve emoji for user-generated content.
- **Generic testimonial cards with stock-photo avatars**
Three round avatars, three star ratings, three made-up quotes — the AI 'social proof' template.
- ✗ `<Avatar src="/photo-1.jpg" /> "Game-changer for our team!" — Sarah, CEO`
- ✓ Real testimonials with real attribution, or omit the section entirely.
- **3D-tilted feature cards on hover**
perspective(1000px) rotateX/rotateY hover effects — 2023 SaaS-template default.
- ✗ `hover:transform hover:rotate-1 hover:scale-105 transition-all`
- ✓ Subtle border-color or background-color change on hover. Static layouts read as confident.
- **Green-checkmark feature lists**
Every AI pricing page has the same ✓ ✓ ✓ list. Becomes wallpaper.
- ✗ `<li><CheckCircle className="text-green-500" /> Unlimited projects</li>`
- ✓ If the list is short, write prose. If it's long, use a comparison table.
- **Center-aligned long-form content**
AI defaults to text-align:center for everything. Long-form reads as ad copy when centered.
- ✗ `<div class="text-center max-w-3xl mx-auto">{long paragraph}</div>`
- ✓ Center hero headlines and short CTA blocks only. Body content is left-aligned.
- **Vague aspirational hero headline**
"Build the future of your business" — meaningless because it would fit any product.
- ✗ `<h1>Empower your team to do their best work</h1>`
- ✓ Name the user, the action, and the outcome. If you swap your product name and the headline still works, rewrite it.
- **Bento grid with mixed card sizes**
The Apple-pages-imitator layout. Used as an excuse not to decide what's important.
- ✗ `Grid of 6 cards, 2 large + 4 small, each with a different feature.`
- ✓ Linear list of features in priority order. If you must use a grid, make all cards equal weight.
- **Animated mesh-gradient background**
The 'I learned about CSS conic-gradient last week' look. Distracts from content, kills perf.
- ✗ `Animated SVG mesh or conic-gradient with @keyframes rotation`
- ✓ Static background. If the page needs energy, get it from typography or content density.
- **Auto-playing hero video loop**
10MB MP4 of generic abstract footage. Page LCP cratered, brand value zero.
- ✗ `<video autoplay loop muted><source src='/abstract-tech.mp4' /></video>`
- ✓ Static image, animated SVG, or a real product screenshot.
- **Translucent navigation with backdrop-blur**
Apple did it once. Now every AI agent puts blur(12px) on every nav.
- ✗ `fixed top-0 bg-white/80 backdrop-blur-md`
- ✓ Solid nav background. If you must, add a 1px bottom border on scroll.
- **Arbitrary Tailwind values everywhere**
p-[13px], text-[15px], bg-[#f3e1c4] — the design system was abandoned line-by-line.
- ✗ `px-[13px] text-[15px] bg-[#f3e1c4]`
- ✓ Use scale tokens. If a value is missing, add it to the theme first.
- **Untouched shadcn slate/zinc default palette**
The 'I installed shadcn and never theme'd it' look. Looks like every AI-generated app.
- ✗ `Using the default `--primary: 222.2 47.4% 11.2%` and `--background: 0 0% 100%` from shadcn init.`
- ✓ Replace the default tokens with your brand palette before shipping.
- **py-32 / py-48 between every section**
Vertical whitespace as a substitute for content. The page scrolls forever, says nothing.
- ✗ `py-32 (everywhere)`
- ✓ Match the rhythm of your content. py-16 to py-24 is usually plenty.
- **One icon per word in headings**
AI agents add lucide icons next to every nav link, button, and bullet — visual noise.
- ✗ `<Button><Sparkles /> Try it free</Button>`
- ✓ Reserve icons for nav and actions where the icon adds meaning the word doesn't.
- **Neumorphism (soft 3D embossed) buttons**
Two opposing shadows on every button to fake 3D. Accessibility nightmare and looks dated.
- ✗ `shadow-[inset_2px_2px_5px_#bbb,_-3px_-3px_5px_#fff]`
- ✓ Flat or border-only. Save 3D for actual physical product mockups.
- **Auto-scrolling logo marquee for 'social proof'**
12 customer logos sliding across the page. Reads as 'we copied Stripe's homepage'.
- ✗ `Animate-x infinite scroll of grayscale customer logos`
- ✓ Static grid of 4-6 real customer logos, no animation.
- **Dark mode = invert all the colors**
Pure-black bg with white text and the same brand color at full saturation — eye-fatigue mode.
- ✗ `html.dark { background: #000; color: #fff; }`
- ✓ Real dark mode uses near-black (not pure), softened text (not pure white), and desaturated accents.
- **Framer-template-style: hero / features / pricing / testimonials / cta / footer**
The same six sections in the same order on every AI-generated landing page.
- ✗ `Hero → Features → Pricing → Testimonials → CTA → Footer with no variation.`
- ✓ Decide what your page actually needs to convince the reader. Skip sections that don't earn their space.
- **Bootstrap-default status colors (red/yellow/green/blue)**
#ff0000 #ffcc00 #00cc00 #0066ff — the 'I didn't theme my status palette' tell.
- ✗ `text-red-500 text-yellow-500 text-green-500 text-blue-500`
- ✓ Tint your status colors toward your brand palette. Desaturate them on dark mode.
- **Mixing a serif "elegant" headline with a sans body for "contrast"** — _avoided here_
Editorial type pairing applied to a SaaS landing — reads as a Squarespace template.
- ✗ `<h1 class="font-serif">Reimagine work</h1><p class="font-sans">…</p>`
- ✓ One typographic voice. If you want hierarchy, use weight and size, not family.
- **Fade-in/slide-up on every section as the user scrolls**
data-aos='fade-up' on every block. The user can't read until they wait for the animation.
- ✗ `Every <section> has an entrance animation triggered by IntersectionObserver.`
- ✓ Static layouts. Reserve motion for actual interactions (hover, focus, modal open).
- **12-column footer with 60+ links**
Copying SaaS-megacorp footers without their actual content depth. Empty links for 'Product / Solutions / Resources'.
- ✗ `<footer> with 6 columns × 10 links each, 80% leading to empty pages.`
- ✓ List the pages you actually have. A 4-link footer is fine.
- **Stat blocks with made-up percentages**
"99% faster", "10× more efficient", "3× ROI" — round numbers no real customer cited.
- ✗ `<div>99%</div><div>faster deploys</div>`
- ✓ Real metrics with real attribution, or skip the section.
- **"Eyebrow" + "Big Claim" + "Subtitle" pattern on every section**
The mandatory three-line section opener. Recognizable as AI output from the silhouette alone.
- ✗ `<small>WHY US</small><h2>Built for teams</h2><p>The platform that scales…</p>`
- ✓ One headline that earns its space. Drop the eyebrow unless it's load-bearing taxonomy.
_Slop catalog is shipped as `slop.json` for programmatic access. Catalog concept popularized by [Impeccable](https://impeccable.style/)._
## Visual reference
Open `.reseed/design-reference.html` in a browser to see every token and
component rendered. Use it to verify visual decisions before committing.
Source: extracted from <https://supabase.com> on 2026-05-07.
Re-extract with `npx reseed-cli update`.
When you run npx reseed-cli init https://supabase.com, Reseed appends this block to your existing CLAUDE.md (or AGENTS.md, or creates one if absent) so your AI editor automatically picks up the rules:
## Design system This project's design language is documented in [.reseed/design-system.md](.reseed/design-system.md). When generating UI, follow the rules and tokens defined there. Open `.reseed/design-reference.html` for a visual reference.
The generated .reseed/design-system.md is the load-bearing file — Cursor, Claude Code, and Windsurf read it transitively from the pointer above on every prompt.
Drop this into your codebase
One command writes all four files into your repo.