④段整套同步(六节 + P/S/F/J + 模板)+ open-design 移到技能根
一、④段整套同步(用户选候选 A)
- 新增 `references/stage-proto-doc/assets/产品文档模板.html`(16 KB/247 行,从备份拷、转 LF)。
- ④段 SKILL.md 换成备份 15:28 那版,并按模板口径改齐:
· 「产品文档框架」从「四块+一附录」改成**六节** —— 页面结构/功能清单/使用场景/操作流程/
跨页与界面状态/待确认与偏离;与模板同构,⛔ 不从空白页重写结构。
· 编号从 R/S/F 改成 **P 页面/S 场景/F 功能/J 二级功能**,各自唯一、按展示顺序通排。
· 保留旧版有价值的要求:每项功能补齐 做什么/入口在哪/输入边界/异常与恢复;重点功能三处标红;
横向流程图每步写清页面/功能/操作/完成判据。
· 完成标准「七节」→「六节」,自查清单同步换掉「需求」那批条目,补模板与配图两条。
· 路径 `designs/<项目>/` → `docs/pm/<项目>/ui/`(2 处)。
· 补回本机那条「每份产出文档开头都要有一张图」的引用(指向主 skill,段内不复述)。
- 主 skill 同步:四段结构表④行、④段沿革、画图小节(④段画页面结构图 + 用户路径)。
二、open-design 移到技能根(用户选候选 A)
- `git mv product-planning/references/stage-delivery/assets/open-design → open-design/`(4178 文件)。
- `.gitignore` 白名单加 `!/open-design/` —— 否则移出去就不再纳入版本控制。
- 引用改 11 处:路径形态 `assets/open-design/...` → `<技能根>/open-design/...`;
「随段携带的自带件」改称「同根技能」;「路径怎么找」那条改成自带件(段内相对路径)与
同根技能(`<技能根>/<技能名>/`)两类分开写。
- open-design 自己的 ATTRIBUTION.md 两处同步(它现在与 oil-ui-pro 同层)。
- 副作用(有益):命名闸门读数由 2063 降到 225 —— 此前它把 open-design 里 919 个第三方 md
当成规则一起扫了;现在只扫本包 23 个 md。已确认④段的 H1 与 4a/4b/4c 子步仍在检查范围内。
三、验收
- check_naming.py --ws E:/ProgramData/AIProject/contentm_agent = 通过 225 / 失败 0 / 提示 27。
- 活文件里 `assets/open-design` 残留 0;工作区 CRLF 文件 0。
This commit is contained in:
1 parent
fa0a9026c8
commit
5afeb6b78a
4184 files changed
+326
-70
No files matched your search
@@ -0,0 +1,258 @@
|
||||
# Design System Inspired by Supabase
|
||||
|
||||
> Category: Backend & Data
|
||||
> Open-source Firebase alternative. Dark emerald theme, code-first.
|
||||
|
||||
## 1. Visual Theme & Atmosphere
|
||||
|
||||
Supabase's website is a dark-mode-native developer platform that channels the aesthetic of a premium code editor — deep black backgrounds (`#0f0f0f`, `#171717`) with emerald green accents (`#3ecf8e`, `#00c573`) that reference the brand's open-source, PostgreSQL-green identity. The design system feels like it was born in a terminal window and evolved into a sophisticated marketing surface without losing its developer soul.
|
||||
|
||||
The typography is built on "Circular" — a geometric sans-serif with rounded terminals that softens the technical edge. At 72px with a 1.00 line-height, the hero text is compressed to its absolute minimum vertical space, creating dense, impactful statements that waste nothing. The monospace companion (Source Code Pro) appears sparingly for uppercase technical labels with 1.2px letter-spacing, creating the "developer console" markers that connect the marketing site to the product experience.
|
||||
|
||||
What makes Supabase distinctive is its sophisticated HSL-based color token system. Rather than flat hex values, Supabase uses HSL with alpha channels for nearly every color (`--colors-crimson4`, `--colors-purple5`, `--colors-slateA12`), enabling a nuanced layering system where colors interact through transparency. This creates depth through translucency — borders at `rgba(46, 46, 46)`, surfaces at `rgba(41, 41, 41, 0.84)`, and accents at partial opacity all blend with the dark background to create a rich, dimensional palette from minimal color ingredients.
|
||||
|
||||
The green accent (`#3ecf8e`) appears selectively — in the Supabase logo, in link colors (`#00c573`), and in border highlights (`rgba(62, 207, 142, 0.3)`) — always as a signal of "this is Supabase" rather than as a decorative element. Pill-shaped buttons (9999px radius) for primary CTAs contrast with standard 6px radius for secondary elements, creating a clear visual hierarchy of importance.
|
||||
|
||||
**Key Characteristics:**
|
||||
- Dark-mode-native: near-black backgrounds (`#0f0f0f`, `#171717`) — never pure black
|
||||
- Emerald green brand accent (`#3ecf8e`, `#00c573`) used sparingly as identity marker
|
||||
- Circular font — geometric sans-serif with rounded terminals
|
||||
- Source Code Pro for uppercase technical labels (1.2px letter-spacing)
|
||||
- HSL-based color token system with alpha channels for translucent layering
|
||||
- Pill buttons (9999px) for primary CTAs, 6px radius for secondary
|
||||
- Neutral gray scale from `#171717` through `#898989` to `#fafafa`
|
||||
- Border system using dark grays (`#2e2e2e`, `#363636`, `#393939`)
|
||||
- Minimal shadows — depth through border contrast and transparency
|
||||
- Radix color primitives (crimson, purple, violet, indigo, yellow, tomato, orange, slate)
|
||||
|
||||
## 2. Color Palette & Roles
|
||||
|
||||
### Brand
|
||||
- **Supabase Green** (`#3ecf8e`): Primary brand color, logo, accent borders
|
||||
- **Green Link** (`#00c573`): Interactive green for links and actions
|
||||
- **Green Border** (`rgba(62, 207, 142, 0.3)`): Subtle green border accent
|
||||
|
||||
### Neutral Scale (Dark Mode)
|
||||
- **Near Black** (`#0f0f0f`): Primary button background, deepest surface
|
||||
- **Dark** (`#171717`): Page background, primary canvas
|
||||
- **Dark Border** (`#242424`): Horizontal rule, section dividers
|
||||
- **Border Dark** (`#2e2e2e`): Card borders, tab borders
|
||||
- **Mid Border** (`#363636`): Button borders, dividers
|
||||
- **Border Light** (`#393939`): Secondary borders
|
||||
- **Charcoal** (`#434343`): Tertiary borders, dark accents
|
||||
- **Dark Gray** (`#4d4d4d`): Heavy secondary text
|
||||
- **Mid Gray** (`#898989`): Muted text, link color
|
||||
- **Light Gray** (`#b4b4b4`): Secondary link text
|
||||
- **Near White** (`#efefef`): Light border, subtle surface
|
||||
- **Off White** (`#fafafa`): Primary text, button text
|
||||
|
||||
### Radix Color Tokens (HSL-based)
|
||||
- **Slate Scale**: `--colors-slate5` through `--colors-slateA12` — neutral progression
|
||||
- **Purple**: `--colors-purple4`, `--colors-purple5`, `--colors-purpleA7` — accent spectrum
|
||||
- **Violet**: `--colors-violet10` (`hsl(251, 63.2%, 63.2%)`) — vibrant accent
|
||||
- **Crimson**: `--colors-crimson4`, `--colors-crimsonA9` — warm accent / alert
|
||||
- **Indigo**: `--colors-indigoA2` — subtle blue wash
|
||||
- **Yellow**: `--colors-yellowA7` — attention/warning
|
||||
- **Tomato**: `--colors-tomatoA4` — error accent
|
||||
- **Orange**: `--colors-orange6` — warm accent
|
||||
|
||||
### Surface & Overlay
|
||||
- **Glass Dark** (`rgba(41, 41, 41, 0.84)`): Translucent dark overlay
|
||||
- **Slate Alpha** (`hsla(210, 87.8%, 16.1%, 0.031)`): Ultra-subtle blue wash
|
||||
- **Fixed Scale Alpha** (`hsla(200, 90.3%, 93.4%, 0.109)`): Light frost overlay
|
||||
|
||||
### Shadows
|
||||
- Supabase uses **almost no shadows** in its dark theme. Depth is created through border contrast and surface color differences rather than box-shadows. Focus states use `rgba(0, 0, 0, 0.1) 0px 4px 12px` — minimal, functional.
|
||||
|
||||
## 3. Typography Rules
|
||||
|
||||
### Font Families
|
||||
- **Primary**: `Circular`, with fallbacks: `custom-font, Helvetica Neue, Helvetica, Arial`
|
||||
- **Monospace**: `Source Code Pro`, with fallbacks: `Office Code Pro, Menlo`
|
||||
|
||||
### Hierarchy
|
||||
|
||||
| Role | Font | Size | Weight | Line Height | Letter Spacing | Notes |
|
||||
|------|------|------|--------|-------------|----------------|-------|
|
||||
| Display Hero | Circular | 72px (4.50rem) | 400 | 1.00 (tight) | normal | Maximum density, zero waste |
|
||||
| Section Heading | Circular | 36px (2.25rem) | 400 | 1.25 (tight) | normal | Feature section titles |
|
||||
| Card Title | Circular | 24px (1.50rem) | 400 | 1.33 | -0.16px | Slight negative tracking |
|
||||
| Sub-heading | Circular | 18px (1.13rem) | 400 | 1.56 | normal | Secondary headings |
|
||||
| Body | Circular | 16px (1.00rem) | 400 | 1.50 | normal | Standard body text |
|
||||
| Nav Link | Circular | 14px (0.88rem) | 500 | 1.00–1.43 | normal | Navigation items |
|
||||
| Button | Circular | 14px (0.88rem) | 500 | 1.14 (tight) | normal | Button labels |
|
||||
| Caption | Circular | 14px (0.88rem) | 400–500 | 1.43 | normal | Metadata, tags |
|
||||
| Small | Circular | 12px (0.75rem) | 400 | 1.33 | normal | Fine print, footer links |
|
||||
| Code Label | Source Code Pro | 12px (0.75rem) | 400 | 1.33 | 1.2px | `text-transform: uppercase` |
|
||||
|
||||
### Principles
|
||||
- **Weight restraint**: Nearly all text uses weight 400 (regular/book). Weight 500 appears only for navigation links and button labels. There is no bold (700) in the detected system — hierarchy is created through size, not weight.
|
||||
- **1.00 hero line-height**: The hero text is compressed to absolute zero leading. This is the defining typographic gesture — text that feels like a terminal command: dense, efficient, no wasted vertical space.
|
||||
- **Negative tracking on cards**: Card titles use -0.16px letter-spacing, a subtle tightening that differentiates them from body text without being obvious.
|
||||
- **Monospace as ritual**: Source Code Pro in uppercase with 1.2px letter-spacing is the "developer console" voice — used sparingly for technical labels that connect to the product experience.
|
||||
- **Geometric personality**: Circular's rounded terminals create warmth in what could otherwise be a cold, technical interface. The font is the humanizing element.
|
||||
|
||||
## 4. Component Stylings
|
||||
|
||||
### Buttons
|
||||
|
||||
**Primary Pill (Dark)**
|
||||
- Background: `#0f0f0f`
|
||||
- Text: `#fafafa`
|
||||
- Padding: 8px 32px
|
||||
- Radius: 9999px (full pill)
|
||||
- Border: `1px solid #fafafa` (white border on dark)
|
||||
- Focus shadow: `rgba(0, 0, 0, 0.1) 0px 4px 12px`
|
||||
- Use: Primary CTA ("Start your project")
|
||||
|
||||
**Secondary Pill (Dark, Muted)**
|
||||
- Background: `#0f0f0f`
|
||||
- Text: `#fafafa`
|
||||
- Padding: 8px 32px
|
||||
- Radius: 9999px
|
||||
- Border: `1px solid #2e2e2e` (dark border)
|
||||
- Opacity: 0.8
|
||||
- Use: Secondary CTA alongside primary
|
||||
|
||||
**Ghost Button**
|
||||
- Background: transparent
|
||||
- Text: `#fafafa`
|
||||
- Padding: 8px
|
||||
- Radius: 6px
|
||||
- Border: `1px solid transparent`
|
||||
- Use: Tertiary actions, icon buttons
|
||||
|
||||
### Cards & Containers
|
||||
- Background: dark surfaces (`#171717` or slightly lighter)
|
||||
- Border: `1px solid #2e2e2e` or `#363636`
|
||||
- Radius: 8px–16px
|
||||
- No visible shadows — borders define edges
|
||||
- Internal padding: 16px–24px
|
||||
|
||||
### Tabs
|
||||
- Border: `1px solid #2e2e2e`
|
||||
- Radius: 9999px (pill tabs)
|
||||
- Active: green accent or lighter surface
|
||||
- Inactive: dark, muted
|
||||
|
||||
### Links
|
||||
- **Green**: `#00c573` — Supabase-branded links
|
||||
- **Primary Light**: `#fafafa` — standard links on dark
|
||||
- **Secondary**: `#b4b4b4` — muted links
|
||||
- **Muted**: `#898989` — tertiary links, footer
|
||||
|
||||
### Navigation
|
||||
- Dark background matching page (`#171717`)
|
||||
- Supabase logo with green icon
|
||||
- Circular 14px weight 500 for nav links
|
||||
- Clean horizontal layout with product dropdown
|
||||
- Green "Start your project" CTA pill button
|
||||
- Sticky header behavior
|
||||
|
||||
## 5. Layout Principles
|
||||
|
||||
### Spacing System
|
||||
- Base unit: 8px
|
||||
- Scale: 1px, 4px, 6px, 8px, 12px, 16px, 20px, 24px, 32px, 40px, 48px, 90px, 96px, 128px
|
||||
- Notable large jumps: 48px → 90px → 96px → 128px for major section spacing
|
||||
|
||||
### Grid & Container
|
||||
- Centered content with generous max-width
|
||||
- Full-width dark sections with constrained inner content
|
||||
- Feature grids: icon-based grids with consistent card sizes
|
||||
- Logo grids for "Trusted by" sections
|
||||
- Footer: multi-column on dark background
|
||||
|
||||
### Breakpoints
|
||||
| Name | Width | Key Changes |
|
||||
|------|-------|-------------|
|
||||
| Mobile | <600px | Single column, stacked layout |
|
||||
| Desktop | >600px | Multi-column grids, expanded layout |
|
||||
|
||||
*Note: Supabase uses a notably minimal breakpoint system — primarily a single 600px breakpoint, suggesting a mobile-first approach with progressive enhancement.*
|
||||
|
||||
### Whitespace Philosophy
|
||||
- **Dramatic section spacing**: 90px–128px between major sections creates a cinematic pacing — each section is its own scene in the dark void.
|
||||
- **Dense content blocks**: Within sections, spacing is tight (16px–24px), creating concentrated information clusters.
|
||||
- **Border-defined space**: Instead of whitespace + shadows for separation, Supabase uses thin borders on dark backgrounds — separation through line, not gap.
|
||||
|
||||
### Border Radius Scale
|
||||
- Standard (6px): Ghost buttons, small elements
|
||||
- Comfortable (8px): Cards, containers
|
||||
- Medium (11px–12px): Mid-size panels
|
||||
- Large (16px): Feature cards, major containers
|
||||
- Pill (9999px): Primary buttons, tab indicators
|
||||
|
||||
## 6. Depth & Elevation
|
||||
|
||||
| Level | Treatment | Use |
|
||||
|-------|-----------|-----|
|
||||
| Flat (Level 0) | No shadow, border `#2e2e2e` | Default state, most surfaces |
|
||||
| Subtle Border (Level 1) | Border `#363636` or `#393939` | Interactive elements, hover |
|
||||
| Focus (Level 2) | `rgba(0, 0, 0, 0.1) 0px 4px 12px` | Focus states only |
|
||||
| Green Accent (Level 3) | Border `rgba(62, 207, 142, 0.3)` | Brand-highlighted elements |
|
||||
|
||||
**Shadow Philosophy**: Supabase deliberately avoids shadows. In a dark-mode-native design, shadows are nearly invisible and serve no purpose. Instead, depth is communicated through a sophisticated border hierarchy — from `#242424` (barely visible) through `#2e2e2e` (standard) to `#393939` (prominent). The green accent border (`rgba(62, 207, 142, 0.3)`) at 30% opacity is the "elevated" state — the brand color itself becomes the depth signal.
|
||||
|
||||
## 7. Do's and Don'ts
|
||||
|
||||
### Do
|
||||
- Use near-black backgrounds (`#0f0f0f`, `#171717`) — depth comes from the gray border hierarchy
|
||||
- Apply Supabase green (`#3ecf8e`, `#00c573`) sparingly — it's an identity marker, not a decoration
|
||||
- Use Circular at weight 400 for nearly everything — 500 only for buttons and nav
|
||||
- Set hero text to 1.00 line-height — the zero-leading is the typographic signature
|
||||
- Create depth through border color differences (`#242424` → `#2e2e2e` → `#363636`)
|
||||
- Use pill shape (9999px) exclusively for primary CTAs and tabs
|
||||
- Employ HSL-based colors with alpha for translucent layering effects
|
||||
- Use Source Code Pro uppercase labels for developer-context markers
|
||||
|
||||
### Don't
|
||||
- Don't add box-shadows — they're invisible on dark backgrounds and break the border-defined depth system
|
||||
- Don't use bold (700) text weight — the system uses 400 and 500 only
|
||||
- Don't apply green to backgrounds or large surfaces — it's for borders, links, and small accents
|
||||
- Don't use warm colors (crimson, orange) as primary design elements — they exist as semantic tokens for states
|
||||
- Don't increase hero line-height above 1.00 — the density is intentional
|
||||
- Don't use large border radius (16px+) on buttons — pills (9999px) or standard (6px), nothing in between
|
||||
- Don't lighten the background above `#171717` for primary surfaces — the darkness is structural
|
||||
- Don't forget the translucent borders — `rgba` border colors are the layering mechanism
|
||||
|
||||
## 8. Responsive Behavior
|
||||
|
||||
### Breakpoints
|
||||
| Name | Width | Key Changes |
|
||||
|------|-------|-------------|
|
||||
| Mobile | <600px | Single column, stacked features, condensed nav |
|
||||
| Desktop | >600px | Multi-column grids, full nav, expanded sections |
|
||||
|
||||
### Collapsing Strategy
|
||||
- Hero: 72px → scales down proportionally
|
||||
- Feature grids: multi-column → single column stacked
|
||||
- Logo row: horizontal → wrapped grid
|
||||
- Navigation: full → hamburger
|
||||
- Section spacing: 90–128px → 48–64px
|
||||
- Buttons: inline → full-width stacked
|
||||
|
||||
## 9. Agent Prompt Guide
|
||||
|
||||
### Quick Color Reference
|
||||
- Background: `#0f0f0f` (button), `#171717` (page)
|
||||
- Text: `#fafafa` (primary), `#b4b4b4` (secondary), `#898989` (muted)
|
||||
- Brand green: `#3ecf8e` (brand), `#00c573` (links)
|
||||
- Borders: `#242424` (subtle), `#2e2e2e` (standard), `#363636` (prominent)
|
||||
- Green border: `rgba(62, 207, 142, 0.3)` (accent)
|
||||
|
||||
### Example Component Prompts
|
||||
- "Create a hero section on #171717 background. Headline at 72px Circular weight 400, line-height 1.00, #fafafa text. Sub-text at 16px Circular weight 400, line-height 1.50, #b4b4b4. Pill CTA button (#0f0f0f bg, #fafafa text, 9999px radius, 8px 32px padding, 1px solid #fafafa border)."
|
||||
- "Design a feature card: #171717 background, 1px solid #2e2e2e border, 16px radius. Title at 24px Circular weight 400, letter-spacing -0.16px. Body at 14px weight 400, #898989 text."
|
||||
- "Build navigation bar: #171717 background. Circular 14px weight 500 for links, #fafafa text. Supabase logo with green icon left-aligned. Green pill CTA 'Start your project' right-aligned."
|
||||
- "Create a technical label: Source Code Pro 12px, uppercase, letter-spacing 1.2px, #898989 text."
|
||||
- "Design a framework logo grid: 6-column layout on dark, grayscale logos at 60% opacity, 1px solid #2e2e2e border between sections."
|
||||
|
||||
### Iteration Guide
|
||||
1. Start with #171717 background — everything is dark-mode-native
|
||||
2. Green is the brand identity marker — use it for links, logo, and accent borders only
|
||||
3. Depth comes from borders (#242424 → #2e2e2e → #363636), not shadows
|
||||
4. Weight 400 is the default for everything — 500 only for interactive elements
|
||||
5. Hero line-height of 1.00 is the signature typographic move
|
||||
6. Pill (9999px) for primary actions, 6px for secondary, 8-16px for cards
|
||||
7. HSL with alpha channels creates the sophisticated translucent layering
|
||||
@@ -0,0 +1,32 @@
|
||||
# Supabase Usage
|
||||
|
||||
Design System 2.0 package guide for OpenDesign agents and reviewers.
|
||||
|
||||
## Read Order
|
||||
|
||||
1. Read this file first to understand the package contract.
|
||||
2. Read `DESIGN.md` for visual intent, constraints, and anti-patterns.
|
||||
3. Paste `tokens.css` into the first artifact `<style>` block before writing component CSS.
|
||||
4. Use `components.manifest.json` for the compact component inventory; open `components.html` when exact selectors or states matter.
|
||||
5. Inspect `preview/` pages when a visual sanity check is useful.
|
||||
|
||||
## Design Highlights
|
||||
|
||||
- Dark-mode-native: near-black backgrounds (`#0f0f0f`, `#171717`) — never pure black
|
||||
- Emerald green brand accent (`#3ecf8e`, `#00c573`) used sparingly as identity marker
|
||||
- Circular font — geometric sans-serif with rounded terminals
|
||||
- Source Code Pro for uppercase technical labels (1.2px letter-spacing)
|
||||
|
||||
## Do
|
||||
|
||||
- Preserve the schema token names exactly so cross-brand switching stays reliable.
|
||||
- Use `--accent` for primary actions, links, focus states, and one clear focal element.
|
||||
- Reuse component groups from `components.manifest.json` before inventing new controls.
|
||||
- Treat `source/` files as audit evidence for the bundled fixture backfill.
|
||||
|
||||
## Avoid
|
||||
|
||||
- Avoid raw hex values outside the copied `:root` token block.
|
||||
- Avoid redefining Tailwind or design-token values independently of `tokens.css`.
|
||||
- Avoid claiming original upstream source evidence; this package is based on the curated bundled fixture.
|
||||
- Avoid adding new component recipes that are not represented in `components.html` or `DESIGN.md`.
|
||||
@@ -0,0 +1,741 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Supabase — reference components</title>
|
||||
<meta
|
||||
name="description"
|
||||
content="Reference fixture for design-systems/supabase. Every visible
|
||||
value comes from tokens.css. Supabase's signature moves: near-black
|
||||
canvas, Postgres-emerald reserved as identity marker, Circular geometric
|
||||
sans with weight restraint, Source Code Pro uppercase for the developer-
|
||||
console voice, depth carried by a tight border hierarchy."
|
||||
/>
|
||||
|
||||
<style>
|
||||
/* :root paste — sourced verbatim from design-systems/supabase/tokens.css. */
|
||||
:root {
|
||||
--bg: #171717;
|
||||
--surface: #1c1c1c;
|
||||
--surface-warm: var(--surface);
|
||||
|
||||
--fg: #fafafa;
|
||||
--fg-2: #b4b4b4;
|
||||
--muted: #898989;
|
||||
--meta: #4d4d4d;
|
||||
|
||||
--border: #2e2e2e;
|
||||
--border-soft: #242424;
|
||||
|
||||
--accent: #3ecf8e;
|
||||
--accent-on: #0f0f0f;
|
||||
--accent-hover: #00c573;
|
||||
--accent-active: color-mix(in oklab, var(--accent), black 14%);
|
||||
|
||||
--success: #16a34a;
|
||||
--warn: #eab308;
|
||||
--danger: #dc2626;
|
||||
|
||||
--font-display: "Circular", "custom-font", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
--font-body: "Circular", "custom-font", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
--font-mono: "Source Code Pro", "Office Code Pro", Menlo, Monaco, Consolas, monospace;
|
||||
|
||||
--text-xs: 12px;
|
||||
--text-sm: 14px;
|
||||
--text-base: 16px;
|
||||
--text-lg: 18px;
|
||||
--text-xl: 24px;
|
||||
--text-2xl: 32px;
|
||||
--text-3xl: 36px;
|
||||
--text-4xl: 72px;
|
||||
|
||||
--leading-body: 1.5;
|
||||
--leading-tight: 1.00;
|
||||
--tracking-display: normal;
|
||||
|
||||
--space-1: 4px;
|
||||
--space-2: 8px;
|
||||
--space-3: 12px;
|
||||
--space-4: 16px;
|
||||
--space-5: 20px;
|
||||
--space-6: 24px;
|
||||
--space-8: 32px;
|
||||
--space-12: 48px;
|
||||
|
||||
--section-y-desktop: 128px;
|
||||
--section-y-tablet: 80px;
|
||||
--section-y-phone: 48px;
|
||||
|
||||
--radius-sm: 6px;
|
||||
--radius-md: 8px;
|
||||
--radius-lg: 16px;
|
||||
--radius-pill: 9999px;
|
||||
|
||||
--elev-flat: none;
|
||||
--elev-ring: 0 0 0 1px var(--border);
|
||||
--elev-raised: 0 0 0 1px var(--border), 0 4px 12px rgba(0, 0, 0, 0.4);
|
||||
|
||||
--focus-ring: 0 0 0 2px color-mix(in oklab, var(--accent), transparent 50%);
|
||||
|
||||
--motion-fast: 150ms;
|
||||
--motion-base: 200ms;
|
||||
--ease-standard: cubic-bezier(0.2, 0, 0, 1);
|
||||
|
||||
--container-max: 1200px;
|
||||
--container-gutter-desktop: 24px;
|
||||
--container-gutter-tablet: 16px;
|
||||
--container-gutter-phone: 16px;
|
||||
}
|
||||
|
||||
/* ─── Reset (minimal) ─────────────────────────────────────── */
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
html, body { margin: 0; padding: 0; }
|
||||
body {
|
||||
background: var(--bg);
|
||||
color: var(--fg-2);
|
||||
font-family: var(--font-body);
|
||||
font-size: var(--text-base);
|
||||
line-height: var(--leading-body);
|
||||
font-weight: 400;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
text-rendering: optimizeLegibility;
|
||||
}
|
||||
|
||||
/* ─── Layout primitives ─────────────────────────────────── */
|
||||
.container {
|
||||
max-width: var(--container-max);
|
||||
margin-inline: auto;
|
||||
padding-inline: var(--container-gutter-desktop);
|
||||
}
|
||||
section {
|
||||
padding-block: var(--section-y-desktop);
|
||||
}
|
||||
section + section {
|
||||
/* DESIGN.md §6: depth comes from borders, not shadows. Section
|
||||
dividers use the standard border tier — a hairline against
|
||||
the dark canvas, the brand's "edges define" promise. */
|
||||
border-top: 1px solid var(--border);
|
||||
}
|
||||
@media (max-width: 1023px) {
|
||||
.container { padding-inline: var(--container-gutter-tablet); }
|
||||
section { padding-block: var(--section-y-tablet); }
|
||||
}
|
||||
@media (max-width: 639px) {
|
||||
.container { padding-inline: var(--container-gutter-phone); }
|
||||
section { padding-block: var(--section-y-phone); }
|
||||
}
|
||||
|
||||
/* ─── Typography ────────────────────────────────────────────
|
||||
* Weight restraint: 400 for prose, 500 for interactive elements.
|
||||
* DESIGN.md §3 Principles: "There is no bold (700) in the
|
||||
* detected system — hierarchy is created through size, not
|
||||
* weight." Display sizes hold at leading 1.00 (the defining
|
||||
* gesture) and tracking `normal`; smaller scales relax leading
|
||||
* upward as the table in DESIGN.md §3 prescribes. */
|
||||
h1, h2, h3, h4 {
|
||||
font-family: var(--font-display);
|
||||
font-weight: 400;
|
||||
margin: 0;
|
||||
color: var(--fg);
|
||||
line-height: var(--leading-tight);
|
||||
letter-spacing: var(--tracking-display);
|
||||
}
|
||||
h1 {
|
||||
font-size: var(--text-4xl);
|
||||
/* DESIGN.md §3 Display Hero: 72px / 1.00 leading / normal
|
||||
tracking — the terminal-density typographic signature. */
|
||||
}
|
||||
h2 {
|
||||
font-size: var(--text-3xl);
|
||||
/* DESIGN.md §3 Section Heading: 36px / 1.25 leading.
|
||||
Overrides the shared 1.00 set above. */
|
||||
line-height: 1.25;
|
||||
}
|
||||
h3 {
|
||||
font-size: var(--text-xl);
|
||||
/* DESIGN.md §3 Card Title: 24px / 1.33 leading / -0.16px
|
||||
tracking ≈ -0.0067em. The subtle negative tracking is the
|
||||
card-title differentiation from body text. */
|
||||
line-height: 1.33;
|
||||
letter-spacing: -0.0067em;
|
||||
}
|
||||
h4 {
|
||||
font-size: var(--text-lg);
|
||||
line-height: 1.56;
|
||||
}
|
||||
p { margin: 0; }
|
||||
|
||||
.lede {
|
||||
font-size: var(--text-base);
|
||||
line-height: var(--leading-body);
|
||||
color: var(--fg-2);
|
||||
max-width: 56ch;
|
||||
}
|
||||
.body-muted { color: var(--muted); }
|
||||
.body-meta { color: var(--meta); font-size: var(--text-sm); }
|
||||
.body-sm { font-size: var(--text-sm); }
|
||||
|
||||
/* Eyebrow uses Source Code Pro uppercase — DESIGN.md §3:
|
||||
"Source Code Pro in uppercase with 1.2px letter-spacing is
|
||||
the 'developer console' voice — used sparingly for technical
|
||||
labels that connect to the product experience." 1.2px at
|
||||
12px ≈ 0.1em. */
|
||||
.eyebrow {
|
||||
font-family: var(--font-mono);
|
||||
font-size: var(--text-xs);
|
||||
font-weight: 400;
|
||||
line-height: 1.33;
|
||||
color: var(--muted);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.1em;
|
||||
}
|
||||
|
||||
.stack-3 > * + * { margin-block-start: var(--space-3); }
|
||||
.stack-4 > * + * { margin-block-start: var(--space-4); }
|
||||
.stack-6 > * + * { margin-block-start: var(--space-6); }
|
||||
|
||||
/* ─── Buttons ───────────────────────────────────────────────
|
||||
* DESIGN.md §4 + §7: primary CTAs are pills (9999px radius),
|
||||
* ghost buttons take the 6px standard radius. The brand
|
||||
* deliberately FORBIDS in-between radii on buttons. The
|
||||
* primary pill is `#0f0f0f` background with `#fafafa` text and
|
||||
* a white border — the brand's "pill on dark" pattern, NOT
|
||||
* `background: var(--accent)`. Emerald stays reserved for the
|
||||
* brand-pill variant below and for links + focus. */
|
||||
.btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: var(--space-2);
|
||||
padding: var(--space-2) var(--space-8);
|
||||
border: 1px solid transparent;
|
||||
border-radius: var(--radius-pill);
|
||||
font-family: var(--font-display);
|
||||
font-size: var(--text-sm);
|
||||
font-weight: 500;
|
||||
line-height: 1.14;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
background: transparent;
|
||||
color: inherit;
|
||||
transition:
|
||||
background-color var(--motion-fast) var(--ease-standard),
|
||||
border-color var(--motion-fast) var(--ease-standard),
|
||||
color var(--motion-fast) var(--ease-standard);
|
||||
}
|
||||
.btn:focus-visible {
|
||||
outline: none;
|
||||
box-shadow: var(--focus-ring);
|
||||
}
|
||||
.btn-primary {
|
||||
background: #0f0f0f;
|
||||
color: var(--fg);
|
||||
border-color: var(--fg);
|
||||
}
|
||||
.btn-primary:hover {
|
||||
background: color-mix(in oklab, #0f0f0f, var(--fg) 6%);
|
||||
}
|
||||
.btn-secondary {
|
||||
background: #0f0f0f;
|
||||
color: var(--fg);
|
||||
border-color: var(--border);
|
||||
opacity: 0.92;
|
||||
}
|
||||
.btn-secondary:hover {
|
||||
border-color: color-mix(in oklab, var(--border), var(--fg) 16%);
|
||||
opacity: 1;
|
||||
}
|
||||
/* Brand pill — the one place emerald appears as a button surface.
|
||||
Reserved for the single highest-intent CTA per screen so the
|
||||
≤2 accent-uses budget stays honest. */
|
||||
.btn-brand {
|
||||
background: var(--accent);
|
||||
color: var(--accent-on);
|
||||
border-color: var(--accent);
|
||||
}
|
||||
.btn-brand:hover {
|
||||
background: var(--accent-hover);
|
||||
border-color: var(--accent-hover);
|
||||
}
|
||||
.btn-brand:active { background: var(--accent-active); }
|
||||
.btn-ghost {
|
||||
background: transparent;
|
||||
color: var(--fg);
|
||||
border-radius: var(--radius-sm);
|
||||
padding: var(--space-2) var(--space-3);
|
||||
border-color: transparent;
|
||||
}
|
||||
.btn-ghost:hover {
|
||||
background: var(--surface);
|
||||
}
|
||||
|
||||
/* ─── Inputs ────────────────────────────────────────────────
|
||||
* Border-defined edges (DESIGN.md §6 — no shadows on dark).
|
||||
* On focus the border resolves to the brand accent at full
|
||||
* saturation, layered with the green focus halo. */
|
||||
.field {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-2);
|
||||
}
|
||||
.field label {
|
||||
font-size: var(--text-sm);
|
||||
font-weight: 500;
|
||||
color: var(--fg);
|
||||
}
|
||||
.field input {
|
||||
padding: var(--space-3) var(--space-4);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-sm);
|
||||
background: var(--bg);
|
||||
color: var(--fg);
|
||||
font-family: inherit;
|
||||
font-size: var(--text-sm);
|
||||
line-height: 1.43;
|
||||
outline: none;
|
||||
transition:
|
||||
border-color var(--motion-fast) var(--ease-standard),
|
||||
box-shadow var(--motion-fast) var(--ease-standard);
|
||||
}
|
||||
.field input::placeholder { color: var(--meta); }
|
||||
.field input:hover { border-color: #393939; }
|
||||
.field input:focus-visible {
|
||||
border-color: var(--accent);
|
||||
box-shadow: var(--focus-ring);
|
||||
}
|
||||
.field-help {
|
||||
font-size: var(--text-xs);
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
/* ─── Cards ─────────────────────────────────────────────────
|
||||
* Border defines the edge (DESIGN.md §4): #2e2e2e at 8px or
|
||||
* 16px radius depending on hierarchy. No shadows by default —
|
||||
* the hover state introduces the green-accent border for the
|
||||
* "brand-highlighted" elevation (DESIGN.md §6 Level 3). */
|
||||
.card {
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-lg);
|
||||
padding: var(--space-6);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-4);
|
||||
transition:
|
||||
border-color var(--motion-base) var(--ease-standard),
|
||||
background-color var(--motion-base) var(--ease-standard);
|
||||
}
|
||||
.card:hover {
|
||||
border-color: color-mix(in oklab, var(--accent), transparent 70%);
|
||||
}
|
||||
|
||||
/* ─── Badges ────────────────────────────────────────────────
|
||||
* Pill badges with hairline borders — Supabase uses these for
|
||||
* status markers and stage labels. The accent badge tints the
|
||||
* brand emerald against the dark surface; the muted badge
|
||||
* sits on the standard border tier. */
|
||||
.badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: var(--space-1);
|
||||
padding: var(--space-1) var(--space-3);
|
||||
border-radius: var(--radius-pill);
|
||||
font-family: var(--font-display);
|
||||
font-size: var(--text-xs);
|
||||
font-weight: 500;
|
||||
line-height: 1.33;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
.badge-accent {
|
||||
color: var(--accent);
|
||||
background: color-mix(in oklab, var(--accent), var(--bg) 88%);
|
||||
border-color: color-mix(in oklab, var(--accent), transparent 70%);
|
||||
}
|
||||
.badge-muted {
|
||||
color: var(--fg-2);
|
||||
background: var(--surface);
|
||||
border-color: var(--border);
|
||||
}
|
||||
.badge-success {
|
||||
color: var(--success);
|
||||
background: color-mix(in oklab, var(--success), var(--bg) 88%);
|
||||
border-color: color-mix(in oklab, var(--success), transparent 75%);
|
||||
}
|
||||
.badge-dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: var(--radius-pill);
|
||||
background: currentColor;
|
||||
}
|
||||
|
||||
/* ─── Links ─────────────────────────────────────────────────
|
||||
* DESIGN.md §4: "Green: #00c573 — Supabase-branded links." We
|
||||
* bind link color to the interactive-green variant (which is
|
||||
* `--accent-hover` in this brand's mapping — see tokens.css §4)
|
||||
* because that's the documented interactive form of the accent. */
|
||||
a {
|
||||
color: var(--accent-hover);
|
||||
text-decoration: none;
|
||||
border-bottom: 1px solid color-mix(in oklab, var(--accent-hover), transparent 70%);
|
||||
transition:
|
||||
color var(--motion-fast) var(--ease-standard),
|
||||
border-color var(--motion-fast) var(--ease-standard);
|
||||
}
|
||||
a:hover {
|
||||
color: var(--accent);
|
||||
border-bottom-color: var(--accent);
|
||||
}
|
||||
a:focus-visible {
|
||||
outline: none;
|
||||
border-radius: 2px;
|
||||
box-shadow: var(--focus-ring);
|
||||
}
|
||||
|
||||
/* ─── Kbd ───────────────────────────────────────────────────
|
||||
* Source Code Pro, hairline border edge. Supabase uses kbd
|
||||
* marks throughout docs with the same border-defined restraint. */
|
||||
kbd {
|
||||
font-family: var(--font-mono);
|
||||
font-size: var(--text-xs);
|
||||
padding: 2px var(--space-2);
|
||||
border-radius: 4px;
|
||||
background: var(--surface);
|
||||
color: var(--fg);
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
|
||||
/* ─── Code chip (inline) ────────────────────────────────────
|
||||
* Source Code Pro at body-adjacent size for inline product
|
||||
* references — table names, env vars, function signatures. */
|
||||
code.chip {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.92em;
|
||||
color: var(--accent);
|
||||
background: color-mix(in oklab, var(--accent), var(--bg) 92%);
|
||||
padding: 2px var(--space-2);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
/* ─── Section-specific layout ─────────────────────────────── */
|
||||
.hero {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
/* Atmospheric green wash — the single chromatic moment behind
|
||||
the hero headline. A radial of `var(--accent)` at low opacity
|
||||
echoes Supabase's logo-as-canvas treatment without violating
|
||||
the ≤2 accent uses budget (the wash is decorative atmosphere,
|
||||
not a labeled accent surface). */
|
||||
.hero::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: -20% -10% auto -10%;
|
||||
height: 70%;
|
||||
background:
|
||||
radial-gradient(
|
||||
55% 60% at 18% 30%,
|
||||
color-mix(in oklab, var(--accent), var(--bg) 70%) 0%,
|
||||
var(--bg) 60%
|
||||
);
|
||||
opacity: 0.55;
|
||||
filter: blur(60px);
|
||||
z-index: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
.hero > * { position: relative; z-index: 1; }
|
||||
.hero .eyebrow { margin-block-end: var(--space-5); }
|
||||
.hero h1 { max-width: 16ch; }
|
||||
.hero .lede {
|
||||
max-width: 56ch;
|
||||
margin-block-start: var(--space-6);
|
||||
font-size: var(--text-lg);
|
||||
line-height: 1.56;
|
||||
}
|
||||
.hero-actions {
|
||||
display: flex;
|
||||
gap: var(--space-3);
|
||||
margin-block-start: var(--space-8);
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.hero-meta {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: var(--space-3);
|
||||
margin-block-start: var(--space-6);
|
||||
color: var(--muted);
|
||||
font-size: var(--text-sm);
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.features-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: var(--space-5);
|
||||
margin-block-start: var(--space-8);
|
||||
}
|
||||
@media (max-width: 1023px) {
|
||||
.features-grid { grid-template-columns: 1fr 1fr; }
|
||||
}
|
||||
@media (max-width: 639px) {
|
||||
.features-grid { grid-template-columns: 1fr; }
|
||||
}
|
||||
.feature-icon {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: var(--radius-md);
|
||||
border: 1px solid var(--border);
|
||||
background: var(--bg);
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--accent);
|
||||
}
|
||||
.feature-icon svg { width: 18px; height: 18px; }
|
||||
|
||||
.form-row {
|
||||
display: grid;
|
||||
grid-template-columns: 1.2fr 1fr;
|
||||
gap: var(--space-12);
|
||||
align-items: start;
|
||||
margin-block-start: var(--space-8);
|
||||
}
|
||||
@media (max-width: 1023px) {
|
||||
.form-row { grid-template-columns: 1fr; gap: var(--space-8); }
|
||||
}
|
||||
.form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-4);
|
||||
max-width: 440px;
|
||||
padding: var(--space-6);
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-md);
|
||||
box-shadow: var(--elev-raised);
|
||||
}
|
||||
.form-actions {
|
||||
display: flex;
|
||||
gap: var(--space-3);
|
||||
margin-block-start: var(--space-2);
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.row-between {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: var(--space-3);
|
||||
}
|
||||
.icon { width: 16px; height: 16px; flex-shrink: 0; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="container">
|
||||
<!-- ════════════════════════════════════════════════════════════
|
||||
HERO — exercises: radial green wash (the one chromatic
|
||||
moment per screen), h1 at 72px Circular weight 400 with
|
||||
leading 1.00 (the terminal-density signature), .lede in
|
||||
--fg-2, .btn-brand (the emerald pill), .btn-secondary
|
||||
(dark pill with hairline border), Source Code Pro eyebrow.
|
||||
Hero copy reflects Supabase's "build in a weekend, scale
|
||||
to millions" voice — confident, technical, terse.
|
||||
═══════════════════════════════════════════════════════════════ -->
|
||||
<section class="hero" data-od-id="hero">
|
||||
<p class="eyebrow">// open source · postgres-native</p>
|
||||
<h1>Build in a weekend. Scale to millions.</h1>
|
||||
<p class="lede">
|
||||
Every Supabase project ships with a Postgres database,
|
||||
authentication, instant APIs, edge functions, realtime
|
||||
subscriptions, and object storage. Start with a
|
||||
<code class="chip">create table</code>, deploy with a
|
||||
<code class="chip">git push</code>, and let the platform
|
||||
carry the load when traffic finds you.
|
||||
</p>
|
||||
<div class="hero-actions">
|
||||
<a href="./tokens.css" class="btn btn-brand" style="border-bottom: none">
|
||||
Start your project
|
||||
<svg
|
||||
class="icon"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.75"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path d="M5 12h14M13 6l6 6-6 6" />
|
||||
</svg>
|
||||
</a>
|
||||
<a href="./DESIGN.md" class="btn btn-secondary" style="border-bottom: none">
|
||||
Read the docs
|
||||
</a>
|
||||
</div>
|
||||
<p class="hero-meta">
|
||||
<span class="badge badge-muted">
|
||||
<span class="badge-dot" aria-hidden="true" style="color: var(--success)"></span>
|
||||
All systems normal
|
||||
</span>
|
||||
<span>Press <kbd>⌘</kbd> <kbd>K</kbd> to search the docs.</span>
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- ════════════════════════════════════════════════════════════
|
||||
FEATURE CARDS — three cards exercising: .card (border-as-
|
||||
depth, no shadow), h3 with -0.0067em tracking and 1.33
|
||||
leading (DESIGN.md card-title row), .feature-icon (hairline
|
||||
bordered square with emerald glyph), .badge-accent (the
|
||||
tinted brand-status pill), link bottom-border underline.
|
||||
Three cards per row at desktop, collapse to two then one.
|
||||
═══════════════════════════════════════════════════════════════ -->
|
||||
<section data-od-id="features">
|
||||
<p class="eyebrow">// the stack</p>
|
||||
<h2 style="max-width: 26ch; margin-block-start: var(--space-4)">
|
||||
The open source backend that grew up.
|
||||
</h2>
|
||||
<p class="body-muted" style="margin-block-start: var(--space-4); max-width: 56ch">
|
||||
One project, six services, all standing on Postgres. Bring
|
||||
your own SQL — the rest of the platform speaks your schema.
|
||||
</p>
|
||||
|
||||
<div class="features-grid">
|
||||
<article class="card">
|
||||
<div class="row-between">
|
||||
<span class="feature-icon" aria-hidden="true">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round">
|
||||
<ellipse cx="12" cy="6" rx="8" ry="3" />
|
||||
<path d="M4 6v6c0 1.66 3.58 3 8 3s8-1.34 8-3V6" />
|
||||
<path d="M4 12v6c0 1.66 3.58 3 8 3s8-1.34 8-3v-6" />
|
||||
</svg>
|
||||
</span>
|
||||
<span class="badge badge-accent">Postgres 16</span>
|
||||
</div>
|
||||
<h3>A dedicated database, on day one.</h3>
|
||||
<p class="body-muted body-sm">
|
||||
Every project gets a fully-managed Postgres instance with
|
||||
extensions, point-in-time recovery, and read replicas. The
|
||||
<code class="chip">supabase</code> CLI streams migrations
|
||||
from <code class="chip">/supabase/migrations</code> straight
|
||||
to production.
|
||||
</p>
|
||||
<a href="./tokens.css" class="body-sm">Explore the database →</a>
|
||||
</article>
|
||||
|
||||
<article class="card">
|
||||
<div class="row-between">
|
||||
<span class="feature-icon" aria-hidden="true">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round">
|
||||
<rect x="3" y="11" width="18" height="10" rx="2" />
|
||||
<path d="M7 11V7a5 5 0 0 1 10 0v4" />
|
||||
</svg>
|
||||
</span>
|
||||
<span class="badge badge-accent">Row-level</span>
|
||||
</div>
|
||||
<h3>Auth that respects your schema.</h3>
|
||||
<p class="body-muted body-sm">
|
||||
Email, OAuth, magic links, and SAML — all writing to a
|
||||
<code class="chip">auth.users</code> table you can join
|
||||
against. Row-level security policies enforce access in
|
||||
the database, not in middleware.
|
||||
</p>
|
||||
<a href="./DESIGN.md" class="body-sm">See the auth flow →</a>
|
||||
</article>
|
||||
|
||||
<article class="card">
|
||||
<div class="row-between">
|
||||
<span class="feature-icon" aria-hidden="true">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M12 2v20M2 12h20" />
|
||||
<circle cx="12" cy="12" r="9" />
|
||||
</svg>
|
||||
</span>
|
||||
<span class="badge badge-success">
|
||||
<span class="badge-dot" aria-hidden="true"></span>
|
||||
Realtime
|
||||
</span>
|
||||
</div>
|
||||
<h3>Subscriptions over your data.</h3>
|
||||
<p class="body-muted body-sm">
|
||||
Listen to row inserts, updates, and deletes from the
|
||||
browser — no extra service, no manual fan-out. Realtime
|
||||
streams Postgres' write-ahead log to authorized clients
|
||||
over a single WebSocket.
|
||||
</p>
|
||||
<a href="./tokens.css" class="body-sm">Inspect the channel →</a>
|
||||
</article>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ════════════════════════════════════════════════════════════
|
||||
FORM — exercises: .field with border-defined input edges,
|
||||
focus-visible swap to the emerald border + green focus
|
||||
halo, .btn-brand and .btn-secondary reuse. Form sits in
|
||||
its own bordered card with the brand's minimal elev-raised
|
||||
shadow so the inputs read as recessed beneath the card.
|
||||
═══════════════════════════════════════════════════════════════ -->
|
||||
<section data-od-id="form">
|
||||
<p class="eyebrow">// get the launch kit</p>
|
||||
<h2 style="margin-block-start: var(--space-4); max-width: 28ch">
|
||||
Ship the schema. We'll handle the rest.
|
||||
</h2>
|
||||
|
||||
<div class="form-row">
|
||||
<div class="stack-4">
|
||||
<p class="body-muted" style="max-width: 48ch">
|
||||
Inputs, focus rings, and edges all derive from
|
||||
<code class="chip">--border</code> and
|
||||
<code class="chip">--accent</code>. The primary CTA reuses
|
||||
<code class="chip">.btn-brand</code> unchanged — emerald
|
||||
fill, near-black label, pill radius. No raw hex anywhere
|
||||
in the component CSS.
|
||||
</p>
|
||||
<p class="body-muted body-sm">
|
||||
Press <kbd>Enter</kbd> on the email field to submit. The
|
||||
focus halo lands at the documented brand-highlight tint
|
||||
(<code class="chip">rgba(62, 207, 142, 0.5)</code>) —
|
||||
visible against the canvas without dominating the page.
|
||||
</p>
|
||||
<p class="body-meta">
|
||||
Full reference at <a href="./tokens.css">tokens.css</a> ·
|
||||
spec at <a href="./DESIGN.md">DESIGN.md</a>.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<form class="form" onsubmit="event.preventDefault();">
|
||||
<div class="row-between">
|
||||
<p class="eyebrow">// launch kit</p>
|
||||
<span class="badge badge-success">
|
||||
<span class="badge-dot" aria-hidden="true"></span>
|
||||
Open
|
||||
</span>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="email">Work email</label>
|
||||
<input
|
||||
id="email"
|
||||
type="email"
|
||||
placeholder="[email protected]"
|
||||
autocomplete="email"
|
||||
required
|
||||
/>
|
||||
<p class="field-help">
|
||||
We'll send the starter repo and a Postgres schema you
|
||||
can <code class="chip">supabase db push</code> on day one.
|
||||
</p>
|
||||
</div>
|
||||
<div class="form-actions">
|
||||
<button type="submit" class="btn btn-brand">
|
||||
Send the kit
|
||||
</button>
|
||||
<button type="button" class="btn btn-ghost">
|
||||
Browse the docs
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,526 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"brandId": "supabase",
|
||||
"source": {
|
||||
"componentsHtml": "components.html",
|
||||
"tokensCss": "tokens.css"
|
||||
},
|
||||
"fixture": {
|
||||
"title": "Supabase — reference components",
|
||||
"description": "Reference fixture for design-systems/supabase. Every visible value comes from tokens.css. Supabase's signature moves: near-black canvas, Postgres-emerald reserved as identity marker, Circular geometric sans with weight restraint, Source Code Pro uppercase for the developer- console voice, depth carried by a tight border hierarchy.",
|
||||
"styleBlockCount": 1,
|
||||
"selectorCount": 67,
|
||||
"classCount": 30,
|
||||
"elementCount": 27
|
||||
},
|
||||
"tokens": {
|
||||
"declared": [
|
||||
"--accent",
|
||||
"--accent-active",
|
||||
"--accent-hover",
|
||||
"--accent-on",
|
||||
"--bg",
|
||||
"--border",
|
||||
"--border-soft",
|
||||
"--container-gutter-desktop",
|
||||
"--container-gutter-phone",
|
||||
"--container-gutter-tablet",
|
||||
"--container-max",
|
||||
"--danger",
|
||||
"--ease-standard",
|
||||
"--elev-flat",
|
||||
"--elev-raised",
|
||||
"--elev-ring",
|
||||
"--fg",
|
||||
"--fg-2",
|
||||
"--focus-ring",
|
||||
"--font-body",
|
||||
"--font-display",
|
||||
"--font-mono",
|
||||
"--leading-body",
|
||||
"--leading-tight",
|
||||
"--meta",
|
||||
"--motion-base",
|
||||
"--motion-fast",
|
||||
"--muted",
|
||||
"--radius-lg",
|
||||
"--radius-md",
|
||||
"--radius-pill",
|
||||
"--radius-sm",
|
||||
"--section-y-desktop",
|
||||
"--section-y-phone",
|
||||
"--section-y-tablet",
|
||||
"--space-1",
|
||||
"--space-12",
|
||||
"--space-2",
|
||||
"--space-3",
|
||||
"--space-4",
|
||||
"--space-5",
|
||||
"--space-6",
|
||||
"--space-8",
|
||||
"--success",
|
||||
"--surface",
|
||||
"--surface-warm",
|
||||
"--text-2xl",
|
||||
"--text-3xl",
|
||||
"--text-4xl",
|
||||
"--text-base",
|
||||
"--text-lg",
|
||||
"--text-sm",
|
||||
"--text-xl",
|
||||
"--text-xs",
|
||||
"--tracking-display",
|
||||
"--warn"
|
||||
],
|
||||
"referenced": [
|
||||
"--accent",
|
||||
"--accent-active",
|
||||
"--accent-hover",
|
||||
"--accent-on",
|
||||
"--bg",
|
||||
"--border",
|
||||
"--container-gutter-desktop",
|
||||
"--container-gutter-phone",
|
||||
"--container-gutter-tablet",
|
||||
"--container-max",
|
||||
"--ease-standard",
|
||||
"--elev-raised",
|
||||
"--fg",
|
||||
"--fg-2",
|
||||
"--focus-ring",
|
||||
"--font-body",
|
||||
"--font-display",
|
||||
"--font-mono",
|
||||
"--leading-body",
|
||||
"--leading-tight",
|
||||
"--meta",
|
||||
"--motion-base",
|
||||
"--motion-fast",
|
||||
"--muted",
|
||||
"--radius-lg",
|
||||
"--radius-md",
|
||||
"--radius-pill",
|
||||
"--radius-sm",
|
||||
"--section-y-desktop",
|
||||
"--section-y-phone",
|
||||
"--section-y-tablet",
|
||||
"--space-1",
|
||||
"--space-12",
|
||||
"--space-2",
|
||||
"--space-3",
|
||||
"--space-4",
|
||||
"--space-5",
|
||||
"--space-6",
|
||||
"--space-8",
|
||||
"--success",
|
||||
"--surface",
|
||||
"--text-3xl",
|
||||
"--text-4xl",
|
||||
"--text-base",
|
||||
"--text-lg",
|
||||
"--text-sm",
|
||||
"--text-xl",
|
||||
"--text-xs",
|
||||
"--tracking-display"
|
||||
],
|
||||
"unusedDeclared": [
|
||||
"--border-soft",
|
||||
"--danger",
|
||||
"--elev-flat",
|
||||
"--elev-ring",
|
||||
"--surface-warm",
|
||||
"--text-2xl",
|
||||
"--warn"
|
||||
],
|
||||
"undeclaredReferenced": []
|
||||
},
|
||||
"selectors": [
|
||||
".badge",
|
||||
".badge-accent",
|
||||
".badge-dot",
|
||||
".badge-muted",
|
||||
".badge-success",
|
||||
".body-meta",
|
||||
".body-muted",
|
||||
".body-sm",
|
||||
".btn",
|
||||
".btn-brand",
|
||||
".btn-brand:active",
|
||||
".btn-brand:hover",
|
||||
".btn-ghost",
|
||||
".btn-ghost:hover",
|
||||
".btn-primary",
|
||||
".btn-primary:hover",
|
||||
".btn-secondary",
|
||||
".btn-secondary:hover",
|
||||
".btn:focus-visible",
|
||||
".card",
|
||||
".card:hover",
|
||||
".container",
|
||||
".eyebrow",
|
||||
".feature-icon",
|
||||
".feature-icon svg",
|
||||
".features-grid",
|
||||
".field",
|
||||
".field input",
|
||||
".field input::placeholder",
|
||||
".field input:focus-visible",
|
||||
".field input:hover",
|
||||
".field label",
|
||||
".field-help",
|
||||
".form",
|
||||
".form-actions",
|
||||
".form-row",
|
||||
".hero",
|
||||
".hero .eyebrow",
|
||||
".hero .lede",
|
||||
".hero > *",
|
||||
".hero h1",
|
||||
".hero-actions",
|
||||
".hero-meta",
|
||||
".hero::before",
|
||||
".icon",
|
||||
".lede",
|
||||
".row-between",
|
||||
".stack-3 > * + *",
|
||||
".stack-4 > * + *",
|
||||
".stack-6 > * + *",
|
||||
"*",
|
||||
"*::after",
|
||||
"*::before",
|
||||
"a",
|
||||
"a:focus-visible",
|
||||
"a:hover",
|
||||
"body",
|
||||
"code.chip",
|
||||
"h1",
|
||||
"h2",
|
||||
"h3",
|
||||
"h4",
|
||||
"html",
|
||||
"kbd",
|
||||
"p",
|
||||
"section",
|
||||
"section + section"
|
||||
],
|
||||
"classes": [
|
||||
"badge",
|
||||
"badge-accent",
|
||||
"badge-dot",
|
||||
"badge-muted",
|
||||
"badge-success",
|
||||
"body-meta",
|
||||
"body-muted",
|
||||
"body-sm",
|
||||
"btn",
|
||||
"btn-brand",
|
||||
"btn-ghost",
|
||||
"btn-secondary",
|
||||
"card",
|
||||
"chip",
|
||||
"container",
|
||||
"eyebrow",
|
||||
"feature-icon",
|
||||
"features-grid",
|
||||
"field",
|
||||
"field-help",
|
||||
"form",
|
||||
"form-actions",
|
||||
"form-row",
|
||||
"hero",
|
||||
"hero-actions",
|
||||
"hero-meta",
|
||||
"icon",
|
||||
"lede",
|
||||
"row-between",
|
||||
"stack-4"
|
||||
],
|
||||
"elements": [
|
||||
"a",
|
||||
"article",
|
||||
"body",
|
||||
"button",
|
||||
"circle",
|
||||
"code",
|
||||
"div",
|
||||
"ellipse",
|
||||
"form",
|
||||
"h1",
|
||||
"h2",
|
||||
"h3",
|
||||
"head",
|
||||
"html",
|
||||
"input",
|
||||
"kbd",
|
||||
"label",
|
||||
"main",
|
||||
"meta",
|
||||
"p",
|
||||
"path",
|
||||
"rect",
|
||||
"section",
|
||||
"span",
|
||||
"style",
|
||||
"svg",
|
||||
"title"
|
||||
],
|
||||
"groups": [
|
||||
{
|
||||
"id": "buttons",
|
||||
"label": "Buttons and calls to action",
|
||||
"present": true,
|
||||
"selectors": [
|
||||
".btn",
|
||||
".btn-brand",
|
||||
".btn-brand:active",
|
||||
".btn-brand:hover",
|
||||
".btn-ghost",
|
||||
".btn-ghost:hover",
|
||||
".btn-primary",
|
||||
".btn-primary:hover",
|
||||
".btn-secondary",
|
||||
".btn-secondary:hover",
|
||||
".btn:focus-visible"
|
||||
],
|
||||
"classes": [
|
||||
"btn",
|
||||
"btn-brand",
|
||||
"btn-ghost",
|
||||
"btn-secondary"
|
||||
],
|
||||
"elements": [
|
||||
"button"
|
||||
],
|
||||
"tokenReferences": [
|
||||
"--accent",
|
||||
"--accent-active",
|
||||
"--accent-on",
|
||||
"--border",
|
||||
"--ease-standard",
|
||||
"--fg",
|
||||
"--font-display",
|
||||
"--motion-fast",
|
||||
"--radius-pill",
|
||||
"--space-2",
|
||||
"--space-8",
|
||||
"--surface",
|
||||
"--text-sm"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "inputs",
|
||||
"label": "Form fields and controls",
|
||||
"present": true,
|
||||
"selectors": [
|
||||
".field",
|
||||
".field input",
|
||||
".field input::placeholder",
|
||||
".field input:focus-visible",
|
||||
".field input:hover",
|
||||
".field label",
|
||||
".field-help"
|
||||
],
|
||||
"classes": [
|
||||
"field",
|
||||
"field-help",
|
||||
"form",
|
||||
"form-actions",
|
||||
"form-row"
|
||||
],
|
||||
"elements": [
|
||||
"form",
|
||||
"input",
|
||||
"label"
|
||||
],
|
||||
"tokenReferences": [
|
||||
"--accent",
|
||||
"--fg",
|
||||
"--focus-ring",
|
||||
"--meta",
|
||||
"--text-sm"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "cards",
|
||||
"label": "Cards and panels",
|
||||
"present": true,
|
||||
"selectors": [
|
||||
".card",
|
||||
".card:hover"
|
||||
],
|
||||
"classes": [
|
||||
"card"
|
||||
],
|
||||
"elements": [],
|
||||
"tokenReferences": [
|
||||
"--border",
|
||||
"--ease-standard",
|
||||
"--motion-base",
|
||||
"--radius-lg",
|
||||
"--space-4",
|
||||
"--space-6",
|
||||
"--surface"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "badges",
|
||||
"label": "Badges, chips, and status labels",
|
||||
"present": true,
|
||||
"selectors": [
|
||||
".badge",
|
||||
".badge-accent",
|
||||
".badge-dot",
|
||||
".badge-muted",
|
||||
".badge-success",
|
||||
"code.chip"
|
||||
],
|
||||
"classes": [
|
||||
"badge",
|
||||
"badge-accent",
|
||||
"badge-dot",
|
||||
"badge-muted",
|
||||
"badge-success",
|
||||
"chip"
|
||||
],
|
||||
"elements": [],
|
||||
"tokenReferences": [
|
||||
"--border",
|
||||
"--fg-2",
|
||||
"--font-display",
|
||||
"--radius-pill",
|
||||
"--space-1",
|
||||
"--space-3",
|
||||
"--surface",
|
||||
"--text-xs"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "links",
|
||||
"label": "Links and inline actions",
|
||||
"present": true,
|
||||
"selectors": [
|
||||
"a",
|
||||
"a:focus-visible",
|
||||
"a:hover"
|
||||
],
|
||||
"classes": [],
|
||||
"elements": [
|
||||
"a"
|
||||
],
|
||||
"tokenReferences": [
|
||||
"--accent"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "keyboard",
|
||||
"label": "Keyboard hints",
|
||||
"present": true,
|
||||
"selectors": [
|
||||
"kbd"
|
||||
],
|
||||
"classes": [],
|
||||
"elements": [
|
||||
"kbd"
|
||||
],
|
||||
"tokenReferences": [
|
||||
"--border",
|
||||
"--fg",
|
||||
"--font-mono",
|
||||
"--space-2",
|
||||
"--surface",
|
||||
"--text-xs"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "icons",
|
||||
"label": "Icon slots",
|
||||
"present": true,
|
||||
"selectors": [
|
||||
".icon"
|
||||
],
|
||||
"classes": [
|
||||
"icon"
|
||||
],
|
||||
"elements": [
|
||||
"svg"
|
||||
],
|
||||
"tokenReferences": []
|
||||
},
|
||||
{
|
||||
"id": "typography",
|
||||
"label": "Typography scale and text utilities",
|
||||
"present": true,
|
||||
"selectors": [
|
||||
".body-muted",
|
||||
".body-sm",
|
||||
".eyebrow",
|
||||
".hero .eyebrow",
|
||||
".hero h1",
|
||||
"h1",
|
||||
"h2",
|
||||
"h3",
|
||||
"h4"
|
||||
],
|
||||
"classes": [
|
||||
"body-muted",
|
||||
"body-sm",
|
||||
"eyebrow"
|
||||
],
|
||||
"elements": [
|
||||
"h1",
|
||||
"h2",
|
||||
"h3",
|
||||
"p"
|
||||
],
|
||||
"tokenReferences": [
|
||||
"--fg",
|
||||
"--font-display",
|
||||
"--font-mono",
|
||||
"--leading-tight",
|
||||
"--muted",
|
||||
"--text-3xl",
|
||||
"--text-lg",
|
||||
"--text-xs",
|
||||
"--tracking-display"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "layout",
|
||||
"label": "Layout primitives",
|
||||
"present": true,
|
||||
"selectors": [
|
||||
".container",
|
||||
".row-between",
|
||||
".stack-3 > * + *",
|
||||
".stack-4 > * + *",
|
||||
".stack-6 > * + *",
|
||||
"section",
|
||||
"section + section"
|
||||
],
|
||||
"classes": [
|
||||
"container",
|
||||
"features-grid",
|
||||
"row-between",
|
||||
"stack-4"
|
||||
],
|
||||
"elements": [
|
||||
"main",
|
||||
"section"
|
||||
],
|
||||
"tokenReferences": [
|
||||
"--border",
|
||||
"--container-gutter-desktop",
|
||||
"--container-gutter-phone",
|
||||
"--container-gutter-tablet",
|
||||
"--container-max",
|
||||
"--space-3",
|
||||
"--space-4"
|
||||
]
|
||||
}
|
||||
],
|
||||
"literals": {
|
||||
"colorExpressions": 13,
|
||||
"pixelValues": 29,
|
||||
"hardcodedFontFamilies": 8
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,701 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"format": "od-design-tokens/v1",
|
||||
"contract": "TOKEN_SCHEMA",
|
||||
"generatedAt": "2026-06-06T00:00:00.000Z",
|
||||
"source": {
|
||||
"tokensCss": "tokens.css",
|
||||
"tokenContractReport": "source/token-contract.report.json"
|
||||
},
|
||||
"summary": {
|
||||
"totalTokens": 56,
|
||||
"declaredTokens": 56,
|
||||
"sourceBackedTokens": 56,
|
||||
"sourceBackedA1": 26,
|
||||
"fallbackTokens": 26,
|
||||
"aliasTokens": 1,
|
||||
"layerCounts": {
|
||||
"A1-identity": 8,
|
||||
"B-slot": 4,
|
||||
"A2": 26,
|
||||
"A1-structure": 18
|
||||
},
|
||||
"score": 100,
|
||||
"grade": "excellent",
|
||||
"recommendRebuild": false
|
||||
},
|
||||
"tokens": [
|
||||
{
|
||||
"name": "--bg",
|
||||
"value": "#171717",
|
||||
"type": "color",
|
||||
"layer": "A1-identity",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --bg; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:122"
|
||||
],
|
||||
"sourceName": "--bg"
|
||||
},
|
||||
{
|
||||
"name": "--surface",
|
||||
"value": "#1c1c1c",
|
||||
"type": "color",
|
||||
"layer": "A1-identity",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --surface; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:123"
|
||||
],
|
||||
"sourceName": "--surface"
|
||||
},
|
||||
{
|
||||
"name": "--surface-warm",
|
||||
"value": "var(--surface)",
|
||||
"type": "color",
|
||||
"layer": "B-slot",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --surface-warm; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:124"
|
||||
],
|
||||
"sourceName": "--surface-warm"
|
||||
},
|
||||
{
|
||||
"name": "--fg",
|
||||
"value": "#fafafa",
|
||||
"type": "color",
|
||||
"layer": "A1-identity",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --fg; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:134"
|
||||
],
|
||||
"sourceName": "--fg"
|
||||
},
|
||||
{
|
||||
"name": "--fg-2",
|
||||
"value": "#b4b4b4",
|
||||
"type": "color",
|
||||
"layer": "B-slot",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --fg-2; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:135"
|
||||
],
|
||||
"sourceName": "--fg-2"
|
||||
},
|
||||
{
|
||||
"name": "--muted",
|
||||
"value": "#898989",
|
||||
"type": "color",
|
||||
"layer": "A1-identity",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --muted; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:136"
|
||||
],
|
||||
"sourceName": "--muted"
|
||||
},
|
||||
{
|
||||
"name": "--meta",
|
||||
"value": "#4d4d4d",
|
||||
"type": "color",
|
||||
"layer": "B-slot",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --meta; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:137"
|
||||
],
|
||||
"sourceName": "--meta"
|
||||
},
|
||||
{
|
||||
"name": "--border",
|
||||
"value": "#2e2e2e",
|
||||
"type": "color",
|
||||
"layer": "A1-identity",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --border; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:145"
|
||||
],
|
||||
"sourceName": "--border"
|
||||
},
|
||||
{
|
||||
"name": "--border-soft",
|
||||
"value": "#242424",
|
||||
"type": "color",
|
||||
"layer": "B-slot",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --border-soft; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:146"
|
||||
],
|
||||
"sourceName": "--border-soft"
|
||||
},
|
||||
{
|
||||
"name": "--accent",
|
||||
"value": "#3ecf8e",
|
||||
"type": "color",
|
||||
"layer": "A1-identity",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --accent; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:163"
|
||||
],
|
||||
"sourceName": "--accent"
|
||||
},
|
||||
{
|
||||
"name": "--accent-on",
|
||||
"value": "#0f0f0f",
|
||||
"type": "color",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --accent-on; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:164"
|
||||
],
|
||||
"sourceName": "--accent-on"
|
||||
},
|
||||
{
|
||||
"name": "--accent-hover",
|
||||
"value": "#00c573",
|
||||
"type": "color",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --accent-hover; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:165"
|
||||
],
|
||||
"sourceName": "--accent-hover"
|
||||
},
|
||||
{
|
||||
"name": "--accent-active",
|
||||
"value": "color-mix(in oklab, var(--accent), black 14%)",
|
||||
"type": "color",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --accent-active; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:166"
|
||||
],
|
||||
"sourceName": "--accent-active"
|
||||
},
|
||||
{
|
||||
"name": "--success",
|
||||
"value": "#16a34a",
|
||||
"type": "color",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --success; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:174"
|
||||
],
|
||||
"sourceName": "--success"
|
||||
},
|
||||
{
|
||||
"name": "--warn",
|
||||
"value": "#eab308",
|
||||
"type": "color",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --warn; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:175"
|
||||
],
|
||||
"sourceName": "--warn"
|
||||
},
|
||||
{
|
||||
"name": "--danger",
|
||||
"value": "#dc2626",
|
||||
"type": "color",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --danger; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:176"
|
||||
],
|
||||
"sourceName": "--danger"
|
||||
},
|
||||
{
|
||||
"name": "--font-display",
|
||||
"value": "\"Circular\", \"custom-font\", \"Helvetica Neue\", Helvetica, Arial, sans-serif",
|
||||
"type": "fontFamily",
|
||||
"layer": "A1-identity",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --font-display; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:188"
|
||||
],
|
||||
"sourceName": "--font-display"
|
||||
},
|
||||
{
|
||||
"name": "--font-body",
|
||||
"value": "\"Circular\", \"custom-font\", \"Helvetica Neue\", Helvetica, Arial, sans-serif",
|
||||
"type": "fontFamily",
|
||||
"layer": "A1-identity",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --font-body; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:189"
|
||||
],
|
||||
"sourceName": "--font-body"
|
||||
},
|
||||
{
|
||||
"name": "--font-mono",
|
||||
"value": "\"Source Code Pro\", \"Office Code Pro\", Menlo, Monaco, Consolas, monospace",
|
||||
"type": "fontFamily",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --font-mono; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:190"
|
||||
],
|
||||
"sourceName": "--font-mono"
|
||||
},
|
||||
{
|
||||
"name": "--text-xs",
|
||||
"value": "12px",
|
||||
"type": "dimension",
|
||||
"layer": "A1-structure",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --text-xs; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:197"
|
||||
],
|
||||
"sourceName": "--text-xs"
|
||||
},
|
||||
{
|
||||
"name": "--text-sm",
|
||||
"value": "14px",
|
||||
"type": "dimension",
|
||||
"layer": "A1-structure",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --text-sm; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:198"
|
||||
],
|
||||
"sourceName": "--text-sm"
|
||||
},
|
||||
{
|
||||
"name": "--text-base",
|
||||
"value": "16px",
|
||||
"type": "dimension",
|
||||
"layer": "A1-structure",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --text-base; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:199"
|
||||
],
|
||||
"sourceName": "--text-base"
|
||||
},
|
||||
{
|
||||
"name": "--text-lg",
|
||||
"value": "18px",
|
||||
"type": "dimension",
|
||||
"layer": "A1-structure",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --text-lg; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:200"
|
||||
],
|
||||
"sourceName": "--text-lg"
|
||||
},
|
||||
{
|
||||
"name": "--text-xl",
|
||||
"value": "24px",
|
||||
"type": "dimension",
|
||||
"layer": "A1-structure",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --text-xl; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:201"
|
||||
],
|
||||
"sourceName": "--text-xl"
|
||||
},
|
||||
{
|
||||
"name": "--text-2xl",
|
||||
"value": "32px",
|
||||
"type": "dimension",
|
||||
"layer": "A1-structure",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --text-2xl; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:202"
|
||||
],
|
||||
"sourceName": "--text-2xl"
|
||||
},
|
||||
{
|
||||
"name": "--text-3xl",
|
||||
"value": "36px",
|
||||
"type": "dimension",
|
||||
"layer": "A1-structure",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --text-3xl; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:203"
|
||||
],
|
||||
"sourceName": "--text-3xl"
|
||||
},
|
||||
{
|
||||
"name": "--text-4xl",
|
||||
"value": "72px",
|
||||
"type": "dimension",
|
||||
"layer": "A1-structure",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --text-4xl; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:204"
|
||||
],
|
||||
"sourceName": "--text-4xl"
|
||||
},
|
||||
{
|
||||
"name": "--leading-body",
|
||||
"value": "1.5",
|
||||
"type": "number",
|
||||
"layer": "A1-structure",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --leading-body; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:212"
|
||||
],
|
||||
"sourceName": "--leading-body"
|
||||
},
|
||||
{
|
||||
"name": "--leading-tight",
|
||||
"value": "1.00",
|
||||
"type": "number",
|
||||
"layer": "A1-structure",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --leading-tight; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:213"
|
||||
],
|
||||
"sourceName": "--leading-tight"
|
||||
},
|
||||
{
|
||||
"name": "--tracking-display",
|
||||
"value": "normal",
|
||||
"type": "dimension",
|
||||
"layer": "A1-structure",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --tracking-display; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:214"
|
||||
],
|
||||
"sourceName": "--tracking-display"
|
||||
},
|
||||
{
|
||||
"name": "--space-1",
|
||||
"value": "4px",
|
||||
"type": "dimension",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --space-1; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:221"
|
||||
],
|
||||
"sourceName": "--space-1"
|
||||
},
|
||||
{
|
||||
"name": "--space-2",
|
||||
"value": "8px",
|
||||
"type": "dimension",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --space-2; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:222"
|
||||
],
|
||||
"sourceName": "--space-2"
|
||||
},
|
||||
{
|
||||
"name": "--space-3",
|
||||
"value": "12px",
|
||||
"type": "dimension",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --space-3; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:223"
|
||||
],
|
||||
"sourceName": "--space-3"
|
||||
},
|
||||
{
|
||||
"name": "--space-4",
|
||||
"value": "16px",
|
||||
"type": "dimension",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --space-4; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:224"
|
||||
],
|
||||
"sourceName": "--space-4"
|
||||
},
|
||||
{
|
||||
"name": "--space-5",
|
||||
"value": "20px",
|
||||
"type": "dimension",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --space-5; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:225"
|
||||
],
|
||||
"sourceName": "--space-5"
|
||||
},
|
||||
{
|
||||
"name": "--space-6",
|
||||
"value": "24px",
|
||||
"type": "dimension",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --space-6; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:226"
|
||||
],
|
||||
"sourceName": "--space-6"
|
||||
},
|
||||
{
|
||||
"name": "--space-8",
|
||||
"value": "32px",
|
||||
"type": "dimension",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --space-8; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:227"
|
||||
],
|
||||
"sourceName": "--space-8"
|
||||
},
|
||||
{
|
||||
"name": "--space-12",
|
||||
"value": "48px",
|
||||
"type": "dimension",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --space-12; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:228"
|
||||
],
|
||||
"sourceName": "--space-12"
|
||||
},
|
||||
{
|
||||
"name": "--section-y-desktop",
|
||||
"value": "128px",
|
||||
"type": "dimension",
|
||||
"layer": "A1-structure",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --section-y-desktop; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:235"
|
||||
],
|
||||
"sourceName": "--section-y-desktop"
|
||||
},
|
||||
{
|
||||
"name": "--section-y-tablet",
|
||||
"value": "80px",
|
||||
"type": "dimension",
|
||||
"layer": "A1-structure",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --section-y-tablet; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:236"
|
||||
],
|
||||
"sourceName": "--section-y-tablet"
|
||||
},
|
||||
{
|
||||
"name": "--section-y-phone",
|
||||
"value": "48px",
|
||||
"type": "dimension",
|
||||
"layer": "A1-structure",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --section-y-phone; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:237"
|
||||
],
|
||||
"sourceName": "--section-y-phone"
|
||||
},
|
||||
{
|
||||
"name": "--radius-sm",
|
||||
"value": "6px",
|
||||
"type": "dimension",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --radius-sm; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:247"
|
||||
],
|
||||
"sourceName": "--radius-sm"
|
||||
},
|
||||
{
|
||||
"name": "--radius-md",
|
||||
"value": "8px",
|
||||
"type": "dimension",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --radius-md; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:248"
|
||||
],
|
||||
"sourceName": "--radius-md"
|
||||
},
|
||||
{
|
||||
"name": "--radius-lg",
|
||||
"value": "16px",
|
||||
"type": "dimension",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --radius-lg; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:249"
|
||||
],
|
||||
"sourceName": "--radius-lg"
|
||||
},
|
||||
{
|
||||
"name": "--radius-pill",
|
||||
"value": "9999px",
|
||||
"type": "dimension",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --radius-pill; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:250"
|
||||
],
|
||||
"sourceName": "--radius-pill"
|
||||
},
|
||||
{
|
||||
"name": "--elev-flat",
|
||||
"value": "none",
|
||||
"type": "shadow",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --elev-flat; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:263"
|
||||
],
|
||||
"sourceName": "--elev-flat"
|
||||
},
|
||||
{
|
||||
"name": "--elev-ring",
|
||||
"value": "0 0 0 1px var(--border)",
|
||||
"type": "shadow",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --elev-ring; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:264"
|
||||
],
|
||||
"sourceName": "--elev-ring"
|
||||
},
|
||||
{
|
||||
"name": "--elev-raised",
|
||||
"value": "0 0 0 1px var(--border), 0 4px 12px rgba(0, 0, 0, 0.4)",
|
||||
"type": "shadow",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --elev-raised; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:265"
|
||||
],
|
||||
"sourceName": "--elev-raised"
|
||||
},
|
||||
{
|
||||
"name": "--focus-ring",
|
||||
"value": "0 0 0 2px color-mix(in oklab, var(--accent), transparent 50%)",
|
||||
"type": "shadow",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --focus-ring; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:274"
|
||||
],
|
||||
"sourceName": "--focus-ring"
|
||||
},
|
||||
{
|
||||
"name": "--motion-fast",
|
||||
"value": "150ms",
|
||||
"type": "duration",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --motion-fast; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:281"
|
||||
],
|
||||
"sourceName": "--motion-fast"
|
||||
},
|
||||
{
|
||||
"name": "--motion-base",
|
||||
"value": "200ms",
|
||||
"type": "duration",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --motion-base; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:282"
|
||||
],
|
||||
"sourceName": "--motion-base"
|
||||
},
|
||||
{
|
||||
"name": "--ease-standard",
|
||||
"value": "cubic-bezier(0.2, 0, 0, 1)",
|
||||
"type": "cubicBezier",
|
||||
"layer": "A2",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --ease-standard; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:283"
|
||||
],
|
||||
"sourceName": "--ease-standard"
|
||||
},
|
||||
{
|
||||
"name": "--container-max",
|
||||
"value": "1200px",
|
||||
"type": "dimension",
|
||||
"layer": "A1-structure",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --container-max; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:290"
|
||||
],
|
||||
"sourceName": "--container-max"
|
||||
},
|
||||
{
|
||||
"name": "--container-gutter-desktop",
|
||||
"value": "24px",
|
||||
"type": "dimension",
|
||||
"layer": "A1-structure",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --container-gutter-desktop; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:291"
|
||||
],
|
||||
"sourceName": "--container-gutter-desktop"
|
||||
},
|
||||
{
|
||||
"name": "--container-gutter-tablet",
|
||||
"value": "16px",
|
||||
"type": "dimension",
|
||||
"layer": "A1-structure",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --container-gutter-tablet; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:292"
|
||||
],
|
||||
"sourceName": "--container-gutter-tablet"
|
||||
},
|
||||
{
|
||||
"name": "--container-gutter-phone",
|
||||
"value": "16px",
|
||||
"type": "dimension",
|
||||
"layer": "A1-structure",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --container-gutter-phone; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:293"
|
||||
],
|
||||
"sourceName": "--container-gutter-phone"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"schemaVersion": "od-design-system-project/v1",
|
||||
"id": "supabase",
|
||||
"name": "Supabase",
|
||||
"category": "Backend & Data",
|
||||
"description": "Bundled OpenDesign package for Supabase, derived from curated DESIGN.md, tokens.css, and components.html fixtures.",
|
||||
"source": {
|
||||
"type": "bundled",
|
||||
"origin": "OpenDesign curated bundled fixture"
|
||||
},
|
||||
"files": {
|
||||
"design": "DESIGN.md",
|
||||
"tokens": "tokens.css",
|
||||
"designTokens": "design-tokens.json",
|
||||
"tailwind": "tailwind-v4.css",
|
||||
"components": "components.html"
|
||||
},
|
||||
"usage": "USAGE.md",
|
||||
"componentsManifest": "components.manifest.json",
|
||||
"importMode": "normalized",
|
||||
"craft": {
|
||||
"applies": [],
|
||||
"suggested": [
|
||||
"color",
|
||||
"accessibility-baseline"
|
||||
],
|
||||
"exemptions": []
|
||||
},
|
||||
"preview": {
|
||||
"dir": "preview",
|
||||
"pages": [
|
||||
{
|
||||
"path": "preview/colors.html",
|
||||
"role": "colors",
|
||||
"title": "Colors"
|
||||
},
|
||||
{
|
||||
"path": "preview/typography.html",
|
||||
"role": "typography",
|
||||
"title": "Typography"
|
||||
},
|
||||
{
|
||||
"path": "preview/spacing.html",
|
||||
"role": "spacing",
|
||||
"title": "Spacing"
|
||||
}
|
||||
]
|
||||
},
|
||||
"sourceFiles": {
|
||||
"evidence": "source/evidence.md",
|
||||
"tokens": "source/tokens.source.json",
|
||||
"report": "source/token-contract.report.json"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Supabase colors</title>
|
||||
<link rel="stylesheet" href="../tokens.css" />
|
||||
<style>
|
||||
body { margin: 0; background: var(--bg); color: var(--fg); font-family: var(--font-body); }
|
||||
main { max-width: var(--container-max); margin: 0 auto; padding: var(--space-12) var(--space-6); }
|
||||
h1 { margin: 0 0 var(--space-6); font-family: var(--font-display); font-size: var(--text-2xl); line-height: var(--leading-tight); letter-spacing: var(--tracking-display); }
|
||||
|
||||
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--space-4); }
|
||||
.swatch { border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--surface); overflow: hidden; box-shadow: var(--elev-ring); }
|
||||
.color { height: 88px; background: var(--value); }
|
||||
.meta { padding: var(--space-3); color: var(--muted); font-size: var(--text-sm); }
|
||||
strong { display: block; margin-bottom: var(--space-1); color: var(--fg); }
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<h1>Color roles</h1>
|
||||
|
||||
<section class="grid">
|
||||
<article class="swatch" style="--value: var(--bg)"><div class="color"></div><div class="meta"><strong>Background</strong>--bg</div></article>
|
||||
<article class="swatch" style="--value: var(--surface)"><div class="color"></div><div class="meta"><strong>Surface</strong>--surface</div></article>
|
||||
<article class="swatch" style="--value: var(--fg)"><div class="color"></div><div class="meta"><strong>Foreground</strong>--fg</div></article>
|
||||
<article class="swatch" style="--value: var(--muted)"><div class="color"></div><div class="meta"><strong>Muted</strong>--muted</div></article>
|
||||
<article class="swatch" style="--value: var(--border)"><div class="color"></div><div class="meta"><strong>Border</strong>--border</div></article>
|
||||
<article class="swatch" style="--value: var(--accent)"><div class="color"></div><div class="meta"><strong>Accent</strong>--accent</div></article>
|
||||
<article class="swatch" style="--value: var(--success)"><div class="color"></div><div class="meta"><strong>Success</strong>--success</div></article>
|
||||
<article class="swatch" style="--value: var(--warn)"><div class="color"></div><div class="meta"><strong>Warning</strong>--warn</div></article>
|
||||
<article class="swatch" style="--value: var(--danger)"><div class="color"></div><div class="meta"><strong>Danger</strong>--danger</div></article>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,41 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Supabase spacing</title>
|
||||
<link rel="stylesheet" href="../tokens.css" />
|
||||
<style>
|
||||
body { margin: 0; background: var(--bg); color: var(--fg); font-family: var(--font-body); }
|
||||
main { max-width: var(--container-max); margin: 0 auto; padding: var(--space-12) var(--space-6); }
|
||||
h1 { margin: 0 0 var(--space-6); font-family: var(--font-display); font-size: var(--text-2xl); line-height: var(--leading-tight); letter-spacing: var(--tracking-display); }
|
||||
|
||||
.stack { display: grid; gap: var(--space-3); margin-bottom: var(--space-8); }
|
||||
.row { display: grid; grid-template-columns: 120px 1fr; align-items: center; gap: var(--space-4); color: var(--muted); font-size: var(--text-sm); }
|
||||
.bar { height: var(--space-4); min-width: 2px; background: var(--accent); }
|
||||
.radii { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--space-4); }
|
||||
.radii article { min-height: 88px; display: grid; place-items: center; border: 1px solid var(--border); background: var(--surface); color: var(--fg-2); font-size: var(--text-sm); box-shadow: var(--elev-ring); }
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<h1>Spacing and radius</h1>
|
||||
|
||||
<section class="stack">
|
||||
<div class="row"><span>--space-2</span><div class="bar" style="width: var(--space-2)"></div></div>
|
||||
<div class="row"><span>--space-4</span><div class="bar" style="width: var(--space-4)"></div></div>
|
||||
<div class="row"><span>--space-6</span><div class="bar" style="width: var(--space-6)"></div></div>
|
||||
<div class="row"><span>--space-8</span><div class="bar" style="width: var(--space-8)"></div></div>
|
||||
<div class="row"><span>--space-12</span><div class="bar" style="width: var(--space-12)"></div></div>
|
||||
</section>
|
||||
<section class="radii">
|
||||
<article style="border-radius: var(--radius-sm)">--radius-sm</article>
|
||||
<article style="border-radius: var(--radius-md)">--radius-md</article>
|
||||
<article style="border-radius: var(--radius-lg)">--radius-lg</article>
|
||||
<article style="border-radius: var(--radius-pill)">--radius-pill</article>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,34 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Supabase typography</title>
|
||||
<link rel="stylesheet" href="../tokens.css" />
|
||||
<style>
|
||||
body { margin: 0; background: var(--bg); color: var(--fg); font-family: var(--font-body); }
|
||||
main { max-width: var(--container-max); margin: 0 auto; padding: var(--space-12) var(--space-6); }
|
||||
h1 { margin: 0 0 var(--space-6); font-family: var(--font-display); font-size: var(--text-2xl); line-height: var(--leading-tight); letter-spacing: var(--tracking-display); }
|
||||
|
||||
.type-stack { display: grid; gap: var(--space-4); max-width: 760px; }
|
||||
.eyebrow { margin: 0; color: var(--accent); font-size: var(--text-xs); letter-spacing: var(--tracking-display); text-transform: uppercase; }
|
||||
h2 { margin: 0; font-family: var(--font-display); font-size: var(--text-4xl); line-height: var(--leading-tight); letter-spacing: var(--tracking-display); }
|
||||
.lede { margin: 0; color: var(--fg-2); font-size: var(--text-lg); line-height: var(--leading-body); }
|
||||
.body { margin: 0; color: var(--muted); font-size: var(--text-base); line-height: var(--leading-body); }
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<h1>Typography</h1>
|
||||
|
||||
<section class="type-stack">
|
||||
<p class="eyebrow">Backend & Data</p>
|
||||
<h2>Display sample for Supabase</h2>
|
||||
<p class="lede">Body rhythm, heading scale, and muted metadata all resolve through the committed token contract.</p>
|
||||
<p class="body">The preview intentionally uses only schema tokens so reviewers can confirm the package remains portable across OpenDesign artifacts.</p>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,17 @@
|
||||
# Supabase Source Evidence
|
||||
|
||||
## Source Scope
|
||||
|
||||
This Design System 2.0 backfill is derived from the curated OpenDesign bundled fixture.
|
||||
It does not claim a fresh crawl of the original upstream brand repository or website.
|
||||
|
||||
## Included Fixture Files
|
||||
|
||||
- design-systems/supabase/DESIGN.md
|
||||
- design-systems/supabase/tokens.css
|
||||
- design-systems/supabase/components.html
|
||||
|
||||
## Token Contract
|
||||
|
||||
`source/token-contract.report.json` maps every TOKEN_SCHEMA binding back to the committed `tokens.css` declaration line.
|
||||
`design-tokens.json` and `tailwind-v4.css` are derived outputs and should be regenerated from the report and token stylesheet rather than edited by hand.
|
||||
@@ -0,0 +1,641 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"contract": "TOKEN_SCHEMA",
|
||||
"generatedAt": "2026-06-06T00:00:00.000Z",
|
||||
"sourceScope": "open-design-bundled-fixture",
|
||||
"summary": {
|
||||
"totalTokens": 56,
|
||||
"declaredTokens": 56,
|
||||
"sourceBackedTokens": 56,
|
||||
"sourceBackedA1": 26,
|
||||
"fallbackTokens": 26,
|
||||
"aliasTokens": 1,
|
||||
"layerCounts": {
|
||||
"A1-identity": 8,
|
||||
"B-slot": 4,
|
||||
"A2": 26,
|
||||
"A1-structure": 18
|
||||
},
|
||||
"score": 100,
|
||||
"grade": "excellent",
|
||||
"recommendRebuild": false
|
||||
},
|
||||
"tokens": [
|
||||
{
|
||||
"name": "--bg",
|
||||
"layer": "A1-identity",
|
||||
"value": "#171717",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --bg; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:122"
|
||||
],
|
||||
"sourceName": "--bg"
|
||||
},
|
||||
{
|
||||
"name": "--surface",
|
||||
"layer": "A1-identity",
|
||||
"value": "#1c1c1c",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --surface; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:123"
|
||||
],
|
||||
"sourceName": "--surface"
|
||||
},
|
||||
{
|
||||
"name": "--surface-warm",
|
||||
"layer": "B-slot",
|
||||
"value": "var(--surface)",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --surface-warm; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:124"
|
||||
],
|
||||
"sourceName": "--surface-warm"
|
||||
},
|
||||
{
|
||||
"name": "--fg",
|
||||
"layer": "A1-identity",
|
||||
"value": "#fafafa",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --fg; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:134"
|
||||
],
|
||||
"sourceName": "--fg"
|
||||
},
|
||||
{
|
||||
"name": "--fg-2",
|
||||
"layer": "B-slot",
|
||||
"value": "#b4b4b4",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --fg-2; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:135"
|
||||
],
|
||||
"sourceName": "--fg-2"
|
||||
},
|
||||
{
|
||||
"name": "--muted",
|
||||
"layer": "A1-identity",
|
||||
"value": "#898989",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --muted; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:136"
|
||||
],
|
||||
"sourceName": "--muted"
|
||||
},
|
||||
{
|
||||
"name": "--meta",
|
||||
"layer": "B-slot",
|
||||
"value": "#4d4d4d",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --meta; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:137"
|
||||
],
|
||||
"sourceName": "--meta"
|
||||
},
|
||||
{
|
||||
"name": "--border",
|
||||
"layer": "A1-identity",
|
||||
"value": "#2e2e2e",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --border; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:145"
|
||||
],
|
||||
"sourceName": "--border"
|
||||
},
|
||||
{
|
||||
"name": "--border-soft",
|
||||
"layer": "B-slot",
|
||||
"value": "#242424",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --border-soft; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:146"
|
||||
],
|
||||
"sourceName": "--border-soft"
|
||||
},
|
||||
{
|
||||
"name": "--accent",
|
||||
"layer": "A1-identity",
|
||||
"value": "#3ecf8e",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --accent; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:163"
|
||||
],
|
||||
"sourceName": "--accent"
|
||||
},
|
||||
{
|
||||
"name": "--accent-on",
|
||||
"layer": "A2",
|
||||
"value": "#0f0f0f",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --accent-on; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:164"
|
||||
],
|
||||
"sourceName": "--accent-on"
|
||||
},
|
||||
{
|
||||
"name": "--accent-hover",
|
||||
"layer": "A2",
|
||||
"value": "#00c573",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --accent-hover; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:165"
|
||||
],
|
||||
"sourceName": "--accent-hover"
|
||||
},
|
||||
{
|
||||
"name": "--accent-active",
|
||||
"layer": "A2",
|
||||
"value": "color-mix(in oklab, var(--accent), black 14%)",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --accent-active; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:166"
|
||||
],
|
||||
"sourceName": "--accent-active"
|
||||
},
|
||||
{
|
||||
"name": "--success",
|
||||
"layer": "A2",
|
||||
"value": "#16a34a",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --success; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:174"
|
||||
],
|
||||
"sourceName": "--success"
|
||||
},
|
||||
{
|
||||
"name": "--warn",
|
||||
"layer": "A2",
|
||||
"value": "#eab308",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --warn; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:175"
|
||||
],
|
||||
"sourceName": "--warn"
|
||||
},
|
||||
{
|
||||
"name": "--danger",
|
||||
"layer": "A2",
|
||||
"value": "#dc2626",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --danger; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:176"
|
||||
],
|
||||
"sourceName": "--danger"
|
||||
},
|
||||
{
|
||||
"name": "--font-display",
|
||||
"layer": "A1-identity",
|
||||
"value": "\"Circular\", \"custom-font\", \"Helvetica Neue\", Helvetica, Arial, sans-serif",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --font-display; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:188"
|
||||
],
|
||||
"sourceName": "--font-display"
|
||||
},
|
||||
{
|
||||
"name": "--font-body",
|
||||
"layer": "A1-identity",
|
||||
"value": "\"Circular\", \"custom-font\", \"Helvetica Neue\", Helvetica, Arial, sans-serif",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --font-body; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:189"
|
||||
],
|
||||
"sourceName": "--font-body"
|
||||
},
|
||||
{
|
||||
"name": "--font-mono",
|
||||
"layer": "A2",
|
||||
"value": "\"Source Code Pro\", \"Office Code Pro\", Menlo, Monaco, Consolas, monospace",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --font-mono; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:190"
|
||||
],
|
||||
"sourceName": "--font-mono"
|
||||
},
|
||||
{
|
||||
"name": "--text-xs",
|
||||
"layer": "A1-structure",
|
||||
"value": "12px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --text-xs; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:197"
|
||||
],
|
||||
"sourceName": "--text-xs"
|
||||
},
|
||||
{
|
||||
"name": "--text-sm",
|
||||
"layer": "A1-structure",
|
||||
"value": "14px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --text-sm; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:198"
|
||||
],
|
||||
"sourceName": "--text-sm"
|
||||
},
|
||||
{
|
||||
"name": "--text-base",
|
||||
"layer": "A1-structure",
|
||||
"value": "16px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --text-base; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:199"
|
||||
],
|
||||
"sourceName": "--text-base"
|
||||
},
|
||||
{
|
||||
"name": "--text-lg",
|
||||
"layer": "A1-structure",
|
||||
"value": "18px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --text-lg; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:200"
|
||||
],
|
||||
"sourceName": "--text-lg"
|
||||
},
|
||||
{
|
||||
"name": "--text-xl",
|
||||
"layer": "A1-structure",
|
||||
"value": "24px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --text-xl; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:201"
|
||||
],
|
||||
"sourceName": "--text-xl"
|
||||
},
|
||||
{
|
||||
"name": "--text-2xl",
|
||||
"layer": "A1-structure",
|
||||
"value": "32px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --text-2xl; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:202"
|
||||
],
|
||||
"sourceName": "--text-2xl"
|
||||
},
|
||||
{
|
||||
"name": "--text-3xl",
|
||||
"layer": "A1-structure",
|
||||
"value": "36px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --text-3xl; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:203"
|
||||
],
|
||||
"sourceName": "--text-3xl"
|
||||
},
|
||||
{
|
||||
"name": "--text-4xl",
|
||||
"layer": "A1-structure",
|
||||
"value": "72px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --text-4xl; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:204"
|
||||
],
|
||||
"sourceName": "--text-4xl"
|
||||
},
|
||||
{
|
||||
"name": "--leading-body",
|
||||
"layer": "A1-structure",
|
||||
"value": "1.5",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --leading-body; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:212"
|
||||
],
|
||||
"sourceName": "--leading-body"
|
||||
},
|
||||
{
|
||||
"name": "--leading-tight",
|
||||
"layer": "A1-structure",
|
||||
"value": "1.00",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --leading-tight; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:213"
|
||||
],
|
||||
"sourceName": "--leading-tight"
|
||||
},
|
||||
{
|
||||
"name": "--tracking-display",
|
||||
"layer": "A1-structure",
|
||||
"value": "normal",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --tracking-display; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:214"
|
||||
],
|
||||
"sourceName": "--tracking-display"
|
||||
},
|
||||
{
|
||||
"name": "--space-1",
|
||||
"layer": "A2",
|
||||
"value": "4px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --space-1; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:221"
|
||||
],
|
||||
"sourceName": "--space-1"
|
||||
},
|
||||
{
|
||||
"name": "--space-2",
|
||||
"layer": "A2",
|
||||
"value": "8px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --space-2; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:222"
|
||||
],
|
||||
"sourceName": "--space-2"
|
||||
},
|
||||
{
|
||||
"name": "--space-3",
|
||||
"layer": "A2",
|
||||
"value": "12px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --space-3; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:223"
|
||||
],
|
||||
"sourceName": "--space-3"
|
||||
},
|
||||
{
|
||||
"name": "--space-4",
|
||||
"layer": "A2",
|
||||
"value": "16px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --space-4; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:224"
|
||||
],
|
||||
"sourceName": "--space-4"
|
||||
},
|
||||
{
|
||||
"name": "--space-5",
|
||||
"layer": "A2",
|
||||
"value": "20px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --space-5; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:225"
|
||||
],
|
||||
"sourceName": "--space-5"
|
||||
},
|
||||
{
|
||||
"name": "--space-6",
|
||||
"layer": "A2",
|
||||
"value": "24px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --space-6; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:226"
|
||||
],
|
||||
"sourceName": "--space-6"
|
||||
},
|
||||
{
|
||||
"name": "--space-8",
|
||||
"layer": "A2",
|
||||
"value": "32px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --space-8; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:227"
|
||||
],
|
||||
"sourceName": "--space-8"
|
||||
},
|
||||
{
|
||||
"name": "--space-12",
|
||||
"layer": "A2",
|
||||
"value": "48px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --space-12; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:228"
|
||||
],
|
||||
"sourceName": "--space-12"
|
||||
},
|
||||
{
|
||||
"name": "--section-y-desktop",
|
||||
"layer": "A1-structure",
|
||||
"value": "128px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --section-y-desktop; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:235"
|
||||
],
|
||||
"sourceName": "--section-y-desktop"
|
||||
},
|
||||
{
|
||||
"name": "--section-y-tablet",
|
||||
"layer": "A1-structure",
|
||||
"value": "80px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --section-y-tablet; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:236"
|
||||
],
|
||||
"sourceName": "--section-y-tablet"
|
||||
},
|
||||
{
|
||||
"name": "--section-y-phone",
|
||||
"layer": "A1-structure",
|
||||
"value": "48px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --section-y-phone; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:237"
|
||||
],
|
||||
"sourceName": "--section-y-phone"
|
||||
},
|
||||
{
|
||||
"name": "--radius-sm",
|
||||
"layer": "A2",
|
||||
"value": "6px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --radius-sm; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:247"
|
||||
],
|
||||
"sourceName": "--radius-sm"
|
||||
},
|
||||
{
|
||||
"name": "--radius-md",
|
||||
"layer": "A2",
|
||||
"value": "8px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --radius-md; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:248"
|
||||
],
|
||||
"sourceName": "--radius-md"
|
||||
},
|
||||
{
|
||||
"name": "--radius-lg",
|
||||
"layer": "A2",
|
||||
"value": "16px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --radius-lg; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:249"
|
||||
],
|
||||
"sourceName": "--radius-lg"
|
||||
},
|
||||
{
|
||||
"name": "--radius-pill",
|
||||
"layer": "A2",
|
||||
"value": "9999px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --radius-pill; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:250"
|
||||
],
|
||||
"sourceName": "--radius-pill"
|
||||
},
|
||||
{
|
||||
"name": "--elev-flat",
|
||||
"layer": "A2",
|
||||
"value": "none",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --elev-flat; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:263"
|
||||
],
|
||||
"sourceName": "--elev-flat"
|
||||
},
|
||||
{
|
||||
"name": "--elev-ring",
|
||||
"layer": "A2",
|
||||
"value": "0 0 0 1px var(--border)",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --elev-ring; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:264"
|
||||
],
|
||||
"sourceName": "--elev-ring"
|
||||
},
|
||||
{
|
||||
"name": "--elev-raised",
|
||||
"layer": "A2",
|
||||
"value": "0 0 0 1px var(--border), 0 4px 12px rgba(0, 0, 0, 0.4)",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --elev-raised; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:265"
|
||||
],
|
||||
"sourceName": "--elev-raised"
|
||||
},
|
||||
{
|
||||
"name": "--focus-ring",
|
||||
"layer": "A2",
|
||||
"value": "0 0 0 2px color-mix(in oklab, var(--accent), transparent 50%)",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --focus-ring; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:274"
|
||||
],
|
||||
"sourceName": "--focus-ring"
|
||||
},
|
||||
{
|
||||
"name": "--motion-fast",
|
||||
"layer": "A2",
|
||||
"value": "150ms",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --motion-fast; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:281"
|
||||
],
|
||||
"sourceName": "--motion-fast"
|
||||
},
|
||||
{
|
||||
"name": "--motion-base",
|
||||
"layer": "A2",
|
||||
"value": "200ms",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --motion-base; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:282"
|
||||
],
|
||||
"sourceName": "--motion-base"
|
||||
},
|
||||
{
|
||||
"name": "--ease-standard",
|
||||
"layer": "A2",
|
||||
"value": "cubic-bezier(0.2, 0, 0, 1)",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --ease-standard; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:283"
|
||||
],
|
||||
"sourceName": "--ease-standard"
|
||||
},
|
||||
{
|
||||
"name": "--container-max",
|
||||
"layer": "A1-structure",
|
||||
"value": "1200px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --container-max; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:290"
|
||||
],
|
||||
"sourceName": "--container-max"
|
||||
},
|
||||
{
|
||||
"name": "--container-gutter-desktop",
|
||||
"layer": "A1-structure",
|
||||
"value": "24px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --container-gutter-desktop; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:291"
|
||||
],
|
||||
"sourceName": "--container-gutter-desktop"
|
||||
},
|
||||
{
|
||||
"name": "--container-gutter-tablet",
|
||||
"layer": "A1-structure",
|
||||
"value": "16px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --container-gutter-tablet; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:292"
|
||||
],
|
||||
"sourceName": "--container-gutter-tablet"
|
||||
},
|
||||
{
|
||||
"name": "--container-gutter-phone",
|
||||
"layer": "A1-structure",
|
||||
"value": "16px",
|
||||
"confidence": "high",
|
||||
"reason": "Bundled tokens.css declares --container-gutter-phone; no upstream recrawl was performed for this backfill.",
|
||||
"sources": [
|
||||
"tokens.css:293"
|
||||
],
|
||||
"sourceName": "--container-gutter-phone"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,349 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"sourceScope": "open-design-bundled-fixture",
|
||||
"brandId": "supabase",
|
||||
"files": [
|
||||
"DESIGN.md",
|
||||
"tokens.css",
|
||||
"components.html"
|
||||
],
|
||||
"generatedAt": "2026-06-06T00:00:00.000Z",
|
||||
"tokens": [
|
||||
{
|
||||
"name": "--bg",
|
||||
"value": "#171717",
|
||||
"layer": "A1-identity",
|
||||
"source": "tokens.css:122"
|
||||
},
|
||||
{
|
||||
"name": "--surface",
|
||||
"value": "#1c1c1c",
|
||||
"layer": "A1-identity",
|
||||
"source": "tokens.css:123"
|
||||
},
|
||||
{
|
||||
"name": "--surface-warm",
|
||||
"value": "var(--surface)",
|
||||
"layer": "B-slot",
|
||||
"source": "tokens.css:124"
|
||||
},
|
||||
{
|
||||
"name": "--fg",
|
||||
"value": "#fafafa",
|
||||
"layer": "A1-identity",
|
||||
"source": "tokens.css:134"
|
||||
},
|
||||
{
|
||||
"name": "--fg-2",
|
||||
"value": "#b4b4b4",
|
||||
"layer": "B-slot",
|
||||
"source": "tokens.css:135"
|
||||
},
|
||||
{
|
||||
"name": "--muted",
|
||||
"value": "#898989",
|
||||
"layer": "A1-identity",
|
||||
"source": "tokens.css:136"
|
||||
},
|
||||
{
|
||||
"name": "--meta",
|
||||
"value": "#4d4d4d",
|
||||
"layer": "B-slot",
|
||||
"source": "tokens.css:137"
|
||||
},
|
||||
{
|
||||
"name": "--border",
|
||||
"value": "#2e2e2e",
|
||||
"layer": "A1-identity",
|
||||
"source": "tokens.css:145"
|
||||
},
|
||||
{
|
||||
"name": "--border-soft",
|
||||
"value": "#242424",
|
||||
"layer": "B-slot",
|
||||
"source": "tokens.css:146"
|
||||
},
|
||||
{
|
||||
"name": "--accent",
|
||||
"value": "#3ecf8e",
|
||||
"layer": "A1-identity",
|
||||
"source": "tokens.css:163"
|
||||
},
|
||||
{
|
||||
"name": "--accent-on",
|
||||
"value": "#0f0f0f",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:164"
|
||||
},
|
||||
{
|
||||
"name": "--accent-hover",
|
||||
"value": "#00c573",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:165"
|
||||
},
|
||||
{
|
||||
"name": "--accent-active",
|
||||
"value": "color-mix(in oklab, var(--accent), black 14%)",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:166"
|
||||
},
|
||||
{
|
||||
"name": "--success",
|
||||
"value": "#16a34a",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:174"
|
||||
},
|
||||
{
|
||||
"name": "--warn",
|
||||
"value": "#eab308",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:175"
|
||||
},
|
||||
{
|
||||
"name": "--danger",
|
||||
"value": "#dc2626",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:176"
|
||||
},
|
||||
{
|
||||
"name": "--font-display",
|
||||
"value": "\"Circular\", \"custom-font\", \"Helvetica Neue\", Helvetica, Arial, sans-serif",
|
||||
"layer": "A1-identity",
|
||||
"source": "tokens.css:188"
|
||||
},
|
||||
{
|
||||
"name": "--font-body",
|
||||
"value": "\"Circular\", \"custom-font\", \"Helvetica Neue\", Helvetica, Arial, sans-serif",
|
||||
"layer": "A1-identity",
|
||||
"source": "tokens.css:189"
|
||||
},
|
||||
{
|
||||
"name": "--font-mono",
|
||||
"value": "\"Source Code Pro\", \"Office Code Pro\", Menlo, Monaco, Consolas, monospace",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:190"
|
||||
},
|
||||
{
|
||||
"name": "--text-xs",
|
||||
"value": "12px",
|
||||
"layer": "A1-structure",
|
||||
"source": "tokens.css:197"
|
||||
},
|
||||
{
|
||||
"name": "--text-sm",
|
||||
"value": "14px",
|
||||
"layer": "A1-structure",
|
||||
"source": "tokens.css:198"
|
||||
},
|
||||
{
|
||||
"name": "--text-base",
|
||||
"value": "16px",
|
||||
"layer": "A1-structure",
|
||||
"source": "tokens.css:199"
|
||||
},
|
||||
{
|
||||
"name": "--text-lg",
|
||||
"value": "18px",
|
||||
"layer": "A1-structure",
|
||||
"source": "tokens.css:200"
|
||||
},
|
||||
{
|
||||
"name": "--text-xl",
|
||||
"value": "24px",
|
||||
"layer": "A1-structure",
|
||||
"source": "tokens.css:201"
|
||||
},
|
||||
{
|
||||
"name": "--text-2xl",
|
||||
"value": "32px",
|
||||
"layer": "A1-structure",
|
||||
"source": "tokens.css:202"
|
||||
},
|
||||
{
|
||||
"name": "--text-3xl",
|
||||
"value": "36px",
|
||||
"layer": "A1-structure",
|
||||
"source": "tokens.css:203"
|
||||
},
|
||||
{
|
||||
"name": "--text-4xl",
|
||||
"value": "72px",
|
||||
"layer": "A1-structure",
|
||||
"source": "tokens.css:204"
|
||||
},
|
||||
{
|
||||
"name": "--leading-body",
|
||||
"value": "1.5",
|
||||
"layer": "A1-structure",
|
||||
"source": "tokens.css:212"
|
||||
},
|
||||
{
|
||||
"name": "--leading-tight",
|
||||
"value": "1.00",
|
||||
"layer": "A1-structure",
|
||||
"source": "tokens.css:213"
|
||||
},
|
||||
{
|
||||
"name": "--tracking-display",
|
||||
"value": "normal",
|
||||
"layer": "A1-structure",
|
||||
"source": "tokens.css:214"
|
||||
},
|
||||
{
|
||||
"name": "--space-1",
|
||||
"value": "4px",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:221"
|
||||
},
|
||||
{
|
||||
"name": "--space-2",
|
||||
"value": "8px",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:222"
|
||||
},
|
||||
{
|
||||
"name": "--space-3",
|
||||
"value": "12px",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:223"
|
||||
},
|
||||
{
|
||||
"name": "--space-4",
|
||||
"value": "16px",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:224"
|
||||
},
|
||||
{
|
||||
"name": "--space-5",
|
||||
"value": "20px",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:225"
|
||||
},
|
||||
{
|
||||
"name": "--space-6",
|
||||
"value": "24px",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:226"
|
||||
},
|
||||
{
|
||||
"name": "--space-8",
|
||||
"value": "32px",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:227"
|
||||
},
|
||||
{
|
||||
"name": "--space-12",
|
||||
"value": "48px",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:228"
|
||||
},
|
||||
{
|
||||
"name": "--section-y-desktop",
|
||||
"value": "128px",
|
||||
"layer": "A1-structure",
|
||||
"source": "tokens.css:235"
|
||||
},
|
||||
{
|
||||
"name": "--section-y-tablet",
|
||||
"value": "80px",
|
||||
"layer": "A1-structure",
|
||||
"source": "tokens.css:236"
|
||||
},
|
||||
{
|
||||
"name": "--section-y-phone",
|
||||
"value": "48px",
|
||||
"layer": "A1-structure",
|
||||
"source": "tokens.css:237"
|
||||
},
|
||||
{
|
||||
"name": "--radius-sm",
|
||||
"value": "6px",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:247"
|
||||
},
|
||||
{
|
||||
"name": "--radius-md",
|
||||
"value": "8px",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:248"
|
||||
},
|
||||
{
|
||||
"name": "--radius-lg",
|
||||
"value": "16px",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:249"
|
||||
},
|
||||
{
|
||||
"name": "--radius-pill",
|
||||
"value": "9999px",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:250"
|
||||
},
|
||||
{
|
||||
"name": "--elev-flat",
|
||||
"value": "none",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:263"
|
||||
},
|
||||
{
|
||||
"name": "--elev-ring",
|
||||
"value": "0 0 0 1px var(--border)",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:264"
|
||||
},
|
||||
{
|
||||
"name": "--elev-raised",
|
||||
"value": "0 0 0 1px var(--border), 0 4px 12px rgba(0, 0, 0, 0.4)",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:265"
|
||||
},
|
||||
{
|
||||
"name": "--focus-ring",
|
||||
"value": "0 0 0 2px color-mix(in oklab, var(--accent), transparent 50%)",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:274"
|
||||
},
|
||||
{
|
||||
"name": "--motion-fast",
|
||||
"value": "150ms",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:281"
|
||||
},
|
||||
{
|
||||
"name": "--motion-base",
|
||||
"value": "200ms",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:282"
|
||||
},
|
||||
{
|
||||
"name": "--ease-standard",
|
||||
"value": "cubic-bezier(0.2, 0, 0, 1)",
|
||||
"layer": "A2",
|
||||
"source": "tokens.css:283"
|
||||
},
|
||||
{
|
||||
"name": "--container-max",
|
||||
"value": "1200px",
|
||||
"layer": "A1-structure",
|
||||
"source": "tokens.css:290"
|
||||
},
|
||||
{
|
||||
"name": "--container-gutter-desktop",
|
||||
"value": "24px",
|
||||
"layer": "A1-structure",
|
||||
"source": "tokens.css:291"
|
||||
},
|
||||
{
|
||||
"name": "--container-gutter-tablet",
|
||||
"value": "16px",
|
||||
"layer": "A1-structure",
|
||||
"source": "tokens.css:292"
|
||||
},
|
||||
{
|
||||
"name": "--container-gutter-phone",
|
||||
"value": "16px",
|
||||
"layer": "A1-structure",
|
||||
"source": "tokens.css:293"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Supabase - Pitch deck</title>
|
||||
<style>
|
||||
:root {
|
||||
--accent: #3ecf8e;
|
||||
--accent-active: color-mix(in oklab, var(--accent), black 14%);
|
||||
--accent-hover: #00c573;
|
||||
--accent-on: #0f0f0f;
|
||||
--bg: #171717;
|
||||
--border: #2e2e2e;
|
||||
--border-soft: #242424;
|
||||
--container-gutter-desktop: 24px;
|
||||
--container-gutter-phone: 16px;
|
||||
--container-gutter-tablet: 16px;
|
||||
--container-max: 1200px;
|
||||
--danger: #dc2626;
|
||||
--ease-standard: cubic-bezier(0.2, 0, 0, 1);
|
||||
--elev-flat: none;
|
||||
--elev-raised: 0 0 0 1px var(--border), 0 4px 12px rgba(0, 0, 0, 0.4);
|
||||
--elev-ring: 0 0 0 1px var(--border);
|
||||
--fg: #fafafa;
|
||||
--fg-2: #b4b4b4;
|
||||
--focus-ring: 0 0 0 2px color-mix(in oklab, var(--accent), transparent 50%);
|
||||
--font-body: "Circular", "custom-font", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
--font-display: "Circular", "custom-font", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
--font-mono: "Source Code Pro", "Office Code Pro", Menlo, Monaco, Consolas, monospace;
|
||||
--leading-body: 1.5;
|
||||
--leading-tight: 1.00;
|
||||
--meta: #4d4d4d;
|
||||
--motion-base: 200ms;
|
||||
--motion-fast: 150ms;
|
||||
--muted: #898989;
|
||||
--radius-lg: 16px;
|
||||
--radius-md: 8px;
|
||||
--radius-pill: 9999px;
|
||||
--radius-sm: 6px;
|
||||
--section-y-desktop: 128px;
|
||||
--section-y-phone: 48px;
|
||||
--section-y-tablet: 80px;
|
||||
--space-1: 4px;
|
||||
--space-12: 48px;
|
||||
--space-2: 8px;
|
||||
--space-3: 12px;
|
||||
--space-4: 16px;
|
||||
--space-5: 20px;
|
||||
--space-6: 24px;
|
||||
--space-8: 32px;
|
||||
--success: #16a34a;
|
||||
--surface: #1c1c1c;
|
||||
--surface-warm: var(--surface);
|
||||
--text-2xl: 32px;
|
||||
--text-3xl: 36px;
|
||||
--text-4xl: 72px;
|
||||
--text-base: 16px;
|
||||
--text-lg: 18px;
|
||||
--text-sm: 14px;
|
||||
--text-xl: 24px;
|
||||
--text-xs: 12px;
|
||||
--tracking-display: normal;
|
||||
--warn: #eab308;
|
||||
}
|
||||
:root {
|
||||
--od-page-bg: #171717;
|
||||
--od-surface: #1c1c1c;
|
||||
--od-text: #fafafa;
|
||||
--od-muted: #898989;
|
||||
--od-border: #2e2e2e;
|
||||
--od-accent: #3ecf8e;
|
||||
--od-radius: 8px;
|
||||
--od-font-body: "Circular", "custom-font", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
--od-font-display: "Circular", "custom-font", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
}
|
||||
* { box-sizing: border-box; }
|
||||
body {
|
||||
margin: 0;
|
||||
min-height: 100vh;
|
||||
background: var(--od-page-bg);
|
||||
color: var(--od-text);
|
||||
font-family: var(--od-font-body);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
a { color: inherit; }
|
||||
.page { width: min(1100px, calc(100vw - 48px)); margin: 0 auto; padding: 72px 0; }
|
||||
.eyebrow { color: var(--od-accent); font-size: 12px; font-weight: 750; letter-spacing: 0; text-transform: uppercase; }
|
||||
.hero { display: grid; grid-template-columns: 1.05fr .95fr; gap: 32px; align-items: center; }
|
||||
h1, h2, h3, p { margin: 0; }
|
||||
h1, h2, h3 { font-family: var(--od-font-display); letter-spacing: 0; line-height: 1.05; }
|
||||
h1 { margin-top: 12px; font-size: 64px; }
|
||||
h2 { font-size: 40px; }
|
||||
h3 { font-size: 22px; }
|
||||
.lead { margin-top: 18px; color: var(--od-muted); font-size: 20px; line-height: 1.55; }
|
||||
.actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }
|
||||
.button { display: inline-flex; min-height: 44px; align-items: center; justify-content: center; border-radius: var(--od-radius); padding: 0 18px; font-weight: 750; text-decoration: none; border: 1px solid var(--od-border); }
|
||||
.button.primary { background: var(--od-accent); border-color: var(--od-accent); color: #ffffff; }
|
||||
.button.secondary { background: var(--od-surface); }
|
||||
.panel, .card, .field, .slide, .email, .poster { border: 1px solid var(--od-border); border-radius: var(--od-radius); background: var(--od-surface); }
|
||||
.panel { padding: 24px; box-shadow: 0 24px 80px rgba(15, 17, 23, 0.08); }
|
||||
.metric-grid, .card-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; margin-top: 22px; }
|
||||
.metric, .card { padding: 18px; }
|
||||
.metric strong { display: block; font-size: 30px; line-height: 1; }
|
||||
.metric span, .card p, .field span { color: var(--od-muted); font-size: 14px; line-height: 1.5; }
|
||||
.chip-row { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }
|
||||
.chip { border: 1px solid var(--od-border); border-radius: 999px; padding: 8px 12px; color: var(--od-muted); }
|
||||
input, textarea, select { width: 100%; min-height: 44px; border: 1px solid var(--od-border); border-radius: var(--od-radius); background: var(--od-page-bg); color: var(--od-text); font: inherit; padding: 10px 12px; }
|
||||
label { display: grid; gap: 8px; color: var(--od-muted); font-size: 13px; font-weight: 700; }
|
||||
@media (max-width: 820px) { .hero, .metric-grid, .card-grid { grid-template-columns: 1fr; } .page { width: min(100vw - 28px, 1100px); padding: 40px 0; } h1 { font-size: 42px; } h2 { font-size: 30px; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="page">
|
||||
<section class="hero">
|
||||
<div>
|
||||
<p class="eyebrow">Deck module</p>
|
||||
<h1>Supabase Executive deck</h1>
|
||||
<p class="lead">Slide-scale title, metric, and section patterns for presentation work.</p>
|
||||
<div class="actions">
|
||||
<a class="button primary" href="#">Continue</a>
|
||||
<a class="button secondary" href="#">View details</a>
|
||||
</div>
|
||||
</div>
|
||||
<article class="panel">
|
||||
<p class="eyebrow">Preview</p>
|
||||
<h3>Pitch deck</h3>
|
||||
<p class="lead" style="font-size:16px">Bundled OpenDesign package for Supabase, derived from curated DESIGN.md, tokens.css, and components.html fixtures.</p>
|
||||
<div class="card-grid" style="grid-template-columns:1fr 1fr">
|
||||
<div class="field"><label>Primary input<input value="Supabase" /></label></div>
|
||||
<div class="field"><label>Status<select><option>Ready</option><option>Draft</option></select></label></div>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,137 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Supabase - Email</title>
|
||||
<style>
|
||||
:root {
|
||||
--accent: #3ecf8e;
|
||||
--accent-active: color-mix(in oklab, var(--accent), black 14%);
|
||||
--accent-hover: #00c573;
|
||||
--accent-on: #0f0f0f;
|
||||
--bg: #171717;
|
||||
--border: #2e2e2e;
|
||||
--border-soft: #242424;
|
||||
--container-gutter-desktop: 24px;
|
||||
--container-gutter-phone: 16px;
|
||||
--container-gutter-tablet: 16px;
|
||||
--container-max: 1200px;
|
||||
--danger: #dc2626;
|
||||
--ease-standard: cubic-bezier(0.2, 0, 0, 1);
|
||||
--elev-flat: none;
|
||||
--elev-raised: 0 0 0 1px var(--border), 0 4px 12px rgba(0, 0, 0, 0.4);
|
||||
--elev-ring: 0 0 0 1px var(--border);
|
||||
--fg: #fafafa;
|
||||
--fg-2: #b4b4b4;
|
||||
--focus-ring: 0 0 0 2px color-mix(in oklab, var(--accent), transparent 50%);
|
||||
--font-body: "Circular", "custom-font", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
--font-display: "Circular", "custom-font", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
--font-mono: "Source Code Pro", "Office Code Pro", Menlo, Monaco, Consolas, monospace;
|
||||
--leading-body: 1.5;
|
||||
--leading-tight: 1.00;
|
||||
--meta: #4d4d4d;
|
||||
--motion-base: 200ms;
|
||||
--motion-fast: 150ms;
|
||||
--muted: #898989;
|
||||
--radius-lg: 16px;
|
||||
--radius-md: 8px;
|
||||
--radius-pill: 9999px;
|
||||
--radius-sm: 6px;
|
||||
--section-y-desktop: 128px;
|
||||
--section-y-phone: 48px;
|
||||
--section-y-tablet: 80px;
|
||||
--space-1: 4px;
|
||||
--space-12: 48px;
|
||||
--space-2: 8px;
|
||||
--space-3: 12px;
|
||||
--space-4: 16px;
|
||||
--space-5: 20px;
|
||||
--space-6: 24px;
|
||||
--space-8: 32px;
|
||||
--success: #16a34a;
|
||||
--surface: #1c1c1c;
|
||||
--surface-warm: var(--surface);
|
||||
--text-2xl: 32px;
|
||||
--text-3xl: 36px;
|
||||
--text-4xl: 72px;
|
||||
--text-base: 16px;
|
||||
--text-lg: 18px;
|
||||
--text-sm: 14px;
|
||||
--text-xl: 24px;
|
||||
--text-xs: 12px;
|
||||
--tracking-display: normal;
|
||||
--warn: #eab308;
|
||||
}
|
||||
:root {
|
||||
--od-page-bg: #171717;
|
||||
--od-surface: #1c1c1c;
|
||||
--od-text: #fafafa;
|
||||
--od-muted: #898989;
|
||||
--od-border: #2e2e2e;
|
||||
--od-accent: #3ecf8e;
|
||||
--od-radius: 8px;
|
||||
--od-font-body: "Circular", "custom-font", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
--od-font-display: "Circular", "custom-font", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
}
|
||||
* { box-sizing: border-box; }
|
||||
body {
|
||||
margin: 0;
|
||||
min-height: 100vh;
|
||||
background: var(--od-page-bg);
|
||||
color: var(--od-text);
|
||||
font-family: var(--od-font-body);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
a { color: inherit; }
|
||||
.page { width: min(1100px, calc(100vw - 48px)); margin: 0 auto; padding: 72px 0; }
|
||||
.eyebrow { color: var(--od-accent); font-size: 12px; font-weight: 750; letter-spacing: 0; text-transform: uppercase; }
|
||||
.hero { display: grid; grid-template-columns: 1.05fr .95fr; gap: 32px; align-items: center; }
|
||||
h1, h2, h3, p { margin: 0; }
|
||||
h1, h2, h3 { font-family: var(--od-font-display); letter-spacing: 0; line-height: 1.05; }
|
||||
h1 { margin-top: 12px; font-size: 64px; }
|
||||
h2 { font-size: 40px; }
|
||||
h3 { font-size: 22px; }
|
||||
.lead { margin-top: 18px; color: var(--od-muted); font-size: 20px; line-height: 1.55; }
|
||||
.actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }
|
||||
.button { display: inline-flex; min-height: 44px; align-items: center; justify-content: center; border-radius: var(--od-radius); padding: 0 18px; font-weight: 750; text-decoration: none; border: 1px solid var(--od-border); }
|
||||
.button.primary { background: var(--od-accent); border-color: var(--od-accent); color: #ffffff; }
|
||||
.button.secondary { background: var(--od-surface); }
|
||||
.panel, .card, .field, .slide, .email, .poster { border: 1px solid var(--od-border); border-radius: var(--od-radius); background: var(--od-surface); }
|
||||
.panel { padding: 24px; box-shadow: 0 24px 80px rgba(15, 17, 23, 0.08); }
|
||||
.metric-grid, .card-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; margin-top: 22px; }
|
||||
.metric, .card { padding: 18px; }
|
||||
.metric strong { display: block; font-size: 30px; line-height: 1; }
|
||||
.metric span, .card p, .field span { color: var(--od-muted); font-size: 14px; line-height: 1.5; }
|
||||
.chip-row { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }
|
||||
.chip { border: 1px solid var(--od-border); border-radius: 999px; padding: 8px 12px; color: var(--od-muted); }
|
||||
input, textarea, select { width: 100%; min-height: 44px; border: 1px solid var(--od-border); border-radius: var(--od-radius); background: var(--od-page-bg); color: var(--od-text); font: inherit; padding: 10px 12px; }
|
||||
label { display: grid; gap: 8px; color: var(--od-muted); font-size: 13px; font-weight: 700; }
|
||||
@media (max-width: 820px) { .hero, .metric-grid, .card-grid { grid-template-columns: 1fr; } .page { width: min(100vw - 28px, 1100px); padding: 40px 0; } h1 { font-size: 42px; } h2 { font-size: 30px; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="page">
|
||||
<section class="hero">
|
||||
<div>
|
||||
<p class="eyebrow">Email module</p>
|
||||
<h1>Supabase Email module</h1>
|
||||
<p class="lead">Transactional header, body copy, and primary call-to-action treatment.</p>
|
||||
<div class="actions">
|
||||
<a class="button primary" href="#">Continue</a>
|
||||
<a class="button secondary" href="#">View details</a>
|
||||
</div>
|
||||
</div>
|
||||
<article class="panel">
|
||||
<p class="eyebrow">Preview</p>
|
||||
<h3>Email</h3>
|
||||
<p class="lead" style="font-size:16px">Bundled OpenDesign package for Supabase, derived from curated DESIGN.md, tokens.css, and components.html fixtures.</p>
|
||||
<div class="card-grid" style="grid-template-columns:1fr 1fr">
|
||||
<div class="field"><label>Primary input<input value="Supabase" /></label></div>
|
||||
<div class="field"><label>Status<select><option>Ready</option><option>Draft</option></select></label></div>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,137 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Supabase - Form page</title>
|
||||
<style>
|
||||
:root {
|
||||
--accent: #3ecf8e;
|
||||
--accent-active: color-mix(in oklab, var(--accent), black 14%);
|
||||
--accent-hover: #00c573;
|
||||
--accent-on: #0f0f0f;
|
||||
--bg: #171717;
|
||||
--border: #2e2e2e;
|
||||
--border-soft: #242424;
|
||||
--container-gutter-desktop: 24px;
|
||||
--container-gutter-phone: 16px;
|
||||
--container-gutter-tablet: 16px;
|
||||
--container-max: 1200px;
|
||||
--danger: #dc2626;
|
||||
--ease-standard: cubic-bezier(0.2, 0, 0, 1);
|
||||
--elev-flat: none;
|
||||
--elev-raised: 0 0 0 1px var(--border), 0 4px 12px rgba(0, 0, 0, 0.4);
|
||||
--elev-ring: 0 0 0 1px var(--border);
|
||||
--fg: #fafafa;
|
||||
--fg-2: #b4b4b4;
|
||||
--focus-ring: 0 0 0 2px color-mix(in oklab, var(--accent), transparent 50%);
|
||||
--font-body: "Circular", "custom-font", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
--font-display: "Circular", "custom-font", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
--font-mono: "Source Code Pro", "Office Code Pro", Menlo, Monaco, Consolas, monospace;
|
||||
--leading-body: 1.5;
|
||||
--leading-tight: 1.00;
|
||||
--meta: #4d4d4d;
|
||||
--motion-base: 200ms;
|
||||
--motion-fast: 150ms;
|
||||
--muted: #898989;
|
||||
--radius-lg: 16px;
|
||||
--radius-md: 8px;
|
||||
--radius-pill: 9999px;
|
||||
--radius-sm: 6px;
|
||||
--section-y-desktop: 128px;
|
||||
--section-y-phone: 48px;
|
||||
--section-y-tablet: 80px;
|
||||
--space-1: 4px;
|
||||
--space-12: 48px;
|
||||
--space-2: 8px;
|
||||
--space-3: 12px;
|
||||
--space-4: 16px;
|
||||
--space-5: 20px;
|
||||
--space-6: 24px;
|
||||
--space-8: 32px;
|
||||
--success: #16a34a;
|
||||
--surface: #1c1c1c;
|
||||
--surface-warm: var(--surface);
|
||||
--text-2xl: 32px;
|
||||
--text-3xl: 36px;
|
||||
--text-4xl: 72px;
|
||||
--text-base: 16px;
|
||||
--text-lg: 18px;
|
||||
--text-sm: 14px;
|
||||
--text-xl: 24px;
|
||||
--text-xs: 12px;
|
||||
--tracking-display: normal;
|
||||
--warn: #eab308;
|
||||
}
|
||||
:root {
|
||||
--od-page-bg: #171717;
|
||||
--od-surface: #1c1c1c;
|
||||
--od-text: #fafafa;
|
||||
--od-muted: #898989;
|
||||
--od-border: #2e2e2e;
|
||||
--od-accent: #3ecf8e;
|
||||
--od-radius: 8px;
|
||||
--od-font-body: "Circular", "custom-font", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
--od-font-display: "Circular", "custom-font", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
}
|
||||
* { box-sizing: border-box; }
|
||||
body {
|
||||
margin: 0;
|
||||
min-height: 100vh;
|
||||
background: var(--od-page-bg);
|
||||
color: var(--od-text);
|
||||
font-family: var(--od-font-body);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
a { color: inherit; }
|
||||
.page { width: min(1100px, calc(100vw - 48px)); margin: 0 auto; padding: 72px 0; }
|
||||
.eyebrow { color: var(--od-accent); font-size: 12px; font-weight: 750; letter-spacing: 0; text-transform: uppercase; }
|
||||
.hero { display: grid; grid-template-columns: 1.05fr .95fr; gap: 32px; align-items: center; }
|
||||
h1, h2, h3, p { margin: 0; }
|
||||
h1, h2, h3 { font-family: var(--od-font-display); letter-spacing: 0; line-height: 1.05; }
|
||||
h1 { margin-top: 12px; font-size: 64px; }
|
||||
h2 { font-size: 40px; }
|
||||
h3 { font-size: 22px; }
|
||||
.lead { margin-top: 18px; color: var(--od-muted); font-size: 20px; line-height: 1.55; }
|
||||
.actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }
|
||||
.button { display: inline-flex; min-height: 44px; align-items: center; justify-content: center; border-radius: var(--od-radius); padding: 0 18px; font-weight: 750; text-decoration: none; border: 1px solid var(--od-border); }
|
||||
.button.primary { background: var(--od-accent); border-color: var(--od-accent); color: #ffffff; }
|
||||
.button.secondary { background: var(--od-surface); }
|
||||
.panel, .card, .field, .slide, .email, .poster { border: 1px solid var(--od-border); border-radius: var(--od-radius); background: var(--od-surface); }
|
||||
.panel { padding: 24px; box-shadow: 0 24px 80px rgba(15, 17, 23, 0.08); }
|
||||
.metric-grid, .card-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; margin-top: 22px; }
|
||||
.metric, .card { padding: 18px; }
|
||||
.metric strong { display: block; font-size: 30px; line-height: 1; }
|
||||
.metric span, .card p, .field span { color: var(--od-muted); font-size: 14px; line-height: 1.5; }
|
||||
.chip-row { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }
|
||||
.chip { border: 1px solid var(--od-border); border-radius: 999px; padding: 8px 12px; color: var(--od-muted); }
|
||||
input, textarea, select { width: 100%; min-height: 44px; border: 1px solid var(--od-border); border-radius: var(--od-radius); background: var(--od-page-bg); color: var(--od-text); font: inherit; padding: 10px 12px; }
|
||||
label { display: grid; gap: 8px; color: var(--od-muted); font-size: 13px; font-weight: 700; }
|
||||
@media (max-width: 820px) { .hero, .metric-grid, .card-grid { grid-template-columns: 1fr; } .page { width: min(100vw - 28px, 1100px); padding: 40px 0; } h1 { font-size: 42px; } h2 { font-size: 30px; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="page">
|
||||
<section class="hero">
|
||||
<div>
|
||||
<p class="eyebrow">Form module</p>
|
||||
<h1>Supabase Capture form</h1>
|
||||
<p class="lead">Input, selection, helper text, and submission states in one focused page.</p>
|
||||
<div class="actions">
|
||||
<a class="button primary" href="#">Continue</a>
|
||||
<a class="button secondary" href="#">View details</a>
|
||||
</div>
|
||||
</div>
|
||||
<article class="panel">
|
||||
<p class="eyebrow">Preview</p>
|
||||
<h3>Form page</h3>
|
||||
<p class="lead" style="font-size:16px">Bundled OpenDesign package for Supabase, derived from curated DESIGN.md, tokens.css, and components.html fixtures.</p>
|
||||
<div class="card-grid" style="grid-template-columns:1fr 1fr">
|
||||
<div class="field"><label>Primary input<input value="Supabase" /></label></div>
|
||||
<div class="field"><label>Status<select><option>Ready</option><option>Draft</option></select></label></div>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,137 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Supabase - Landing page</title>
|
||||
<style>
|
||||
:root {
|
||||
--accent: #3ecf8e;
|
||||
--accent-active: color-mix(in oklab, var(--accent), black 14%);
|
||||
--accent-hover: #00c573;
|
||||
--accent-on: #0f0f0f;
|
||||
--bg: #171717;
|
||||
--border: #2e2e2e;
|
||||
--border-soft: #242424;
|
||||
--container-gutter-desktop: 24px;
|
||||
--container-gutter-phone: 16px;
|
||||
--container-gutter-tablet: 16px;
|
||||
--container-max: 1200px;
|
||||
--danger: #dc2626;
|
||||
--ease-standard: cubic-bezier(0.2, 0, 0, 1);
|
||||
--elev-flat: none;
|
||||
--elev-raised: 0 0 0 1px var(--border), 0 4px 12px rgba(0, 0, 0, 0.4);
|
||||
--elev-ring: 0 0 0 1px var(--border);
|
||||
--fg: #fafafa;
|
||||
--fg-2: #b4b4b4;
|
||||
--focus-ring: 0 0 0 2px color-mix(in oklab, var(--accent), transparent 50%);
|
||||
--font-body: "Circular", "custom-font", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
--font-display: "Circular", "custom-font", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
--font-mono: "Source Code Pro", "Office Code Pro", Menlo, Monaco, Consolas, monospace;
|
||||
--leading-body: 1.5;
|
||||
--leading-tight: 1.00;
|
||||
--meta: #4d4d4d;
|
||||
--motion-base: 200ms;
|
||||
--motion-fast: 150ms;
|
||||
--muted: #898989;
|
||||
--radius-lg: 16px;
|
||||
--radius-md: 8px;
|
||||
--radius-pill: 9999px;
|
||||
--radius-sm: 6px;
|
||||
--section-y-desktop: 128px;
|
||||
--section-y-phone: 48px;
|
||||
--section-y-tablet: 80px;
|
||||
--space-1: 4px;
|
||||
--space-12: 48px;
|
||||
--space-2: 8px;
|
||||
--space-3: 12px;
|
||||
--space-4: 16px;
|
||||
--space-5: 20px;
|
||||
--space-6: 24px;
|
||||
--space-8: 32px;
|
||||
--success: #16a34a;
|
||||
--surface: #1c1c1c;
|
||||
--surface-warm: var(--surface);
|
||||
--text-2xl: 32px;
|
||||
--text-3xl: 36px;
|
||||
--text-4xl: 72px;
|
||||
--text-base: 16px;
|
||||
--text-lg: 18px;
|
||||
--text-sm: 14px;
|
||||
--text-xl: 24px;
|
||||
--text-xs: 12px;
|
||||
--tracking-display: normal;
|
||||
--warn: #eab308;
|
||||
}
|
||||
:root {
|
||||
--od-page-bg: #171717;
|
||||
--od-surface: #1c1c1c;
|
||||
--od-text: #fafafa;
|
||||
--od-muted: #898989;
|
||||
--od-border: #2e2e2e;
|
||||
--od-accent: #3ecf8e;
|
||||
--od-radius: 8px;
|
||||
--od-font-body: "Circular", "custom-font", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
--od-font-display: "Circular", "custom-font", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
}
|
||||
* { box-sizing: border-box; }
|
||||
body {
|
||||
margin: 0;
|
||||
min-height: 100vh;
|
||||
background: var(--od-page-bg);
|
||||
color: var(--od-text);
|
||||
font-family: var(--od-font-body);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
a { color: inherit; }
|
||||
.page { width: min(1100px, calc(100vw - 48px)); margin: 0 auto; padding: 72px 0; }
|
||||
.eyebrow { color: var(--od-accent); font-size: 12px; font-weight: 750; letter-spacing: 0; text-transform: uppercase; }
|
||||
.hero { display: grid; grid-template-columns: 1.05fr .95fr; gap: 32px; align-items: center; }
|
||||
h1, h2, h3, p { margin: 0; }
|
||||
h1, h2, h3 { font-family: var(--od-font-display); letter-spacing: 0; line-height: 1.05; }
|
||||
h1 { margin-top: 12px; font-size: 64px; }
|
||||
h2 { font-size: 40px; }
|
||||
h3 { font-size: 22px; }
|
||||
.lead { margin-top: 18px; color: var(--od-muted); font-size: 20px; line-height: 1.55; }
|
||||
.actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }
|
||||
.button { display: inline-flex; min-height: 44px; align-items: center; justify-content: center; border-radius: var(--od-radius); padding: 0 18px; font-weight: 750; text-decoration: none; border: 1px solid var(--od-border); }
|
||||
.button.primary { background: var(--od-accent); border-color: var(--od-accent); color: #ffffff; }
|
||||
.button.secondary { background: var(--od-surface); }
|
||||
.panel, .card, .field, .slide, .email, .poster { border: 1px solid var(--od-border); border-radius: var(--od-radius); background: var(--od-surface); }
|
||||
.panel { padding: 24px; box-shadow: 0 24px 80px rgba(15, 17, 23, 0.08); }
|
||||
.metric-grid, .card-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; margin-top: 22px; }
|
||||
.metric, .card { padding: 18px; }
|
||||
.metric strong { display: block; font-size: 30px; line-height: 1; }
|
||||
.metric span, .card p, .field span { color: var(--od-muted); font-size: 14px; line-height: 1.5; }
|
||||
.chip-row { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }
|
||||
.chip { border: 1px solid var(--od-border); border-radius: 999px; padding: 8px 12px; color: var(--od-muted); }
|
||||
input, textarea, select { width: 100%; min-height: 44px; border: 1px solid var(--od-border); border-radius: var(--od-radius); background: var(--od-page-bg); color: var(--od-text); font: inherit; padding: 10px 12px; }
|
||||
label { display: grid; gap: 8px; color: var(--od-muted); font-size: 13px; font-weight: 700; }
|
||||
@media (max-width: 820px) { .hero, .metric-grid, .card-grid { grid-template-columns: 1fr; } .page { width: min(100vw - 28px, 1100px); padding: 40px 0; } h1 { font-size: 42px; } h2 { font-size: 30px; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="page">
|
||||
<section class="hero">
|
||||
<div>
|
||||
<p class="eyebrow">Landing module</p>
|
||||
<h1>Supabase Launch narrative</h1>
|
||||
<p class="lead">Hero, proof points, and conversion actions composed from the design system tokens.</p>
|
||||
<div class="actions">
|
||||
<a class="button primary" href="#">Continue</a>
|
||||
<a class="button secondary" href="#">View details</a>
|
||||
</div>
|
||||
</div>
|
||||
<article class="panel">
|
||||
<p class="eyebrow">Preview</p>
|
||||
<h3>Landing page</h3>
|
||||
<p class="lead" style="font-size:16px">Bundled OpenDesign package for Supabase, derived from curated DESIGN.md, tokens.css, and components.html fixtures.</p>
|
||||
<div class="card-grid" style="grid-template-columns:1fr 1fr">
|
||||
<div class="field"><label>Primary input<input value="Supabase" /></label></div>
|
||||
<div class="field"><label>Status<select><option>Ready</option><option>Draft</option></select></label></div>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,137 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Supabase - Newsletter</title>
|
||||
<style>
|
||||
:root {
|
||||
--accent: #3ecf8e;
|
||||
--accent-active: color-mix(in oklab, var(--accent), black 14%);
|
||||
--accent-hover: #00c573;
|
||||
--accent-on: #0f0f0f;
|
||||
--bg: #171717;
|
||||
--border: #2e2e2e;
|
||||
--border-soft: #242424;
|
||||
--container-gutter-desktop: 24px;
|
||||
--container-gutter-phone: 16px;
|
||||
--container-gutter-tablet: 16px;
|
||||
--container-max: 1200px;
|
||||
--danger: #dc2626;
|
||||
--ease-standard: cubic-bezier(0.2, 0, 0, 1);
|
||||
--elev-flat: none;
|
||||
--elev-raised: 0 0 0 1px var(--border), 0 4px 12px rgba(0, 0, 0, 0.4);
|
||||
--elev-ring: 0 0 0 1px var(--border);
|
||||
--fg: #fafafa;
|
||||
--fg-2: #b4b4b4;
|
||||
--focus-ring: 0 0 0 2px color-mix(in oklab, var(--accent), transparent 50%);
|
||||
--font-body: "Circular", "custom-font", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
--font-display: "Circular", "custom-font", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
--font-mono: "Source Code Pro", "Office Code Pro", Menlo, Monaco, Consolas, monospace;
|
||||
--leading-body: 1.5;
|
||||
--leading-tight: 1.00;
|
||||
--meta: #4d4d4d;
|
||||
--motion-base: 200ms;
|
||||
--motion-fast: 150ms;
|
||||
--muted: #898989;
|
||||
--radius-lg: 16px;
|
||||
--radius-md: 8px;
|
||||
--radius-pill: 9999px;
|
||||
--radius-sm: 6px;
|
||||
--section-y-desktop: 128px;
|
||||
--section-y-phone: 48px;
|
||||
--section-y-tablet: 80px;
|
||||
--space-1: 4px;
|
||||
--space-12: 48px;
|
||||
--space-2: 8px;
|
||||
--space-3: 12px;
|
||||
--space-4: 16px;
|
||||
--space-5: 20px;
|
||||
--space-6: 24px;
|
||||
--space-8: 32px;
|
||||
--success: #16a34a;
|
||||
--surface: #1c1c1c;
|
||||
--surface-warm: var(--surface);
|
||||
--text-2xl: 32px;
|
||||
--text-3xl: 36px;
|
||||
--text-4xl: 72px;
|
||||
--text-base: 16px;
|
||||
--text-lg: 18px;
|
||||
--text-sm: 14px;
|
||||
--text-xl: 24px;
|
||||
--text-xs: 12px;
|
||||
--tracking-display: normal;
|
||||
--warn: #eab308;
|
||||
}
|
||||
:root {
|
||||
--od-page-bg: #171717;
|
||||
--od-surface: #1c1c1c;
|
||||
--od-text: #fafafa;
|
||||
--od-muted: #898989;
|
||||
--od-border: #2e2e2e;
|
||||
--od-accent: #3ecf8e;
|
||||
--od-radius: 8px;
|
||||
--od-font-body: "Circular", "custom-font", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
--od-font-display: "Circular", "custom-font", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
}
|
||||
* { box-sizing: border-box; }
|
||||
body {
|
||||
margin: 0;
|
||||
min-height: 100vh;
|
||||
background: var(--od-page-bg);
|
||||
color: var(--od-text);
|
||||
font-family: var(--od-font-body);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
a { color: inherit; }
|
||||
.page { width: min(1100px, calc(100vw - 48px)); margin: 0 auto; padding: 72px 0; }
|
||||
.eyebrow { color: var(--od-accent); font-size: 12px; font-weight: 750; letter-spacing: 0; text-transform: uppercase; }
|
||||
.hero { display: grid; grid-template-columns: 1.05fr .95fr; gap: 32px; align-items: center; }
|
||||
h1, h2, h3, p { margin: 0; }
|
||||
h1, h2, h3 { font-family: var(--od-font-display); letter-spacing: 0; line-height: 1.05; }
|
||||
h1 { margin-top: 12px; font-size: 64px; }
|
||||
h2 { font-size: 40px; }
|
||||
h3 { font-size: 22px; }
|
||||
.lead { margin-top: 18px; color: var(--od-muted); font-size: 20px; line-height: 1.55; }
|
||||
.actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }
|
||||
.button { display: inline-flex; min-height: 44px; align-items: center; justify-content: center; border-radius: var(--od-radius); padding: 0 18px; font-weight: 750; text-decoration: none; border: 1px solid var(--od-border); }
|
||||
.button.primary { background: var(--od-accent); border-color: var(--od-accent); color: #ffffff; }
|
||||
.button.secondary { background: var(--od-surface); }
|
||||
.panel, .card, .field, .slide, .email, .poster { border: 1px solid var(--od-border); border-radius: var(--od-radius); background: var(--od-surface); }
|
||||
.panel { padding: 24px; box-shadow: 0 24px 80px rgba(15, 17, 23, 0.08); }
|
||||
.metric-grid, .card-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; margin-top: 22px; }
|
||||
.metric, .card { padding: 18px; }
|
||||
.metric strong { display: block; font-size: 30px; line-height: 1; }
|
||||
.metric span, .card p, .field span { color: var(--od-muted); font-size: 14px; line-height: 1.5; }
|
||||
.chip-row { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }
|
||||
.chip { border: 1px solid var(--od-border); border-radius: 999px; padding: 8px 12px; color: var(--od-muted); }
|
||||
input, textarea, select { width: 100%; min-height: 44px; border: 1px solid var(--od-border); border-radius: var(--od-radius); background: var(--od-page-bg); color: var(--od-text); font: inherit; padding: 10px 12px; }
|
||||
label { display: grid; gap: 8px; color: var(--od-muted); font-size: 13px; font-weight: 700; }
|
||||
@media (max-width: 820px) { .hero, .metric-grid, .card-grid { grid-template-columns: 1fr; } .page { width: min(100vw - 28px, 1100px); padding: 40px 0; } h1 { font-size: 42px; } h2 { font-size: 30px; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="page">
|
||||
<section class="hero">
|
||||
<div>
|
||||
<p class="eyebrow">Newsletter module</p>
|
||||
<h1>Supabase Editorial issue</h1>
|
||||
<p class="lead">Readable long-form layout with heading hierarchy and compact story modules.</p>
|
||||
<div class="actions">
|
||||
<a class="button primary" href="#">Continue</a>
|
||||
<a class="button secondary" href="#">View details</a>
|
||||
</div>
|
||||
</div>
|
||||
<article class="panel">
|
||||
<p class="eyebrow">Preview</p>
|
||||
<h3>Newsletter</h3>
|
||||
<p class="lead" style="font-size:16px">Bundled OpenDesign package for Supabase, derived from curated DESIGN.md, tokens.css, and components.html fixtures.</p>
|
||||
<div class="card-grid" style="grid-template-columns:1fr 1fr">
|
||||
<div class="field"><label>Primary input<input value="Supabase" /></label></div>
|
||||
<div class="field"><label>Status<select><option>Ready</option><option>Draft</option></select></label></div>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,137 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Supabase - Poster</title>
|
||||
<style>
|
||||
:root {
|
||||
--accent: #3ecf8e;
|
||||
--accent-active: color-mix(in oklab, var(--accent), black 14%);
|
||||
--accent-hover: #00c573;
|
||||
--accent-on: #0f0f0f;
|
||||
--bg: #171717;
|
||||
--border: #2e2e2e;
|
||||
--border-soft: #242424;
|
||||
--container-gutter-desktop: 24px;
|
||||
--container-gutter-phone: 16px;
|
||||
--container-gutter-tablet: 16px;
|
||||
--container-max: 1200px;
|
||||
--danger: #dc2626;
|
||||
--ease-standard: cubic-bezier(0.2, 0, 0, 1);
|
||||
--elev-flat: none;
|
||||
--elev-raised: 0 0 0 1px var(--border), 0 4px 12px rgba(0, 0, 0, 0.4);
|
||||
--elev-ring: 0 0 0 1px var(--border);
|
||||
--fg: #fafafa;
|
||||
--fg-2: #b4b4b4;
|
||||
--focus-ring: 0 0 0 2px color-mix(in oklab, var(--accent), transparent 50%);
|
||||
--font-body: "Circular", "custom-font", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
--font-display: "Circular", "custom-font", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
--font-mono: "Source Code Pro", "Office Code Pro", Menlo, Monaco, Consolas, monospace;
|
||||
--leading-body: 1.5;
|
||||
--leading-tight: 1.00;
|
||||
--meta: #4d4d4d;
|
||||
--motion-base: 200ms;
|
||||
--motion-fast: 150ms;
|
||||
--muted: #898989;
|
||||
--radius-lg: 16px;
|
||||
--radius-md: 8px;
|
||||
--radius-pill: 9999px;
|
||||
--radius-sm: 6px;
|
||||
--section-y-desktop: 128px;
|
||||
--section-y-phone: 48px;
|
||||
--section-y-tablet: 80px;
|
||||
--space-1: 4px;
|
||||
--space-12: 48px;
|
||||
--space-2: 8px;
|
||||
--space-3: 12px;
|
||||
--space-4: 16px;
|
||||
--space-5: 20px;
|
||||
--space-6: 24px;
|
||||
--space-8: 32px;
|
||||
--success: #16a34a;
|
||||
--surface: #1c1c1c;
|
||||
--surface-warm: var(--surface);
|
||||
--text-2xl: 32px;
|
||||
--text-3xl: 36px;
|
||||
--text-4xl: 72px;
|
||||
--text-base: 16px;
|
||||
--text-lg: 18px;
|
||||
--text-sm: 14px;
|
||||
--text-xl: 24px;
|
||||
--text-xs: 12px;
|
||||
--tracking-display: normal;
|
||||
--warn: #eab308;
|
||||
}
|
||||
:root {
|
||||
--od-page-bg: #171717;
|
||||
--od-surface: #1c1c1c;
|
||||
--od-text: #fafafa;
|
||||
--od-muted: #898989;
|
||||
--od-border: #2e2e2e;
|
||||
--od-accent: #3ecf8e;
|
||||
--od-radius: 8px;
|
||||
--od-font-body: "Circular", "custom-font", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
--od-font-display: "Circular", "custom-font", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
}
|
||||
* { box-sizing: border-box; }
|
||||
body {
|
||||
margin: 0;
|
||||
min-height: 100vh;
|
||||
background: var(--od-page-bg);
|
||||
color: var(--od-text);
|
||||
font-family: var(--od-font-body);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
a { color: inherit; }
|
||||
.page { width: min(1100px, calc(100vw - 48px)); margin: 0 auto; padding: 72px 0; }
|
||||
.eyebrow { color: var(--od-accent); font-size: 12px; font-weight: 750; letter-spacing: 0; text-transform: uppercase; }
|
||||
.hero { display: grid; grid-template-columns: 1.05fr .95fr; gap: 32px; align-items: center; }
|
||||
h1, h2, h3, p { margin: 0; }
|
||||
h1, h2, h3 { font-family: var(--od-font-display); letter-spacing: 0; line-height: 1.05; }
|
||||
h1 { margin-top: 12px; font-size: 64px; }
|
||||
h2 { font-size: 40px; }
|
||||
h3 { font-size: 22px; }
|
||||
.lead { margin-top: 18px; color: var(--od-muted); font-size: 20px; line-height: 1.55; }
|
||||
.actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }
|
||||
.button { display: inline-flex; min-height: 44px; align-items: center; justify-content: center; border-radius: var(--od-radius); padding: 0 18px; font-weight: 750; text-decoration: none; border: 1px solid var(--od-border); }
|
||||
.button.primary { background: var(--od-accent); border-color: var(--od-accent); color: #ffffff; }
|
||||
.button.secondary { background: var(--od-surface); }
|
||||
.panel, .card, .field, .slide, .email, .poster { border: 1px solid var(--od-border); border-radius: var(--od-radius); background: var(--od-surface); }
|
||||
.panel { padding: 24px; box-shadow: 0 24px 80px rgba(15, 17, 23, 0.08); }
|
||||
.metric-grid, .card-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; margin-top: 22px; }
|
||||
.metric, .card { padding: 18px; }
|
||||
.metric strong { display: block; font-size: 30px; line-height: 1; }
|
||||
.metric span, .card p, .field span { color: var(--od-muted); font-size: 14px; line-height: 1.5; }
|
||||
.chip-row { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }
|
||||
.chip { border: 1px solid var(--od-border); border-radius: 999px; padding: 8px 12px; color: var(--od-muted); }
|
||||
input, textarea, select { width: 100%; min-height: 44px; border: 1px solid var(--od-border); border-radius: var(--od-radius); background: var(--od-page-bg); color: var(--od-text); font: inherit; padding: 10px 12px; }
|
||||
label { display: grid; gap: 8px; color: var(--od-muted); font-size: 13px; font-weight: 700; }
|
||||
@media (max-width: 820px) { .hero, .metric-grid, .card-grid { grid-template-columns: 1fr; } .page { width: min(100vw - 28px, 1100px); padding: 40px 0; } h1 { font-size: 42px; } h2 { font-size: 30px; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="page">
|
||||
<section class="hero">
|
||||
<div>
|
||||
<p class="eyebrow">Poster module</p>
|
||||
<h1>Supabase Campaign poster</h1>
|
||||
<p class="lead">High-impact display composition using the system color, type, and spacing rhythm.</p>
|
||||
<div class="actions">
|
||||
<a class="button primary" href="#">Continue</a>
|
||||
<a class="button secondary" href="#">View details</a>
|
||||
</div>
|
||||
</div>
|
||||
<article class="panel">
|
||||
<p class="eyebrow">Preview</p>
|
||||
<h3>Poster</h3>
|
||||
<p class="lead" style="font-size:16px">Bundled OpenDesign package for Supabase, derived from curated DESIGN.md, tokens.css, and components.html fixtures.</p>
|
||||
<div class="card-grid" style="grid-template-columns:1fr 1fr">
|
||||
<div class="field"><label>Primary input<input value="Supabase" /></label></div>
|
||||
<div class="field"><label>Status<select><option>Ready</option><option>Draft</option></select></label></div>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,128 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Supabase - system assets</title>
|
||||
<style>
|
||||
:root {
|
||||
--accent: #3ecf8e;
|
||||
--accent-active: color-mix(in oklab, var(--accent), black 14%);
|
||||
--accent-hover: #00c573;
|
||||
--accent-on: #0f0f0f;
|
||||
--bg: #171717;
|
||||
--border: #2e2e2e;
|
||||
--border-soft: #242424;
|
||||
--container-gutter-desktop: 24px;
|
||||
--container-gutter-phone: 16px;
|
||||
--container-gutter-tablet: 16px;
|
||||
--container-max: 1200px;
|
||||
--danger: #dc2626;
|
||||
--ease-standard: cubic-bezier(0.2, 0, 0, 1);
|
||||
--elev-flat: none;
|
||||
--elev-raised: 0 0 0 1px var(--border), 0 4px 12px rgba(0, 0, 0, 0.4);
|
||||
--elev-ring: 0 0 0 1px var(--border);
|
||||
--fg: #fafafa;
|
||||
--fg-2: #b4b4b4;
|
||||
--focus-ring: 0 0 0 2px color-mix(in oklab, var(--accent), transparent 50%);
|
||||
--font-body: "Circular", "custom-font", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
--font-display: "Circular", "custom-font", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
--font-mono: "Source Code Pro", "Office Code Pro", Menlo, Monaco, Consolas, monospace;
|
||||
--leading-body: 1.5;
|
||||
--leading-tight: 1.00;
|
||||
--meta: #4d4d4d;
|
||||
--motion-base: 200ms;
|
||||
--motion-fast: 150ms;
|
||||
--muted: #898989;
|
||||
--radius-lg: 16px;
|
||||
--radius-md: 8px;
|
||||
--radius-pill: 9999px;
|
||||
--radius-sm: 6px;
|
||||
--section-y-desktop: 128px;
|
||||
--section-y-phone: 48px;
|
||||
--section-y-tablet: 80px;
|
||||
--space-1: 4px;
|
||||
--space-12: 48px;
|
||||
--space-2: 8px;
|
||||
--space-3: 12px;
|
||||
--space-4: 16px;
|
||||
--space-5: 20px;
|
||||
--space-6: 24px;
|
||||
--space-8: 32px;
|
||||
--success: #16a34a;
|
||||
--surface: #1c1c1c;
|
||||
--surface-warm: var(--surface);
|
||||
--text-2xl: 32px;
|
||||
--text-3xl: 36px;
|
||||
--text-4xl: 72px;
|
||||
--text-base: 16px;
|
||||
--text-lg: 18px;
|
||||
--text-sm: 14px;
|
||||
--text-xl: 24px;
|
||||
--text-xs: 12px;
|
||||
--tracking-display: normal;
|
||||
--warn: #eab308;
|
||||
}
|
||||
:root {
|
||||
--od-page-bg: #171717;
|
||||
--od-surface: #1c1c1c;
|
||||
--od-text: #fafafa;
|
||||
--od-muted: #898989;
|
||||
--od-border: #2e2e2e;
|
||||
--od-accent: #3ecf8e;
|
||||
--od-radius: 8px;
|
||||
--od-font-body: "Circular", "custom-font", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
--od-font-display: "Circular", "custom-font", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
}
|
||||
* { box-sizing: border-box; }
|
||||
body {
|
||||
margin: 0;
|
||||
min-height: 100vh;
|
||||
background: var(--od-page-bg);
|
||||
color: var(--od-text);
|
||||
font-family: var(--od-font-body);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
a { color: inherit; }
|
||||
.page { width: min(1100px, calc(100vw - 48px)); margin: 0 auto; padding: 72px 0; }
|
||||
.eyebrow { color: var(--od-accent); font-size: 12px; font-weight: 750; letter-spacing: 0; text-transform: uppercase; }
|
||||
.hero { display: grid; grid-template-columns: 1.05fr .95fr; gap: 32px; align-items: center; }
|
||||
h1, h2, h3, p { margin: 0; }
|
||||
h1, h2, h3 { font-family: var(--od-font-display); letter-spacing: 0; line-height: 1.05; }
|
||||
h1 { margin-top: 12px; font-size: 64px; }
|
||||
h2 { font-size: 40px; }
|
||||
h3 { font-size: 22px; }
|
||||
.lead { margin-top: 18px; color: var(--od-muted); font-size: 20px; line-height: 1.55; }
|
||||
.actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }
|
||||
.button { display: inline-flex; min-height: 44px; align-items: center; justify-content: center; border-radius: var(--od-radius); padding: 0 18px; font-weight: 750; text-decoration: none; border: 1px solid var(--od-border); }
|
||||
.button.primary { background: var(--od-accent); border-color: var(--od-accent); color: #ffffff; }
|
||||
.button.secondary { background: var(--od-surface); }
|
||||
.panel, .card, .field, .slide, .email, .poster { border: 1px solid var(--od-border); border-radius: var(--od-radius); background: var(--od-surface); }
|
||||
.panel { padding: 24px; box-shadow: 0 24px 80px rgba(15, 17, 23, 0.08); }
|
||||
.metric-grid, .card-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; margin-top: 22px; }
|
||||
.metric, .card { padding: 18px; }
|
||||
.metric strong { display: block; font-size: 30px; line-height: 1; }
|
||||
.metric span, .card p, .field span { color: var(--od-muted); font-size: 14px; line-height: 1.5; }
|
||||
.chip-row { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }
|
||||
.chip { border: 1px solid var(--od-border); border-radius: 999px; padding: 8px 12px; color: var(--od-muted); }
|
||||
input, textarea, select { width: 100%; min-height: 44px; border: 1px solid var(--od-border); border-radius: var(--od-radius); background: var(--od-page-bg); color: var(--od-text); font: inherit; padding: 10px 12px; }
|
||||
label { display: grid; gap: 8px; color: var(--od-muted); font-size: 13px; font-weight: 700; }
|
||||
@media (max-width: 820px) { .hero, .metric-grid, .card-grid { grid-template-columns: 1fr; } .page { width: min(100vw - 28px, 1100px); padding: 40px 0; } h1 { font-size: 42px; } h2 { font-size: 30px; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="page">
|
||||
<p class="eyebrow">Backend & Data</p>
|
||||
<h1>Supabase system assets</h1>
|
||||
<p class="lead">Generated preview modules for bundled official presets.</p>
|
||||
<section class="card-grid"><a class="card" href="kit.html"><h3>Component kit</h3><p>kit.html</p></a>
|
||||
<a class="card" href="kit.dark.html"><h3>Dark component kit</h3><p>kit.dark.html</p></a>
|
||||
<a class="card" href="artifacts/landing.html"><h3>Landing page</h3><p>artifacts/landing.html</p></a>
|
||||
<a class="card" href="artifacts/deck.html"><h3>Pitch deck</h3><p>artifacts/deck.html</p></a>
|
||||
<a class="card" href="artifacts/poster.html"><h3>Poster</h3><p>artifacts/poster.html</p></a>
|
||||
<a class="card" href="artifacts/email.html"><h3>Email</h3><p>artifacts/email.html</p></a>
|
||||
<a class="card" href="artifacts/newsletter.html"><h3>Newsletter</h3><p>artifacts/newsletter.html</p></a>
|
||||
<a class="card" href="artifacts/form.html"><h3>Form page</h3><p>artifacts/form.html</p></a></section>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,149 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Supabase - dark component kit</title>
|
||||
<style>
|
||||
:root {
|
||||
--accent: #3ecf8e;
|
||||
--accent-active: color-mix(in oklab, var(--accent), black 14%);
|
||||
--accent-hover: #00c573;
|
||||
--accent-on: #0f0f0f;
|
||||
--bg: #171717;
|
||||
--border: #2e2e2e;
|
||||
--border-soft: #242424;
|
||||
--container-gutter-desktop: 24px;
|
||||
--container-gutter-phone: 16px;
|
||||
--container-gutter-tablet: 16px;
|
||||
--container-max: 1200px;
|
||||
--danger: #dc2626;
|
||||
--ease-standard: cubic-bezier(0.2, 0, 0, 1);
|
||||
--elev-flat: none;
|
||||
--elev-raised: 0 0 0 1px var(--border), 0 4px 12px rgba(0, 0, 0, 0.4);
|
||||
--elev-ring: 0 0 0 1px var(--border);
|
||||
--fg: #fafafa;
|
||||
--fg-2: #b4b4b4;
|
||||
--focus-ring: 0 0 0 2px color-mix(in oklab, var(--accent), transparent 50%);
|
||||
--font-body: "Circular", "custom-font", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
--font-display: "Circular", "custom-font", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
--font-mono: "Source Code Pro", "Office Code Pro", Menlo, Monaco, Consolas, monospace;
|
||||
--leading-body: 1.5;
|
||||
--leading-tight: 1.00;
|
||||
--meta: #4d4d4d;
|
||||
--motion-base: 200ms;
|
||||
--motion-fast: 150ms;
|
||||
--muted: #898989;
|
||||
--radius-lg: 16px;
|
||||
--radius-md: 8px;
|
||||
--radius-pill: 9999px;
|
||||
--radius-sm: 6px;
|
||||
--section-y-desktop: 128px;
|
||||
--section-y-phone: 48px;
|
||||
--section-y-tablet: 80px;
|
||||
--space-1: 4px;
|
||||
--space-12: 48px;
|
||||
--space-2: 8px;
|
||||
--space-3: 12px;
|
||||
--space-4: 16px;
|
||||
--space-5: 20px;
|
||||
--space-6: 24px;
|
||||
--space-8: 32px;
|
||||
--success: #16a34a;
|
||||
--surface: #1c1c1c;
|
||||
--surface-warm: var(--surface);
|
||||
--text-2xl: 32px;
|
||||
--text-3xl: 36px;
|
||||
--text-4xl: 72px;
|
||||
--text-base: 16px;
|
||||
--text-lg: 18px;
|
||||
--text-sm: 14px;
|
||||
--text-xl: 24px;
|
||||
--text-xs: 12px;
|
||||
--tracking-display: normal;
|
||||
--warn: #eab308;
|
||||
}
|
||||
:root {
|
||||
--od-page-bg: #0f1115;
|
||||
--od-surface: #171a21;
|
||||
--od-text: #f8fafc;
|
||||
--od-muted: #a7adba;
|
||||
--od-border: #2a2f3a;
|
||||
--od-accent: #3ecf8e;
|
||||
--od-radius: 8px;
|
||||
--od-font-body: "Circular", "custom-font", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
--od-font-display: "Circular", "custom-font", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
}
|
||||
* { box-sizing: border-box; }
|
||||
body {
|
||||
margin: 0;
|
||||
min-height: 100vh;
|
||||
background: var(--od-page-bg);
|
||||
color: var(--od-text);
|
||||
font-family: var(--od-font-body);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
a { color: inherit; }
|
||||
.page { width: min(1100px, calc(100vw - 48px)); margin: 0 auto; padding: 72px 0; }
|
||||
.eyebrow { color: var(--od-accent); font-size: 12px; font-weight: 750; letter-spacing: 0; text-transform: uppercase; }
|
||||
.hero { display: grid; grid-template-columns: 1.05fr .95fr; gap: 32px; align-items: center; }
|
||||
h1, h2, h3, p { margin: 0; }
|
||||
h1, h2, h3 { font-family: var(--od-font-display); letter-spacing: 0; line-height: 1.05; }
|
||||
h1 { margin-top: 12px; font-size: 64px; }
|
||||
h2 { font-size: 40px; }
|
||||
h3 { font-size: 22px; }
|
||||
.lead { margin-top: 18px; color: var(--od-muted); font-size: 20px; line-height: 1.55; }
|
||||
.actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }
|
||||
.button { display: inline-flex; min-height: 44px; align-items: center; justify-content: center; border-radius: var(--od-radius); padding: 0 18px; font-weight: 750; text-decoration: none; border: 1px solid var(--od-border); }
|
||||
.button.primary { background: var(--od-accent); border-color: var(--od-accent); color: #0b0b0b; }
|
||||
.button.secondary { background: var(--od-surface); }
|
||||
.panel, .card, .field, .slide, .email, .poster { border: 1px solid var(--od-border); border-radius: var(--od-radius); background: var(--od-surface); }
|
||||
.panel { padding: 24px; box-shadow: 0 24px 80px rgba(15, 17, 23, 0.32); }
|
||||
.metric-grid, .card-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; margin-top: 22px; }
|
||||
.metric, .card { padding: 18px; }
|
||||
.metric strong { display: block; font-size: 30px; line-height: 1; }
|
||||
.metric span, .card p, .field span { color: var(--od-muted); font-size: 14px; line-height: 1.5; }
|
||||
.chip-row { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }
|
||||
.chip { border: 1px solid var(--od-border); border-radius: 999px; padding: 8px 12px; color: var(--od-muted); }
|
||||
input, textarea, select { width: 100%; min-height: 44px; border: 1px solid var(--od-border); border-radius: var(--od-radius); background: var(--od-page-bg); color: var(--od-text); font: inherit; padding: 10px 12px; }
|
||||
label { display: grid; gap: 8px; color: var(--od-muted); font-size: 13px; font-weight: 700; }
|
||||
@media (max-width: 820px) { .hero, .metric-grid, .card-grid { grid-template-columns: 1fr; } .page { width: min(100vw - 28px, 1100px); padding: 40px 0; } h1 { font-size: 42px; } h2 { font-size: 30px; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="page">
|
||||
<section class="hero">
|
||||
<div>
|
||||
<p class="eyebrow">Backend & Data system</p>
|
||||
<h1>Supabase component kit</h1>
|
||||
<p class="lead">Bundled OpenDesign package for Supabase, derived from curated DESIGN.md, tokens.css, and components.html fixtures.</p>
|
||||
<div class="actions">
|
||||
<a class="button primary" href="#">Primary</a>
|
||||
<a class="button secondary" href="#">Default</a>
|
||||
<a class="button secondary" href="#">Dashed</a>
|
||||
</div>
|
||||
</div>
|
||||
<article class="panel">
|
||||
<p class="eyebrow">Reference module</p>
|
||||
<h3>Token-driven surface</h3>
|
||||
<div class="metric-grid">
|
||||
<div class="metric"><strong>12</strong><span>Components</span></div>
|
||||
<div class="metric"><strong>4</strong><span>States</span></div>
|
||||
<div class="metric"><strong>1</strong><span>Token contract</span></div>
|
||||
</div>
|
||||
<div class="chip-row">
|
||||
<span class="chip">Hover</span>
|
||||
<span class="chip">Focus</span>
|
||||
<span class="chip">Active</span>
|
||||
<span class="chip">Disabled</span>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
<section class="card-grid" aria-label="Component examples">
|
||||
<article class="card"><h3>Buttons</h3><p>Primary, secondary, text, and destructive treatments resolve through shared color tokens.</p></article>
|
||||
<article class="card"><h3>Inputs</h3><p>Labels, helper text, and focus state use the same spacing and radius scale.</p></article>
|
||||
<article class="card"><h3>Cards</h3><p>Information modules keep elevation, border, and padding consistent across breakpoints.</p></article>
|
||||
</section>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,149 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Supabase - component kit</title>
|
||||
<style>
|
||||
:root {
|
||||
--accent: #3ecf8e;
|
||||
--accent-active: color-mix(in oklab, var(--accent), black 14%);
|
||||
--accent-hover: #00c573;
|
||||
--accent-on: #0f0f0f;
|
||||
--bg: #171717;
|
||||
--border: #2e2e2e;
|
||||
--border-soft: #242424;
|
||||
--container-gutter-desktop: 24px;
|
||||
--container-gutter-phone: 16px;
|
||||
--container-gutter-tablet: 16px;
|
||||
--container-max: 1200px;
|
||||
--danger: #dc2626;
|
||||
--ease-standard: cubic-bezier(0.2, 0, 0, 1);
|
||||
--elev-flat: none;
|
||||
--elev-raised: 0 0 0 1px var(--border), 0 4px 12px rgba(0, 0, 0, 0.4);
|
||||
--elev-ring: 0 0 0 1px var(--border);
|
||||
--fg: #fafafa;
|
||||
--fg-2: #b4b4b4;
|
||||
--focus-ring: 0 0 0 2px color-mix(in oklab, var(--accent), transparent 50%);
|
||||
--font-body: "Circular", "custom-font", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
--font-display: "Circular", "custom-font", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
--font-mono: "Source Code Pro", "Office Code Pro", Menlo, Monaco, Consolas, monospace;
|
||||
--leading-body: 1.5;
|
||||
--leading-tight: 1.00;
|
||||
--meta: #4d4d4d;
|
||||
--motion-base: 200ms;
|
||||
--motion-fast: 150ms;
|
||||
--muted: #898989;
|
||||
--radius-lg: 16px;
|
||||
--radius-md: 8px;
|
||||
--radius-pill: 9999px;
|
||||
--radius-sm: 6px;
|
||||
--section-y-desktop: 128px;
|
||||
--section-y-phone: 48px;
|
||||
--section-y-tablet: 80px;
|
||||
--space-1: 4px;
|
||||
--space-12: 48px;
|
||||
--space-2: 8px;
|
||||
--space-3: 12px;
|
||||
--space-4: 16px;
|
||||
--space-5: 20px;
|
||||
--space-6: 24px;
|
||||
--space-8: 32px;
|
||||
--success: #16a34a;
|
||||
--surface: #1c1c1c;
|
||||
--surface-warm: var(--surface);
|
||||
--text-2xl: 32px;
|
||||
--text-3xl: 36px;
|
||||
--text-4xl: 72px;
|
||||
--text-base: 16px;
|
||||
--text-lg: 18px;
|
||||
--text-sm: 14px;
|
||||
--text-xl: 24px;
|
||||
--text-xs: 12px;
|
||||
--tracking-display: normal;
|
||||
--warn: #eab308;
|
||||
}
|
||||
:root {
|
||||
--od-page-bg: #171717;
|
||||
--od-surface: #1c1c1c;
|
||||
--od-text: #fafafa;
|
||||
--od-muted: #898989;
|
||||
--od-border: #2e2e2e;
|
||||
--od-accent: #3ecf8e;
|
||||
--od-radius: 8px;
|
||||
--od-font-body: "Circular", "custom-font", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
--od-font-display: "Circular", "custom-font", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
}
|
||||
* { box-sizing: border-box; }
|
||||
body {
|
||||
margin: 0;
|
||||
min-height: 100vh;
|
||||
background: var(--od-page-bg);
|
||||
color: var(--od-text);
|
||||
font-family: var(--od-font-body);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
a { color: inherit; }
|
||||
.page { width: min(1100px, calc(100vw - 48px)); margin: 0 auto; padding: 72px 0; }
|
||||
.eyebrow { color: var(--od-accent); font-size: 12px; font-weight: 750; letter-spacing: 0; text-transform: uppercase; }
|
||||
.hero { display: grid; grid-template-columns: 1.05fr .95fr; gap: 32px; align-items: center; }
|
||||
h1, h2, h3, p { margin: 0; }
|
||||
h1, h2, h3 { font-family: var(--od-font-display); letter-spacing: 0; line-height: 1.05; }
|
||||
h1 { margin-top: 12px; font-size: 64px; }
|
||||
h2 { font-size: 40px; }
|
||||
h3 { font-size: 22px; }
|
||||
.lead { margin-top: 18px; color: var(--od-muted); font-size: 20px; line-height: 1.55; }
|
||||
.actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }
|
||||
.button { display: inline-flex; min-height: 44px; align-items: center; justify-content: center; border-radius: var(--od-radius); padding: 0 18px; font-weight: 750; text-decoration: none; border: 1px solid var(--od-border); }
|
||||
.button.primary { background: var(--od-accent); border-color: var(--od-accent); color: #ffffff; }
|
||||
.button.secondary { background: var(--od-surface); }
|
||||
.panel, .card, .field, .slide, .email, .poster { border: 1px solid var(--od-border); border-radius: var(--od-radius); background: var(--od-surface); }
|
||||
.panel { padding: 24px; box-shadow: 0 24px 80px rgba(15, 17, 23, 0.08); }
|
||||
.metric-grid, .card-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; margin-top: 22px; }
|
||||
.metric, .card { padding: 18px; }
|
||||
.metric strong { display: block; font-size: 30px; line-height: 1; }
|
||||
.metric span, .card p, .field span { color: var(--od-muted); font-size: 14px; line-height: 1.5; }
|
||||
.chip-row { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }
|
||||
.chip { border: 1px solid var(--od-border); border-radius: 999px; padding: 8px 12px; color: var(--od-muted); }
|
||||
input, textarea, select { width: 100%; min-height: 44px; border: 1px solid var(--od-border); border-radius: var(--od-radius); background: var(--od-page-bg); color: var(--od-text); font: inherit; padding: 10px 12px; }
|
||||
label { display: grid; gap: 8px; color: var(--od-muted); font-size: 13px; font-weight: 700; }
|
||||
@media (max-width: 820px) { .hero, .metric-grid, .card-grid { grid-template-columns: 1fr; } .page { width: min(100vw - 28px, 1100px); padding: 40px 0; } h1 { font-size: 42px; } h2 { font-size: 30px; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main class="page">
|
||||
<section class="hero">
|
||||
<div>
|
||||
<p class="eyebrow">Backend & Data system</p>
|
||||
<h1>Supabase component kit</h1>
|
||||
<p class="lead">Bundled OpenDesign package for Supabase, derived from curated DESIGN.md, tokens.css, and components.html fixtures.</p>
|
||||
<div class="actions">
|
||||
<a class="button primary" href="#">Primary</a>
|
||||
<a class="button secondary" href="#">Default</a>
|
||||
<a class="button secondary" href="#">Dashed</a>
|
||||
</div>
|
||||
</div>
|
||||
<article class="panel">
|
||||
<p class="eyebrow">Reference module</p>
|
||||
<h3>Token-driven surface</h3>
|
||||
<div class="metric-grid">
|
||||
<div class="metric"><strong>12</strong><span>Components</span></div>
|
||||
<div class="metric"><strong>4</strong><span>States</span></div>
|
||||
<div class="metric"><strong>1</strong><span>Token contract</span></div>
|
||||
</div>
|
||||
<div class="chip-row">
|
||||
<span class="chip">Hover</span>
|
||||
<span class="chip">Focus</span>
|
||||
<span class="chip">Active</span>
|
||||
<span class="chip">Disabled</span>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
<section class="card-grid" aria-label="Component examples">
|
||||
<article class="card"><h3>Buttons</h3><p>Primary, secondary, text, and destructive treatments resolve through shared color tokens.</p></article>
|
||||
<article class="card"><h3>Inputs</h3><p>Labels, helper text, and focus state use the same spacing and radius scale.</p></article>
|
||||
<article class="card"><h3>Cards</h3><p>Information modules keep elevation, border, and padding consistent across breakpoints.</p></article>
|
||||
</section>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"colorPrimary": "#3ecf8e",
|
||||
"colorPrimaryBg": "var(--surface)",
|
||||
"colorPrimaryHover": "#00c573",
|
||||
"colorPrimaryActive": "color-mix(in oklab, var(--accent), black 14%)",
|
||||
"fontSize": 16,
|
||||
"borderRadius": 8
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/* Derived from tokens.css. Keep tokens.css as the source of truth. */
|
||||
@import "tailwindcss";
|
||||
@import "./tokens.css";
|
||||
|
||||
@theme {
|
||||
--color-bg: var(--bg);
|
||||
--color-surface: var(--surface);
|
||||
--color-surface-warm: var(--surface-warm);
|
||||
--color-fg: var(--fg);
|
||||
--color-fg-2: var(--fg-2);
|
||||
--color-muted: var(--muted);
|
||||
--color-meta: var(--meta);
|
||||
--color-border: var(--border);
|
||||
--color-border-soft: var(--border-soft);
|
||||
--color-accent: var(--accent);
|
||||
--color-accent-on: var(--accent-on);
|
||||
--color-accent-hover: var(--accent-hover);
|
||||
--color-accent-active: var(--accent-active);
|
||||
--color-success: var(--success);
|
||||
--color-warn: var(--warn);
|
||||
--color-danger: var(--danger);
|
||||
--font-display: var(--font-display);
|
||||
--font-body: var(--font-body);
|
||||
--font-sans: var(--font-body);
|
||||
--font-mono: var(--font-mono);
|
||||
--text-xs: var(--text-xs);
|
||||
--text-sm: var(--text-sm);
|
||||
--text-base: var(--text-base);
|
||||
--text-lg: var(--text-lg);
|
||||
--text-xl: var(--text-xl);
|
||||
--text-2xl: var(--text-2xl);
|
||||
--text-3xl: var(--text-3xl);
|
||||
--text-4xl: var(--text-4xl);
|
||||
--leading-body: var(--leading-body);
|
||||
--leading-tight: var(--leading-tight);
|
||||
--tracking-display: var(--tracking-display);
|
||||
--spacing-1: var(--space-1);
|
||||
--spacing-2: var(--space-2);
|
||||
--spacing-3: var(--space-3);
|
||||
--spacing-4: var(--space-4);
|
||||
--spacing-5: var(--space-5);
|
||||
--spacing-6: var(--space-6);
|
||||
--spacing-8: var(--space-8);
|
||||
--spacing-12: var(--space-12);
|
||||
--spacing-section-desktop: var(--section-y-desktop);
|
||||
--spacing-section-tablet: var(--section-y-tablet);
|
||||
--spacing-section-phone: var(--section-y-phone);
|
||||
--radius-sm: var(--radius-sm);
|
||||
--radius-md: var(--radius-md);
|
||||
--radius-lg: var(--radius-lg);
|
||||
--radius-pill: var(--radius-pill);
|
||||
--shadow-flat: var(--elev-flat);
|
||||
--shadow-ring: var(--elev-ring);
|
||||
--shadow-raised: var(--elev-raised);
|
||||
--shadow-focus-ring: var(--focus-ring);
|
||||
--duration-fast: var(--motion-fast);
|
||||
--duration-base: var(--motion-base);
|
||||
--ease-standard: var(--ease-standard);
|
||||
--container-max: var(--container-max);
|
||||
--spacing-container-desktop: var(--container-gutter-desktop);
|
||||
--spacing-container-tablet: var(--container-gutter-tablet);
|
||||
--spacing-container-phone: var(--container-gutter-phone);
|
||||
}
|
||||
@@ -0,0 +1,294 @@
|
||||
/* ─────────────────────────────────────────────────────────────────────────
|
||||
* design-systems/supabase/tokens.css
|
||||
*
|
||||
* Structured token bindings for "Supabase" — the open-source Firebase
|
||||
* alternative whose marketing surface reads like a dark-mode editor that
|
||||
* grew up: near-black canvas (#171717), Postgres-emerald (#3ecf8e) reserved
|
||||
* for the chromatic moments, Circular geometric sans for prose, Source
|
||||
* Code Pro uppercase for the developer-console voice, and depth carried
|
||||
* by a tight border hierarchy instead of drop shadows.
|
||||
*
|
||||
* Agents generating an artifact for Supabase should paste the `:root`
|
||||
* block verbatim into the first `<style>` of the artifact, then reference
|
||||
* everything via `var(--*)`.
|
||||
*
|
||||
* Brand-specific schema decisions (each bends a schema convention to
|
||||
* match Supabase's voice rather than the cross-brand default):
|
||||
*
|
||||
* 1. `--bg: #171717` and `--surface: #1c1c1c` instead of pure black.
|
||||
* DESIGN.md §1: "deep black backgrounds (`#0f0f0f`, `#171717`)" but
|
||||
* "never pure black". The #1c1c1c surface gives cards a faint
|
||||
* luminance step above the page without warm-shifting; Supabase
|
||||
* has no warm tier, so `--surface-warm` aliases `--surface` rather
|
||||
* than introducing a tint that doesn't exist in the brand.
|
||||
*
|
||||
* 2. Four-level foreground ramp — `#fafafa → #b4b4b4 → #898989 →
|
||||
* #4d4d4d` — bound to `--fg / --fg-2 / --muted / --meta`. DESIGN.md
|
||||
* §2 documents exactly these four text tiers (Off White / Light
|
||||
* Gray / Mid Gray / Dark Gray) and §9 calls them out as the
|
||||
* primary / secondary / muted / heavy-secondary ramp. Binding them
|
||||
* independently (no aliasing) lets the marketing surface render
|
||||
* genuine four-tier hierarchy — the dark canvas hides any two-tier
|
||||
* collapse, so the differentiation is real.
|
||||
*
|
||||
* 3. `--border: #2e2e2e` and `--border-soft: #242424` as solid hex,
|
||||
* not rgba. DESIGN.md §6 makes border-as-depth THE depth system
|
||||
* ("depth comes from borders, not shadows") and §9 names #242424
|
||||
* as the subtle tier and #2e2e2e as the standard tier. The hex
|
||||
* form (instead of rgba over the dark bg) is intentional: it
|
||||
* keeps the border's luminance constant regardless of what surface
|
||||
* it sits on, which is the brand's "edges define" promise.
|
||||
*
|
||||
* 4. `--accent: #3ecf8e` — Supabase brand green, the Postgres-emerald
|
||||
* identity marker. Used SPARINGLY (DESIGN.md §1: "always as a
|
||||
* signal of 'this is Supabase' rather than as a decorative
|
||||
* element"). `--accent-on` is `#0f0f0f` (near-black), not the
|
||||
* schema default of `#ffffff`, because emerald at this luminance
|
||||
* reads with dark text far better than white — the contrast ratio
|
||||
* against the bright green is what makes the brand button legible.
|
||||
* `--accent-hover` binds to `#00c573`, the documented "green link"
|
||||
* color (DESIGN.md §2 Brand) — Supabase ships TWO emerald values
|
||||
* with semantic distinction (brand vs. interactive) and the
|
||||
* hover state is exactly where the interactive variant belongs.
|
||||
*
|
||||
* 5. `--font-display` and `--font-body` share the Circular stack.
|
||||
* Hierarchy comes from size + weight (400 for prose, 500 for
|
||||
* interactive), never from a separate display face. DESIGN.md §3
|
||||
* Principles: "There is no bold (700) in the detected system —
|
||||
* hierarchy is created through size, not weight."
|
||||
* `--font-mono: "Source Code Pro"` for the developer-console
|
||||
* voice — the uppercase technical labels with 1.2px tracking that
|
||||
* DESIGN.md §3 calls "the developer-console marker that connects
|
||||
* the marketing site to the product".
|
||||
*
|
||||
* 6. `--text-4xl: 72px` with `--leading-tight: 1.00`. DESIGN.md §3
|
||||
* makes the 1.00 hero line-height "the defining typographic
|
||||
* gesture — text that feels like a terminal command: dense,
|
||||
* efficient, no wasted vertical space." Tracking stays at
|
||||
* `normal` (per DESIGN.md §3 hero row) — Supabase reads dense
|
||||
* from the leading collapse, not from negative letter-spacing
|
||||
* like Vercel's `-0.05em`.
|
||||
*
|
||||
* 7. Section rhythm is generous: 128px desktop, 80px tablet, 48px
|
||||
* phone. DESIGN.md §5 names 90–128px desktop spacing as
|
||||
* "dramatic, cinematic pacing — each section is its own scene in
|
||||
* the dark void". The top of that range (128px) matches the
|
||||
* brand's confidence; the 48px phone floor is the documented
|
||||
* mobile collapse.
|
||||
*
|
||||
* 8. Radius scale 6 / 8 / 16 / 9999. DESIGN.md §5: standard 6px
|
||||
* (ghost buttons, secondary), comfortable 8px (cards), large 16px
|
||||
* (feature cards), pill 9999px (primary CTAs and tab indicators).
|
||||
* DESIGN.md §7 forbids the 16px tier on buttons — "pills (9999px)
|
||||
* or standard (6px), nothing in between". Component CSS enforces
|
||||
* that policy at the component level.
|
||||
*
|
||||
* 9. `--elev-raised` uses the brand's "border + minimal shadow"
|
||||
* compromise: `0 0 0 1px var(--border), 0 4px 12px rgba(0, 0, 0,
|
||||
* 0.4)`. DESIGN.md §6 says Supabase "deliberately avoids shadows"
|
||||
* but uses `rgba(0, 0, 0, 0.1) 0px 4px 12px` for focus states —
|
||||
* we deepen that alpha for the raised tier so a card actually
|
||||
* separates from the dark canvas, while keeping the ring as the
|
||||
* primary depth signal.
|
||||
*
|
||||
* 10. `--focus-ring` is a 2px ring at `color-mix(var(--accent),
|
||||
* transparent 50%)` — the green-tinted halo that DESIGN.md §6
|
||||
* Level 3 names as the "brand-highlighted" elevation. On a near-
|
||||
* black canvas the schema's default (3px alpha glow over accent)
|
||||
* reads weak; 2px at 50% transparency lands at the documented
|
||||
* `rgba(62, 207, 142, 0.3)`-ish weight and stays unmistakably
|
||||
* Supabase.
|
||||
*
|
||||
* Source contracts:
|
||||
* - Standard token names: design-systems/_schema/tokens.schema.ts
|
||||
* - A2 fallback parity: design-systems/_schema/defaults.css
|
||||
* - Lint enforcement: apps/daemon/src/lint-artifact.ts
|
||||
*
|
||||
* Keep this file additive: never invent token names not also documented
|
||||
* in DESIGN.md or the schema. Circular and Source Code Pro do not need
|
||||
* a CDN reference here — the font stacks list Helvetica Neue / Menlo
|
||||
* fallbacks so artifacts render acceptably even when the brand faces
|
||||
* are not loaded, and any host that wants the real Circular face links
|
||||
* it externally.
|
||||
* ─────────────────────────────────────────────────────────────────── */
|
||||
|
||||
:root {
|
||||
/* ─── Surface (3 levels — schema slot) ─────────────────────────────
|
||||
* #171717 is the documented page canvas (DESIGN.md §1 "Dark"). The
|
||||
* card surface bumps one luminance step to #1c1c1c so elevated
|
||||
* containers carry a faint lift without warm-shifting — Supabase
|
||||
* has no warm tier, so `--surface-warm` aliases `--surface` exactly
|
||||
* the way Vercel's achromatic canvas does. */
|
||||
--bg: #171717;
|
||||
--surface: #1c1c1c;
|
||||
--surface-warm: var(--surface); /* alias — Supabase has no warm tier */
|
||||
|
||||
/* ─── Foreground ramp (4 levels) ──────────────────────────────────
|
||||
* Off White → Light Gray → Mid Gray → Dark Gray, the documented
|
||||
* four-tier text scale from DESIGN.md §2. Each tier is independently
|
||||
* bound (no aliasing) because Supabase genuinely uses four distinct
|
||||
* text registers: heading white, body silver, caption gray, and
|
||||
* tertiary metadata gray. The four-stop ramp is the typography
|
||||
* system; collapsing it to two tiers would flatten the marketing
|
||||
* surface's voice. */
|
||||
--fg: #fafafa; /* Off White — primary text, headings */
|
||||
--fg-2: #b4b4b4; /* Light Gray — secondary body, links */
|
||||
--muted: #898989; /* Mid Gray — captions, footer, muted */
|
||||
--meta: #4d4d4d; /* Dark Gray — tertiary metadata, disabled */
|
||||
|
||||
/* ─── Border (2 levels) ──────────────────────────────────────────
|
||||
* Border-as-depth is THE depth system (DESIGN.md §6: "depth comes
|
||||
* from borders, not shadows"). #2e2e2e is the standard card edge,
|
||||
* #242424 the inner-row divider that "should not visually compete".
|
||||
* Solid hex (not rgba over bg) keeps luminance constant regardless
|
||||
* of what surface the border sits on. */
|
||||
--border: #2e2e2e; /* standard border — cards, tabs, dividers */
|
||||
--border-soft: #242424; /* subtle divider — inner row separators */
|
||||
|
||||
/* ─── Accent ─────────────────────────────────────────────────────
|
||||
* Supabase brand emerald — the Postgres-green identity marker.
|
||||
* Hard cap of ≤2 visible uses per screen (lint enforced) because
|
||||
* DESIGN.md §7 forbids using green "to backgrounds or large
|
||||
* surfaces — it's for borders, links, and small accents".
|
||||
*
|
||||
* `--accent-on` is `#0f0f0f` (near-black), NOT the schema default
|
||||
* `#ffffff` — bright emerald reads with dark text far better than
|
||||
* white, and #0f0f0f is the documented "near-black" button surface
|
||||
* already in the brand's neutral scale.
|
||||
*
|
||||
* `--accent-hover` is `#00c573` — DESIGN.md §2 documents this as
|
||||
* the "green link" interactive variant of the brand color. Mapping
|
||||
* it to the hover state preserves the brand's distinction between
|
||||
* identity-green (#3ecf8e) and interactive-green (#00c573). */
|
||||
--accent: #3ecf8e; /* Supabase emerald — brand identity marker */
|
||||
--accent-on: #0f0f0f; /* near-black label on bright emerald */
|
||||
--accent-hover: #00c573; /* documented interactive green link variant */
|
||||
--accent-active: color-mix(in oklab, var(--accent), black 14%);
|
||||
|
||||
/* ─── Semantic ───────────────────────────────────────────────────
|
||||
* Supabase's marketing surface rarely renders state. DESIGN.md §7
|
||||
* specifically forbids using the Radix warm tones (crimson, orange)
|
||||
* as primary design elements — they exist purely as semantic
|
||||
* tokens. We inherit the schema defaults rather than designing a
|
||||
* custom warm palette that doesn't appear in the brand voice. */
|
||||
--success: #16a34a;
|
||||
--warn: #eab308;
|
||||
--danger: #dc2626;
|
||||
|
||||
/* ─── Typography ─────────────────────────────────────────────────
|
||||
* Circular is Supabase's signature face — a geometric sans-serif
|
||||
* with rounded terminals that softens the technical edge.
|
||||
* `--font-display` and `--font-body` share the stack; the Helvetica
|
||||
* Neue / Helvetica / Arial fallbacks come straight from DESIGN.md
|
||||
* §3 and ensure artifacts render legibly even when Circular is not
|
||||
* loaded. Source Code Pro is the developer-console voice — the
|
||||
* uppercase technical labels with 1.2px tracking that DESIGN.md §3
|
||||
* calls "the marker that connects the marketing site to the
|
||||
* product". Office Code Pro / Menlo fallbacks match DESIGN.md §3. */
|
||||
--font-display: "Circular", "custom-font", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
--font-body: "Circular", "custom-font", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
--font-mono: "Source Code Pro", "Office Code Pro", Menlo, Monaco, Consolas, monospace;
|
||||
|
||||
/* Type scale (px) — derived from DESIGN.md §3 hierarchy table.
|
||||
* The scale tops out at 72px (display hero) and shoots straight up
|
||||
* from 36px (section heading) — the missing intermediate steps are
|
||||
* deliberate. Supabase reads BIG because the hero leading collapses
|
||||
* to 1.00, not because the px count climbs gradually. */
|
||||
--text-xs: 12px; /* small — fine print, code labels */
|
||||
--text-sm: 14px; /* button, nav link, caption */
|
||||
--text-base: 16px; /* body — standard reading */
|
||||
--text-lg: 18px; /* sub-heading — secondary headings */
|
||||
--text-xl: 24px; /* card title */
|
||||
--text-2xl: 32px; /* mid-large heading */
|
||||
--text-3xl: 36px; /* section heading */
|
||||
--text-4xl: 72px; /* display hero — terminal-density */
|
||||
|
||||
/* `--leading-tight` is 1.00 — DESIGN.md §3 names this "the defining
|
||||
* typographic gesture" and forbids relaxing it ("Don't increase
|
||||
* hero line-height above 1.00 — the density is intentional").
|
||||
* `--tracking-display` is `normal` (DESIGN.md §3 hero row) —
|
||||
* Supabase reads dense from the leading collapse, not from negative
|
||||
* letter-spacing like Vercel's -0.05em. */
|
||||
--leading-body: 1.5;
|
||||
--leading-tight: 1.00;
|
||||
--tracking-display: normal;
|
||||
|
||||
/* ─── Spacing ────────────────────────────────────────────────────
|
||||
* 4px-grid base scale. DESIGN.md §5 documents micro-stops (1px /
|
||||
* 4px / 6px) that are too fine to belong in the shared schema —
|
||||
* those are inlined per-component when needed. The 4/8/12/16/20/
|
||||
* 24/32/48 tier covers the structural rhythm of cards and stacks. */
|
||||
--space-1: 4px;
|
||||
--space-2: 8px;
|
||||
--space-3: 12px;
|
||||
--space-4: 16px;
|
||||
--space-5: 20px;
|
||||
--space-6: 24px;
|
||||
--space-8: 32px;
|
||||
--space-12: 48px;
|
||||
|
||||
/* Section rhythm — DESIGN.md §5: "Dramatic section spacing 90–128px
|
||||
* creates a cinematic pacing — each section is its own scene in the
|
||||
* dark void". We sit at the top of that range (128px desktop) to
|
||||
* honor the brand confidence, drop to 80px on tablet, and 48px on
|
||||
* phone (the documented mobile floor). */
|
||||
--section-y-desktop: 128px;
|
||||
--section-y-tablet: 80px;
|
||||
--section-y-phone: 48px;
|
||||
|
||||
/* ─── Radius ─────────────────────────────────────────────────────
|
||||
* DESIGN.md §5 radius scale: 6 / 8 / 11–12 / 16 / 9999. We bind
|
||||
* the four schema tiers to 6 (ghost / functional / secondary), 8
|
||||
* (cards / containers), 16 (feature cards / major containers),
|
||||
* 9999 (primary CTAs and pill tabs). The 11–12px mid-panel tier is
|
||||
* component-specific and not part of the shared schema. DESIGN.md
|
||||
* §7 forbids in-between radii on buttons — components MUST pick
|
||||
* pill or 6px, never 8/12/16. */
|
||||
--radius-sm: 6px; /* ghost buttons, secondary, functional */
|
||||
--radius-md: 8px; /* cards, containers */
|
||||
--radius-lg: 16px; /* feature cards, major containers */
|
||||
--radius-pill: 9999px; /* primary CTAs, tab indicators */
|
||||
|
||||
/* ─── Elevation (3 levels) ───────────────────────────────────────
|
||||
* DESIGN.md §6: Supabase "deliberately avoids shadows" because they
|
||||
* read as invisible on a dark canvas; depth is the border hierarchy
|
||||
* (#242424 → #2e2e2e → #393939 → green-accent border). We map:
|
||||
*
|
||||
* --elev-flat no shadow (page background, text blocks)
|
||||
* --elev-ring 1px hairline ring at --border (the standard tier)
|
||||
* --elev-raised ring + minimal ambient shadow (the brand's
|
||||
* compromise: DESIGN.md's focus shadow alpha
|
||||
* deepened from 0.1 to 0.4 so a card actually
|
||||
* separates from the dark canvas at distance) */
|
||||
--elev-flat: none;
|
||||
--elev-ring: 0 0 0 1px var(--border);
|
||||
--elev-raised: 0 0 0 1px var(--border), 0 4px 12px rgba(0, 0, 0, 0.4);
|
||||
|
||||
/* ─── Focus ring ─────────────────────────────────────────────────
|
||||
* 2px ring at `color-mix(var(--accent), transparent 50%)` — the
|
||||
* green-tinted halo that DESIGN.md §6 Level 3 names the "brand-
|
||||
* highlighted" elevation (`rgba(62, 207, 142, 0.3)`). On a near-
|
||||
* black canvas the schema's default 3px alpha glow reads weak;
|
||||
* 2px at 50% transparency lands at the documented weight and stays
|
||||
* unmistakably Supabase without dominating the surface. */
|
||||
--focus-ring: 0 0 0 2px color-mix(in oklab, var(--accent), transparent 50%);
|
||||
|
||||
/* ─── Motion ─────────────────────────────────────────────────────
|
||||
* Two durations + one easing curve, per the anti-ai-slop "short,
|
||||
* purposeful transitions (150–250ms) with stable easing". Supabase
|
||||
* transitions are quick and unobtrusive — the brand reads as
|
||||
* engineered, never choreographed. */
|
||||
--motion-fast: 150ms;
|
||||
--motion-base: 200ms;
|
||||
--ease-standard: cubic-bezier(0.2, 0, 0, 1);
|
||||
|
||||
/* ─── Layout ─────────────────────────────────────────────────────
|
||||
* 1200px max content width — typical for marketing surfaces.
|
||||
* Mobile gutter holds at 16px (instead of dropping to 12px) so
|
||||
* code blocks and badges retain padding context on small screens;
|
||||
* Supabase's developer-doc voice rarely edge-bleeds. */
|
||||
--container-max: 1200px;
|
||||
--container-gutter-desktop: 24px;
|
||||
--container-gutter-tablet: 16px;
|
||||
--container-gutter-phone: 16px;
|
||||
}
|
||||
Reference in new issue
Block a user