④段整套同步(六节 + 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:
admin committed 2026-10-15 21:17:28 +08:00
1 parent fa0a9026c8
commit 5afeb6b78a
4184 files changed
+326 -70

No files matched your search

@@ -0,0 +1,370 @@
# Design System Inspired by Linear
> Category: Productivity & SaaS
> Project management. Ultra-minimal, precise, purple accent.
## 1. Visual Theme & Atmosphere
Linear's website is a masterclass in dark-mode-first product design — a near-black canvas (`#08090a`) where content emerges from darkness like starlight. The overall impression is one of extreme precision engineering: every element exists in a carefully calibrated hierarchy of luminance, from barely-visible borders (`rgba(255,255,255,0.05)`) to soft, luminous text (`#f7f8f8`). This is not a dark theme applied to a light design — it is darkness as the native medium, where information density is managed through subtle gradations of white opacity rather than color variation.
The typography system is built entirely on Inter Variable with OpenType features `"cv01"` and `"ss03"` enabled globally, giving the typeface a cleaner, more geometric character. Inter is used at a remarkable range of weights — from 300 (light body) through 510 (medium, Linear's signature weight) to 590 (semibold emphasis). The 510 weight is particularly distinctive: it sits between regular and medium, creating a subtle emphasis that doesn't shout. At display sizes (72px, 64px, 48px), Inter uses aggressive negative letter-spacing (-1.584px to -1.056px), creating compressed, authoritative headlines that feel engineered rather than designed. Berkeley Mono serves as the monospace companion for code and technical labels, with fallbacks to ui-monospace, SF Mono, and Menlo.
The color system is almost entirely achromatic — dark backgrounds with white/gray text — punctuated by a single brand accent: Linear's signature indigo-violet (`#5e6ad2` for backgrounds, `#7170ff` for interactive accents). This accent color is used sparingly and intentionally, appearing only on CTAs, active states, and brand elements. The border system uses ultra-thin, semi-transparent white borders (`rgba(255,255,255,0.05)` to `rgba(255,255,255,0.08)`) that create structure without visual noise, like wireframes drawn in moonlight.
**Key Characteristics:**
- Dark-mode-native: `#08090a` marketing background, `#0f1011` panel background, `#191a1b` elevated surfaces
- Inter Variable with `"cv01", "ss03"` globally — geometric alternates for a cleaner aesthetic
- Signature weight 510 (between regular and medium) for most UI text
- Aggressive negative letter-spacing at display sizes (-1.584px at 72px, -1.056px at 48px)
- Brand indigo-violet: `#5e6ad2` (bg) / `#7170ff` (accent) / `#828fff` (hover) — the only chromatic color in the system
- Semi-transparent white borders throughout: `rgba(255,255,255,0.05)` to `rgba(255,255,255,0.08)`
- Button backgrounds at near-zero opacity: `rgba(255,255,255,0.02)` to `rgba(255,255,255,0.05)`
- Multi-layered shadows with inset variants for depth on dark surfaces
- Radix UI primitives as the component foundation (6 detected primitives)
- Success green (`#27a644`, `#10b981`) used only for status indicators
## 2. Color Palette & Roles
### Background Surfaces
- **Marketing Black** (`#010102` / `#08090a`): The deepest background — the canvas for hero sections and marketing pages. Near-pure black with an imperceptible blue-cool undertone.
- **Panel Dark** (`#0f1011`): Sidebar and panel backgrounds. One step up from the marketing black.
- **Level 3 Surface** (`#191a1b`): Elevated surface areas, card backgrounds, dropdowns.
- **Secondary Surface** (`#28282c`): The lightest dark surface — used for hover states and slightly elevated components.
### Text & Content
- **Primary Text** (`#f7f8f8`): Near-white with a barely-warm cast. The default text color — not pure white, preventing eye strain on dark backgrounds.
- **Secondary Text** (`#d0d6e0`): Cool silver-gray for body text, descriptions, and secondary content.
- **Tertiary Text** (`#8a8f98`): Muted gray for placeholders, metadata, and de-emphasized content.
- **Quaternary Text** (`#62666d`): The most subdued text — timestamps, disabled states, subtle labels.
### Brand & Accent
- **Brand Indigo** (`#5e6ad2`): Primary brand color — used for CTA button backgrounds, brand marks, and key interactive surfaces.
- **Accent Violet** (`#7170ff`): Brighter variant for interactive elements — links, active states, selected items.
- **Accent Hover** (`#828fff`): Lighter, more saturated variant for hover states on accent elements.
- **Security Lavender** (`#7a7fad`): Muted indigo used specifically for security-related UI elements.
### Status Colors
- **Green** (`#27a644`): Primary success/active status. Used for "in progress" indicators.
- **Emerald** (`#10b981`): Secondary success — pill badges, completion states.
### Border & Divider
- **Border Primary** (`#23252a`): Solid dark border for prominent separations.
- **Border Secondary** (`#34343a`): Slightly lighter solid border.
- **Border Tertiary** (`#3e3e44`): Lightest solid border variant.
- **Border Subtle** (`rgba(255,255,255,0.05)`): Ultra-subtle semi-transparent border — the default.
- **Border Standard** (`rgba(255,255,255,0.08)`): Standard semi-transparent border for cards, inputs, code blocks.
- **Line Tint** (`#141516`): Nearly invisible line for the subtlest divisions.
- **Line Tertiary** (`#18191a`): Slightly more visible divider line.
### Light Mode Neutrals (for light theme contexts)
- **Light Background** (`#f7f8f8`): Page background in light mode.
- **Light Surface** (`#f3f4f5` / `#f5f6f7`): Subtle surface tinting.
- **Light Border** (`#d0d6e0`): Visible border in light contexts.
- **Light Border Alt** (`#e6e6e6`): Alternative lighter border.
- **Pure White** (`#ffffff`): Card surfaces, highlights.
### Overlay
- **Overlay Primary** (`rgba(0,0,0,0.85)`): Modal/dialog backdrop — extremely dark for focus isolation.
## 3. Typography Rules
### Font Family
- **Primary**: `Inter Variable`, with fallbacks: `SF Pro Display, -apple-system, system-ui, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Open Sans, Helvetica Neue`
- **Monospace**: `Berkeley Mono`, with fallbacks: `ui-monospace, SF Mono, Menlo`
- **OpenType Features**: `"cv01", "ss03"` enabled globally — cv01 provides an alternate lowercase 'a' (single-story), ss03 adjusts specific letterforms for a cleaner geometric appearance.
### Hierarchy
| Role | Font | Size | Weight | Line Height | Letter Spacing | Notes |
|------|------|------|--------|-------------|----------------|-------|
| Display XL | Inter Variable | 72px (4.50rem) | 510 | 1.00 (tight) | -1.584px | Hero headlines, maximum impact |
| Display Large | Inter Variable | 64px (4.00rem) | 510 | 1.00 (tight) | -1.408px | Secondary hero text |
| Display | Inter Variable | 48px (3.00rem) | 510 | 1.00 (tight) | -1.056px | Section headlines |
| Heading 1 | Inter Variable | 32px (2.00rem) | 400 | 1.13 (tight) | -0.704px | Major section titles |
| Heading 2 | Inter Variable | 24px (1.50rem) | 400 | 1.33 | -0.288px | Sub-section headings |
| Heading 3 | Inter Variable | 20px (1.25rem) | 590 | 1.33 | -0.24px | Feature titles, card headers |
| Body Large | Inter Variable | 18px (1.13rem) | 400 | 1.60 (relaxed) | -0.165px | Introduction text, feature descriptions |
| Body Emphasis | Inter Variable | 17px (1.06rem) | 590 | 1.60 (relaxed) | normal | Emphasized body, sub-headings in content |
| Body | Inter Variable | 16px (1.00rem) | 400 | 1.50 | normal | Standard reading text |
| Body Medium | Inter Variable | 16px (1.00rem) | 510 | 1.50 | normal | Navigation, labels |
| Body Semibold | Inter Variable | 16px (1.00rem) | 590 | 1.50 | normal | Strong emphasis |
| Small | Inter Variable | 15px (0.94rem) | 400 | 1.60 (relaxed) | -0.165px | Secondary body text |
| Small Medium | Inter Variable | 15px (0.94rem) | 510 | 1.60 (relaxed) | -0.165px | Emphasized small text |
| Small Semibold | Inter Variable | 15px (0.94rem) | 590 | 1.60 (relaxed) | -0.165px | Strong small text |
| Small Light | Inter Variable | 15px (0.94rem) | 300 | 1.47 | -0.165px | De-emphasized body |
| Caption Large | Inter Variable | 14px (0.88rem) | 510–590 | 1.50 | -0.182px | Sub-labels, category headers |
| Caption | Inter Variable | 13px (0.81rem) | 400–510 | 1.50 | -0.13px | Metadata, timestamps |
| Label | Inter Variable | 12px (0.75rem) | 400–590 | 1.40 | normal | Button text, small labels |
| Micro | Inter Variable | 11px (0.69rem) | 510 | 1.40 | normal | Tiny labels |
| Tiny | Inter Variable | 10px (0.63rem) | 400–510 | 1.50 | -0.15px | Overline text, sometimes uppercase |
| Link Large | Inter Variable | 16px (1.00rem) | 400 | 1.50 | normal | Standard links |
| Link Medium | Inter Variable | 15px (0.94rem) | 510 | 2.67 | normal | Spaced navigation links |
| Link Small | Inter Variable | 14px (0.88rem) | 510 | 1.50 | normal | Compact links |
| Link Caption | Inter Variable | 13px (0.81rem) | 400–510 | 1.50 | -0.13px | Footer, metadata links |
| Mono Body | Berkeley Mono | 14px (0.88rem) | 400 | 1.50 | normal | Code blocks |
| Mono Caption | Berkeley Mono | 13px (0.81rem) | 400 | 1.50 | normal | Code labels |
| Mono Label | Berkeley Mono | 12px (0.75rem) | 400 | 1.40 | normal | Code metadata, sometimes uppercase |
### Principles
- **510 is the signature weight**: Linear uses Inter Variable's 510 weight (between regular 400 and medium 500) as its default emphasis weight. This creates a subtly bolded feel without the heaviness of traditional medium or semibold.
- **Compression at scale**: Display sizes use progressively tighter letter-spacing — -1.584px at 72px, -1.408px at 64px, -1.056px at 48px, -0.704px at 32px. Below 24px, spacing relaxes toward normal.
- **OpenType as identity**: `"cv01", "ss03"` aren't decorative — they transform Inter into Linear's distinctive typeface, giving it a more geometric, purposeful character.
- **Three-tier weight system**: 400 (reading), 510 (emphasis/UI), 590 (strong emphasis). The 300 weight appears only in deliberately de-emphasized contexts.
## 4. Component Stylings
### Buttons
**Ghost Button (Default)**
- Background: `rgba(255,255,255,0.02)`
- Text: `#e2e4e7` (near-white)
- Padding: comfortable
- Radius: 6px
- Border: `1px solid rgb(36, 40, 44)`
- Outline: none
- Focus shadow: `rgba(0,0,0,0.1) 0px 4px 12px`
- Use: Standard actions, secondary CTAs
**Subtle Button**
- Background: `rgba(255,255,255,0.04)`
- Text: `#d0d6e0` (silver-gray)
- Padding: 0px 6px
- Radius: 6px
- Use: Toolbar actions, contextual buttons
**Primary Brand Button (Inferred)**
- Background: `#5e6ad2` (brand indigo)
- Text: `#ffffff`
- Padding: 8px 16px
- Radius: 6px
- Hover: `#828fff` shift
- Use: Primary CTAs ("Start building", "Sign up")
**Icon Button (Circle)**
- Background: `rgba(255,255,255,0.03)` or `rgba(255,255,255,0.05)`
- Text: `#f7f8f8` or `#ffffff`
- Radius: 50%
- Border: `1px solid rgba(255,255,255,0.08)`
- Use: Close, menu toggle, icon-only actions
**Pill Button**
- Background: transparent
- Text: `#d0d6e0`
- Padding: 0px 10px 0px 5px
- Radius: 9999px
- Border: `1px solid rgb(35, 37, 42)`
- Use: Filter chips, tags, status indicators
**Small Toolbar Button**
- Background: `rgba(255,255,255,0.05)`
- Text: `#62666d` (muted)
- Radius: 2px
- Border: `1px solid rgba(255,255,255,0.05)`
- Shadow: `rgba(0,0,0,0.03) 0px 1.2px 0px 0px`
- Font: 12px weight 510
- Use: Toolbar actions, quick-access controls
### Cards & Containers
- Background: `rgba(255,255,255,0.02)` to `rgba(255,255,255,0.05)` (never solid — always translucent)
- Border: `1px solid rgba(255,255,255,0.08)` (standard) or `1px solid rgba(255,255,255,0.05)` (subtle)
- Radius: 8px (standard), 12px (featured), 22px (large panels)
- Shadow: `rgba(0,0,0,0.2) 0px 0px 0px 1px` or layered multi-shadow stacks
- Hover: subtle background opacity increase
### Inputs & Forms
**Text Area**
- Background: `rgba(255,255,255,0.02)`
- Text: `#d0d6e0`
- Border: `1px solid rgba(255,255,255,0.08)`
- Padding: 12px 14px
- Radius: 6px
**Search Input**
- Background: transparent
- Text: `#f7f8f8`
- Padding: 1px 32px (icon-aware)
**Button-style Input**
- Text: `#8a8f98`
- Padding: 1px 6px
- Radius: 5px
- Focus shadow: multi-layer stack
### Badges & Pills
**Success Pill**
- Background: `#10b981`
- Text: `#f7f8f8`
- Radius: 50% (circular)
- Font: 10px weight 510
- Use: Status dots, completion indicators
**Neutral Pill**
- Background: transparent
- Text: `#d0d6e0`
- Padding: 0px 10px 0px 5px
- Radius: 9999px
- Border: `1px solid rgb(35, 37, 42)`
- Font: 12px weight 510
- Use: Tags, filter chips, category labels
**Subtle Badge**
- Background: `rgba(255,255,255,0.05)`
- Text: `#f7f8f8`
- Padding: 0px 8px 0px 2px
- Radius: 2px
- Border: `1px solid rgba(255,255,255,0.05)`
- Font: 10px weight 510
- Use: Inline labels, version tags
### Navigation
- Dark sticky header on near-black background
- Linear logomark left-aligned (SVG icon)
- Links: Inter Variable 13–14px weight 510, `#d0d6e0` text
- Active/hover: text lightens to `#f7f8f8`
- CTA: Brand indigo button or ghost button
- Mobile: hamburger collapse
- Search: command palette trigger (`/` or `Cmd+K`)
### Image Treatment
- Product screenshots on dark backgrounds with subtle border (`rgba(255,255,255,0.08)`)
- Top-rounded images: `12px 12px 0px 0px` radius
- Dashboard/issue previews dominate feature sections
- Subtle shadow beneath screenshots: `rgba(0,0,0,0.4) 0px 2px 4px`
## 5. Layout Principles
### Spacing System
- Base unit: 8px
- Scale: 1px, 4px, 7px, 8px, 11px, 12px, 16px, 19px, 20px, 22px, 24px, 28px, 32px, 35px
- The 7px and 11px values suggest micro-adjustments for optical alignment
- Primary rhythm: 8px, 16px, 24px, 32px (standard 8px grid)
### Grid & Container
- Max content width: approximately 1200px
- Hero: centered single-column with generous vertical padding
- Feature sections: 2–3 column grids for feature cards
- Full-width dark sections with internal max-width constraints
- Changelog: single-column timeline layout
### Whitespace Philosophy
- **Darkness as space**: On Linear's dark canvas, empty space isn't white — it's absence. The near-black background IS the whitespace, and content emerges from it.
- **Compressed headlines, expanded surroundings**: Display text at 72px with -1.584px tracking is dense and compressed, but sits within vast dark padding. The contrast between typographic density and spatial generosity creates tension.
- **Section isolation**: Each feature section is separated by generous vertical padding (80px+) with no visible dividers — the dark background provides natural separation.
### Border Radius Scale
- Micro (2px): Inline badges, toolbar buttons, subtle tags
- Standard (4px): Small containers, list items
- Comfortable (6px): Buttons, inputs, functional elements
- Card (8px): Cards, dropdowns, popovers
- Panel (12px): Panels, featured cards, section containers
- Large (22px): Large panel elements
- Full Pill (9999px): Chips, filter pills, status tags
- Circle (50%): Icon buttons, avatars, status dots
## 6. Depth & Elevation
| Level | Treatment | Use |
|-------|-----------|-----|
| Flat (Level 0) | No shadow, `#010102` bg | Page background, deepest canvas |
| Subtle (Level 1) | `rgba(0,0,0,0.03) 0px 1.2px 0px` | Toolbar buttons, micro-elevation |
| Surface (Level 2) | `rgba(255,255,255,0.05)` bg + `1px solid rgba(255,255,255,0.08)` border | Cards, input fields, containers |
| Inset (Level 2b) | `rgba(0,0,0,0.2) 0px 0px 12px 0px inset` | Recessed panels, inner shadows |
| Ring (Level 3) | `rgba(0,0,0,0.2) 0px 0px 0px 1px` | Border-as-shadow technique |
| Elevated (Level 4) | `rgba(0,0,0,0.4) 0px 2px 4px` | Floating elements, dropdowns |
| Dialog (Level 5) | Multi-layer stack: `rgba(0,0,0,0) 0px 8px 2px, rgba(0,0,0,0.01) 0px 5px 2px, rgba(0,0,0,0.04) 0px 3px 2px, rgba(0,0,0,0.07) 0px 1px 1px, rgba(0,0,0,0.08) 0px 0px 1px` | Popovers, command palette, modals |
| Focus | `rgba(0,0,0,0.1) 0px 4px 12px` + additional layers | Keyboard focus on interactive elements |
**Shadow Philosophy**: On dark surfaces, traditional shadows (dark on dark) are nearly invisible. Linear solves this by using semi-transparent white borders as the primary depth indicator. Elevation isn't communicated through shadow darkness but through background luminance steps — each level slightly increases the white opacity of the surface background (`0.02` → `0.04` → `0.05`), creating a subtle stacking effect. The inset shadow technique (`rgba(0,0,0,0.2) 0px 0px 12px 0px inset`) creates a unique "sunken" effect for recessed panels, adding dimensional depth that traditional dark themes lack.
## 7. Do's and Don'ts
### Do
- Use Inter Variable with `"cv01", "ss03"` on ALL text — these features are fundamental to Linear's typeface identity
- Use weight 510 as your default emphasis weight — it's Linear's signature between-weight
- Apply aggressive negative letter-spacing at display sizes (-1.584px at 72px, -1.056px at 48px)
- Build on near-black backgrounds: `#08090a` for marketing, `#0f1011` for panels, `#191a1b` for elevated surfaces
- Use semi-transparent white borders (`rgba(255,255,255,0.05)` to `rgba(255,255,255,0.08)`) instead of solid dark borders
- Keep button backgrounds nearly transparent: `rgba(255,255,255,0.02)` to `rgba(255,255,255,0.05)`
- Reserve brand indigo (`#5e6ad2` / `#7170ff`) for primary CTAs and interactive accents only
- Use `#f7f8f8` for primary text — not pure `#ffffff`, which would be too harsh
- Apply the luminance stacking model: deeper = darker bg, elevated = slightly lighter bg
### Don't
- Don't use pure white (`#ffffff`) as primary text — `#f7f8f8` prevents eye strain
- Don't use solid colored backgrounds for buttons — transparency is the system (rgba white at 0.02–0.05)
- Don't apply the brand indigo decoratively — it's reserved for interactive/CTA elements only
- Don't use positive letter-spacing on display text — Inter at large sizes always runs negative
- Don't use visible/opaque borders on dark backgrounds — borders should be whisper-thin semi-transparent white
- Don't skip the OpenType features (`"cv01", "ss03"`) — without them, it's generic Inter, not Linear's Inter
- Don't use weight 700 (bold) — Linear's maximum weight is 590, with 510 as the workhorse
- Don't introduce warm colors into the UI chrome — the palette is cool gray with blue-violet accent only
- Don't use drop shadows for elevation on dark surfaces — use background luminance stepping instead
## 8. Responsive Behavior
### Breakpoints
| Name | Width | Key Changes |
|------|-------|-------------|
| Mobile Small | <600px | Single column, compact padding |
| Mobile | 600–640px | Standard mobile layout |
| Tablet | 640–768px | Two-column grids begin |
| Desktop Small | 768–1024px | Full card grids, expanded padding |
| Desktop | 1024–1280px | Standard desktop, full navigation |
| Large Desktop | >1280px | Full layout, generous margins |
### Touch Targets
- Buttons use comfortable padding with 6px radius minimum
- Navigation links at 13–14px with adequate spacing
- Pill tags have 10px horizontal padding for touch accessibility
- Icon buttons at 50% radius ensure circular, easy-to-tap targets
- Search trigger is prominently placed with generous hit area
### Collapsing Strategy
- Hero: 72px → 48px → 32px display text, tracking adjusts proportionally
- Navigation: horizontal links + CTAs → hamburger menu at 768px
- Feature cards: 3-column → 2-column → single column stacked
- Product screenshots: maintain aspect ratio, may reduce padding
- Changelog: timeline maintains single-column through all sizes
- Footer: multi-column → stacked single column
- Section spacing: 80px+ → 48px on mobile
### Image Behavior
- Dashboard screenshots maintain border treatment at all sizes
- Hero visuals simplify on mobile (fewer floating UI elements)
- Product screenshots use responsive sizing with consistent radius
- Dark background ensures screenshots blend naturally at any viewport
## 9. Agent Prompt Guide
### Quick Color Reference
- Primary CTA: Brand Indigo (`#5e6ad2`)
- Page Background: Marketing Black (`#08090a`)
- Panel Background: Panel Dark (`#0f1011`)
- Surface: Level 3 (`#191a1b`)
- Heading text: Primary White (`#f7f8f8`)
- Body text: Silver Gray (`#d0d6e0`)
- Muted text: Tertiary Gray (`#8a8f98`)
- Subtle text: Quaternary Gray (`#62666d`)
- Accent: Violet (`#7170ff`)
- Accent Hover: Light Violet (`#828fff`)
- Border (default): `rgba(255,255,255,0.08)`
- Border (subtle): `rgba(255,255,255,0.05)`
- Focus ring: Multi-layer shadow stack
### Example Component Prompts
- "Create a hero section on `#08090a` background. Headline at 48px Inter Variable weight 510, line-height 1.00, letter-spacing -1.056px, color `#f7f8f8`, font-feature-settings `'cv01', 'ss03'`. Subtitle at 18px weight 400, line-height 1.60, color `#8a8f98`. Brand CTA button (`#5e6ad2`, 6px radius, 8px 16px padding) and ghost button (`rgba(255,255,255,0.02)` bg, `1px solid rgba(255,255,255,0.08)` border, 6px radius)."
- "Design a card on dark background: `rgba(255,255,255,0.02)` background, `1px solid rgba(255,255,255,0.08)` border, 8px radius. Title at 20px Inter Variable weight 590, letter-spacing -0.24px, color `#f7f8f8`. Body at 15px weight 400, color `#8a8f98`, letter-spacing -0.165px."
- "Build a pill badge: transparent background, `#d0d6e0` text, 9999px radius, 0px 10px padding, `1px solid #23252a` border, 12px Inter Variable weight 510."
- "Create navigation: dark sticky header on `#0f1011`. Inter Variable 13px weight 510 for links, `#d0d6e0` text. Brand indigo CTA `#5e6ad2` right-aligned with 6px radius. Bottom border: `1px solid rgba(255,255,255,0.05)`."
- "Design a command palette: `#191a1b` background, `1px solid rgba(255,255,255,0.08)` border, 12px radius, multi-layer shadow stack. Input at 16px Inter Variable weight 400, `#f7f8f8` text. Results list with 13px weight 510 labels in `#d0d6e0` and 12px metadata in `#62666d`."
### Iteration Guide
1. Always set font-feature-settings `"cv01", "ss03"` on all Inter text — this is non-negotiable for Linear's look
2. Letter-spacing scales with font size: -1.584px at 72px, -1.056px at 48px, -0.704px at 32px, normal below 16px
3. Three weights: 400 (read), 510 (emphasize/navigate), 590 (announce)
4. Surface elevation via background opacity: `rgba(255,255,255, 0.02 → 0.04 → 0.05)` — never solid backgrounds on dark
5. Brand indigo (`#5e6ad2` / `#7170ff`) is the only chromatic color — everything else is grayscale
6. Borders are always semi-transparent white, never solid dark colors on dark backgrounds
7. Berkeley Mono for any code or technical content, Inter Variable for everything else
@@ -0,0 +1,32 @@
# Linear 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: `#08090a` marketing background, `#0f1011` panel background, `#191a1b` elevated surfaces
- Inter Variable with `"cv01", "ss03"` globally — geometric alternates for a cleaner aesthetic
- Signature weight 510 (between regular and medium) for most UI text
- Aggressive negative letter-spacing at display sizes (-1.584px at 72px, -1.056px at 48px)
## 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,370 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Linear — reference components</title>
<meta
name="description"
content="Reference fixture for design-systems/linear-app. Every visible
value comes from tokens.css. Linear's signature moves: near-black
canvas, Inter Variable with cv01+ss03, weight-510 emphasis, indigo
accent, semi-transparent white borders, luminance stepping for depth."
/>
<style>
:root {
--bg: #08090a;
--surface: #191a1b;
--surface-warm: var(--surface);
--fg: #f7f8f8;
--fg-2: #d0d6e0;
--muted: #8a8f98;
--meta: #62666d;
--border: rgba(255, 255, 255, 0.08);
--border-soft: rgba(255, 255, 255, 0.05);
--accent: #5e6ad2;
--accent-on: #ffffff;
--accent-hover: #828fff;
--accent-active: #4752c4;
--success: #27a644;
--warn: #eab308;
--danger: #dc2626;
--font-display: "Inter Variable", "Inter", "SF Pro Display", -apple-system, system-ui, "Segoe UI", Roboto, sans-serif;
--font-body: "Inter Variable", "Inter", "SF Pro Display", -apple-system, system-ui, "Segoe UI", Roboto, sans-serif;
--font-mono: "Berkeley Mono", ui-monospace, "SF Mono", Menlo, Monaco, Consolas, monospace;
--text-xs: 12px;
--text-sm: 14px;
--text-base: 16px;
--text-lg: 18px;
--text-xl: 24px;
--text-2xl: 32px;
--text-3xl: 48px;
--text-4xl: 72px;
--leading-body: 1.5;
--leading-tight: 1.00;
--tracking-display: -0.022em;
--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: 80px;
--section-y-tablet: 48px;
--section-y-phone: 32px;
--radius-sm: 6px;
--radius-md: 8px;
--radius-lg: 12px;
--radius-pill: 9999px;
--elev-flat: none;
--elev-ring: 0 0 0 1px var(--border);
--elev-raised:
rgba(0, 0, 0, 0.4) 0px 2px 4px,
0 0 0 1px rgba(255, 255, 255, 0.05);
--focus-ring: 0 0 0 2px color-mix(in oklab, var(--accent), transparent 30%), 0 4px 12px rgba(0, 0, 0, 0.1);
--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: 12px;
}
*, *::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);
/* Linear's signature: cv01 (alternate 'a') + ss03 (geometric alternates). */
font-feature-settings: "cv01", "ss03";
-webkit-font-smoothing: antialiased;
}
.container {
max-width: var(--container-max);
margin-inline: auto;
padding-inline: var(--container-gutter-desktop);
}
section { padding-block: var(--section-y-desktop); }
section + section { 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 ────────────────────────────────────────────── */
h1, h2, h3 {
font-family: var(--font-display);
font-weight: 510; /* Linear's signature between-weight */
margin: 0;
color: var(--fg);
font-feature-settings: "cv01", "ss03";
line-height: var(--leading-tight);
}
h1 {
font-size: var(--text-4xl);
letter-spacing: var(--tracking-display);
}
h2 {
font-size: var(--text-2xl);
/* 32px heading 1: line-height 1.13, tracking -0.704px (-0.022em). */
line-height: 1.13;
letter-spacing: -0.022em;
}
h3 {
font-size: var(--text-xl);
/* 24px heading 2: line-height 1.33, tracking -0.288px (-0.012em).
Overrides the shared 1.00 set on h1/h2/h3 above. */
line-height: 1.33;
letter-spacing: -0.012em;
font-weight: 590;
}
p { margin: 0; }
.lead {
font-size: var(--text-lg);
line-height: 1.60;
color: var(--muted);
font-weight: 400;
letter-spacing: -0.009em;
}
.body-muted { color: var(--muted); }
.body-sm { font-size: var(--text-sm); color: var(--muted); }
.eyebrow {
font-size: var(--text-xs);
font-weight: 510;
color: var(--meta);
text-transform: uppercase;
letter-spacing: 0.08em;
}
.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 ───────────────────────────────────────────────── */
.btn {
display: inline-flex;
align-items: center;
gap: var(--space-2);
padding: 8px 16px;
border-radius: var(--radius-sm);
font-family: var(--font-display);
font-size: var(--text-sm);
font-weight: 510;
font-feature-settings: "cv01", "ss03";
line-height: 1;
cursor: pointer;
border: 1px solid transparent;
transition: background-color var(--motion-fast) var(--ease-standard),
color var(--motion-fast) var(--ease-standard);
text-decoration: none;
}
.btn:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.btn-primary {
background: var(--accent);
color: var(--accent-on);
}
.btn-primary:hover { background: var(--accent-hover); }
.btn-ghost {
background: rgba(255, 255, 255, 0.02);
color: #e2e4e7;
border-color: rgba(36, 40, 44, 1);
}
.btn-ghost:hover { background: rgba(255, 255, 255, 0.05); }
/* ─── Pill badges ───────────────────────────────────────────── */
.pill {
display: inline-flex;
align-items: center;
padding: 0 10px 0 5px;
border-radius: var(--radius-pill);
font-size: var(--text-xs);
font-weight: 510;
color: var(--fg-2);
border: 1px solid #23252a;
line-height: 1.8;
}
/* ─── Cards ─────────────────────────────────────────────────── */
.card {
background: rgba(255, 255, 255, 0.02);
border: 1px solid var(--border);
border-radius: var(--radius-md);
padding: var(--space-6);
transition: background-color var(--motion-base) var(--ease-standard);
}
.card:hover { background: rgba(255, 255, 255, 0.04); }
/* ─── Inputs ────────────────────────────────────────────────── */
.field { display: flex; flex-direction: column; gap: var(--space-2); }
.field label {
font-size: var(--text-sm);
font-weight: 510;
color: var(--fg-2);
font-feature-settings: "cv01", "ss03";
}
.field input {
background: rgba(255, 255, 255, 0.02);
color: var(--fg-2);
border: 1px solid var(--border);
border-radius: var(--radius-sm);
padding: 12px 14px;
font-family: var(--font-body);
font-size: var(--text-base);
font-feature-settings: "cv01", "ss03";
outline: none;
transition: border-color var(--motion-fast) var(--ease-standard);
}
.field input::placeholder { color: var(--meta); }
.field input:focus { border-color: var(--accent); }
/* ─── Layout ────────────────────────────────────────────────── */
.hero-grid {
display: grid;
grid-template-columns: 1.2fr 1fr;
gap: var(--space-12);
align-items: center;
}
@media (max-width: 1023px) { .hero-grid { grid-template-columns: 1fr; } }
.features-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: var(--space-4);
}
@media (max-width: 1023px) { .features-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 639px) { .features-grid { grid-template-columns: 1fr; } }
.hero-actions { display: flex; gap: var(--space-3); margin-block-start: var(--space-6); }
.icon { width: 16px; height: 16px; flex-shrink: 0; }
</style>
</head>
<body>
<main class="container">
<!-- HERO -->
<section data-od-id="hero">
<div class="hero-grid">
<div class="stack-4">
<p class="eyebrow">Reference fixture · linear</p>
<h1>Built for the next era of product development.</h1>
<p class="lead" style="max-width:50ch">
Linear streamlines software projects, sprints, tasks, and bug
tracking. Precision engineered — from the 510 between-weight to
the semi-transparent white borders. Every value from tokens.css.
</p>
<div class="hero-actions">
<a href="./tokens.css" class="btn btn-primary">Start building</a>
<a href="./DESIGN.md" class="btn btn-ghost">Read the spec</a>
</div>
</div>
<aside style="display:flex;flex-direction:column;gap:var(--space-4)">
<div class="card">
<p class="eyebrow" style="margin-bottom:var(--space-3)">Issue tracker</p>
<div style="display:flex;flex-direction:column;gap:var(--space-2)">
<div style="display:flex;align-items:center;gap:var(--space-3);font-size:var(--text-sm);color:var(--fg-2)">
<span style="width:8px;height:8px;border-radius:50%;background:#27a644;flex-shrink:0"></span>
Fix token channel drift in derive script
</div>
<div style="display:flex;align-items:center;gap:var(--space-3);font-size:var(--text-sm);color:var(--muted)">
<span style="width:8px;height:8px;border-radius:50%;background:var(--accent);flex-shrink:0"></span>
Add 10 brand oracle fixtures
</div>
<div style="display:flex;align-items:center;gap:var(--space-3);font-size:var(--text-sm);color:var(--meta)">
<span style="width:8px;height:8px;border-radius:2px;background:rgba(255,255,255,0.1);flex-shrink:0"></span>
Ship PR-B derive script
</div>
</div>
</div>
</aside>
</div>
</section>
<!-- FEATURES -->
<section data-od-id="features">
<div class="stack-3">
<p class="eyebrow">What this fixture exercises</p>
<h2 style="max-width:28ch">Darkness as the native medium.</h2>
</div>
<div class="features-grid" style="margin-block-start:var(--space-6)">
<article class="card stack-3">
<h3>Dark-first</h3>
<p class="body-sm">
#08090a marketing black → #191a1b elevated surface. Luminance
stepping, not color: each level increases white opacity by 0.02.
</p>
</article>
<article class="card stack-3">
<h3>Weight 510</h3>
<p class="body-sm">
Inter Variable's between-weight. Not 500, not 600 — precisely 510.
cv01+ss03 on all text transforms generic Inter into Linear's face.
</p>
</article>
<article class="card stack-3">
<h3>Indigo accent</h3>
<p class="body-sm">
#5e6ad2 for CTA backgrounds; #7170ff for interactive; #828fff
on hover. The only chromatic color in an otherwise achromatic system.
</p>
</article>
</div>
<div style="margin-block-start:var(--space-6);display:flex;gap:var(--space-2);flex-wrap:wrap">
<span class="pill">All issues</span>
<span class="pill">Active</span>
<span class="pill">Backlog</span>
<span class="pill">Done</span>
</div>
</section>
<!-- FORM -->
<section data-od-id="form">
<div style="display:grid;grid-template-columns:1.2fr 1fr;gap:var(--space-12);align-items:start">
<div class="stack-4">
<p class="eyebrow">Form components</p>
<h2>Inputs on dark surfaces.</h2>
<p class="lead" style="max-width:44ch">
rgba(255,255,255,0.02) background, border: 1px solid rgba(255,255,255,0.08).
Focus shifts border to --accent; no halo, no blue ring.
</p>
</div>
<form style="display:flex;flex-direction:column;gap:var(--space-4);max-width:400px"
onsubmit="event.preventDefault()">
<div class="field">
<label for="email">Work email</label>
<input id="email" type="email" placeholder="[email protected]" />
</div>
<div style="display:flex;gap:var(--space-3);margin-top:var(--space-2)">
<button type="submit" class="btn btn-primary">Sign up</button>
<button type="button" class="btn btn-ghost">Learn more</button>
</div>
</form>
</div>
</section>
</main>
</body>
</html>
@@ -0,0 +1,407 @@
{
"schemaVersion": 1,
"brandId": "linear-app",
"source": {
"componentsHtml": "components.html",
"tokensCss": "tokens.css"
},
"fixture": {
"title": "Linear — reference components",
"description": "Reference fixture for design-systems/linear-app. Every visible value comes from tokens.css. Linear's signature moves: near-black canvas, Inter Variable with cv01+ss03, weight-510 emphasis, indigo accent, semi-transparent white borders, luminance stepping for depth.",
"styleBlockCount": 1,
"selectorCount": 37,
"classCount": 15,
"elementCount": 21
},
"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-hover",
"--accent-on",
"--bg",
"--border",
"--container-gutter-desktop",
"--container-gutter-phone",
"--container-gutter-tablet",
"--container-max",
"--ease-standard",
"--fg",
"--fg-2",
"--focus-ring",
"--font-body",
"--font-display",
"--leading-body",
"--leading-tight",
"--meta",
"--motion-base",
"--motion-fast",
"--muted",
"--radius-md",
"--radius-pill",
"--radius-sm",
"--section-y-desktop",
"--section-y-phone",
"--section-y-tablet",
"--space-12",
"--space-2",
"--space-3",
"--space-4",
"--space-6",
"--surface",
"--text-2xl",
"--text-4xl",
"--text-base",
"--text-lg",
"--text-sm",
"--text-xl",
"--text-xs",
"--tracking-display"
],
"unusedDeclared": [
"--accent-active",
"--border-soft",
"--danger",
"--elev-flat",
"--elev-raised",
"--elev-ring",
"--font-mono",
"--radius-lg",
"--space-1",
"--space-5",
"--space-8",
"--success",
"--surface-warm",
"--text-3xl",
"--warn"
],
"undeclaredReferenced": []
},
"selectors": [
".body-muted",
".body-sm",
".btn",
".btn-ghost",
".btn-ghost:hover",
".btn-primary",
".btn-primary:hover",
".btn:focus-visible",
".card",
".card:hover",
".container",
".eyebrow",
".features-grid",
".field",
".field input",
".field input::placeholder",
".field input:focus",
".field label",
".hero-actions",
".hero-grid",
".icon",
".lead",
".pill",
".stack-3 > * + *",
".stack-4 > * + *",
".stack-6 > * + *",
"*",
"*::after",
"*::before",
"body",
"h1",
"h2",
"h3",
"html",
"p",
"section",
"section + section"
],
"classes": [
"body-sm",
"btn",
"btn-ghost",
"btn-primary",
"card",
"container",
"eyebrow",
"features-grid",
"field",
"hero-actions",
"hero-grid",
"lead",
"pill",
"stack-3",
"stack-4"
],
"elements": [
"a",
"article",
"aside",
"body",
"button",
"div",
"form",
"h1",
"h2",
"h3",
"head",
"html",
"input",
"label",
"main",
"meta",
"p",
"section",
"span",
"style",
"title"
],
"groups": [
{
"id": "buttons",
"label": "Buttons and calls to action",
"present": true,
"selectors": [
".btn",
".btn-ghost",
".btn-ghost:hover",
".btn-primary",
".btn-primary:hover",
".btn:focus-visible"
],
"classes": [
"btn",
"btn-ghost",
"btn-primary"
],
"elements": [
"button"
],
"tokenReferences": [
"--accent",
"--accent-on",
"--ease-standard",
"--font-display",
"--motion-fast",
"--radius-sm",
"--space-2",
"--text-sm"
]
},
{
"id": "inputs",
"label": "Form fields and controls",
"present": true,
"selectors": [
".field",
".field input",
".field input::placeholder",
".field input:focus",
".field label"
],
"classes": [
"field"
],
"elements": [
"form",
"input",
"label"
],
"tokenReferences": [
"--fg-2",
"--meta",
"--text-sm"
]
},
{
"id": "cards",
"label": "Cards and panels",
"present": true,
"selectors": [
".card",
".card:hover"
],
"classes": [
"card"
],
"elements": [],
"tokenReferences": []
},
{
"id": "badges",
"label": "Badges, chips, and status labels",
"present": true,
"selectors": [
".pill"
],
"classes": [
"pill"
],
"elements": [],
"tokenReferences": [
"--fg-2",
"--radius-pill",
"--text-xs"
]
},
{
"id": "links",
"label": "Links and inline actions",
"present": true,
"selectors": [],
"classes": [],
"elements": [
"a"
],
"tokenReferences": []
},
{
"id": "keyboard",
"label": "Keyboard hints",
"present": false,
"selectors": [],
"classes": [],
"elements": [],
"tokenReferences": []
},
{
"id": "icons",
"label": "Icon slots",
"present": true,
"selectors": [
".icon"
],
"classes": [],
"elements": [],
"tokenReferences": []
},
{
"id": "typography",
"label": "Typography scale and text utilities",
"present": true,
"selectors": [
".body-muted",
".body-sm",
".eyebrow",
".lead",
"h1",
"h2",
"h3"
],
"classes": [
"body-sm",
"eyebrow",
"lead"
],
"elements": [
"h1",
"h2",
"h3",
"p"
],
"tokenReferences": [
"--fg",
"--font-display",
"--leading-tight",
"--meta",
"--muted",
"--text-2xl",
"--text-xs"
]
},
{
"id": "layout",
"label": "Layout primitives",
"present": true,
"selectors": [
".container",
".stack-3 > * + *",
".stack-4 > * + *",
".stack-6 > * + *",
"section",
"section + section"
],
"classes": [
"container",
"features-grid",
"hero-grid",
"stack-3",
"stack-4"
],
"elements": [
"main",
"section"
],
"tokenReferences": [
"--border",
"--container-gutter-desktop",
"--container-gutter-phone",
"--container-gutter-tablet",
"--container-max",
"--space-4"
]
}
],
"literals": {
"colorExpressions": 8,
"pixelValues": 18,
"hardcodedFontFamilies": 4
}
}
@@ -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": "#08090a",
"type": "color",
"layer": "A1-identity",
"confidence": "high",
"reason": "Bundled tokens.css declares --bg; no upstream recrawl was performed for this backfill.",
"sources": [
"tokens.css:32"
],
"sourceName": "--bg"
},
{
"name": "--surface",
"value": "#191a1b",
"type": "color",
"layer": "A1-identity",
"confidence": "high",
"reason": "Bundled tokens.css declares --surface; no upstream recrawl was performed for this backfill.",
"sources": [
"tokens.css:33"
],
"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:34"
],
"sourceName": "--surface-warm"
},
{
"name": "--fg",
"value": "#f7f8f8",
"type": "color",
"layer": "A1-identity",
"confidence": "high",
"reason": "Bundled tokens.css declares --fg; no upstream recrawl was performed for this backfill.",
"sources": [
"tokens.css:37"
],
"sourceName": "--fg"
},
{
"name": "--fg-2",
"value": "#d0d6e0",
"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:38"
],
"sourceName": "--fg-2"
},
{
"name": "--muted",
"value": "#8a8f98",
"type": "color",
"layer": "A1-identity",
"confidence": "high",
"reason": "Bundled tokens.css declares --muted; no upstream recrawl was performed for this backfill.",
"sources": [
"tokens.css:39"
],
"sourceName": "--muted"
},
{
"name": "--meta",
"value": "#62666d",
"type": "color",
"layer": "B-slot",
"confidence": "high",
"reason": "Bundled tokens.css declares --meta; no upstream recrawl was performed for this backfill.",
"sources": [
"tokens.css:40"
],
"sourceName": "--meta"
},
{
"name": "--border",
"value": "rgba(255, 255, 255, 0.08)",
"type": "color",
"layer": "A1-identity",
"confidence": "high",
"reason": "Bundled tokens.css declares --border; no upstream recrawl was performed for this backfill.",
"sources": [
"tokens.css:43"
],
"sourceName": "--border"
},
{
"name": "--border-soft",
"value": "rgba(255, 255, 255, 0.05)",
"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:44"
],
"sourceName": "--border-soft"
},
{
"name": "--accent",
"value": "#5e6ad2",
"type": "color",
"layer": "A1-identity",
"confidence": "high",
"reason": "Bundled tokens.css declares --accent; no upstream recrawl was performed for this backfill.",
"sources": [
"tokens.css:47"
],
"sourceName": "--accent"
},
{
"name": "--accent-on",
"value": "#ffffff",
"type": "color",
"layer": "A2",
"confidence": "high",
"reason": "Bundled tokens.css declares --accent-on; no upstream recrawl was performed for this backfill.",
"sources": [
"tokens.css:48"
],
"sourceName": "--accent-on"
},
{
"name": "--accent-hover",
"value": "#828fff",
"type": "color",
"layer": "A2",
"confidence": "high",
"reason": "Bundled tokens.css declares --accent-hover; no upstream recrawl was performed for this backfill.",
"sources": [
"tokens.css:49"
],
"sourceName": "--accent-hover"
},
{
"name": "--accent-active",
"value": "#4752c4",
"type": "color",
"layer": "A2",
"confidence": "high",
"reason": "Bundled tokens.css declares --accent-active; no upstream recrawl was performed for this backfill.",
"sources": [
"tokens.css:50"
],
"sourceName": "--accent-active"
},
{
"name": "--success",
"value": "#27a644",
"type": "color",
"layer": "A2",
"confidence": "high",
"reason": "Bundled tokens.css declares --success; no upstream recrawl was performed for this backfill.",
"sources": [
"tokens.css:53"
],
"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:54"
],
"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:55"
],
"sourceName": "--danger"
},
{
"name": "--font-display",
"value": "\"Inter Variable\", \"Inter\", \"SF Pro Display\", -apple-system, system-ui, \"Segoe UI\", Roboto, 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:58"
],
"sourceName": "--font-display"
},
{
"name": "--font-body",
"value": "\"Inter Variable\", \"Inter\", \"SF Pro Display\", -apple-system, system-ui, \"Segoe UI\", Roboto, 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:59"
],
"sourceName": "--font-body"
},
{
"name": "--font-mono",
"value": "\"Berkeley Mono\", ui-monospace, \"SF Mono\", 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:60"
],
"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:65"
],
"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:66"
],
"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:67"
],
"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:68"
],
"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:69"
],
"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:70"
],
"sourceName": "--text-2xl"
},
{
"name": "--text-3xl",
"value": "48px",
"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:71"
],
"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:72"
],
"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:78"
],
"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:79"
],
"sourceName": "--leading-tight"
},
{
"name": "--tracking-display",
"value": "-0.022em",
"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:80"
],
"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:83"
],
"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:84"
],
"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:85"
],
"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:86"
],
"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:87"
],
"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:88"
],
"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:89"
],
"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:90"
],
"sourceName": "--space-12"
},
{
"name": "--section-y-desktop",
"value": "80px",
"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:93"
],
"sourceName": "--section-y-desktop"
},
{
"name": "--section-y-tablet",
"value": "48px",
"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:94"
],
"sourceName": "--section-y-tablet"
},
{
"name": "--section-y-phone",
"value": "32px",
"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:95"
],
"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:99"
],
"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:100"
],
"sourceName": "--radius-md"
},
{
"name": "--radius-lg",
"value": "12px",
"type": "dimension",
"layer": "A2",
"confidence": "high",
"reason": "Bundled tokens.css declares --radius-lg; no upstream recrawl was performed for this backfill.",
"sources": [
"tokens.css:101"
],
"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:102"
],
"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:107"
],
"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:108"
],
"sourceName": "--elev-ring"
},
{
"name": "--elev-raised",
"value": "rgba(0, 0, 0, 0.4) 0px 2px 4px, 0 0 0 1px rgba(255, 255, 255, 0.05)",
"type": "shadow",
"layer": "A2",
"confidence": "high",
"reason": "Bundled tokens.css declares --elev-raised; no upstream recrawl was performed for this backfill.",
"sources": [
"tokens.css:109"
],
"sourceName": "--elev-raised"
},
{
"name": "--focus-ring",
"value": "0 0 0 2px color-mix(in oklab, var(--accent), transparent 30%), 0 4px 12px rgba(0, 0, 0, 0.1)",
"type": "shadow",
"layer": "A2",
"confidence": "high",
"reason": "Bundled tokens.css declares --focus-ring; no upstream recrawl was performed for this backfill.",
"sources": [
"tokens.css:116"
],
"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:121"
],
"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:122"
],
"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:123"
],
"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:126"
],
"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:127"
],
"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:128"
],
"sourceName": "--container-gutter-tablet"
},
{
"name": "--container-gutter-phone",
"value": "12px",
"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:129"
],
"sourceName": "--container-gutter-phone"
}
]
}
@@ -0,0 +1,54 @@
{
"schemaVersion": "od-design-system-project/v1",
"id": "linear-app",
"name": "Linear",
"category": "Productivity & SaaS",
"description": "Bundled OpenDesign package for Linear, 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>Linear 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>Linear 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>Linear 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">Productivity & SaaS</p>
<h2>Display sample for Linear</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 @@
# Linear 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/linear-app/DESIGN.md
- design-systems/linear-app/tokens.css
- design-systems/linear-app/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": "#08090a",
"confidence": "high",
"reason": "Bundled tokens.css declares --bg; no upstream recrawl was performed for this backfill.",
"sources": [
"tokens.css:32"
],
"sourceName": "--bg"
},
{
"name": "--surface",
"layer": "A1-identity",
"value": "#191a1b",
"confidence": "high",
"reason": "Bundled tokens.css declares --surface; no upstream recrawl was performed for this backfill.",
"sources": [
"tokens.css:33"
],
"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:34"
],
"sourceName": "--surface-warm"
},
{
"name": "--fg",
"layer": "A1-identity",
"value": "#f7f8f8",
"confidence": "high",
"reason": "Bundled tokens.css declares --fg; no upstream recrawl was performed for this backfill.",
"sources": [
"tokens.css:37"
],
"sourceName": "--fg"
},
{
"name": "--fg-2",
"layer": "B-slot",
"value": "#d0d6e0",
"confidence": "high",
"reason": "Bundled tokens.css declares --fg-2; no upstream recrawl was performed for this backfill.",
"sources": [
"tokens.css:38"
],
"sourceName": "--fg-2"
},
{
"name": "--muted",
"layer": "A1-identity",
"value": "#8a8f98",
"confidence": "high",
"reason": "Bundled tokens.css declares --muted; no upstream recrawl was performed for this backfill.",
"sources": [
"tokens.css:39"
],
"sourceName": "--muted"
},
{
"name": "--meta",
"layer": "B-slot",
"value": "#62666d",
"confidence": "high",
"reason": "Bundled tokens.css declares --meta; no upstream recrawl was performed for this backfill.",
"sources": [
"tokens.css:40"
],
"sourceName": "--meta"
},
{
"name": "--border",
"layer": "A1-identity",
"value": "rgba(255, 255, 255, 0.08)",
"confidence": "high",
"reason": "Bundled tokens.css declares --border; no upstream recrawl was performed for this backfill.",
"sources": [
"tokens.css:43"
],
"sourceName": "--border"
},
{
"name": "--border-soft",
"layer": "B-slot",
"value": "rgba(255, 255, 255, 0.05)",
"confidence": "high",
"reason": "Bundled tokens.css declares --border-soft; no upstream recrawl was performed for this backfill.",
"sources": [
"tokens.css:44"
],
"sourceName": "--border-soft"
},
{
"name": "--accent",
"layer": "A1-identity",
"value": "#5e6ad2",
"confidence": "high",
"reason": "Bundled tokens.css declares --accent; no upstream recrawl was performed for this backfill.",
"sources": [
"tokens.css:47"
],
"sourceName": "--accent"
},
{
"name": "--accent-on",
"layer": "A2",
"value": "#ffffff",
"confidence": "high",
"reason": "Bundled tokens.css declares --accent-on; no upstream recrawl was performed for this backfill.",
"sources": [
"tokens.css:48"
],
"sourceName": "--accent-on"
},
{
"name": "--accent-hover",
"layer": "A2",
"value": "#828fff",
"confidence": "high",
"reason": "Bundled tokens.css declares --accent-hover; no upstream recrawl was performed for this backfill.",
"sources": [
"tokens.css:49"
],
"sourceName": "--accent-hover"
},
{
"name": "--accent-active",
"layer": "A2",
"value": "#4752c4",
"confidence": "high",
"reason": "Bundled tokens.css declares --accent-active; no upstream recrawl was performed for this backfill.",
"sources": [
"tokens.css:50"
],
"sourceName": "--accent-active"
},
{
"name": "--success",
"layer": "A2",
"value": "#27a644",
"confidence": "high",
"reason": "Bundled tokens.css declares --success; no upstream recrawl was performed for this backfill.",
"sources": [
"tokens.css:53"
],
"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:54"
],
"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:55"
],
"sourceName": "--danger"
},
{
"name": "--font-display",
"layer": "A1-identity",
"value": "\"Inter Variable\", \"Inter\", \"SF Pro Display\", -apple-system, system-ui, \"Segoe UI\", Roboto, sans-serif",
"confidence": "high",
"reason": "Bundled tokens.css declares --font-display; no upstream recrawl was performed for this backfill.",
"sources": [
"tokens.css:58"
],
"sourceName": "--font-display"
},
{
"name": "--font-body",
"layer": "A1-identity",
"value": "\"Inter Variable\", \"Inter\", \"SF Pro Display\", -apple-system, system-ui, \"Segoe UI\", Roboto, sans-serif",
"confidence": "high",
"reason": "Bundled tokens.css declares --font-body; no upstream recrawl was performed for this backfill.",
"sources": [
"tokens.css:59"
],
"sourceName": "--font-body"
},
{
"name": "--font-mono",
"layer": "A2",
"value": "\"Berkeley Mono\", ui-monospace, \"SF Mono\", Menlo, Monaco, Consolas, monospace",
"confidence": "high",
"reason": "Bundled tokens.css declares --font-mono; no upstream recrawl was performed for this backfill.",
"sources": [
"tokens.css:60"
],
"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:65"
],
"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:66"
],
"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:67"
],
"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:68"
],
"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:69"
],
"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:70"
],
"sourceName": "--text-2xl"
},
{
"name": "--text-3xl",
"layer": "A1-structure",
"value": "48px",
"confidence": "high",
"reason": "Bundled tokens.css declares --text-3xl; no upstream recrawl was performed for this backfill.",
"sources": [
"tokens.css:71"
],
"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:72"
],
"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:78"
],
"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:79"
],
"sourceName": "--leading-tight"
},
{
"name": "--tracking-display",
"layer": "A1-structure",
"value": "-0.022em",
"confidence": "high",
"reason": "Bundled tokens.css declares --tracking-display; no upstream recrawl was performed for this backfill.",
"sources": [
"tokens.css:80"
],
"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:83"
],
"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:84"
],
"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:85"
],
"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:86"
],
"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:87"
],
"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:88"
],
"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:89"
],
"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:90"
],
"sourceName": "--space-12"
},
{
"name": "--section-y-desktop",
"layer": "A1-structure",
"value": "80px",
"confidence": "high",
"reason": "Bundled tokens.css declares --section-y-desktop; no upstream recrawl was performed for this backfill.",
"sources": [
"tokens.css:93"
],
"sourceName": "--section-y-desktop"
},
{
"name": "--section-y-tablet",
"layer": "A1-structure",
"value": "48px",
"confidence": "high",
"reason": "Bundled tokens.css declares --section-y-tablet; no upstream recrawl was performed for this backfill.",
"sources": [
"tokens.css:94"
],
"sourceName": "--section-y-tablet"
},
{
"name": "--section-y-phone",
"layer": "A1-structure",
"value": "32px",
"confidence": "high",
"reason": "Bundled tokens.css declares --section-y-phone; no upstream recrawl was performed for this backfill.",
"sources": [
"tokens.css:95"
],
"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:99"
],
"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:100"
],
"sourceName": "--radius-md"
},
{
"name": "--radius-lg",
"layer": "A2",
"value": "12px",
"confidence": "high",
"reason": "Bundled tokens.css declares --radius-lg; no upstream recrawl was performed for this backfill.",
"sources": [
"tokens.css:101"
],
"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:102"
],
"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:107"
],
"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:108"
],
"sourceName": "--elev-ring"
},
{
"name": "--elev-raised",
"layer": "A2",
"value": "rgba(0, 0, 0, 0.4) 0px 2px 4px, 0 0 0 1px rgba(255, 255, 255, 0.05)",
"confidence": "high",
"reason": "Bundled tokens.css declares --elev-raised; no upstream recrawl was performed for this backfill.",
"sources": [
"tokens.css:109"
],
"sourceName": "--elev-raised"
},
{
"name": "--focus-ring",
"layer": "A2",
"value": "0 0 0 2px color-mix(in oklab, var(--accent), transparent 30%), 0 4px 12px rgba(0, 0, 0, 0.1)",
"confidence": "high",
"reason": "Bundled tokens.css declares --focus-ring; no upstream recrawl was performed for this backfill.",
"sources": [
"tokens.css:116"
],
"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:121"
],
"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:122"
],
"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:123"
],
"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:126"
],
"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:127"
],
"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:128"
],
"sourceName": "--container-gutter-tablet"
},
{
"name": "--container-gutter-phone",
"layer": "A1-structure",
"value": "12px",
"confidence": "high",
"reason": "Bundled tokens.css declares --container-gutter-phone; no upstream recrawl was performed for this backfill.",
"sources": [
"tokens.css:129"
],
"sourceName": "--container-gutter-phone"
}
]
}
@@ -0,0 +1,349 @@
{
"schemaVersion": 1,
"sourceScope": "open-design-bundled-fixture",
"brandId": "linear-app",
"files": [
"DESIGN.md",
"tokens.css",
"components.html"
],
"generatedAt": "2026-06-06T00:00:00.000Z",
"tokens": [
{
"name": "--bg",
"value": "#08090a",
"layer": "A1-identity",
"source": "tokens.css:32"
},
{
"name": "--surface",
"value": "#191a1b",
"layer": "A1-identity",
"source": "tokens.css:33"
},
{
"name": "--surface-warm",
"value": "var(--surface)",
"layer": "B-slot",
"source": "tokens.css:34"
},
{
"name": "--fg",
"value": "#f7f8f8",
"layer": "A1-identity",
"source": "tokens.css:37"
},
{
"name": "--fg-2",
"value": "#d0d6e0",
"layer": "B-slot",
"source": "tokens.css:38"
},
{
"name": "--muted",
"value": "#8a8f98",
"layer": "A1-identity",
"source": "tokens.css:39"
},
{
"name": "--meta",
"value": "#62666d",
"layer": "B-slot",
"source": "tokens.css:40"
},
{
"name": "--border",
"value": "rgba(255, 255, 255, 0.08)",
"layer": "A1-identity",
"source": "tokens.css:43"
},
{
"name": "--border-soft",
"value": "rgba(255, 255, 255, 0.05)",
"layer": "B-slot",
"source": "tokens.css:44"
},
{
"name": "--accent",
"value": "#5e6ad2",
"layer": "A1-identity",
"source": "tokens.css:47"
},
{
"name": "--accent-on",
"value": "#ffffff",
"layer": "A2",
"source": "tokens.css:48"
},
{
"name": "--accent-hover",
"value": "#828fff",
"layer": "A2",
"source": "tokens.css:49"
},
{
"name": "--accent-active",
"value": "#4752c4",
"layer": "A2",
"source": "tokens.css:50"
},
{
"name": "--success",
"value": "#27a644",
"layer": "A2",
"source": "tokens.css:53"
},
{
"name": "--warn",
"value": "#eab308",
"layer": "A2",
"source": "tokens.css:54"
},
{
"name": "--danger",
"value": "#dc2626",
"layer": "A2",
"source": "tokens.css:55"
},
{
"name": "--font-display",
"value": "\"Inter Variable\", \"Inter\", \"SF Pro Display\", -apple-system, system-ui, \"Segoe UI\", Roboto, sans-serif",
"layer": "A1-identity",
"source": "tokens.css:58"
},
{
"name": "--font-body",
"value": "\"Inter Variable\", \"Inter\", \"SF Pro Display\", -apple-system, system-ui, \"Segoe UI\", Roboto, sans-serif",
"layer": "A1-identity",
"source": "tokens.css:59"
},
{
"name": "--font-mono",
"value": "\"Berkeley Mono\", ui-monospace, \"SF Mono\", Menlo, Monaco, Consolas, monospace",
"layer": "A2",
"source": "tokens.css:60"
},
{
"name": "--text-xs",
"value": "12px",
"layer": "A1-structure",
"source": "tokens.css:65"
},
{
"name": "--text-sm",
"value": "14px",
"layer": "A1-structure",
"source": "tokens.css:66"
},
{
"name": "--text-base",
"value": "16px",
"layer": "A1-structure",
"source": "tokens.css:67"
},
{
"name": "--text-lg",
"value": "18px",
"layer": "A1-structure",
"source": "tokens.css:68"
},
{
"name": "--text-xl",
"value": "24px",
"layer": "A1-structure",
"source": "tokens.css:69"
},
{
"name": "--text-2xl",
"value": "32px",
"layer": "A1-structure",
"source": "tokens.css:70"
},
{
"name": "--text-3xl",
"value": "48px",
"layer": "A1-structure",
"source": "tokens.css:71"
},
{
"name": "--text-4xl",
"value": "72px",
"layer": "A1-structure",
"source": "tokens.css:72"
},
{
"name": "--leading-body",
"value": "1.5",
"layer": "A1-structure",
"source": "tokens.css:78"
},
{
"name": "--leading-tight",
"value": "1.00",
"layer": "A1-structure",
"source": "tokens.css:79"
},
{
"name": "--tracking-display",
"value": "-0.022em",
"layer": "A1-structure",
"source": "tokens.css:80"
},
{
"name": "--space-1",
"value": "4px",
"layer": "A2",
"source": "tokens.css:83"
},
{
"name": "--space-2",
"value": "8px",
"layer": "A2",
"source": "tokens.css:84"
},
{
"name": "--space-3",
"value": "12px",
"layer": "A2",
"source": "tokens.css:85"
},
{
"name": "--space-4",
"value": "16px",
"layer": "A2",
"source": "tokens.css:86"
},
{
"name": "--space-5",
"value": "20px",
"layer": "A2",
"source": "tokens.css:87"
},
{
"name": "--space-6",
"value": "24px",
"layer": "A2",
"source": "tokens.css:88"
},
{
"name": "--space-8",
"value": "32px",
"layer": "A2",
"source": "tokens.css:89"
},
{
"name": "--space-12",
"value": "48px",
"layer": "A2",
"source": "tokens.css:90"
},
{
"name": "--section-y-desktop",
"value": "80px",
"layer": "A1-structure",
"source": "tokens.css:93"
},
{
"name": "--section-y-tablet",
"value": "48px",
"layer": "A1-structure",
"source": "tokens.css:94"
},
{
"name": "--section-y-phone",
"value": "32px",
"layer": "A1-structure",
"source": "tokens.css:95"
},
{
"name": "--radius-sm",
"value": "6px",
"layer": "A2",
"source": "tokens.css:99"
},
{
"name": "--radius-md",
"value": "8px",
"layer": "A2",
"source": "tokens.css:100"
},
{
"name": "--radius-lg",
"value": "12px",
"layer": "A2",
"source": "tokens.css:101"
},
{
"name": "--radius-pill",
"value": "9999px",
"layer": "A2",
"source": "tokens.css:102"
},
{
"name": "--elev-flat",
"value": "none",
"layer": "A2",
"source": "tokens.css:107"
},
{
"name": "--elev-ring",
"value": "0 0 0 1px var(--border)",
"layer": "A2",
"source": "tokens.css:108"
},
{
"name": "--elev-raised",
"value": "rgba(0, 0, 0, 0.4) 0px 2px 4px, 0 0 0 1px rgba(255, 255, 255, 0.05)",
"layer": "A2",
"source": "tokens.css:109"
},
{
"name": "--focus-ring",
"value": "0 0 0 2px color-mix(in oklab, var(--accent), transparent 30%), 0 4px 12px rgba(0, 0, 0, 0.1)",
"layer": "A2",
"source": "tokens.css:116"
},
{
"name": "--motion-fast",
"value": "150ms",
"layer": "A2",
"source": "tokens.css:121"
},
{
"name": "--motion-base",
"value": "200ms",
"layer": "A2",
"source": "tokens.css:122"
},
{
"name": "--ease-standard",
"value": "cubic-bezier(0.2, 0, 0, 1)",
"layer": "A2",
"source": "tokens.css:123"
},
{
"name": "--container-max",
"value": "1200px",
"layer": "A1-structure",
"source": "tokens.css:126"
},
{
"name": "--container-gutter-desktop",
"value": "24px",
"layer": "A1-structure",
"source": "tokens.css:127"
},
{
"name": "--container-gutter-tablet",
"value": "16px",
"layer": "A1-structure",
"source": "tokens.css:128"
},
{
"name": "--container-gutter-phone",
"value": "12px",
"layer": "A1-structure",
"source": "tokens.css:129"
}
]
}
@@ -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>Linear - Pitch deck</title>
<style>
:root {
--accent: #5e6ad2;
--accent-active: #4752c4;
--accent-hover: #828fff;
--accent-on: #ffffff;
--bg: #08090a;
--border: rgba(255, 255, 255, 0.08);
--border-soft: rgba(255, 255, 255, 0.05);
--container-gutter-desktop: 24px;
--container-gutter-phone: 12px;
--container-gutter-tablet: 16px;
--container-max: 1200px;
--danger: #dc2626;
--ease-standard: cubic-bezier(0.2, 0, 0, 1);
--elev-flat: none;
--elev-raised: rgba(0, 0, 0, 0.4) 0px 2px 4px, 0 0 0 1px rgba(255, 255, 255, 0.05);
--elev-ring: 0 0 0 1px var(--border);
--fg: #f7f8f8;
--fg-2: #d0d6e0;
--focus-ring: 0 0 0 2px color-mix(in oklab, var(--accent), transparent 30%), 0 4px 12px rgba(0, 0, 0, 0.1);
--font-body: "Inter Variable", "Inter", "SF Pro Display", -apple-system, system-ui, "Segoe UI", Roboto, sans-serif;
--font-display: "Inter Variable", "Inter", "SF Pro Display", -apple-system, system-ui, "Segoe UI", Roboto, sans-serif;
--font-mono: "Berkeley Mono", ui-monospace, "SF Mono", Menlo, Monaco, Consolas, monospace;
--leading-body: 1.5;
--leading-tight: 1.00;
--meta: #62666d;
--motion-base: 200ms;
--motion-fast: 150ms;
--muted: #8a8f98;
--radius-lg: 12px;
--radius-md: 8px;
--radius-pill: 9999px;
--radius-sm: 6px;
--section-y-desktop: 80px;
--section-y-phone: 32px;
--section-y-tablet: 48px;
--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: #27a644;
--surface: #191a1b;
--surface-warm: var(--surface);
--text-2xl: 32px;
--text-3xl: 48px;
--text-4xl: 72px;
--text-base: 16px;
--text-lg: 18px;
--text-sm: 14px;
--text-xl: 24px;
--text-xs: 12px;
--tracking-display: -0.022em;
--warn: #eab308;
}
:root {
--od-page-bg: #08090a;
--od-surface: #191a1b;
--od-text: #f7f8f8;
--od-muted: #8a8f98;
--od-border: rgba(255, 255, 255, 0.08);
--od-accent: #5e6ad2;
--od-radius: 8px;
--od-font-body: "Inter Variable", "Inter", "SF Pro Display", -apple-system, system-ui, "Segoe UI", Roboto, sans-serif;
--od-font-display: "Inter Variable", "Inter", "SF Pro Display", -apple-system, system-ui, "Segoe UI", Roboto, 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>Linear 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 Linear, 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="Linear" /></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>Linear - Email</title>
<style>
:root {
--accent: #5e6ad2;
--accent-active: #4752c4;
--accent-hover: #828fff;
--accent-on: #ffffff;
--bg: #08090a;
--border: rgba(255, 255, 255, 0.08);
--border-soft: rgba(255, 255, 255, 0.05);
--container-gutter-desktop: 24px;
--container-gutter-phone: 12px;
--container-gutter-tablet: 16px;
--container-max: 1200px;
--danger: #dc2626;
--ease-standard: cubic-bezier(0.2, 0, 0, 1);
--elev-flat: none;
--elev-raised: rgba(0, 0, 0, 0.4) 0px 2px 4px, 0 0 0 1px rgba(255, 255, 255, 0.05);
--elev-ring: 0 0 0 1px var(--border);
--fg: #f7f8f8;
--fg-2: #d0d6e0;
--focus-ring: 0 0 0 2px color-mix(in oklab, var(--accent), transparent 30%), 0 4px 12px rgba(0, 0, 0, 0.1);
--font-body: "Inter Variable", "Inter", "SF Pro Display", -apple-system, system-ui, "Segoe UI", Roboto, sans-serif;
--font-display: "Inter Variable", "Inter", "SF Pro Display", -apple-system, system-ui, "Segoe UI", Roboto, sans-serif;
--font-mono: "Berkeley Mono", ui-monospace, "SF Mono", Menlo, Monaco, Consolas, monospace;
--leading-body: 1.5;
--leading-tight: 1.00;
--meta: #62666d;
--motion-base: 200ms;
--motion-fast: 150ms;
--muted: #8a8f98;
--radius-lg: 12px;
--radius-md: 8px;
--radius-pill: 9999px;
--radius-sm: 6px;
--section-y-desktop: 80px;
--section-y-phone: 32px;
--section-y-tablet: 48px;
--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: #27a644;
--surface: #191a1b;
--surface-warm: var(--surface);
--text-2xl: 32px;
--text-3xl: 48px;
--text-4xl: 72px;
--text-base: 16px;
--text-lg: 18px;
--text-sm: 14px;
--text-xl: 24px;
--text-xs: 12px;
--tracking-display: -0.022em;
--warn: #eab308;
}
:root {
--od-page-bg: #08090a;
--od-surface: #191a1b;
--od-text: #f7f8f8;
--od-muted: #8a8f98;
--od-border: rgba(255, 255, 255, 0.08);
--od-accent: #5e6ad2;
--od-radius: 8px;
--od-font-body: "Inter Variable", "Inter", "SF Pro Display", -apple-system, system-ui, "Segoe UI", Roboto, sans-serif;
--od-font-display: "Inter Variable", "Inter", "SF Pro Display", -apple-system, system-ui, "Segoe UI", Roboto, 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>Linear 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 Linear, 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="Linear" /></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>Linear - Form page</title>
<style>
:root {
--accent: #5e6ad2;
--accent-active: #4752c4;
--accent-hover: #828fff;
--accent-on: #ffffff;
--bg: #08090a;
--border: rgba(255, 255, 255, 0.08);
--border-soft: rgba(255, 255, 255, 0.05);
--container-gutter-desktop: 24px;
--container-gutter-phone: 12px;
--container-gutter-tablet: 16px;
--container-max: 1200px;
--danger: #dc2626;
--ease-standard: cubic-bezier(0.2, 0, 0, 1);
--elev-flat: none;
--elev-raised: rgba(0, 0, 0, 0.4) 0px 2px 4px, 0 0 0 1px rgba(255, 255, 255, 0.05);
--elev-ring: 0 0 0 1px var(--border);
--fg: #f7f8f8;
--fg-2: #d0d6e0;
--focus-ring: 0 0 0 2px color-mix(in oklab, var(--accent), transparent 30%), 0 4px 12px rgba(0, 0, 0, 0.1);
--font-body: "Inter Variable", "Inter", "SF Pro Display", -apple-system, system-ui, "Segoe UI", Roboto, sans-serif;
--font-display: "Inter Variable", "Inter", "SF Pro Display", -apple-system, system-ui, "Segoe UI", Roboto, sans-serif;
--font-mono: "Berkeley Mono", ui-monospace, "SF Mono", Menlo, Monaco, Consolas, monospace;
--leading-body: 1.5;
--leading-tight: 1.00;
--meta: #62666d;
--motion-base: 200ms;
--motion-fast: 150ms;
--muted: #8a8f98;
--radius-lg: 12px;
--radius-md: 8px;
--radius-pill: 9999px;
--radius-sm: 6px;
--section-y-desktop: 80px;
--section-y-phone: 32px;
--section-y-tablet: 48px;
--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: #27a644;
--surface: #191a1b;
--surface-warm: var(--surface);
--text-2xl: 32px;
--text-3xl: 48px;
--text-4xl: 72px;
--text-base: 16px;
--text-lg: 18px;
--text-sm: 14px;
--text-xl: 24px;
--text-xs: 12px;
--tracking-display: -0.022em;
--warn: #eab308;
}
:root {
--od-page-bg: #08090a;
--od-surface: #191a1b;
--od-text: #f7f8f8;
--od-muted: #8a8f98;
--od-border: rgba(255, 255, 255, 0.08);
--od-accent: #5e6ad2;
--od-radius: 8px;
--od-font-body: "Inter Variable", "Inter", "SF Pro Display", -apple-system, system-ui, "Segoe UI", Roboto, sans-serif;
--od-font-display: "Inter Variable", "Inter", "SF Pro Display", -apple-system, system-ui, "Segoe UI", Roboto, 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>Linear 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 Linear, 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="Linear" /></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>Linear - Landing page</title>
<style>
:root {
--accent: #5e6ad2;
--accent-active: #4752c4;
--accent-hover: #828fff;
--accent-on: #ffffff;
--bg: #08090a;
--border: rgba(255, 255, 255, 0.08);
--border-soft: rgba(255, 255, 255, 0.05);
--container-gutter-desktop: 24px;
--container-gutter-phone: 12px;
--container-gutter-tablet: 16px;
--container-max: 1200px;
--danger: #dc2626;
--ease-standard: cubic-bezier(0.2, 0, 0, 1);
--elev-flat: none;
--elev-raised: rgba(0, 0, 0, 0.4) 0px 2px 4px, 0 0 0 1px rgba(255, 255, 255, 0.05);
--elev-ring: 0 0 0 1px var(--border);
--fg: #f7f8f8;
--fg-2: #d0d6e0;
--focus-ring: 0 0 0 2px color-mix(in oklab, var(--accent), transparent 30%), 0 4px 12px rgba(0, 0, 0, 0.1);
--font-body: "Inter Variable", "Inter", "SF Pro Display", -apple-system, system-ui, "Segoe UI", Roboto, sans-serif;
--font-display: "Inter Variable", "Inter", "SF Pro Display", -apple-system, system-ui, "Segoe UI", Roboto, sans-serif;
--font-mono: "Berkeley Mono", ui-monospace, "SF Mono", Menlo, Monaco, Consolas, monospace;
--leading-body: 1.5;
--leading-tight: 1.00;
--meta: #62666d;
--motion-base: 200ms;
--motion-fast: 150ms;
--muted: #8a8f98;
--radius-lg: 12px;
--radius-md: 8px;
--radius-pill: 9999px;
--radius-sm: 6px;
--section-y-desktop: 80px;
--section-y-phone: 32px;
--section-y-tablet: 48px;
--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: #27a644;
--surface: #191a1b;
--surface-warm: var(--surface);
--text-2xl: 32px;
--text-3xl: 48px;
--text-4xl: 72px;
--text-base: 16px;
--text-lg: 18px;
--text-sm: 14px;
--text-xl: 24px;
--text-xs: 12px;
--tracking-display: -0.022em;
--warn: #eab308;
}
:root {
--od-page-bg: #08090a;
--od-surface: #191a1b;
--od-text: #f7f8f8;
--od-muted: #8a8f98;
--od-border: rgba(255, 255, 255, 0.08);
--od-accent: #5e6ad2;
--od-radius: 8px;
--od-font-body: "Inter Variable", "Inter", "SF Pro Display", -apple-system, system-ui, "Segoe UI", Roboto, sans-serif;
--od-font-display: "Inter Variable", "Inter", "SF Pro Display", -apple-system, system-ui, "Segoe UI", Roboto, 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>Linear 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 Linear, 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="Linear" /></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>Linear - Newsletter</title>
<style>
:root {
--accent: #5e6ad2;
--accent-active: #4752c4;
--accent-hover: #828fff;
--accent-on: #ffffff;
--bg: #08090a;
--border: rgba(255, 255, 255, 0.08);
--border-soft: rgba(255, 255, 255, 0.05);
--container-gutter-desktop: 24px;
--container-gutter-phone: 12px;
--container-gutter-tablet: 16px;
--container-max: 1200px;
--danger: #dc2626;
--ease-standard: cubic-bezier(0.2, 0, 0, 1);
--elev-flat: none;
--elev-raised: rgba(0, 0, 0, 0.4) 0px 2px 4px, 0 0 0 1px rgba(255, 255, 255, 0.05);
--elev-ring: 0 0 0 1px var(--border);
--fg: #f7f8f8;
--fg-2: #d0d6e0;
--focus-ring: 0 0 0 2px color-mix(in oklab, var(--accent), transparent 30%), 0 4px 12px rgba(0, 0, 0, 0.1);
--font-body: "Inter Variable", "Inter", "SF Pro Display", -apple-system, system-ui, "Segoe UI", Roboto, sans-serif;
--font-display: "Inter Variable", "Inter", "SF Pro Display", -apple-system, system-ui, "Segoe UI", Roboto, sans-serif;
--font-mono: "Berkeley Mono", ui-monospace, "SF Mono", Menlo, Monaco, Consolas, monospace;
--leading-body: 1.5;
--leading-tight: 1.00;
--meta: #62666d;
--motion-base: 200ms;
--motion-fast: 150ms;
--muted: #8a8f98;
--radius-lg: 12px;
--radius-md: 8px;
--radius-pill: 9999px;
--radius-sm: 6px;
--section-y-desktop: 80px;
--section-y-phone: 32px;
--section-y-tablet: 48px;
--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: #27a644;
--surface: #191a1b;
--surface-warm: var(--surface);
--text-2xl: 32px;
--text-3xl: 48px;
--text-4xl: 72px;
--text-base: 16px;
--text-lg: 18px;
--text-sm: 14px;
--text-xl: 24px;
--text-xs: 12px;
--tracking-display: -0.022em;
--warn: #eab308;
}
:root {
--od-page-bg: #08090a;
--od-surface: #191a1b;
--od-text: #f7f8f8;
--od-muted: #8a8f98;
--od-border: rgba(255, 255, 255, 0.08);
--od-accent: #5e6ad2;
--od-radius: 8px;
--od-font-body: "Inter Variable", "Inter", "SF Pro Display", -apple-system, system-ui, "Segoe UI", Roboto, sans-serif;
--od-font-display: "Inter Variable", "Inter", "SF Pro Display", -apple-system, system-ui, "Segoe UI", Roboto, 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>Linear 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 Linear, 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="Linear" /></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>Linear - Poster</title>
<style>
:root {
--accent: #5e6ad2;
--accent-active: #4752c4;
--accent-hover: #828fff;
--accent-on: #ffffff;
--bg: #08090a;
--border: rgba(255, 255, 255, 0.08);
--border-soft: rgba(255, 255, 255, 0.05);
--container-gutter-desktop: 24px;
--container-gutter-phone: 12px;
--container-gutter-tablet: 16px;
--container-max: 1200px;
--danger: #dc2626;
--ease-standard: cubic-bezier(0.2, 0, 0, 1);
--elev-flat: none;
--elev-raised: rgba(0, 0, 0, 0.4) 0px 2px 4px, 0 0 0 1px rgba(255, 255, 255, 0.05);
--elev-ring: 0 0 0 1px var(--border);
--fg: #f7f8f8;
--fg-2: #d0d6e0;
--focus-ring: 0 0 0 2px color-mix(in oklab, var(--accent), transparent 30%), 0 4px 12px rgba(0, 0, 0, 0.1);
--font-body: "Inter Variable", "Inter", "SF Pro Display", -apple-system, system-ui, "Segoe UI", Roboto, sans-serif;
--font-display: "Inter Variable", "Inter", "SF Pro Display", -apple-system, system-ui, "Segoe UI", Roboto, sans-serif;
--font-mono: "Berkeley Mono", ui-monospace, "SF Mono", Menlo, Monaco, Consolas, monospace;
--leading-body: 1.5;
--leading-tight: 1.00;
--meta: #62666d;
--motion-base: 200ms;
--motion-fast: 150ms;
--muted: #8a8f98;
--radius-lg: 12px;
--radius-md: 8px;
--radius-pill: 9999px;
--radius-sm: 6px;
--section-y-desktop: 80px;
--section-y-phone: 32px;
--section-y-tablet: 48px;
--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: #27a644;
--surface: #191a1b;
--surface-warm: var(--surface);
--text-2xl: 32px;
--text-3xl: 48px;
--text-4xl: 72px;
--text-base: 16px;
--text-lg: 18px;
--text-sm: 14px;
--text-xl: 24px;
--text-xs: 12px;
--tracking-display: -0.022em;
--warn: #eab308;
}
:root {
--od-page-bg: #08090a;
--od-surface: #191a1b;
--od-text: #f7f8f8;
--od-muted: #8a8f98;
--od-border: rgba(255, 255, 255, 0.08);
--od-accent: #5e6ad2;
--od-radius: 8px;
--od-font-body: "Inter Variable", "Inter", "SF Pro Display", -apple-system, system-ui, "Segoe UI", Roboto, sans-serif;
--od-font-display: "Inter Variable", "Inter", "SF Pro Display", -apple-system, system-ui, "Segoe UI", Roboto, 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>Linear 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 Linear, 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="Linear" /></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>Linear - system assets</title>
<style>
:root {
--accent: #5e6ad2;
--accent-active: #4752c4;
--accent-hover: #828fff;
--accent-on: #ffffff;
--bg: #08090a;
--border: rgba(255, 255, 255, 0.08);
--border-soft: rgba(255, 255, 255, 0.05);
--container-gutter-desktop: 24px;
--container-gutter-phone: 12px;
--container-gutter-tablet: 16px;
--container-max: 1200px;
--danger: #dc2626;
--ease-standard: cubic-bezier(0.2, 0, 0, 1);
--elev-flat: none;
--elev-raised: rgba(0, 0, 0, 0.4) 0px 2px 4px, 0 0 0 1px rgba(255, 255, 255, 0.05);
--elev-ring: 0 0 0 1px var(--border);
--fg: #f7f8f8;
--fg-2: #d0d6e0;
--focus-ring: 0 0 0 2px color-mix(in oklab, var(--accent), transparent 30%), 0 4px 12px rgba(0, 0, 0, 0.1);
--font-body: "Inter Variable", "Inter", "SF Pro Display", -apple-system, system-ui, "Segoe UI", Roboto, sans-serif;
--font-display: "Inter Variable", "Inter", "SF Pro Display", -apple-system, system-ui, "Segoe UI", Roboto, sans-serif;
--font-mono: "Berkeley Mono", ui-monospace, "SF Mono", Menlo, Monaco, Consolas, monospace;
--leading-body: 1.5;
--leading-tight: 1.00;
--meta: #62666d;
--motion-base: 200ms;
--motion-fast: 150ms;
--muted: #8a8f98;
--radius-lg: 12px;
--radius-md: 8px;
--radius-pill: 9999px;
--radius-sm: 6px;
--section-y-desktop: 80px;
--section-y-phone: 32px;
--section-y-tablet: 48px;
--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: #27a644;
--surface: #191a1b;
--surface-warm: var(--surface);
--text-2xl: 32px;
--text-3xl: 48px;
--text-4xl: 72px;
--text-base: 16px;
--text-lg: 18px;
--text-sm: 14px;
--text-xl: 24px;
--text-xs: 12px;
--tracking-display: -0.022em;
--warn: #eab308;
}
:root {
--od-page-bg: #08090a;
--od-surface: #191a1b;
--od-text: #f7f8f8;
--od-muted: #8a8f98;
--od-border: rgba(255, 255, 255, 0.08);
--od-accent: #5e6ad2;
--od-radius: 8px;
--od-font-body: "Inter Variable", "Inter", "SF Pro Display", -apple-system, system-ui, "Segoe UI", Roboto, sans-serif;
--od-font-display: "Inter Variable", "Inter", "SF Pro Display", -apple-system, system-ui, "Segoe UI", Roboto, 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">Productivity &amp; SaaS</p>
<h1>Linear 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>Linear - dark component kit</title>
<style>
:root {
--accent: #5e6ad2;
--accent-active: #4752c4;
--accent-hover: #828fff;
--accent-on: #ffffff;
--bg: #08090a;
--border: rgba(255, 255, 255, 0.08);
--border-soft: rgba(255, 255, 255, 0.05);
--container-gutter-desktop: 24px;
--container-gutter-phone: 12px;
--container-gutter-tablet: 16px;
--container-max: 1200px;
--danger: #dc2626;
--ease-standard: cubic-bezier(0.2, 0, 0, 1);
--elev-flat: none;
--elev-raised: rgba(0, 0, 0, 0.4) 0px 2px 4px, 0 0 0 1px rgba(255, 255, 255, 0.05);
--elev-ring: 0 0 0 1px var(--border);
--fg: #f7f8f8;
--fg-2: #d0d6e0;
--focus-ring: 0 0 0 2px color-mix(in oklab, var(--accent), transparent 30%), 0 4px 12px rgba(0, 0, 0, 0.1);
--font-body: "Inter Variable", "Inter", "SF Pro Display", -apple-system, system-ui, "Segoe UI", Roboto, sans-serif;
--font-display: "Inter Variable", "Inter", "SF Pro Display", -apple-system, system-ui, "Segoe UI", Roboto, sans-serif;
--font-mono: "Berkeley Mono", ui-monospace, "SF Mono", Menlo, Monaco, Consolas, monospace;
--leading-body: 1.5;
--leading-tight: 1.00;
--meta: #62666d;
--motion-base: 200ms;
--motion-fast: 150ms;
--muted: #8a8f98;
--radius-lg: 12px;
--radius-md: 8px;
--radius-pill: 9999px;
--radius-sm: 6px;
--section-y-desktop: 80px;
--section-y-phone: 32px;
--section-y-tablet: 48px;
--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: #27a644;
--surface: #191a1b;
--surface-warm: var(--surface);
--text-2xl: 32px;
--text-3xl: 48px;
--text-4xl: 72px;
--text-base: 16px;
--text-lg: 18px;
--text-sm: 14px;
--text-xl: 24px;
--text-xs: 12px;
--tracking-display: -0.022em;
--warn: #eab308;
}
:root {
--od-page-bg: #0f1115;
--od-surface: #171a21;
--od-text: #f8fafc;
--od-muted: #a7adba;
--od-border: #2a2f3a;
--od-accent: #5e6ad2;
--od-radius: 8px;
--od-font-body: "Inter Variable", "Inter", "SF Pro Display", -apple-system, system-ui, "Segoe UI", Roboto, sans-serif;
--od-font-display: "Inter Variable", "Inter", "SF Pro Display", -apple-system, system-ui, "Segoe UI", Roboto, 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">Productivity &amp; SaaS system</p>
<h1>Linear component kit</h1>
<p class="lead">Bundled OpenDesign package for Linear, 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>Linear - component kit</title>
<style>
:root {
--accent: #5e6ad2;
--accent-active: #4752c4;
--accent-hover: #828fff;
--accent-on: #ffffff;
--bg: #08090a;
--border: rgba(255, 255, 255, 0.08);
--border-soft: rgba(255, 255, 255, 0.05);
--container-gutter-desktop: 24px;
--container-gutter-phone: 12px;
--container-gutter-tablet: 16px;
--container-max: 1200px;
--danger: #dc2626;
--ease-standard: cubic-bezier(0.2, 0, 0, 1);
--elev-flat: none;
--elev-raised: rgba(0, 0, 0, 0.4) 0px 2px 4px, 0 0 0 1px rgba(255, 255, 255, 0.05);
--elev-ring: 0 0 0 1px var(--border);
--fg: #f7f8f8;
--fg-2: #d0d6e0;
--focus-ring: 0 0 0 2px color-mix(in oklab, var(--accent), transparent 30%), 0 4px 12px rgba(0, 0, 0, 0.1);
--font-body: "Inter Variable", "Inter", "SF Pro Display", -apple-system, system-ui, "Segoe UI", Roboto, sans-serif;
--font-display: "Inter Variable", "Inter", "SF Pro Display", -apple-system, system-ui, "Segoe UI", Roboto, sans-serif;
--font-mono: "Berkeley Mono", ui-monospace, "SF Mono", Menlo, Monaco, Consolas, monospace;
--leading-body: 1.5;
--leading-tight: 1.00;
--meta: #62666d;
--motion-base: 200ms;
--motion-fast: 150ms;
--muted: #8a8f98;
--radius-lg: 12px;
--radius-md: 8px;
--radius-pill: 9999px;
--radius-sm: 6px;
--section-y-desktop: 80px;
--section-y-phone: 32px;
--section-y-tablet: 48px;
--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: #27a644;
--surface: #191a1b;
--surface-warm: var(--surface);
--text-2xl: 32px;
--text-3xl: 48px;
--text-4xl: 72px;
--text-base: 16px;
--text-lg: 18px;
--text-sm: 14px;
--text-xl: 24px;
--text-xs: 12px;
--tracking-display: -0.022em;
--warn: #eab308;
}
:root {
--od-page-bg: #08090a;
--od-surface: #191a1b;
--od-text: #f7f8f8;
--od-muted: #8a8f98;
--od-border: rgba(255, 255, 255, 0.08);
--od-accent: #5e6ad2;
--od-radius: 8px;
--od-font-body: "Inter Variable", "Inter", "SF Pro Display", -apple-system, system-ui, "Segoe UI", Roboto, sans-serif;
--od-font-display: "Inter Variable", "Inter", "SF Pro Display", -apple-system, system-ui, "Segoe UI", Roboto, 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">Productivity &amp; SaaS system</p>
<h1>Linear component kit</h1>
<p class="lead">Bundled OpenDesign package for Linear, 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": "#5e6ad2",
"colorPrimaryBg": "var(--surface)",
"colorPrimaryHover": "#828fff",
"colorPrimaryActive": "#4752c4",
"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,130 @@
/* ─────────────────────────────────────────────────────────────────────────
* design-systems/linear-app/tokens.css
*
* Structured token bindings for the "Linear" brand — the dark-mode-native
* project management tool's precision engineering voice.
*
* Brand identity in three sentences:
* 1. Darkness as the native medium — near-black canvas (#08090a) where
* information density is managed through luminance steps rather than
* color variation; semi-transparent white borders throughout.
* 2. Inter Variable with OpenType "cv01","ss03" at all sizes, signature
* weight 510 (between regular and medium), aggressive negative
* letter-spacing at display sizes (-1.584px at 72px).
* 3. Almost entirely achromatic — the single chromatic color is Linear's
* indigo-violet (#5e6ad2 bg / #7170ff interactive), used only for
* CTAs and active states; everything else is grayscale.
*
* Schema decisions:
* - --bg: #08090a (marketing black); --surface: #191a1b (elevated).
* - --surface-warm aliases --surface (dark system, no warm tier).
* - --fg: #f7f8f8 (near-white — not pure white, prevents eye strain).
* - --fg-2: #d0d6e0 (silver-gray body text).
* - --border: rgba(255,255,255,0.08); --border-soft: rgba(255,255,255,0.05).
* - --accent: #5e6ad2 (brand indigo bg); --accent-hover: #828fff.
* - --tracking-display: -0.022em (-1.584px / 72px normalized).
* - --radius-sm: 6px (buttons/inputs); --radius-md: 8px (cards).
* - --elev-raised: luminance stepping — no opaque shadow on dark.
* ─────────────────────────────────────────────────────────────────── */
:root {
/* ─── Surface ──────────────────────────────────────────────────── */
--bg: #08090a; /* marketing black — hero canvas */
--surface: #191a1b; /* elevated surface — cards, dropdowns */
--surface-warm: var(--surface); /* no warm tier in dark achromatic system */
/* ─── Foreground ───────────────────────────────────────────────── */
--fg: #f7f8f8; /* near-white primary text */
--fg-2: #d0d6e0; /* silver-gray body / secondary text */
--muted: #8a8f98; /* tertiary — placeholders, metadata */
--meta: #62666d; /* quaternary — timestamps, disabled */
/* ─── Border ───────────────────────────────────────────────────── */
--border: rgba(255, 255, 255, 0.08); /* standard semi-transparent white */
--border-soft: rgba(255, 255, 255, 0.05); /* ultra-subtle divider */
/* ─── Accent ───────────────────────────────────────────────────── */
--accent: #5e6ad2; /* brand indigo — CTA backgrounds */
--accent-on: #ffffff;
--accent-hover: #828fff; /* lighter saturated hover */
--accent-active: #4752c4; /* darker pressed state */
/* ─── Semantic ─────────────────────────────────────────────────── */
--success: #27a644; /* Linear green */
--warn: #eab308;
--danger: #dc2626;
/* ─── Typography ───────────────────────────────────────────────── */
--font-display: "Inter Variable", "Inter", "SF Pro Display", -apple-system, system-ui, "Segoe UI", Roboto, sans-serif;
--font-body: "Inter Variable", "Inter", "SF Pro Display", -apple-system, system-ui, "Segoe UI", Roboto, sans-serif;
--font-mono: "Berkeley Mono", ui-monospace, "SF Mono", Menlo, Monaco, Consolas, monospace;
/* Type scale — DESIGN.md §Typography Hierarchy.
* Linear's display range 72px→10px; the 8 schema slots map the
* key stops. 64px secondary-hero lives inline in components.html. */
--text-xs: 12px; /* label / micro */
--text-sm: 14px; /* caption large / link small */
--text-base: 16px; /* body — standard reading */
--text-lg: 18px; /* body large — feature descriptions */
--text-xl: 24px; /* heading 2 */
--text-2xl: 32px; /* heading 1 */
--text-3xl: 48px; /* display — section headlines */
--text-4xl: 72px; /* display XL — hero */
/* Leading + tracking.
* --leading-tight=1.00: Linear's signature "engineered" compression.
* h2 (32px) → 1.13; h3 (24px) → 1.33 per DESIGN.md spec.
* --tracking-display: -0.022em = -1.584px / 72px normalized. */
--leading-body: 1.5;
--leading-tight: 1.00;
--tracking-display: -0.022em;
/* ─── Spacing ──────────────────────────────────────────────────── */
--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 §Whitespace Philosophy. */
--section-y-desktop: 80px;
--section-y-tablet: 48px;
--section-y-phone: 32px;
/* ─── Radius ───────────────────────────────────────────────────── */
/* 6px for buttons/inputs (comfortable), 8px cards, 12px panels. */
--radius-sm: 6px;
--radius-md: 8px;
--radius-lg: 12px;
--radius-pill: 9999px;
/* ─── Elevation ────────────────────────────────────────────────── */
/* On dark surfaces: luminance stepping, not opaque drop shadows.
--elev-raised uses semi-transparent border-as-shadow technique. */
--elev-flat: none;
--elev-ring: 0 0 0 1px var(--border);
--elev-raised:
rgba(0, 0, 0, 0.4) 0px 2px 4px,
0 0 0 1px rgba(255, 255, 255, 0.05);
/* ─── Focus ────────────────────────────────────────────────────── */
/* Multi-layer stack per DESIGN.md §6 + §7: accent ring makes the
indicator visible on the near-black #08090a canvas. */
--focus-ring:
0 0 0 2px color-mix(in oklab, var(--accent), transparent 30%),
0 4px 12px rgba(0, 0, 0, 0.1);
/* ─── Motion ───────────────────────────────────────────────────── */
--motion-fast: 150ms;
--motion-base: 200ms;
--ease-standard: cubic-bezier(0.2, 0, 0, 1);
/* ─── Layout ───────────────────────────────────────────────────── */
--container-max: 1200px;
--container-gutter-desktop: 24px;
--container-gutter-tablet: 16px;
--container-gutter-phone: 12px;
}