- fg
#000000- bg
#FFFFFF- APCA Lc
- +106
- Use
- foreground on background
Supabase
Open-source Postgres platform with developer-warm confidence — pure dark ground, accent-only brand green, Circular + Source Code Pro. Technical depth behind a welcoming front door.

Editorial disclaimer
This entry documents observable design-language patterns for educational transfer and AI-agent briefing. Screenshots and trademarks are property of their respective owners. AI2 Design is not affiliated with or endorsed by the featured brand. Inspiration here is about language and rhythm - do not reproduce brand identity, logo, product copy, or proprietary features.
Fair Use & Gallery PolicyCopy the full design language into your agent
A typed, paste-ready design system brief - philosophy, tokens, rules, techniques, and fitness checks. Drop it into Claude, Cursor, v0 or any coding agent and it builds in Supabase’s language, not just a screenshot.
Near-monochrome developer surface with one homeopathic signal color. The body lives on a neutral-gray ladder (#171717 / #707070 / #525252 / #b2b2b2) over white #ffffff or pure-black #000000; Circular carries voice across a tight 400/500 weight pair while Source Code Pro handles code and tracked labels (letter-spacing 1.2px). The single brand green #3fcf8e behaves as a status light — accent only, never a fill. Elevation is delivered through hairline 1px borders (#dfdfdf / #c7c7c7), not drop shadows. Motion is a single functional tempo: 0.15s on cubic-bezier(0.4, 0, 0.2, 1). Legibility over decoration, evidence over spectacle.
Use this capture as a design language transfer brief for my project. Adopt the palette (neutral-gray reading ladder on white or pure-black canvas + a single homeopathic green #3fcf8e accent used like a status light), typographic register (Circular-class sans at a 400/500 weight pair, with a Source Code Pro-class monospace for code and tracked uppercase labels at 1.2px letter-spacing), the 4px-based spacing scale, border-first elevation (hairline 1px borders, no drop shadows), the cubic-bezier(0.4, 0, 0.2, 1) motion curve at 0.15s, and a docs-grade information density across every page and component I ship. Treat this as my project's constitution — any new component I author should pass as if crafted in the same studio. Apply the language, not the source brand's specific copy or identity. When I ask you to build a page or component, enforce these rules by default and call out any decision that deviates.
- Layout
- Grid
- Content width
- Bounded
- Framing
- Flat
- Grid strength
- Strong
Near-monochrome canvas — white #ffffff (or pure-black #000000 for dark sections) carrying a neutral-gray reading ladder: #171717 primary text → #525252 → #707070 → #b2b2b2 secondary, with hairline borders at #dfdfdf and #c7c7c7. The single brand green #3fcf8e is the only chromatic note, appearing as accent — links, focus, live indicators — at well under 2% of the surface. A deeper green #00bb68 and a mint #a9f1ca exist only for rare semantic positive states.
- Primary text #171717 on white (or near-white on black) does the dominant reading work — measured at the highest text frequency in the capture (~1125 occurrences).
- Secondary gray ladder #525252 / #707070 / #b2b2b2 for captions, metadata, and progressively de-emphasized labels.
- Hairline borders #dfdfdf (dominant, ~1918 occurrences) and #c7c7c7 carve structure — borders, not shadows, are the primary delimiter.
- Brand green #3fcf8e reserved for accent only — links, focus rings, live/active indicators — surface area under ~2% (a measured 14 occurrences, flagged brand-tier).
- Semantic-only greens: #00bb68 for emphatic positive text, mint #a9f1ca for subtle positive backgrounds — never decorative, never a default fill.
Gradients (paste-ready)
linear-gradient(rgb(223, 223, 223) 0px, oklab(0.904028 0.0000411272 0.0000180602 / 0.5) 100%) linear-gradient(to top, rgba(0, 0, 0, 0) 0px, rgba(0, 0, 0, 0) 50%, rgb(255, 255, 255) 85%) linear-gradient(to right in oklab, rgba(0, 0, 0, 0) 0px, rgb(223, 223, 223) 50%, rgba(0, 0, 0, 0) 100%)
- Primary family: Circular (geometric sans). Monospace companion: Source Code Pro for code blocks, kbd, and tracked uppercase labels. Two families only — no third display face.
- Weight pair: 400 (reading + most headings) / 500 (emphasized body, UI labels). The capture shows headings carried by size, not heavy weight — do not reach for 600/700.
- Type scale (observed px): 12 / 14 / 16 / 18 / 24 / 36 / 72. Hero runs 72px with unitless 1.0 line-height (72px/72px); section headings 36px/45px and 24px/32px; body 16px/24px; UI 14px/20px; fine print 12px/16px.
- Letter-spacing is normal at every sans size except the 24px body lead (-0.16px optical correction). Tracked monospace labels use Source Code Pro 12px with +1.2px letter-spacing — the signature 'developer label' register.
- Line-height ladder: 1.0 on the 72px hero (tight display), ~1.25 on 36px headings (45px), ~1.33 on 24px (32px), 1.5 on 16px body (24px), ~1.43 on 14px UI (20px), ~1.33 on 12px (16px).
- Switch to monospace deliberately — code, inline tokens, and small uppercase eyebrow labels only. The sans/mono register change is meaning-bearing, not stylistic noise.
- No italic for emphasis — shift weight (400→500) or switch to mono. Paragraph measure 45-65 ch at 16px body.
- 4px base unit. Scale (observed px): 1 / 4 / 6 / 8 / 10 / 12 / 16 / 20 / 24 / 32 / 40 / 48. The dominant rhythm sits on 8 / 16 / 24; the 1px step is hairline-border alignment, not layout padding.
- Container max-widths step through 672 → 1152 → 1400 → 1536 → 1600 px. The 1536px container is the workhorse (most frequent); 672px is the narrow reading rail for prose clusters.
- Card padding: 16-24px on desktop, 12-16px on mobile — always from scale values, never a magic number.
- Flex/grid gutters draw from 4 / 8 / 12 / 16 / 20 / 24 / 32 px; 8px is by far the most frequent gap, with 16px second.
- Section vertical rhythm leans on the 32 / 40 / 48 px steps for block separation; tighten to 16-24px inside dense feature grids.
- Primary elevation is a hairline 1px solid border (#dfdfdf on light, #c7c7c7 for slightly stronger delineation) — reach for this before any shadow. Border width is uniformly 1px (the only observed width).
- Drop shadows are near-absent: the dominant shadow token is fully transparent (rgba(0,0,0,0) layers). A single soft elevation exists — rgba(0,0,0,0.1) 0px 10px 15px -3px + 0px 4px 6px -4px — reserved for genuinely floating UI (popovers, command menu).
- Layering depth comes from background-shift (white ↔ near-black sections) and border presence, not stacked shadow.
- Focus state uses the brand green #3fcf8e as a ring — never an outer bloom or glow.
Techniques
Hairline 1px border as surface delimiter
Cards and panels default to `border: 1px solid #dfdfdf` (step up to #c7c7c7 for stronger separation). On a dark section the equivalent is a low-alpha white hairline. Hover shifts the border toward the accent or a darker neutral — never switches to a drop shadow.
Soft float for menus only
Command palettes, dropdowns, and popovers may use the single captured shadow `0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -4px rgba(0,0,0,0.1)` — a tight, low-opacity lift with zero spread. Everything anchored to the page stays flat and border-delimited.
- Radius scale (observed px): 6 / 8 / 11 / 12 / 16. The 8px and 16px steps are the most frequent; 11px is a Supabase-specific optical value (don't round it to 12).
- Buttons and inputs default to 6-8px radius, cards 12px, larger panels/modals 16px, pills `rounded-full` for status badges only.
- Icons are stroke-based at 1.5-2px weight; no filled or duotone variants in the default set.
- Tap targets minimum 40×40px on pointer, 44×44px on touch.
button-primary- backgroundColor
- #3fcf8e
- textColor
- #171717
- radius
- 8px
- padding
- 8px 16px
- border
- 1px solid #3fcf8e
- boxShadow
- none
- fontWeight
- 500
- fontSize
- 14px
- lineHeight
- 20px
Tailwind
inline-flex min-h-[40px] items-center gap-2 rounded-[8px] border border-[#3fcf8e] bg-[#3fcf8e] px-4 py-2 text-[14px] font-medium leading-[20px] text-[#171717] transition-colors duration-150 ease-[cubic-bezier(0.4,0,0.2,1)] hover:bg-[#00bb68] hover:border-[#00bb68] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#3fcf8e] focus-visible:ring-offset-2
button-secondary- backgroundColor
- #ffffff
- textColor
- #171717
- radius
- 8px
- padding
- 8px 16px
- border
- 1px solid #dfdfdf
- boxShadow
- none
- fontWeight
- 500
- fontSize
- 14px
- lineHeight
- 20px
Tailwind
inline-flex min-h-[40px] items-center gap-2 rounded-[8px] border border-[#dfdfdf] bg-white px-4 py-2 text-[14px] font-medium leading-[20px] text-[#171717] transition-colors duration-150 ease-[cubic-bezier(0.4,0,0.2,1)] hover:border-[#c7c7c7] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#3fcf8e] focus-visible:ring-offset-2
card-surface- backgroundColor
- #ffffff
- textColor
- #171717
- radius
- 12px
- padding
- 24px
- border
- 1px solid #dfdfdf
- boxShadow
- none
Tailwind
rounded-[12px] border border-[#dfdfdf] bg-white p-6 text-[#171717] transition-colors duration-150 ease-[cubic-bezier(0.4,0,0.2,1)] hover:border-[#c7c7c7]
input-field- backgroundColor
- #ffffff
- textColor
- #171717
- radius
- 8px
- padding
- 8px 12px
- border
- 1px solid #dfdfdf
- boxShadow
- none
- fontWeight
- 400
- fontSize
- 14px
- lineHeight
- 20px
Tailwind
w-full rounded-[8px] border border-[#dfdfdf] bg-white px-3 py-2 text-[14px] leading-[20px] text-[#171717] placeholder:text-[#b2b2b2] transition-colors duration-150 ease-[cubic-bezier(0.4,0,0.2,1)] focus-visible:outline-none focus-visible:border-[#3fcf8e] focus-visible:ring-2 focus-visible:ring-[#3fcf8e]
code-label- fontFamily
- Source Code Pro, monospace
- textColor
- #707070
- fontSize
- 12px
- lineHeight
- 16px
- letterSpacing
- 1.2px
- textTransform
- uppercase
Tailwind
font-mono text-[12px] leading-[16px] tracking-[1.2px] uppercase text-[#707070]
link-inline- color
- #3fcf8e
- textDecoration
- none
- fontWeight
- 500
- transition
- color 0.15s cubic-bezier(0.4, 0, 0.2, 1)
Tailwind
font-medium text-[#3fcf8e] no-underline transition-colors duration-150 ease-[cubic-bezier(0.4,0,0.2,1)] hover:text-[#00bb68] focus-visible:outline-none focus-visible:underline focus-visible:decoration-[#3fcf8e]
Easings
cubic-bezier(0.4, 0, 0.2, 1)cubic-bezier(0, 0, 0.2, 1)cubic-bezier(0.4, 0, 0.6, 1)linearease-outScroll patterns
- Intersection-triggered reveals on the 0.2-0.3s tier with cubic-bezier(0, 0, 0.2, 1) (decelerate-out) for entrances
- Looping marquee logo rails run on `linear` at long durations (30 / 35 / 40 / 50 / 90s) — purely ambient, not affordance
- `pulse` keyframe at 0.6s on cubic-bezier(0.4, 0, 0.6, 1) for live/loading indicators
- No parallax; depth comes from borders and section background-shift, not movement
- Primary easing: cubic-bezier(0.4, 0, 0.2, 1) — the standard ease-in-out — anchors the vast majority of transitions (measured ~230 occurrences).
- Supporting easings: cubic-bezier(0, 0, 0.2, 1) (decelerate) for entrances/reveals; cubic-bezier(0.4, 0, 0.6, 1) for the pulse indicator; linear for marquee loops; ease-out for the single long 0.75s transform.
- Durations captured: 0.15s (dominant — most interactive state changes), 0.2s (transforms + reveals), 0.3s (longer reveals / fadeIn), 0.6s (pulse). Loop animations (marquee) sit at 30-90s on linear and are ambient-only.
- Most hover/focus state changes are 0.15s on cubic-bezier(0.4, 0, 0.2, 1) — keep interactive feedback on this single tempo.
- Framer Motion is present (window.MotionIsMounted) — use it for reveals, but constrain to the captured durations/easings.
- useReducedMotion mandatory: marquee and pulse loops disable; reveals collapse to opacity-only.
- Spring animations forbidden — deterministic cubic-bezier or linear only.
- Segmented controls for binary/ternary choices (pricing period, doc version) — not toggle switches.
- Accordion: single-open for FAQ; multi-open only for deeply nested documentation.
- Tooltips reveal on hover + focus, dismiss instantly on blur; keep copy to one line.
- Modals for destructive confirmations; command palette (mono-flavored) for navigation; never nested modals.
- Form validation: inline below field on blur; submit disabled until validation passes.
- Empty states: small icon + one-line 14px copy + a single primary action. No illustrations.
- Loading states: `pulse` skeleton (0.6s) for content; inline spinner for buttons. No full-page overlays.
Desktop-first because the audience is engineers on wide displays reading docs-grade content (the workhorse container runs to 1536px, with a 1600px maximum). Mobile reflows the same language — the dense feature grid collapses to a single column and the marquee logo rails keep scrolling — without inventing a separate mobile architecture. The page is the page, just narrowed.
- Breakpoints: sm 640 / md 768 / lg 1024 / xl 1280 / 2xl 1536 — standard Tailwind ladder; an explicit (max-width: 600px) query handles the smallest phones.
- Container max-width steps through 672 → 1152 → 1400 → 1536 → 1600 px for bounded content at each tier.
- Hide-on-mobile is discouraged — if a control exists on desktop it should reach mobile via reflow.
- Tap target minimum 44×44 on touch; 40×40 on pointer devices.
- Typography scales down proportionally: hero 72 → ~48 → ~36, section headings drop ~25% per tier; body holds at 16px for legibility.
- focus-visible: 2px brand-green #3fcf8e ring (with offset on solid surfaces). Mandatory on every interactive element — the accent doubles as the focus signal.
- All interactive elements reachable via Tab in logical reading order; never rely on hover to expose actions.
- Color contrast: #171717 on #ffffff ≈ 16:1 (AAA); secondary #707070 on #ffffff ≈ 4.7:1 (AA); never drop body text below 4.5:1. On black #000000, raise text toward near-white before shipping.
- Brand green #3fcf8e on white is ~1.7:1 — never use it for body text; it is for accents, borders, and large/bold or icon use only, paired with a non-color signal.
- ARIA labels on icon-only buttons; aria-expanded on collapsible regions; aria-live='polite' on toast and status updates.
- Motion respects prefers-reduced-motion — marquee and pulse loops disable; reveals reduce to opacity-only.
- Never signal state with the green alone — pair the accent with text or an icon so color-blind users get the same information.
- Form errors announced via aria-describedby on the associated input; never color-only signaling.
Framer Motion is directly observable in the capture (window.MotionIsMounted) and drives reveals on cubic-bezier(0, 0, 0.2, 1). The image profile is SVG-dominant (78 of 80 assets are SVG — partner logos in the marquee rails), with the Postgres hero served through Next/Image (`_next/image` with a full responsive srcset). Icons are stroke-based at 1.5-2px weight.
- Framer Motion `motion.div` with `whileInView` + `viewport={{ once: true, margin: '-10%' }}` for scroll reveals
- Transitions use `ease: [0.4, 0, 0.2, 1]` and `duration: 0.15` (or 0.2 / 0.3) — constants only; reveals may use `[0, 0, 0.2, 1]`
- useReducedMotion guard wraps every animation primitive — marquee + pulse disable, no exceptions
- Next/Image with `sizes` always set; `priority` only on the LCP hero (the Postgres product image)
- Marquee logo rails: SVG marks at a uniform 48px display height, CSS/Framer translate loop on `linear` (30-90s)
- No canvas, no WebGL, no Lottie — SVG-first, animated-discreet
- Spend the surface on the neutral-gray ladder (#171717 / #525252 / #707070 / #b2b2b2) and let the green #3fcf8e stay under ~2% as a status-light accent.
- Reach for a hairline 1px border (#dfdfdf / #c7c7c7) before any drop shadow — borders carry the structure.
- Switch to Source Code Pro for code, kbd, and tracked uppercase labels (12px / +1.2px letter-spacing); keep Circular for everything else.
- Default interactive transitions to 0.15s on cubic-bezier(0.4, 0, 0.2, 1); reach for cubic-bezier(0, 0, 0.2, 1) only for entrance reveals.
- Keep the type weight pair at 400/500 and carry hierarchy with size (12/14/16/18/24/36/72).
- Use the brand green for focus rings as well as links — one accent, doing double duty.
- Pass every page through useReducedMotion before shipping (marquee + pulse must collapse).
- Never let the green #3fcf8e become a default fill — the moment it covers more than a couple percent of the surface it stops reading as a signal.
- Never use #3fcf8e for body text — at ~1.7:1 on white it fails contrast; keep it to accents, borders, large/bold, and icons.
- Never substitute 600/700 weights for the 400/500 pair — hierarchy here is carried by size, not heavy weight.
- Never introduce a third typeface — Circular + Source Code Pro is the boundary; no decorative display face.
- Never replace the hairline-border structure with stacked drop shadows; the single soft shadow is for floating menus only.
- Never invent durations outside the captured set {0.15, 0.2, 0.3, 0.6}s (plus 30-90s ambient marquee); never add a sixth interactive easing beyond {cubic-bezier(0.4,0,0.2,1), cubic-bezier(0,0,0.2,1), cubic-bezier(0.4,0,0.6,1), linear, ease-out}.
- Never round the 11px radius to 12 — it's a captured optical value in the scale 6/8/11/12/16.
- Tailwind v4 @theme inline only — no runtime style concatenation, no CSS-in-JS.
- Spacing base 4px, scale 1/4/6/8/10/12/16/20/24/32/40/48 (dominant rhythm 8/16/24).
- Container max 1600px; workhorse 1536px; narrow reading rail 672px — do not exceed 1600.
- Two font families only: Circular (sans) + Source Code Pro (mono). Weight pair 400/500.
- Type scale strictly 12 / 14 / 16 / 18 / 24 / 36 / 72 px.
- Motion: four interactive durations (0.15 / 0.2 / 0.3 / 0.6 s) and five easings (cubic-bezier(0.4,0,0.2,1) primary, cubic-bezier(0,0,0.2,1), cubic-bezier(0.4,0,0.6,1), linear, ease-out). Ambient marquee 30-90s on linear. No springs.
- Radius scale: 6 / 8 / 11 / 12 / 16 px. Border width uniformly 1px.
- Brand green #3fcf8e is accent-only; body stays on the neutral-gray ladder over white #ffffff or black #000000.
- Accent audit: brand green #3fcf8e appears only as accent (links, focus, indicators) and covers under ~2% of the surface; the body is neutral gray.
- Contrast audit: #3fcf8e never used for body text (fails ~1.7:1 on white); body text #171717/#707070 on #ffffff stays ≥ 4.5:1.
- Border audit: every elevation uses a hairline 1px border first; drop shadow appears only on floating menus.
- Font weight grep: only 400 and 500 appear — no 600/700.
- Font family grep: exactly two families — Circular (sans) and Source Code Pro (mono); mono carries code + tracked uppercase labels (+1.2px).
- Type scale grep: font-size values draw from {12, 14, 16, 18, 24, 36, 72}px only.
- Spacing grep: no values outside the 1/4/6/8/10/12/16/20/24/32/40/48 ladder.
- Radius grep: corner radii draw from {6, 8, 11, 12, 16}px; border width uniformly 1px.
- Transition grep: timing-function values from {cubic-bezier(0.4,0,0.2,1), cubic-bezier(0,0,0.2,1), cubic-bezier(0.4,0,0.6,1), linear, ease-out}; durations from {0.15, 0.2, 0.3, 0.6}s plus ambient marquee.
- Container width: no bounded content exceeds 1600px; the 1536px container carries the page.
Design tokens
Observed token system
Color, type, spacing, gradients, and stacking order captured from the live page and rendered here as living, paste-ready previews.
Inspector
Observable layers
Structure, breakpoints, motion, fonts, and images captured from the live page and kept paste-ready alongside the tokens.
Depth-first walk of the meaningful sections. 6 nodes across 4 levels, shallow to deep by color.
- body1
- div3
- div1
- Nav
- Main
- Footer
Accessibility
Contrast matrix
88 combinations - 38 pass AA - 30 pass AAA. Each pair is previewed with its real foreground on background; APCA Lc sits alongside the WCAG 2.1 ratio for draft WCAG 3 awareness.
- fg
#FFFFFF- bg
#000000- APCA Lc
- -108
- Use
- background on foreground
- fg
#171717- bg
#FFFFFF- APCA Lc
- +105
- Use
- foreground on background
- fg
#FFFFFF- bg
#171717- APCA Lc
- -107
- Use
- background on foreground
- fg
#000000- bg
#A9F1CA- APCA Lc
- +89
- Use
- foreground on accent
- fg
#A9F1CA- bg
#000000- APCA Lc
- -89
- Use
- accent on foreground
- fg
#DFDFDF- bg
#000000- APCA Lc
- -87
- Use
- neutral on foreground
- fg
#000000- bg
#DFDFDF- APCA Lc
- +87
- Use
- foreground on neutral
- fg
#171717- bg
#A9F1CA- APCA Lc
- +87
- Use
- foreground on accent
Images
Image strategy
Observable image posture - total count, lazy-loading ratio, and format mix. The hero image is measured above the fold.
- svg78 · 98%
- unknown2 · 3%
Hero image
https://supabase.com/_next/image?url=%2Fimages%2Findex%2Fproducts%2Fdatabase-light.png&w=1920&q=100- Format
- UNKNOWN
- Dimensions
- 780x860
- Loading
- auto
- srcset
- yes
- Industry
- developer-tools
- Industry
- saas
- Theme
- Dark
- Added
- 2026-06-23
FAQ
Questions people ask about Supabase
3questionsAnswers are pulled from the curator verdict and design brief - the same text your AI agent sees when it paste-reads this page.
Compare this with



