feat: IMAP mail sync with thread-to-contact matching (PRD §6.1)
Real IMAP connection via imapflow library: - Connects to IMAP server (IMAPFlow, TLS on port 993) - Fetches recent messages (configurable limit, default 20) - Extracts: from, fromEmail, subject, date, snippet (200 chars) - Thread-to-contact matching (PRD §6.1): 1. Match sender email against persons table 2. If no person match, extract domain and match against company.website 3. Returns matchedCompany + matchedPerson for each email - Audit-logged (action: crm.mailsync:imap) - Zod validated (host, port, user, password, folder, limit) - 502 on IMAP connection failure with detail - 400 on validation failure Tested: invalid creds → 502 'IMAP connection failed', missing host → 400
This commit is contained in:
1 parent
7acc0c5451
commit
e45b68bb8b
1089 files changed
+260614
No files matched your search
@@ -0,0 +1,166 @@
|
||||
---
|
||||
version: alpha
|
||||
name: Github
|
||||
description: "Code-forward platform. Functional density, blue-on-white precision, Primer foundations."
|
||||
category: "Developer Tools"
|
||||
colors:
|
||||
palette: ["#ffffff", "#0d1117", "#0969da", "#1a7f37", "#d0d7de", "#f6f8fa"]
|
||||
typography:
|
||||
fonts: "Helvetica"
|
||||
note: "Frontmatter is auto-extracted; the prose body below is the authoritative source for full tokens, components, and rules."
|
||||
---
|
||||
# Design System Inspired by GitHub
|
||||
|
||||
> Category: Developer Tools
|
||||
> Code-forward platform. Functional density, blue-on-white precision, Primer foundations.
|
||||
|
||||
## 1. Visual Theme & Atmosphere
|
||||
|
||||
GitHub's surface is engineered, not decorated. Every pixel announces a stance: this is a tool for people who care about diffs, builds, and pull requests. The page background is a clean `#ffffff` (light) or `#0d1117` (dark), with content arranged on dense rectangular panes separated by hairline borders rather than negative space. Information density is the brand — list rows, code lines, repository headers, and notification cards are all packed close together so a power user can scan a hundred items without scrolling.
|
||||
|
||||
The signature accents are the **Primer blue** (`#0969da`) for links and primary actions, and **GitHub green** (`#1a7f37`) for merged states, success, and the merge button itself. Both feel slightly muted compared to consumer-product blues and greens — saturated enough to read against the dense gray text, restrained enough to disappear into the background when several appear in one viewport.
|
||||
|
||||
Typography uses the **system-ui** stack across the entire product so text renders crisply on every OS, paired with **SFMono / Menlo / Consolas** for code. There is no editorial display font; GitHub's voice is the voice of the system you're already on.
|
||||
|
||||
**Key Characteristics:**
|
||||
- True white canvas (`#ffffff`) or deep navy-black (`#0d1117`) — no warmth, no tint
|
||||
- Hairline gray borders (`#d0d7de`) define every pane and panel
|
||||
- Primer blue (`#0969da`) for links/primary; GitHub green (`#1a7f37`) for success/merge
|
||||
- system-ui for prose; SFMono for code — no custom typeface
|
||||
- Dense list rows with minimal padding; whitespace is rare
|
||||
- Octicon iconography at 16px / 24px — single-stroke, geometric, consistent
|
||||
- Pill-shaped status badges with strong color semantics
|
||||
|
||||
## 2. Color Palette & Roles
|
||||
|
||||
### Primary
|
||||
- **Canvas Default** (`#ffffff`): Primary page background, light theme.
|
||||
- **Canvas Subtle** (`#f6f8fa`): Secondary surface, sidebar, input background, header strip.
|
||||
- **Canvas Inset** (`#eaeef2`): Code block background, deep-inset surface.
|
||||
- **Fg Default** (`#1f2328`): Primary text, headlines, ink.
|
||||
- **Fg Muted** (`#656d76`): Secondary text, captions, file paths.
|
||||
|
||||
### Brand Accent
|
||||
- **Primer Blue** (`#0969da`): Links, primary CTAs, focus ring base — the universal interactive color.
|
||||
- **Primer Blue Hover** (`#0550ae`): Hover/pressed for primary blue.
|
||||
- **Accent Subtle** (`#ddf4ff`): Soft blue surface for callouts, info banners.
|
||||
|
||||
### Semantic
|
||||
- **Success / Merge Green** (`#1a7f37`): Merged PRs, success badges, merge button.
|
||||
- **Success Subtle** (`#dafbe1`): Success surface tint.
|
||||
- **Open Green** (`#1a7f37`): "Open" issue/PR state.
|
||||
- **Closed / Danger Red** (`#cf222e`): Closed PRs, destructive action, validation error.
|
||||
- **Danger Subtle** (`#ffebe9`): Error banner surface.
|
||||
- **Attention / Warning Yellow** (`#9a6700`): Warning text on amber surface.
|
||||
- **Attention Subtle** (`#fff8c5`): Warning banner surface.
|
||||
- **Done Purple** (`#8250df`): Merged-and-archived, "done" state, premium badge.
|
||||
- **Sponsor Pink** (`#bf3989`): Sponsors heart, GitHub sponsors brand.
|
||||
|
||||
### Border & Divider
|
||||
- **Border Default** (`#d0d7de`): Standard hairline border, panel outline.
|
||||
- **Border Muted** (`#d8dee4`): Inner dividers within a panel.
|
||||
- **Border Subtle** (`#eaeef2`): Faint table row dividers.
|
||||
|
||||
### Dark Theme
|
||||
- **Dark Canvas** (`#0d1117`): Dark page background.
|
||||
- **Dark Surface** (`#161b22`): Sidebar, header, secondary surface.
|
||||
- **Dark Border** (`#30363d`): Standard dark-mode border.
|
||||
- **Dark Fg** (`#e6edf3`): Primary text on dark.
|
||||
|
||||
## 3. Typography Rules
|
||||
|
||||
### Font Family
|
||||
- **Body / UI**: `-apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif`
|
||||
- **Code / Mono**: `ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace`
|
||||
- **Emoji**: `"Apple Color Emoji", "Segoe UI Emoji"`
|
||||
|
||||
### Hierarchy
|
||||
|
||||
| Role | Font | Size | Weight | Line Height | Letter Spacing | Notes |
|
||||
|------|------|------|--------|-------------|----------------|-------|
|
||||
| Display | system-ui | 32px (2rem) | 600 | 1.25 | -0.01em | Repo header, marketing hero |
|
||||
| H1 | system-ui | 24px (1.5rem) | 600 | 1.25 | normal | Page heading |
|
||||
| H2 | system-ui | 20px (1.25rem) | 600 | 1.25 | normal | Section heading |
|
||||
| H3 | system-ui | 16px (1rem) | 600 | 1.25 | normal | Sub-section, panel header |
|
||||
| Body | system-ui | 14px (0.875rem) | 400 | 1.5 | normal | Default text size — not 16px |
|
||||
| Body Small | system-ui | 12px (0.75rem) | 400 | 1.4 | normal | Captions, file metadata |
|
||||
| Code | SFMono | 12px (0.75rem) | 400 | 1.45 | normal | Code blocks, diff |
|
||||
| Code Inline | SFMono | 0.85em | 400 | inherit | normal | Inline `code` spans |
|
||||
|
||||
### Principles
|
||||
- **14px body, not 16px**: GitHub's prose density is its identity. The product reads at 14px to fit more rows in a viewport.
|
||||
- **Weight binary**: 400 for everything by default; 600 for headlines and emphasis. No 500, no 700.
|
||||
- **System fonts always**: never load a webfont for chrome — text must render instantly on slow connections.
|
||||
|
||||
## 4. Component Stylings
|
||||
|
||||
### Buttons
|
||||
|
||||
**Primary (Green)**
|
||||
- Background: `#1f883d`
|
||||
- Text: `#ffffff`
|
||||
- Border: 1px solid `rgba(31, 35, 40, 0.15)`
|
||||
- Padding: 5px 16px
|
||||
- Radius: 6px
|
||||
- Shadow: `0 1px 0 rgba(31,35,40,0.1)`
|
||||
- Hover: background `#1a7f37`
|
||||
- Use: "Create repository", "Merge pull request"
|
||||
|
||||
**Default**
|
||||
- Background: `#f6f8fa`
|
||||
- Text: `#1f2328`
|
||||
- Border: 1px solid `#d0d7de`
|
||||
- Padding: 5px 16px
|
||||
- Radius: 6px
|
||||
- Hover: background `#f3f4f6`, border `#d0d7de`
|
||||
|
||||
**Outline (Blue Link Style)**
|
||||
- Background: `#ffffff`
|
||||
- Text: `#0969da`
|
||||
- Border: 1px solid `#d0d7de`
|
||||
- Hover: background `#0969da`, text `#ffffff`
|
||||
|
||||
**Danger**
|
||||
- Background: `#ffffff`
|
||||
- Text: `#cf222e`
|
||||
- Border: 1px solid `#d0d7de`
|
||||
- Hover: background `#a40e26`, text `#ffffff`, border `#a40e26`
|
||||
|
||||
### Cards / Boxes
|
||||
- Background: `#ffffff`
|
||||
- Border: 1px solid `#d0d7de`
|
||||
- Radius: 6px
|
||||
- Padding: 16px (header) + 16px (body)
|
||||
- Header has a `#f6f8fa` strip with bottom border.
|
||||
|
||||
### Inputs
|
||||
- Background: `#ffffff`
|
||||
- Border: 1px solid `#d0d7de`
|
||||
- Radius: 6px
|
||||
- Padding: 5px 12px
|
||||
- Focus: border `#0969da`, ring `0 0 0 3px rgba(9,105,218,0.3)`
|
||||
|
||||
### Status Pills (Issue / PR)
|
||||
- **Open**: background `#1a7f37`, text white, padding 4px 10px, radius 9999px.
|
||||
- **Closed**: background `#cf222e`, text white.
|
||||
- **Merged**: background `#8250df`, text white.
|
||||
- **Draft**: background `#6e7781`, text white.
|
||||
|
||||
### Labels (Tags on Issues/PRs)
|
||||
- Padding: 0 7px
|
||||
- Radius: 9999px
|
||||
- Font: 12px / 500
|
||||
- Background and text are programmatic (label color → text computed for contrast).
|
||||
|
||||
## 5. Spacing & Layout
|
||||
|
||||
- **Base unit**: 4px. Spacing scale: 4, 8, 12, 16, 24, 32, 40, 48.
|
||||
- **Page max-width**: 1280px (`Container-xl`).
|
||||
- **Sidebar**: 296px on desktop, collapses below 1012px.
|
||||
- **Row padding**: 16px horizontal, 12px vertical (lists are dense by design).
|
||||
|
||||
## 6. Motion
|
||||
|
||||
- **Duration**: 80ms for hover; 200ms for menu/popover open.
|
||||
- **Easing**: `ease-out` for opens, `ease-in` for closes.
|
||||
- **Avoided**: page-load animation, parallax, persistent micro-interactions. Things appear; they do not perform.
|
||||
@@ -0,0 +1,383 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>GitHub — reference components</title>
|
||||
<meta
|
||||
name="description"
|
||||
content="Reference fixture for design-systems/github. Every visible
|
||||
value comes from tokens.css. GitHub's signature moves: true white
|
||||
canvas, hairline borders (#d0d7de), Primer blue CTAs, GitHub green
|
||||
for success/merge, system-ui fonts, 14px body density."
|
||||
/>
|
||||
|
||||
<style>
|
||||
:root {
|
||||
--bg: #ffffff;
|
||||
--surface: #f6f8fa;
|
||||
--surface-warm: var(--surface);
|
||||
|
||||
--fg: #1f2328;
|
||||
--fg-2: #1f2328;
|
||||
--muted: #656d76;
|
||||
--meta: #656d76;
|
||||
|
||||
--border: #d0d7de;
|
||||
--border-soft: #d8dee4;
|
||||
|
||||
--accent: #0969da;
|
||||
--accent-on: #ffffff;
|
||||
--accent-hover: #0550ae;
|
||||
--accent-active: color-mix(in oklab, var(--accent), black 14%);
|
||||
|
||||
--success: #1a7f37;
|
||||
--warn: #9a6700;
|
||||
--danger: #cf222e;
|
||||
|
||||
--font-display: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
|
||||
--font-body: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
|
||||
--font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
|
||||
|
||||
--text-xs: 12px;
|
||||
--text-sm: 14px;
|
||||
--text-base: 14px;
|
||||
--text-lg: 16px;
|
||||
--text-xl: 20px;
|
||||
--text-2xl: 24px;
|
||||
--text-3xl: 28px;
|
||||
--text-4xl: 32px;
|
||||
|
||||
--leading-body: 1.5;
|
||||
--leading-tight: 1.25;
|
||||
--tracking-display: -0.01em;
|
||||
|
||||
--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: 64px;
|
||||
--section-y-tablet: 48px;
|
||||
--section-y-phone: 32px;
|
||||
|
||||
--radius-sm: 6px;
|
||||
--radius-md: 6px;
|
||||
--radius-lg: 12px;
|
||||
--radius-pill: 9999px;
|
||||
|
||||
--elev-flat: none;
|
||||
--elev-ring: 0 0 0 1px var(--border);
|
||||
--elev-raised: 0 1px 3px rgba(31, 35, 40, 0.12), 0 8px 24px rgba(66, 74, 83, 0.12);
|
||||
|
||||
--focus-ring: 0 0 0 3px rgba(9, 105, 218, 0.3);
|
||||
|
||||
--motion-fast: 80ms;
|
||||
--motion-base: 200ms;
|
||||
--ease-standard: ease-out;
|
||||
|
||||
--container-max: 1280px;
|
||||
--container-gutter-desktop: 24px;
|
||||
--container-gutter-tablet: 16px;
|
||||
--container-gutter-phone: 16px;
|
||||
}
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
html, body { margin: 0; padding: 0; }
|
||||
body {
|
||||
background: var(--bg);
|
||||
color: var(--fg);
|
||||
font-family: var(--font-body);
|
||||
font-size: var(--text-base);
|
||||
line-height: var(--leading-body);
|
||||
-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: 600;
|
||||
margin: 0;
|
||||
line-height: var(--leading-tight);
|
||||
}
|
||||
h1 {
|
||||
font-size: var(--text-4xl);
|
||||
letter-spacing: var(--tracking-display);
|
||||
}
|
||||
h2 {
|
||||
font-size: var(--text-xl);
|
||||
/* 20px section heading: line-height 1.25, normal tracking. */
|
||||
}
|
||||
h3 {
|
||||
font-size: var(--text-lg);
|
||||
/* 16px sub-section/panel header: line-height 1.25.
|
||||
Overrides the shared --leading-tight set above. */
|
||||
}
|
||||
p { margin: 0; }
|
||||
.body-muted { color: var(--muted); }
|
||||
.body-sm { font-size: var(--text-sm); }
|
||||
.body-xs { font-size: var(--text-xs); }
|
||||
.eyebrow {
|
||||
font-size: var(--text-xs);
|
||||
font-weight: 600;
|
||||
color: var(--muted);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
}
|
||||
code {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.85em;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-sm);
|
||||
padding: 1px 4px;
|
||||
}
|
||||
.stack-3 > * + * { margin-block-start: var(--space-3); }
|
||||
.stack-4 > * + * { margin-block-start: var(--space-4); }
|
||||
|
||||
/* ─── Buttons ────────────────────────────── */
|
||||
.btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: var(--space-2);
|
||||
padding: 5px 16px;
|
||||
border-radius: var(--radius-sm);
|
||||
font-family: var(--font-body);
|
||||
font-size: var(--text-sm);
|
||||
font-weight: 400;
|
||||
line-height: 1.5;
|
||||
cursor: pointer;
|
||||
border: 1px solid transparent;
|
||||
transition: background-color var(--motion-fast) var(--ease-standard),
|
||||
border-color var(--motion-fast) var(--ease-standard);
|
||||
text-decoration: none;
|
||||
}
|
||||
.btn:focus-visible { outline: none; box-shadow: var(--focus-ring); }
|
||||
.btn-primary {
|
||||
background: #1f883d;
|
||||
color: #ffffff;
|
||||
border-color: rgba(31, 35, 40, 0.15);
|
||||
box-shadow: 0 1px 0 rgba(31, 35, 40, 0.1);
|
||||
font-weight: 500;
|
||||
}
|
||||
.btn-primary:hover { background: var(--success); }
|
||||
.btn-default {
|
||||
background: var(--surface);
|
||||
color: var(--fg);
|
||||
border-color: var(--border);
|
||||
}
|
||||
.btn-default:hover { background: #f3f4f6; }
|
||||
.btn-outline {
|
||||
background: var(--bg);
|
||||
color: var(--accent);
|
||||
border-color: var(--border);
|
||||
}
|
||||
.btn-outline:hover { background: var(--accent); color: white; }
|
||||
|
||||
/* ─── Status pills ───────────────────────── */
|
||||
.status-pill {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: var(--space-1);
|
||||
padding: 4px 10px;
|
||||
border-radius: var(--radius-pill);
|
||||
font-size: var(--text-xs);
|
||||
font-weight: 500;
|
||||
color: white;
|
||||
line-height: 1;
|
||||
}
|
||||
.status-open { background: #1a7f37; }
|
||||
.status-closed { background: #cf222e; }
|
||||
.status-merged { background: #8250df; }
|
||||
.status-draft { background: #6e7781; }
|
||||
|
||||
/* ─── Box / Card ─────────────────────────── */
|
||||
.box {
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-sm);
|
||||
overflow: hidden;
|
||||
}
|
||||
.box-header {
|
||||
background: var(--surface);
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding: var(--space-3) var(--space-4);
|
||||
font-weight: 600;
|
||||
font-size: var(--text-sm);
|
||||
}
|
||||
.box-body { padding: var(--space-4); }
|
||||
|
||||
/* ─── Inputs ─────────────────────────────── */
|
||||
.field { display: flex; flex-direction: column; gap: var(--space-2); }
|
||||
.field label { font-size: var(--text-sm); font-weight: 600; color: var(--fg); }
|
||||
.field input {
|
||||
background: var(--bg);
|
||||
color: var(--fg);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius-sm);
|
||||
padding: 5px 12px;
|
||||
font-family: var(--font-body);
|
||||
font-size: var(--text-sm);
|
||||
outline: none;
|
||||
transition: border-color var(--motion-fast) var(--ease-standard),
|
||||
box-shadow var(--motion-fast) var(--ease-standard);
|
||||
}
|
||||
.field input::placeholder { color: var(--muted); }
|
||||
.field input:focus {
|
||||
border-color: var(--accent);
|
||||
box-shadow: var(--focus-ring);
|
||||
}
|
||||
|
||||
/* ─── Layout ─────────────────────────────── */
|
||||
.hero-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1.2fr 1fr;
|
||||
gap: var(--space-8);
|
||||
align-items: start;
|
||||
}
|
||||
@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-4); flex-wrap: wrap; }
|
||||
.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 · github</p>
|
||||
<h1>Where the world builds software.</h1>
|
||||
<p class="body-muted" style="max-width:48ch;font-size:var(--text-lg);line-height:1.5;margin-top:var(--space-3)">
|
||||
Millions of developers and companies build, ship, and maintain
|
||||
their software on GitHub. Every value below comes from tokens.css
|
||||
— no raw hex, no off-token type.
|
||||
</p>
|
||||
<div class="hero-actions">
|
||||
<a href="./tokens.css" class="btn btn-primary">Sign up for free</a>
|
||||
<a href="./DESIGN.md" class="btn btn-default">Read the spec</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<aside>
|
||||
<div class="box">
|
||||
<div class="box-header">open-design / design-systems</div>
|
||||
<div class="box-body stack-3">
|
||||
<div style="display:flex;align-items:center;justify-content:space-between">
|
||||
<span class="body-sm" style="font-weight:600;color:var(--accent)">Pull requests</span>
|
||||
<span class="status-pill status-open">Open</span>
|
||||
</div>
|
||||
<div style="font-size:var(--text-xs);color:var(--muted)">
|
||||
#1652 · feat: add structured tokens for 5 brands
|
||||
</div>
|
||||
<div style="font-size:var(--text-xs);color:var(--muted)">
|
||||
#1653 · feat: add batch 2 token fixtures
|
||||
</div>
|
||||
<div style="display:flex;gap:var(--space-2);margin-top:var(--space-2)">
|
||||
<span class="status-pill status-merged">Merged</span>
|
||||
<span class="status-pill status-draft">Draft</span>
|
||||
<span class="status-pill status-closed">Closed</span>
|
||||
</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>Dense, functional, system-native.</h2>
|
||||
</div>
|
||||
|
||||
<div class="features-grid" style="margin-block-start:var(--space-6)">
|
||||
<article class="box stack-3">
|
||||
<div class="box-header">14px body</div>
|
||||
<div class="box-body">
|
||||
<p class="body-sm body-muted">
|
||||
Not 16px — GitHub's prose density is its identity. 14px base
|
||||
fits more content per viewport. system-ui renders instantly on
|
||||
every OS with zero webfont load.
|
||||
</p>
|
||||
</div>
|
||||
</article>
|
||||
<article class="box stack-3">
|
||||
<div class="box-header">Hairline borders</div>
|
||||
<div class="box-body">
|
||||
<p class="body-sm body-muted">
|
||||
<code>#d0d7de</code> — every pane, panel, and card. Structure
|
||||
communicated by stroke, not shadow. Density without visual noise.
|
||||
</p>
|
||||
</div>
|
||||
</article>
|
||||
<article class="box stack-3">
|
||||
<div class="box-header">Primer blue + green</div>
|
||||
<div class="box-body">
|
||||
<p class="body-sm body-muted">
|
||||
<code>#0969da</code> for all interactive affordances.
|
||||
<code>#1a7f37</code> exclusively for success/merge states.
|
||||
Both restrained — never decorative.
|
||||
</p>
|
||||
</div>
|
||||
</article>
|
||||
</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>Primer form inputs.</h2>
|
||||
<p class="body-muted" style="max-width:44ch">
|
||||
Focus: border <code>#0969da</code> + <code>0 0 0 3px rgba(9,105,218,0.3)</code>.
|
||||
5px 12px padding. 6px radius. Weight 600 label.
|
||||
</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">Email address</label>
|
||||
<input id="email" type="email" placeholder="you@example.com" />
|
||||
</div>
|
||||
<div class="field">
|
||||
<label for="repo">Repository name</label>
|
||||
<input id="repo" type="text" placeholder="my-project" />
|
||||
</div>
|
||||
<div style="display:flex;gap:var(--space-3);margin-top:var(--space-2)">
|
||||
<button type="submit" class="btn btn-primary">Create repository</button>
|
||||
<button type="button" class="btn btn-default">Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,125 @@
|
||||
/* ─────────────────────────────────────────────────────────────────────────
|
||||
* design-systems/github/tokens.css
|
||||
*
|
||||
* Structured token bindings for the "GitHub" brand — Primer foundations,
|
||||
* functional density, blue-on-white precision.
|
||||
*
|
||||
* Brand identity in three sentences:
|
||||
* 1. True white canvas (#ffffff) with a clean canvas-subtle (#f6f8fa)
|
||||
* secondary surface; hairline borders (#d0d7de) define every pane
|
||||
* — density over decoration, information over aesthetics.
|
||||
* 2. System-ui stack throughout — no custom webfont; type renders at
|
||||
* instant on every OS; 14px body (not 16px) is the identity.
|
||||
* 3. Primer blue (#0969da) for all interactive affordances; GitHub
|
||||
* green (#1a7f37) reserved for success/merge states only.
|
||||
*
|
||||
* Schema decisions:
|
||||
* - --bg: #ffffff; --surface: #f6f8fa (canvas-subtle).
|
||||
* - --surface-warm aliases --surface (no warm tier in Primer).
|
||||
* - --fg: #1f2328 (fg-default); --muted: #656d76 (fg-muted).
|
||||
* - --border: #d0d7de (1px hairline — the structural backbone).
|
||||
* - --accent: #0969da (Primer Blue); --accent-hover: #0550ae.
|
||||
* - --success bound to GitHub green (#1a7f37) — merge / open state.
|
||||
* - --tracking-display: -0.01em (only display-size headings use it).
|
||||
* - --text-base: 14px (the 14px body IS GitHub's product density).
|
||||
* - --radius-sm: 6px (universal Primer radius for buttons/inputs).
|
||||
* ─────────────────────────────────────────────────────────────────── */
|
||||
|
||||
:root {
|
||||
/* ─── Surface ──────────────────────────────────────────────────── */
|
||||
--bg: #ffffff;
|
||||
--surface: #f6f8fa; /* canvas-subtle — sidebar, input bg */
|
||||
--surface-warm: var(--surface); /* Primer has no warm tier */
|
||||
|
||||
/* ─── Foreground ───────────────────────────────────────────────── */
|
||||
--fg: #1f2328; /* fg-default — ink */
|
||||
--fg-2: #1f2328; /* same ink; no B-slot split in Primer */
|
||||
--muted: #656d76; /* fg-muted — captions, file paths */
|
||||
--meta: #656d76; /* same muted tier */
|
||||
|
||||
/* ─── Border ───────────────────────────────────────────────────── */
|
||||
--border: #d0d7de; /* border-default — hairline structural */
|
||||
--border-soft: #d8dee4; /* border-muted — inner panel dividers */
|
||||
|
||||
/* ─── Accent ───────────────────────────────────────────────────── */
|
||||
--accent: #0969da; /* Primer Blue — links, primary CTAs */
|
||||
--accent-on: #ffffff;
|
||||
--accent-hover: #0550ae; /* darker pressed state */
|
||||
--accent-active: color-mix(in oklab, var(--accent), black 14%);
|
||||
|
||||
/* ─── Semantic ─────────────────────────────────────────────────── */
|
||||
--success: #1a7f37; /* GitHub green — merge, open, success */
|
||||
--warn: #9a6700; /* attention amber text */
|
||||
--danger: #cf222e; /* closed / destructive red */
|
||||
|
||||
/* ─── Typography ───────────────────────────────────────────────── */
|
||||
/* System fonts only — no webfonts load in GitHub. */
|
||||
--font-display: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
|
||||
--font-body: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
|
||||
--font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
|
||||
|
||||
/* Type scale — DESIGN.md §Typography.
|
||||
* GitHub's prose density: 14px body (not 16px). Display sits at 32px.
|
||||
* h2 (20px) and h3 (16px) collapse close together for density. */
|
||||
--text-xs: 12px; /* body-small — captions, metadata */
|
||||
--text-sm: 14px; /* body — default UI (GitHub's base) */
|
||||
--text-base: 14px; /* body baseline = 14px for density */
|
||||
--text-lg: 16px; /* h3 / panel header */
|
||||
--text-xl: 20px; /* h2 — section heading */
|
||||
--text-2xl: 24px; /* h1 — page heading */
|
||||
--text-3xl: 28px; /* subpage display */
|
||||
--text-4xl: 32px; /* display — repo header / hero */
|
||||
|
||||
/* Leading + tracking.
|
||||
* GitHub uses 1.25 for headings (tight-but-readable), 1.5 for body.
|
||||
* Only display gets the -0.01em tracking. */
|
||||
--leading-body: 1.5;
|
||||
--leading-tight: 1.25;
|
||||
--tracking-display: -0.01em;
|
||||
|
||||
/* ─── Spacing ──────────────────────────────────────────────────── */
|
||||
/* 4px base grid — Primer spacing. Row padding 16px h, 12px v. */
|
||||
--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 — GitHub marketing pages. */
|
||||
--section-y-desktop: 64px;
|
||||
--section-y-tablet: 48px;
|
||||
--section-y-phone: 32px;
|
||||
|
||||
/* ─── Radius ───────────────────────────────────────────────────── */
|
||||
/* 6px is the universal Primer radius for all interactive elements. */
|
||||
--radius-sm: 6px;
|
||||
--radius-md: 6px;
|
||||
--radius-lg: 12px;
|
||||
--radius-pill: 9999px;
|
||||
|
||||
/* ─── Elevation ────────────────────────────────────────────────── */
|
||||
/* GitHub uses hairline borders, not shadows, as the primary depth
|
||||
signal. --elev-raised is a whisper for the rare floating element. */
|
||||
--elev-flat: none;
|
||||
--elev-ring: 0 0 0 1px var(--border);
|
||||
--elev-raised: 0 1px 3px rgba(31, 35, 40, 0.12), 0 8px 24px rgba(66, 74, 83, 0.12);
|
||||
|
||||
/* ─── Focus ────────────────────────────────────────────────────── */
|
||||
/* Primer focus: 3px rgba ring on the accent color. */
|
||||
--focus-ring: 0 0 0 3px rgba(9, 105, 218, 0.3);
|
||||
|
||||
/* ─── Motion ───────────────────────────────────────────────────── */
|
||||
/* GitHub avoids animation. 80ms hover, 200ms open — short and purposeful. */
|
||||
--motion-fast: 80ms;
|
||||
--motion-base: 200ms;
|
||||
--ease-standard: ease-out;
|
||||
|
||||
/* ─── Layout ───────────────────────────────────────────────────── */
|
||||
--container-max: 1280px;
|
||||
--container-gutter-desktop: 24px;
|
||||
--container-gutter-tablet: 16px;
|
||||
--container-gutter-phone: 16px;
|
||||
}
|
||||
Reference in new issue
Block a user