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:
Z User committed 2026-10-27 22:50:50 +00:00
1 parent 7acc0c5451
commit e45b68bb8b
1089 files changed
+260614

No files matched your search

@@ -0,0 +1,537 @@
---
version: alpha
name: Cursor
description: "An AI-first code editor whose marketing site reads like a quietly-confident developer-tools brand with a warm-cream editorial canvas (`#f7f7f4`) instead of the typical dark IDE atmosphere. Near-black warm ink (`#26251e`) carries body and display alike — display sits at weight 400 with negative letter-spacing for a magazine feel rather than a bold tech voice. The single brand voltage is **Cursor Orange** (`#f54e00`) reserved for primary CTAs and the wordmark. A signature pastel timeline palette (peach, mint, blue, lavender, gold) marks AI-action stages (Thinking / Reading / Editing / Grepping / Done) — only inside in-product timeline visualizations. Cards use minimal hairlines, no shadows, generous 80px section rhythm. CursorGothic for display/body, JetBrains Mono on every code surface (which is roughly half the page)."
colors:
primary: "#f54e00"
primary-active: "#d04200"
ink: "#26251e"
body: "#5a5852"
body-strong: "#26251e"
muted: "#807d72"
muted-soft: "#a09c92"
hairline: "#e6e5e0"
hairline-soft: "#efeee8"
hairline-strong: "#cfcdc4"
canvas: "#f7f7f4"
canvas-soft: "#fafaf7"
surface-card: "#ffffff"
surface-strong: "#e6e5e0"
on-primary: "#ffffff"
timeline-thinking: "#dfa88f"
timeline-grep: "#9fc9a2"
timeline-read: "#9fbbe0"
timeline-edit: "#c0a8dd"
timeline-done: "#c08532"
semantic-error: "#cf2d56"
semantic-success: "#1f8a65"
typography:
display-mega:
fontFamily: "'CursorGothic', system-ui, 'Helvetica Neue', Helvetica, Arial, sans-serif"
fontSize: 72px
fontWeight: 400
lineHeight: 1.1
letterSpacing: -2.16px
display-lg:
fontFamily: "'CursorGothic', sans-serif"
fontSize: 36px
fontWeight: 400
lineHeight: 1.2
letterSpacing: -0.72px
display-md:
fontFamily: "'CursorGothic', sans-serif"
fontSize: 26px
fontWeight: 400
lineHeight: 1.25
letterSpacing: -0.325px
display-sm:
fontFamily: "'CursorGothic', sans-serif"
fontSize: 22px
fontWeight: 400
lineHeight: 1.3
letterSpacing: -0.11px
title-md:
fontFamily: "'CursorGothic', sans-serif"
fontSize: 18px
fontWeight: 600
lineHeight: 1.4
letterSpacing: 0
title-sm:
fontFamily: "'CursorGothic', sans-serif"
fontSize: 16px
fontWeight: 600
lineHeight: 1.4
letterSpacing: 0
body-md:
fontFamily: "'CursorGothic', sans-serif"
fontSize: 16px
fontWeight: 400
lineHeight: 1.5
letterSpacing: 0
body-tracked:
fontFamily: "'CursorGothic', sans-serif"
fontSize: 16px
fontWeight: 400
lineHeight: 1.5
letterSpacing: 0.08px
body-sm:
fontFamily: "'CursorGothic', sans-serif"
fontSize: 14px
fontWeight: 400
lineHeight: 1.5
letterSpacing: 0
caption:
fontFamily: "'CursorGothic', sans-serif"
fontSize: 13px
fontWeight: 400
lineHeight: 1.4
letterSpacing: 0
caption-uppercase:
fontFamily: "'CursorGothic', sans-serif"
fontSize: 11px
fontWeight: 600
lineHeight: 1.4
letterSpacing: 0.88px
textTransform: uppercase
code:
fontFamily: "'JetBrains Mono', 'Fira Code', monospace"
fontSize: 13px
fontWeight: 400
lineHeight: 1.5
letterSpacing: 0
button:
fontFamily: "'CursorGothic', sans-serif"
fontSize: 14px
fontWeight: 500
lineHeight: 1.0
letterSpacing: 0
nav-link:
fontFamily: "'CursorGothic', sans-serif"
fontSize: 14px
fontWeight: 500
lineHeight: 1.4
letterSpacing: 0
rounded:
none: 0px
xs: 4px
sm: 6px
md: 8px
lg: 12px
xl: 16px
pill: 9999px
full: 9999px
spacing:
xxs: 4px
xs: 8px
sm: 12px
base: 16px
md: 20px
lg: 24px
xl: 32px
xxl: 48px
section: 80px
components:
top-nav:
backgroundColor: "{colors.canvas}"
textColor: "{colors.ink}"
typography: "{typography.nav-link}"
height: 64px
button-primary:
backgroundColor: "{colors.primary}"
textColor: "{colors.on-primary}"
typography: "{typography.button}"
rounded: "{rounded.md}"
padding: 10px 18px
height: 40px
button-primary-active:
backgroundColor: "{colors.primary-active}"
textColor: "{colors.on-primary}"
rounded: "{rounded.md}"
button-secondary:
backgroundColor: "{colors.surface-card}"
textColor: "{colors.ink}"
typography: "{typography.button}"
rounded: "{rounded.md}"
padding: 9px 17px
height: 40px
button-tertiary-text:
backgroundColor: transparent
textColor: "{colors.ink}"
typography: "{typography.button}"
button-download:
backgroundColor: "{colors.ink}"
textColor: "{colors.canvas}"
typography: "{typography.button}"
rounded: "{rounded.md}"
padding: 12px 20px
height: 44px
hero-band:
backgroundColor: "{colors.canvas}"
textColor: "{colors.ink}"
typography: "{typography.display-mega}"
padding: 80px
ide-mockup-card:
backgroundColor: "{colors.surface-card}"
textColor: "{colors.ink}"
rounded: "{rounded.lg}"
padding: 0
ide-pane:
backgroundColor: "{colors.canvas-soft}"
textColor: "{colors.body}"
typography: "{typography.code}"
rounded: "{rounded.md}"
padding: 16px
feature-card:
backgroundColor: "{colors.surface-card}"
textColor: "{colors.ink}"
typography: "{typography.title-md}"
rounded: "{rounded.lg}"
padding: 24px
comparison-card:
backgroundColor: "{colors.surface-card}"
textColor: "{colors.ink}"
typography: "{typography.body-md}"
rounded: "{rounded.lg}"
padding: 24px
timeline-pill-thinking:
backgroundColor: "{colors.timeline-thinking}"
textColor: "{colors.ink}"
typography: "{typography.caption-uppercase}"
rounded: "{rounded.pill}"
padding: 4px 10px
timeline-pill-grep:
backgroundColor: "{colors.timeline-grep}"
textColor: "{colors.ink}"
typography: "{typography.caption-uppercase}"
rounded: "{rounded.pill}"
padding: 4px 10px
timeline-pill-read:
backgroundColor: "{colors.timeline-read}"
textColor: "{colors.ink}"
typography: "{typography.caption-uppercase}"
rounded: "{rounded.pill}"
padding: 4px 10px
timeline-pill-edit:
backgroundColor: "{colors.timeline-edit}"
textColor: "{colors.ink}"
typography: "{typography.caption-uppercase}"
rounded: "{rounded.pill}"
padding: 4px 10px
timeline-pill-done:
backgroundColor: "{colors.timeline-done}"
textColor: "{colors.on-primary}"
typography: "{typography.caption-uppercase}"
rounded: "{rounded.pill}"
padding: 4px 10px
code-block:
backgroundColor: "{colors.surface-card}"
textColor: "{colors.ink}"
typography: "{typography.code}"
rounded: "{rounded.lg}"
padding: 20px
pricing-tier-card:
backgroundColor: "{colors.surface-card}"
textColor: "{colors.ink}"
typography: "{typography.body-md}"
rounded: "{rounded.lg}"
padding: 32px
pricing-tier-featured:
backgroundColor: "{colors.ink}"
textColor: "{colors.canvas}"
typography: "{typography.body-md}"
rounded: "{rounded.lg}"
padding: 32px
text-input:
backgroundColor: "{colors.surface-card}"
textColor: "{colors.ink}"
typography: "{typography.body-md}"
rounded: "{rounded.md}"
padding: 12px 16px
height: 44px
badge-pill:
backgroundColor: "{colors.surface-strong}"
textColor: "{colors.ink}"
typography: "{typography.caption-uppercase}"
rounded: "{rounded.pill}"
padding: 4px 10px
cta-band:
backgroundColor: "{colors.canvas}"
textColor: "{colors.ink}"
typography: "{typography.display-lg}"
padding: 96px
testimonial-card:
backgroundColor: "{colors.surface-card}"
textColor: "{colors.body}"
typography: "{typography.body-md}"
rounded: "{rounded.lg}"
padding: 24px
footer:
backgroundColor: "{colors.canvas}"
textColor: "{colors.body}"
typography: "{typography.body-sm}"
padding: 64px 48px
footer-link:
backgroundColor: transparent
textColor: "{colors.body}"
typography: "{typography.body-sm}"
---
## Overview
Cursor's marketing site reads as a quietly-confident developer brand that believes in editorial calm over IDE-darkness. The base canvas is **warm cream** (`{colors.canvas}` — #f7f7f4) holding warm near-black ink (`{colors.ink}` — #26251e) for body and display alike. The single brand voltage is **Cursor Orange** (`{colors.primary}` — #f54e00) reserved for primary CTAs and the wordmark — used scarcely.
Type runs **CursorGothic** as the single sans family. Display sits at weight 400 with negative letter-spacing — a magazine-editorial voice rather than tech-bombastic. JetBrains Mono carries every code surface (and code surfaces are roughly half the page).
The brand's strongest visual signature is the **AI-timeline pill palette**: five pastel pills (peach `{colors.timeline-thinking}`, mint `{colors.timeline-grep}`, blue `{colors.timeline-read}`, lavender `{colors.timeline-edit}`, gold `{colors.timeline-done}`) marking AI-action stages inside in-product timeline visualizations. Used only in product UI — never as system action colors.
**Key Characteristics:**
- Warm cream canvas, not white. Ink is warm (#26251e), not pure black.
- Single CTA color: `{colors.primary}` (Cursor Orange #f54e00). Used scarcely.
- Display weight stays at 400 — never bold. Magazine voice.
- AI timeline pastels: 5 dedicated tokens for in-product agent action stages.
- Compact 8px CTA radius — developer dialect.
- Hairline-only depth; no drop shadows.
- 80px section rhythm.
## Colors
### Brand & Accent
- **Cursor Orange** (`{colors.primary}` — #f54e00): Primary CTA pills, wordmark, hero accent. Used scarcely.
- **Cursor Orange Active** (`{colors.primary-active}` — #d04200): Press state.
### Surface
- **Canvas** (`{colors.canvas}` — #f7f7f4): Warm cream page floor.
- **Canvas Soft** (`{colors.canvas-soft}` — #fafaf7): IDE-pane background inside mockups.
- **Surface Card** (`{colors.surface-card}` — #ffffff): Pure white card surface — slight contrast against the cream canvas.
- **Surface Strong** (`{colors.surface-strong}` — #e6e5e0): Badges, tag pills.
### Hairlines
- **Hairline** (`{colors.hairline}` — #e6e5e0): 1px divider.
- **Hairline Soft** (`{colors.hairline-soft}` — #efeee8): Lighter divider.
- **Hairline Strong** (`{colors.hairline-strong}` — #cfcdc4): Stronger panel outline.
### Text
- **Ink** (`{colors.ink}` — #26251e): Display, body emphasis. Warm near-black.
- **Body** (`{colors.body}` — #5a5852): Default running-text.
- **Body Strong** (`{colors.body-strong}` — #26251e): Same as ink.
- **Muted** (`{colors.muted}` — #807d72): Sub-titles.
- **Muted Soft** (`{colors.muted-soft}` — #a09c92): Disabled text.
- **On Primary** (`{colors.on-primary}` — #ffffff): White text on Cursor Orange.
### Timeline (AI-action signature)
- **Thinking** (`{colors.timeline-thinking}` — #dfa88f): Peach. Used inside in-product agent timeline only.
- **Grep** (`{colors.timeline-grep}` — #9fc9a2): Mint.
- **Read** (`{colors.timeline-read}` — #9fbbe0): Pastel blue.
- **Edit** (`{colors.timeline-edit}` — #c0a8dd): Lavender.
- **Done** (`{colors.timeline-done}` — #c08532): Warm gold.
### Semantic
- **Success** (`{colors.semantic-success}` — #1f8a65): Confirmation indicators.
- **Error** (`{colors.semantic-error}` — #cf2d56): Validation errors.
## Typography
### Font Family
**CursorGothic** is the licensed display + body family. Fallback: `system-ui, "Helvetica Neue", Helvetica, Arial, sans-serif`. Code surfaces switch to **JetBrains Mono**.
### Hierarchy
| Token | Size | Weight | Line Height | Letter Spacing | Use |
|---|---|---|---|---|---|
| `{typography.display-mega}` | 72px | 400 | 1.1 | -2.16px | Homepage hero h1 |
| `{typography.display-lg}` | 36px | 400 | 1.2 | -0.72px | Section heads |
| `{typography.display-md}` | 26px | 400 | 1.25 | -0.325px | Sub-section heads |
| `{typography.display-sm}` | 22px | 400 | 1.3 | -0.11px | Card group titles |
| `{typography.title-md}` | 18px | 600 | 1.4 | 0 | Component titles |
| `{typography.title-sm}` | 16px | 600 | 1.4 | 0 | List labels |
| `{typography.body-md}` | 16px | 400 | 1.5 | 0 | Default body |
| `{typography.body-tracked}` | 16px | 400 | 1.5 | 0.08px | Tracked editorial body |
| `{typography.body-sm}` | 14px | 400 | 1.5 | 0 | Footer body |
| `{typography.caption}` | 13px | 400 | 1.4 | 0 | Photo captions |
| `{typography.caption-uppercase}` | 11px | 600 | 1.4 | 0.88px | Section labels, timeline pill labels |
| `{typography.code}` | 13px | 400 | 1.5 | 0 | Code blocks — JetBrains Mono |
| `{typography.button}` | 14px | 500 | 1.0 | 0 | CTA pill labels |
| `{typography.nav-link}` | 14px | 500 | 1.4 | 0 | Top-nav menu |
### Principles
- **Display weight stays at 400.** Magazine voice, never bold.
- **Negative letter-spacing on display only.** -0.11px to -2.16px tracking.
- **JetBrains Mono on every code surface.**
### Note on Font Substitutes
CursorGothic is licensed. Open-source substitute: **Inter** at weight 400 with letter-spacing -1.5%. Or **GT Sectra** for a more editorial feel.
## Layout
### Spacing System
- **Base unit:** 4px.
- **Tokens:** `{spacing.xxs}` 4px · `{spacing.xs}` 8px · `{spacing.sm}` 12px · `{spacing.base}` 16px · `{spacing.md}` 20px · `{spacing.lg}` 24px · `{spacing.xl}` 32px · `{spacing.xxl}` 48px · `{spacing.section}` 80px.
- **Section padding:** 80px.
### Grid & Container
- Max content width: ~1200px.
- Editorial body: 12-column grid.
- Feature card grids: 2-up at desktop for splits, 3-up for benefits.
- Footer: 5-column at desktop.
### Whitespace Philosophy
Generous editorial pacing — closer to a print magazine than a tech site. The cream canvas has plenty of breathing room; cards within bands sit close (16-24px gap).
## Elevation & Depth
The system uses **hairline-only depth**. No drop shadows, no elevation tiers. Cards float above the canvas via 1px hairlines and the slight white-on-cream contrast.
| Level | Treatment | Use |
|---|---|---|
| Flat (canvas) | `{colors.canvas}` (#f7f7f4) | Body bands, footer |
| Card | `{colors.surface-card}` (#ffffff) | Content cards |
| Hairline border | 1px `{colors.hairline}` | Card outlines, dividers |
| IDE pane | `{colors.canvas-soft}` (#fafaf7) | Inside IDE mockup cards |
### Decorative Depth
- **IDE-mockup cards** are the only "elevated" element. White card on cream canvas with internal pane structure mimicking the actual Cursor editor.
- **Timeline pastel pills** add chromatic depth without surface elevation.
## Shapes
### Border Radius Scale
| Token | Value | Use |
|---|---|---|
| `{rounded.none}` | 0px | Reserved |
| `{rounded.xs}` | 4px | Inline tags |
| `{rounded.sm}` | 6px | Compact rows |
| `{rounded.md}` | 8px | CTA buttons, form inputs |
| `{rounded.lg}` | 12px | Cards, IDE panes |
| `{rounded.xl}` | 16px | Larger feature cards (rare) |
| `{rounded.pill}` | 9999px | Timeline pills, badges |
| `{rounded.full}` | 9999px | Avatars (rare) |
## Components
### Top Navigation
**`top-nav`** — Background `{colors.canvas}`, text `{colors.ink}`, height 64px. Layout: Cursor wordmark left, primary horizontal menu (Pricing / Features / Enterprise / Blog / Forum / Careers), Sign In + Download primary CTA right.
### Buttons
**`button-primary`** — The signature Cursor Orange CTA. Background `{colors.primary}`, text `{colors.on-primary}`, type `{typography.button}` (14px / 500), padding 10px × 18px, height 40px, rounded `{rounded.md}` (8px).
**`button-primary-active`** — Press state. Background `{colors.primary-active}`.
**`button-secondary`** — White card pill on cream canvas. Background `{colors.surface-card}`, text `{colors.ink}`, 1px `{colors.hairline-strong}` border.
**`button-tertiary-text`** — Inline ink text link.
**`button-download`** — Larger ink-canvas CTA. Background `{colors.ink}`, text `{colors.canvas}`, padding 12px × 20px, height 44px. Used for "Download for macOS" type CTAs.
### Hero & IDE Mockups
**`hero-band`** — Background `{colors.canvas}`, full-width display headline in `{typography.display-mega}` (72px / 400 / -2.16px), subhead in `{typography.body-md}`, two CTAs (`button-download` + `button-tertiary-text`), and a centered IDE-mockup card below the hero copy.
**`ide-mockup-card`** — A white card containing a multi-pane IDE mockup (sidebar + main editor + chat panel + terminal). Background `{colors.surface-card}`, rounded `{rounded.lg}` (12px), 1px `{colors.hairline}` border, no padding (panes fill the card edge-to-edge).
**`ide-pane`** — Individual IDE pane inside the mockup. Background `{colors.canvas-soft}`, text `{colors.body}` in `{typography.code}` (JetBrains Mono 13px), rounded `{rounded.md}` (8px), padding 16px.
### Cards
**`feature-card`** — Background `{colors.surface-card}`, text `{colors.ink}`, type `{typography.title-md}`, rounded `{rounded.lg}`, padding 24px. 1px `{colors.hairline}` border.
**`comparison-card`** — Side-by-side "Cursor vs other tools" card. Same surface and rounding; internally split into 2 columns.
**`testimonial-card`** — Quote card. Background `{colors.surface-card}`, text `{colors.body}`, rounded `{rounded.lg}`, padding 24px.
### AI Timeline (signature)
**`timeline-pill-thinking`** — Peach pill. Background `{colors.timeline-thinking}`, text `{colors.ink}`, type `{typography.caption-uppercase}` (11px / 600 / 0.88px tracking, uppercase), rounded `{rounded.pill}`, padding 4px × 10px. Marks "Thinking" stage in product timeline.
**`timeline-pill-grep`** — Mint pill. Same shape, background `{colors.timeline-grep}`. Marks "Grepping" stage.
**`timeline-pill-read`** — Pastel-blue pill. Background `{colors.timeline-read}`. Marks "Reading" stage.
**`timeline-pill-edit`** — Lavender pill. Background `{colors.timeline-edit}`. Marks "Editing" stage.
**`timeline-pill-done`** — Gold pill. Background `{colors.timeline-done}`, text `{colors.on-primary}` white. Marks "Done" stage.
### Code
**`code-block`** — Inline code block. Background `{colors.surface-card}`, text `{colors.ink}` in `{typography.code}`, rounded `{rounded.lg}`, padding 20px, 1px `{colors.hairline}` border.
### Pricing
**`pricing-tier-card`** — Background `{colors.surface-card}`, rounded `{rounded.lg}`, padding 32px, 1px `{colors.hairline}` border.
**`pricing-tier-featured`** — Featured tier inverts to ink. Background `{colors.ink}`, text `{colors.canvas}`. Same shape, dark inversion signals "highlighted" without colored ribbon.
### Forms & Tags
**`text-input`** — Background `{colors.surface-card}`, text `{colors.ink}`, rounded `{rounded.md}` (8px), padding 12px × 16px, height 44px.
**`badge-pill`** — Small uppercase pill. Background `{colors.surface-strong}`, text `{colors.ink}`, type `{typography.caption-uppercase}`, rounded `{rounded.pill}`, padding 4px × 10px.
### CTA / Footer
**`cta-band`** — Pre-footer "Try Cursor now" band. Background `{colors.canvas}`, centered display headline in `{typography.display-lg}`, single Cursor Orange CTA. 96px vertical padding.
**`footer`** — Closing footer. Background `{colors.canvas}`, text `{colors.body}`. 5-column link list. 64×48px padding.
**`footer-link`** — Background transparent, text `{colors.body}`, type `{typography.body-sm}`.
## Do's and Don'ts
### Do
- Reserve `{colors.primary}` (Cursor Orange) for primary CTAs and brand wordmark.
- Keep display weight at 400. The editorial voice depends on this.
- Use the cream `{colors.canvas}` page floor — never pure white.
- Render every code surface (inline, blocks, IDE panes) in JetBrains Mono.
- Use timeline pastels only inside in-product agent visualizations — never as system action colors.
### Don't
- Don't introduce a secondary brand action color. Cursor Orange is the only one.
- Don't drop display to bold weights (700+). Magazine voice depends on 400.
- Don't add drop shadows. Hairlines + ink-on-cream contrast carry the depth.
- Don't use timeline pastels on non-timeline UI. They're scoped to the agent timeline only.
- Don't extract a CTA color from a third-party widget (cookie consent, OneTrust). The brand's CTA is what appears on actual product CTAs.
## Responsive Behavior
### Breakpoints
| Name | Width | Key Changes |
|---|---|---|
| Mobile | < 640px | Hero h1 72→32px; IDE mockup collapses to single pane preview; feature grid 1-up; nav hamburger. |
| Tablet | 640–1024px | Hero h1 56px; IDE mockup compresses; feature grid 2-up. |
| Desktop | 1024–1280px | Full hero h1 72px; full multi-pane IDE mockup; feature grid 3-up. |
| Wide | > 1280px | Content caps at 1200px. |
### Touch Targets
- Primary CTA at 40px height — at WCAG AA, padded for AAA.
- Download CTA at 44px — at AAA.
### Collapsing Strategy
- Top nav switches to hamburger below 768px.
- IDE mockup multi-pane collapses to a single primary pane preview on mobile.
- Feature grid: 3-up → 2-up → 1-up.
## Iteration Guide
1. Focus on a single component at a time.
2. CTAs default to `{rounded.md}` (8px). Cards use `{rounded.lg}` (12px).
3. Variants live as separate entries inside `components:`.
4. Use `{token.refs}` everywhere — never inline hex.
5. Hover state never documented.
6. CursorGothic 400 for display, 400/500/600 for body. JetBrains Mono on every code surface.
7. Cursor Orange stays scarce.
8. Timeline pastels stay scoped to in-product agent visualizations.
## Known Gaps
- CursorGothic is a licensed typeface; Inter is the substitute.
- Animation timings (timeline pill entrance, IDE pane reveal) out of scope.
- In-app surfaces (code editor, chat panel, agent timeline) only partially captured via marketing IDE mockups.
- Form validation states beyond focus not visible on captured surfaces.
@@ -0,0 +1,5 @@
# Cursor Inspired Design System
Design system details have been moved to: https://getdesign.md/cursor/design-md
You can also view previews, dark mode examples, and download options on getdesign.md.
@@ -0,0 +1,654 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Cursor — reference components</title>
<meta
name="description"
content="Reference fixture for design-systems/cursor. Every visible
value comes from tokens.css; if the agent paste-replaces the
:root block and reuses the component selectors below verbatim,
the artifact passes lint without further audit. Cursor's
signature moves: warm cream surfaces, three typographic voices
(CursorGothic / jjannon / berkeleyMono), oklab borders rendered
as rgba fallback, hover-text shifts to --danger crimson, and
diffused atmospheric shadows."
/>
<style>
/* :root paste — sourced verbatim from
design-systems/cursor/tokens.css. Keep this block in sync
when tokens.css changes. The agent prompt instructs the
Designer panelist to paste this block as the FIRST thing in
their <style>, then reference everything below via var(...). */
:root {
--bg: #f2f1ed;
--surface: #e6e5e0;
--surface-warm: #ebeae5;
--fg: #26251e;
--fg-2: rgba(38, 37, 30, 0.9);
--muted: rgba(38, 37, 30, 0.55);
--meta: rgba(38, 37, 30, 0.4);
--border: rgba(38, 37, 30, 0.1);
--border-soft: rgba(38, 37, 30, 0.06);
--accent: #f54e00;
--accent-on: #ffffff;
--accent-hover: color-mix(in oklab, var(--accent), black 8%);
--accent-active: color-mix(in oklab, var(--accent), black 14%);
--success: #1f8a65;
--warn: #eab308;
--danger: #cf2d56;
--font-display: "CursorGothic", "CursorGothic Fallback", system-ui, "Helvetica Neue", Helvetica, Arial, sans-serif;
--font-body: "jjannon", "Iowan Old Style", "Palatino Linotype", "URW Palladio L", P052, ui-serif, Georgia, Cambria, "Times New Roman", Times, serif;
--font-mono: "berkeleyMono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
--text-xs: 11px;
--text-sm: 14px;
--text-base: 16px;
--text-lg: 19.2px;
--text-xl: 22px;
--text-2xl: 26px;
--text-3xl: 36px;
--text-4xl: 72px;
--leading-body: 1.5;
--leading-tight: 1.10;
--tracking-display: -0.03em;
--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: 8px;
--radius-md: 10px;
--radius-lg: 12px;
--radius-pill: 9999px;
--elev-flat: none;
--elev-ring: 0 0 0 1px var(--border);
--elev-raised:
0 28px 70px rgba(0, 0, 0, 0.14),
0 14px 32px rgba(0, 0, 0, 0.1),
0 0 0 1px var(--border);
--focus-ring: 0 4px 12px rgba(0, 0, 0, 0.1);
--motion-fast: 150ms;
--motion-base: 200ms;
--ease-standard: ease;
--container-max: 1200px;
--container-gutter-desktop: 24px;
--container-gutter-tablet: 16px;
--container-gutter-phone: 12px;
}
/* ─── Reset (minimal) ───────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
background: var(--bg);
color: var(--fg);
/* Body uses jjannon serif. The three-voice system is a brand
signature; do not collapse to one font for "simplicity". */
font-family: var(--font-body);
font-size: var(--text-base);
line-height: var(--leading-body);
font-feature-settings: "cswh"; /* contextual swash alternates */
-webkit-font-smoothing: antialiased;
}
/* ─── Layout primitives ─────────────────────────────────── */
.container {
max-width: var(--container-max);
margin-inline: auto;
padding-inline: var(--container-gutter-desktop);
}
section { padding-block: var(--section-y-desktop); }
section + section {
/* Cursor's section separation is via tone shift + spacing,
not hard rules. The ring is intentionally faint. */
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);
line-height: var(--leading-tight);
margin: 0;
/* CursorGothic uses weight 400 almost exclusively; size +
tracking carry hierarchy, not weight (DESIGN.md §3.4). */
font-weight: 400;
}
h1 {
/* Hero uses --text-4xl=72px with the full -0.03em tracking. */
font-size: var(--text-4xl);
letter-spacing: var(--tracking-display);
}
h2 {
font-size: var(--text-3xl);
/* 36px section heading: line-height 1.20, tracking -0.72px (-0.02em).
Overrides the shared 1.10 (--leading-tight) set on h1/h2/h3 above. */
line-height: 1.20;
letter-spacing: -0.02em;
}
h3 {
font-size: var(--text-2xl);
/* 26px sub-heading: line-height 1.25, tracking -0.325px (-0.0125em).
Overrides the shared 1.10 (--leading-tight) set on h1/h2/h3 above. */
line-height: 1.25;
letter-spacing: -0.0125em;
}
p { margin: 0; }
.lead {
/* Lead body in serif voice — Cursor's editorial signature. */
font-family: var(--font-body);
font-size: var(--text-lg);
line-height: 1.35;
color: var(--muted);
}
.body-muted { color: var(--muted); }
.body-sm { font-size: var(--text-sm); }
.body-mono { font-family: var(--font-mono); font-size: var(--text-sm); }
/* `.eyebrow` — uppercase micro label, system-ui voice. Letter
spacing is well above craft/typography.md's 0.06em floor. */
.eyebrow {
font-family: var(--font-display);
font-size: var(--text-xs);
color: var(--muted);
text-transform: uppercase;
letter-spacing: 0.08em;
font-weight: 500;
}
.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 ───────────────────────────────────────────── */
/* Cursor's primary CTA is NOT accent-bg — it is warm-surface bg
with dark text, signature for the brand. The accent orange
appears on link decoration and on the "accent pill" CTA used
sparingly (≤1 per screen). The hover signature is a text-color
shift to --danger (warm crimson), not bg-darken. */
.btn {
display: inline-flex;
align-items: center;
gap: var(--space-2);
padding: 10px 14px;
border-radius: var(--radius-sm);
font-family: var(--font-display);
font-size: var(--text-sm);
font-weight: 400;
line-height: 1;
cursor: pointer;
border: 1px solid transparent;
transition:
color var(--motion-fast) var(--ease-standard),
background-color var(--motion-fast) var(--ease-standard),
box-shadow var(--motion-base) var(--ease-standard);
text-decoration: none;
}
.btn:focus-visible {
outline: none;
/* DESIGN.md §7: focus is depth (4 12 0.1), not halo. */
box-shadow: var(--focus-ring);
}
/* Primary — warm-surface CTA. */
.btn-primary {
background: var(--surface-warm);
color: var(--fg);
}
.btn-primary:hover { color: var(--danger); }
.btn-primary:active { background: var(--surface); }
/* Secondary — ghost on warm surface. */
.btn-secondary {
background: transparent;
color: var(--muted);
border-color: var(--border);
}
.btn-secondary:hover {
color: var(--danger);
border-color: rgba(38, 37, 30, 0.2);
}
/* Accent pill — used at most once per screen for the loudest CTA.
This is the only place on the page where --accent is a bg. */
.btn-accent {
background: var(--accent);
color: var(--accent-on);
border-radius: var(--radius-pill);
padding: 10px 18px;
}
.btn-accent:hover { background: var(--accent-hover); }
.btn-accent:active { background: var(--accent-active); }
/* ─── Pill tags ─────────────────────────────────────────── */
/* Cursor's full-pill (9999px) badges/filters — DESIGN.md §4.1. */
.pill {
display: inline-flex;
align-items: center;
gap: var(--space-2);
padding: 3px 10px;
border-radius: var(--radius-pill);
background: var(--surface);
color: var(--meta);
font-family: var(--font-display);
font-size: var(--text-sm);
font-weight: 400;
line-height: 1.5;
}
.pill-active {
background: rgba(38, 37, 30, 0.06); /* deeper surface for selected state */
color: var(--fg);
}
/* ─── Inputs ────────────────────────────────────────────── */
.field {
display: flex;
flex-direction: column;
gap: var(--space-2);
}
.field label {
font-family: var(--font-display);
font-size: var(--text-sm);
font-weight: 500;
color: var(--fg);
}
.field input {
padding: 10px 12px;
border-radius: var(--radius-sm);
border: 1px solid var(--border);
background: var(--bg);
color: var(--fg);
font-family: var(--font-body);
font-size: var(--text-base);
outline: none;
transition:
border-color var(--motion-fast) var(--ease-standard),
box-shadow var(--motion-base) var(--ease-standard);
}
.field input:focus-visible {
outline: none;
border-color: rgba(38, 37, 30, 0.2);
box-shadow: var(--focus-ring);
}
.field input::placeholder { color: var(--meta); }
.field-help {
font-family: var(--font-body);
font-size: var(--text-sm);
color: var(--muted);
}
/* ─── Cards ─────────────────────────────────────────────── */
.card {
background: var(--surface);
border: 1px solid var(--border);
border-radius: var(--radius-sm);
padding: var(--space-5);
display: flex;
flex-direction: column;
gap: var(--space-3);
transition: box-shadow var(--motion-base) var(--ease-standard);
}
.card:hover {
/* DESIGN.md §7: hover shadow intensification (ambient → elevated). */
box-shadow: var(--elev-raised);
}
.card-featured {
/* Featured card uses the larger 10px radius (DESIGN.md §5.4). */
border-radius: var(--radius-md);
background: var(--bg);
}
/* ─── Badges ────────────────────────────────────────────── */
.badge {
display: inline-flex;
align-items: center;
gap: var(--space-2);
padding: 2px var(--space-3);
border-radius: var(--radius-pill);
font-family: var(--font-display);
font-size: var(--text-xs);
font-weight: 500;
line-height: 1.6;
}
.badge-success {
color: var(--success);
background: color-mix(in oklab, var(--success), transparent 90%);
}
.badge-muted {
color: var(--muted);
background: color-mix(in oklab, var(--muted), transparent 88%);
}
.badge-dot {
width: 6px;
height: 6px;
border-radius: 50%;
background: currentColor;
}
/* ─── Links ─────────────────────────────────────────────── */
a {
color: var(--accent);
text-decoration: none;
}
a:hover {
text-decoration: underline;
text-underline-offset: 3px;
text-decoration-color: var(--meta);
}
/* ─── Kbd ───────────────────────────────────────────────── */
kbd {
font-family: var(--font-mono);
font-size: var(--text-xs);
padding: 2px 6px;
border-radius: 4px;
border: 1px solid var(--border);
background: var(--surface);
color: var(--muted);
}
/* ─── AI timeline (decorative, signature element) ──────── */
/* DESIGN.md §4.7 — Cursor's AI timeline shows four states with
soft "warm pastel" colors. These are decorative state markers,
intentionally NOT promoted to brand surface tokens. */
.timeline {
display: flex;
flex-direction: column;
gap: var(--space-3);
padding: var(--space-4);
background: var(--bg);
border: 1px solid var(--border);
border-radius: var(--radius-md);
}
.timeline-step {
display: flex;
align-items: center;
gap: var(--space-3);
font-family: var(--font-mono);
font-size: var(--text-sm);
color: var(--fg-2);
}
.timeline-dot {
width: 8px;
height: 8px;
border-radius: 50%;
flex-shrink: 0;
}
.timeline-thinking .timeline-dot { background: #dfa88f; }
.timeline-grep .timeline-dot { background: #9fc9a2; }
.timeline-read .timeline-dot { background: #9fbbe0; }
.timeline-edit .timeline-dot { background: #c0a8dd; }
/* ─── Section-specific layout ───────────────────────────── */
.hero-grid {
display: grid;
/* Asymmetric hero — keeps the page from looking like an
AI-default centered template. */
grid-template-columns: 1.4fr 1fr;
gap: var(--space-12);
align-items: end;
}
@media (max-width: 1023px) {
.hero-grid { grid-template-columns: 1fr; gap: var(--space-8); }
}
.hero-actions {
display: flex;
gap: var(--space-3);
margin-block-start: var(--space-6);
}
.hero-meta {
display: flex;
flex-direction: column;
gap: var(--space-3);
padding: var(--space-4);
border: 1px solid var(--border);
border-radius: var(--radius-md);
background: var(--bg);
}
.features-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: var(--space-5);
}
@media (max-width: 1023px) {
.features-grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 639px) {
.features-grid { grid-template-columns: 1fr; }
}
.form-row {
display: grid;
grid-template-columns: 1.4fr 1fr;
gap: var(--space-12);
align-items: start;
}
@media (max-width: 1023px) {
.form-row { grid-template-columns: 1fr; }
}
.form {
display: flex;
flex-direction: column;
gap: var(--space-4);
max-width: 420px;
}
.form-actions {
display: flex;
gap: var(--space-3);
margin-block-start: var(--space-2);
}
.filter-row {
display: flex;
gap: var(--space-2);
flex-wrap: wrap;
}
.icon { width: 16px; height: 16px; flex-shrink: 0; }
.row-between {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--space-3);
}
</style>
</head>
<body>
<main class="container">
<!-- ════════════════════════════════════════════════════════════
HERO — exercises: h1 (CursorGothic 72px / -0.03em),
.lead (jjannon serif), .eyebrow, .btn-primary (warm-surface
CTA + crimson hover), .btn-accent (orange pill, used once
per page max), kbd (berkeleyMono), .badge-success.
═══════════════════════════════════════════════════════════════ -->
<section data-od-id="hero">
<div class="hero-grid">
<div class="stack-4">
<p class="eyebrow">Reference fixture · cursor</p>
<h1>The editor your team writes through, not at.</h1>
<p class="lead" style="max-width: 52ch">
Cursor pairs a serif voice with gothic compression so
feature copy reads like a publication and headlines hit
like an engineered statement. Three fonts, one warm cream
canvas, every value below comes from tokens.css.
</p>
<div class="hero-actions">
<a href="./tokens.css" class="btn btn-accent">
View tokens
<svg
class="icon"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1.75"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
>
<path d="M5 12h14M13 6l6 6-6 6" />
</svg>
</a>
<a href="./DESIGN.md" class="btn btn-primary">Read the spec</a>
</div>
</div>
<aside class="hero-meta" aria-label="System status">
<div class="row-between">
<span class="body-sm">System status</span>
<span class="badge badge-success">
<span class="badge-dot" aria-hidden="true"></span>
Stable
</span>
</div>
<p class="body-sm body-muted">
Last reviewed
<time datetime="2026-05-14">2026-05-14</time> · v0.1
</p>
<p class="body-sm body-muted">
Press <kbd>⌘</kbd> <kbd>K</kbd> to search tokens.
</p>
</aside>
</div>
</section>
<!-- ════════════════════════════════════════════════════════════
FEATURES — exercises: h2, h3, .card (warm surface + hover
shadow lift), .body-muted, .pill / .pill-active (full-pill
filter row), .features-grid, AI timeline component (the
cursor signature element).
═══════════════════════════════════════════════════════════════ -->
<section data-od-id="features">
<div class="stack-3">
<p class="eyebrow">What this fixture exercises</p>
<h2 style="max-width: 28ch">
Every component below uses only var(--*) — no raw hex, no
off-token type.
</h2>
</div>
<div class="filter-row" style="margin-block-start: var(--space-6)">
<button class="pill pill-active">All</button>
<button class="pill">Surfaces</button>
<button class="pill">Typography</button>
<button class="pill">Motion</button>
</div>
<div class="features-grid" style="margin-block-start: var(--space-6)">
<article class="card">
<h3>Warm surfaces</h3>
<p class="body-muted body-sm">
--bg, --surface, --surface-warm form a three-tier cream
ladder. Pure white only inside code panels; the page
never reaches it on the canvas.
</p>
<a href="./tokens.css" class="body-sm">Inspect tokens →</a>
</article>
<article class="card">
<h3>Three voices</h3>
<p class="body-muted body-sm">
CursorGothic for display, jjannon serif for body,
berkeleyMono for code. Each voice carries one role; the
system never collapses to two faces.
</p>
<a href="./DESIGN.md" class="body-sm">Read the spec →</a>
</article>
<article class="card card-featured">
<h3>oklab borders</h3>
<p class="body-muted body-sm">
Borders ship as rgba fallbacks of the oklab originals at
0.1 / 0.06 alpha — perceptually uniform across every
warm surface.
</p>
<a href="./tokens.css" class="body-sm">Inspect borders →</a>
</article>
</div>
<div class="timeline" style="margin-block-start: var(--space-8); max-width: 480px">
<p class="eyebrow">AI timeline · signature element</p>
<div class="timeline-step timeline-thinking">
<span class="timeline-dot" aria-hidden="true"></span>
<span>thinking…</span>
</div>
<div class="timeline-step timeline-grep">
<span class="timeline-dot" aria-hidden="true"></span>
<span>grep "tokens.css" -r design-systems/</span>
</div>
<div class="timeline-step timeline-read">
<span class="timeline-dot" aria-hidden="true"></span>
<span>read default/tokens.css</span>
</div>
<div class="timeline-step timeline-edit">
<span class="timeline-dot" aria-hidden="true"></span>
<span>edit cursor/tokens.css → +56 tokens</span>
</div>
</div>
</section>
<!-- ════════════════════════════════════════════════════════════
FORM — exercises: .field (jjannon body input), focus-visible
depth shadow (no halo), .btn-primary (warm-surface CTA),
.btn-secondary (ghost border), .field-help.
═══════════════════════════════════════════════════════════════ -->
<section data-od-id="form">
<div class="form-row">
<div class="stack-4">
<p class="eyebrow">Form components</p>
<h2>Inputs inherit the same tokens.</h2>
<p class="body-muted" style="max-width: 48ch">
The focus state is a soft 4px-12px depth shadow — no
cool-blue halo. Border weights stay at oklab 0.1; on
focus the active border lifts to 0.2.
</p>
</div>
<form class="form" onsubmit="event.preventDefault();">
<div class="field">
<label for="email">Work email</label>
<input
id="email"
type="email"
placeholder="you@team.dev"
autocomplete="email"
required
/>
<p class="field-help">
We'll send the spec PDF and nothing else.
</p>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">
Send the spec
</button>
<button type="button" class="btn btn-secondary">
Skip for now
</button>
</div>
</form>
</div>
</section>
</main>
</body>
</html>
@@ -0,0 +1,218 @@
/* ─────────────────────────────────────────────────────────────────────────
* design-systems/cursor/tokens.css
*
* Structured token bindings for the "Cursor" brand — the AI-first code
* editor's marketing voice translated into the shared schema. Like
* `default/tokens.css` and `kami/tokens.css`, agents are expected to
* paste the `:root { … }` block verbatim into the first `<style>` of
* every artifact, then reference values via `var(--name)`.
*
* Why this file exists:
* DESIGN.md describes Cursor in prose ("warm cream `#f2f1ed`, warm
* near-black `#26251e` text, oklab borders") — agents have to translate
* that prose into shared token names without inventing brand variants
* like `--cursor-cream`. This file pre-translates once.
*
* Brand identity in three sentences:
* 1. Warm-shifted everything — cream surfaces, near-black-with-yellow
* text, oklab-space borders. Pure white / pure black are reserved
* for code-editor panels and nowhere else.
* 2. Three typographic voices — CursorGothic at display sizes with
* aggressive negative letter-spacing (signature), jjannon serif for
* editorial body, berkeleyMono for code/kbd.
* 3. Hover semantic is text→crimson (`--danger`), not bg-darken.
* Component CSS reading `--accent-hover` still gets the schema's
* darken formula because some artifacts (CTA pills with accent bg)
* do need it; the brand-signature crimson hover is component-level
* not token-level.
*
* Schema decisions specific to Cursor:
* - --surface-warm binds to a real warmer tier (#ebeae5 — the
* "Surface 300" button-default), not aliased to surface. Cursor's
* surface scale 100→500 is a hallmark; the schema slot maps to the
* middle tier that buttons rest on.
* - --fg-2, --meta, --border-soft bind to oklab-fallback rgba values
* at distinct alpha levels (0.9 / 0.4 / 0.06) rather than aliasing,
* because Cursor genuinely has the richer ramp.
* - --tracking-display is set to -0.03em (the 72px hero value
* normalized to em). Smaller display sizes in components should
* scale tracking proportionally; the schema only carries one slot.
* - --elev-raised binds to Cursor's signature 28px/70px diffused
* shadow rather than the schema fallback. This is the depth move
* that makes Cursor feel like a print publication.
* - --focus-ring is depth-only (0 4px 12px), not the halo formula.
* Cursor never paints cool-blue rings.
* - --ease-standard: ease (per DESIGN.md §Interaction & Motion), not
* the schema's cubic-bezier. Brand authenticity over micro-control.
*
* Tokens NOT lifted (intentional):
* - The fine-grained sub-8px spacing scale (1.5px, 2px, 2.5px, 3px,
* 5px, 6px) used for icon/text micro-alignment is component-internal
* in this fixture. Promote to C-extension via BRAND_EXTENSIONS only
* if cross-component reuse demands it.
* - The named surface scale 100/200/300/400/500 is encoded via the
* three schema slots (--bg / --surface / --surface-warm). The
* extreme tiers (100 lightest, 500 deepest) live as inline
* declarations in components.html where needed.
* - The timeline state colors (Thinking peach, Grep sage, Read blue,
* Edit lavender) are decorative state markers, not brand surface
* tokens. They belong in component CSS for the AI timeline element,
* not in :root.
* ─────────────────────────────────────────────────────────────────── */
:root {
/* ─── Surface (3 levels) ──────────────────────────────────────────
* Cream canvas that defines the entire warm system. Default's
* `#fafafa → #ffffff` ladder gets replaced by `#f2f1ed → #e6e5e0`,
* with the warmer surface tier (#ebeae5) bound to --surface-warm
* for buttons that rest on the page background. */
--bg: #f2f1ed; /* Surface 200 — warm off-white */
--surface: #e6e5e0; /* Surface 400 — card / lifted */
--surface-warm: #ebeae5; /* Surface 300 — button default */
/* ─── Foreground ramp (4 levels) ────────────────────────────────
* Cursor genuinely has a 4-tier ramp: solid for headings/body,
* 90% for "light surface" button labels, 55% for secondary text,
* 40% for link underlines and metadata. All bind to the same
* oklab-fallback rgba (warm brown) at different alphas. */
--fg: #26251e; /* warm near-black */
--fg-2: rgba(38, 37, 30, 0.9); /* solid headings on light surfaces */
--muted: rgba(38, 37, 30, 0.55); /* secondary text */
--meta: rgba(38, 37, 30, 0.4); /* metadata, link decoration */
/* ─── Border (2 levels) ─────────────────────────────────────────
* DESIGN.md §Color Palette specifies oklab-space borders as the
* brand signature. The CSS-compatible fallback (rgba) is what
* actually ships per DESIGN.md §Agent Prompt Guide rule 3. */
--border: rgba(38, 37, 30, 0.1); /* primary border, 10% warm brown */
--border-soft: rgba(38, 37, 30, 0.06); /* row separators, ghost-button bg */
/* ─── Accent ──────────────────────────────────────────────────────
* Cursor Orange — primary CTAs, link color, ONE hero accent per
* screen. Hard cap of 2 visible uses per screen still applies via
* lint. Note: the signature hover semantic in DESIGN.md is text
* shifting to --danger (crimson) on buttons; the schema's
* --accent-hover is reserved for the bg-darken case (when accent
* IS the bg, e.g. accent-pill CTA). */
--accent: #f54e00;
--accent-on: #ffffff;
--accent-hover: color-mix(in oklab, var(--accent), black 8%);
--accent-active: color-mix(in oklab, var(--accent), black 14%);
/* ─── Semantic ────────────────────────────────────────────────────
* --danger is Cursor's signature interaction color (hover crimson
* on buttons), so it gets the brand-specific warm value rather
* than the schema fallback's pure red. --success is a muted
* teal-green (warm-shifted). --warn keeps the schema fallback;
* Cursor's marketing site has no native warn token. */
--success: #1f8a65; /* muted teal-green */
--warn: #eab308;
--danger: #cf2d56; /* warm crimson — hover signature */
/* ─── Typography ──────────────────────────────────────────────────
* Three voices, three roles:
* --font-display: CursorGothic for headings + UI labels
* --font-body: jjannon serif for editorial body (literary warmth)
* --font-mono: berkeleyMono for code, kbd, terminal text
* The three-voice system is the typographic signature; component
* CSS should never substitute fewer voices for "simplicity". */
--font-display: "CursorGothic", "CursorGothic Fallback", system-ui, "Helvetica Neue", Helvetica, Arial, sans-serif;
--font-body: "jjannon", "Iowan Old Style", "Palatino Linotype", "URW Palladio L", P052, ui-serif, Georgia, Cambria, "Times New Roman", Times, serif;
--font-mono: "berkeleyMono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
/* Type scale — distilled from DESIGN.md §Typography Hierarchy.
* Cursor has more than 8 sizes in production (caption 11, body
* sans 16, body serif sm 17.28, body serif 19.2, title small 22,
* sub-heading 26, section 36, hero 72); the schema's 8 slots
* cover the spine. 17.28px / 19.2px live inline in components.html
* where the body-serif distinction matters. */
--text-xs: 11px; /* caption, system micro */
--text-sm: 14px; /* button label, system caption */
--text-base: 16px; /* body sans, ui body */
--text-lg: 19.2px; /* body serif (1.20rem) */
--text-xl: 22px; /* title small */
--text-2xl: 26px; /* sub-heading */
--text-3xl: 36px; /* section heading */
--text-4xl: 72px; /* display hero */
/* Leading + tracking — DESIGN.md §Typography Hierarchy.
* --leading-tight=1.10 is Cursor's hero rhythm (matches the
* 72px display); brands with relaxed display rhythms set 1.20.
* --tracking-display=-0.03em is the 72px-normalized hero tracking
* (-2.16px / 72px). Smaller display sizes in components.html
* use proportional inline overrides. */
--leading-body: 1.5;
--leading-tight: 1.10;
--tracking-display: -0.03em;
/* ─── Spacing ─────────────────────────────────────────────────────
* 8px-rooted scale from DESIGN.md §Layout Principles (with the
* --space-1=4px tier kept for icon/dot rhythm). Cursor's
* sub-8px micro-scale (1.5/2/2.5/3/5/6) is component-internal —
* see the elev-ring / icon-rule decisions in components.html. */
--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 §Responsive Behavior collapsing
* strategy: "Section spacing: 80px+ → 48px → 32px on mobile". */
--section-y-desktop: 80px;
--section-y-tablet: 48px;
--section-y-phone: 32px;
/* ─── Radius ──────────────────────────────────────────────────────
* DESIGN.md §Border Radius Scale: comfortable 8px (primary
* buttons/cards/menus), featured 10px (larger containers), full
* pill 9999px (tags/filters). Schema's --radius-md gets 10px
* rather than 12px to honor the cursor-specific featured tier;
* --radius-lg keeps 12px because no Cursor surface uses 16px+. */
--radius-sm: 8px;
--radius-md: 10px;
--radius-lg: 12px;
--radius-pill: 9999px;
/* ─── Elevation ───────────────────────────────────────────────────
* Cursor's depth signature (DESIGN.md §Depth & Elevation): no
* crisp drop shadows. Border ring + diffused atmospheric lift.
* --elev-flat: pages, text blocks
* --elev-ring: standard card edge (1px warm-brown ring)
* --elev-raised: signature heavy-blur shadow with oklab ring,
* used for elevated cards / popovers / modals. */
--elev-flat: none;
--elev-ring: 0 0 0 1px var(--border);
--elev-raised:
0 28px 70px rgba(0, 0, 0, 0.14),
0 14px 32px rgba(0, 0, 0, 0.1),
0 0 0 1px var(--border);
/* ─── Focus ───────────────────────────────────────────────────────
* DESIGN.md §Interaction & Motion: "Shadow-based focus:
* rgba(0,0,0,0.1) 0px 4px 12px for depth-based focus indication.
* Consistent warm tone in all focus states — no cold blue focus
* rings." Implemented as box-shadow so it layers without
* affecting layout. */
--focus-ring: 0 4px 12px rgba(0, 0, 0, 0.1);
/* ─── Motion ──────────────────────────────────────────────────────
* DESIGN.md §Interaction & Motion specifies 150ms color / 200ms
* shadow with `ease` easing. Cursor uses the keyword `ease`
* rather than a custom cubic-bezier; component authors should
* not rebind to a more aggressive curve. */
--motion-fast: 150ms;
--motion-base: 200ms;
--ease-standard: ease;
/* ─── Layout ──────────────────────────────────────────────────────
* DESIGN.md §Grid & Container: "Max content width: approximately
* 1200px". Gutters not explicitly specified; using cross-brand
* defaults that match default. */
--container-max: 1200px;
--container-gutter-desktop: 24px;
--container-gutter-tablet: 16px;
--container-gutter-phone: 12px;
}