diff --git a/DESIGN.md b/DESIGN.md new file mode 100644 index 00000000..d1f3ce3d --- /dev/null +++ b/DESIGN.md @@ -0,0 +1,86 @@ +# Design System — gstack + +## Product Context +- **What this is:** Community website for gstack — a CLI tool that turns Claude Code into a virtual engineering team +- **Who it's for:** Developers discovering gstack, existing community members +- **Space/industry:** Developer tools (peers: Linear, Raycast, Warp, Zed) +- **Project type:** Community dashboard + marketing site + +## Aesthetic Direction +- **Direction:** Industrial/Utilitarian — function-first, data-dense, monospace as personality font +- **Decoration level:** Intentional — subtle noise/grain texture on surfaces for materiality +- **Mood:** Serious tool built by someone who cares about craft. Warm, not cold. The CLI heritage IS the brand. +- **Reference sites:** formulae.brew.sh (competitor, but ours is live and interactive), Linear (dark + restrained), Warp (warm accents) + +## Typography +- **Display/Hero:** Satoshi (Black 900 / Bold 700) — geometric with warmth, distinctive letterforms (the lowercase 'a' and 'g'). Not Inter, not Geist. Loaded from Fontshare CDN. +- **Body:** DM Sans (Regular 400 / Medium 500 / Semibold 600) — clean, readable, slightly friendlier than geometric display. Loaded from Google Fonts. +- **UI/Labels:** DM Sans (same as body) +- **Data/Tables:** JetBrains Mono (Regular 400 / Medium 500) — the personality font. Supports tabular-nums. Monospace should be prominent, not hidden in code blocks. Loaded from Google Fonts. +- **Code:** JetBrains Mono +- **Loading:** Google Fonts for DM Sans + JetBrains Mono, Fontshare for Satoshi. Use `display=swap`. +- **Scale:** + - Hero: 72px / clamp(40px, 6vw, 72px) + - H1: 48px + - H2: 32px + - H3: 24px + - H4: 18px + - Body: 16px + - Small: 14px + - Caption: 13px + - Micro: 12px + - Nano: 11px (JetBrains Mono labels) + +## Color +- **Approach:** Restrained — amber accent is rare and meaningful. Dashboard data gets the color; chrome stays neutral. +- **Primary (dark mode):** amber-500 #F59E0B — warm, energetic, reads as "terminal cursor" +- **Primary (light mode):** amber-600 #D97706 — darker for contrast against white backgrounds +- **Primary text accent (dark mode):** amber-400 #FBBF24 +- **Primary text accent (light mode):** amber-700 #B45309 +- **Neutrals:** Cool zinc grays + - zinc-50: #FAFAFA (lightest) + - zinc-400: #A1A1AA + - zinc-600: #52525B + - zinc-800: #27272A + - Surface (dark): #141414 + - Base (dark): #0C0C0C + - Surface (light): #FFFFFF + - Base (light): #FAFAF9 +- **Semantic:** success #22C55E, warning #F59E0B, error #EF4444, info #3B82F6 +- **Dark mode:** Default. Near-black base (#0C0C0C), surface cards at #141414, borders at #262626. +- **Light mode:** Warm stone base (#FAFAF9), white surface cards, stone borders (#E7E5E4). Amber accent shifts to amber-600 for contrast. + +## Spacing +- **Base unit:** 4px +- **Density:** Comfortable — not cramped (not Bloomberg Terminal), not spacious (not a marketing site) +- **Scale:** 2xs(2px) xs(4px) sm(8px) md(16px) lg(24px) xl(32px) 2xl(48px) 3xl(64px) + +## Layout +- **Approach:** Grid-disciplined for dashboard, editorial hero for landing page +- **Grid:** 12 columns at lg+, 1 column at mobile +- **Max content width:** 1200px (6xl) +- **Border radius:** sm:4px, md:8px, lg:12px, full:9999px + - Cards/panels: lg (12px) + - Buttons/inputs: md (8px) + - Badges/pills: full (9999px) + - Skill bars: sm (4px) + +## Motion +- **Approach:** Minimal-functional — only transitions that aid comprehension. The dashboard's live feed IS the motion. +- **Easing:** enter(ease-out / cubic-bezier(0.16,1,0.3,1)) exit(ease-in) move(ease-in-out) +- **Duration:** micro(50-100ms) short(150ms) medium(250ms) long(400ms) +- **Animated elements:** live feed dot pulse (2s infinite), skill bar fill (600ms ease-out), hover states (150ms) + +## Grain Texture +Apply a subtle noise overlay to the entire page for materiality: +- Dark mode: opacity 0.03 +- Light mode: opacity 0.02 +- Use SVG feTurbulence filter as a CSS background-image on body::after +- pointer-events: none, position: fixed, z-index: 9999 + +## Decisions Log +| Date | Decision | Rationale | +|------|----------|-----------| +| 2026-03-21 | Initial design system | Created by /design-consultation. Industrial aesthetic, warm amber accent, Satoshi + DM Sans + JetBrains Mono. | +| 2026-03-21 | Light mode amber-600 | amber-500 too bright/washed against white; amber-700 too brown/umber. amber-600 is the sweet spot. | +| 2026-03-21 | Grain texture | Adds materiality to flat dark surfaces. Prevents the "generic SaaS template" sameness. | diff --git a/extension/content.css b/extension/content.css index a5d3dd22..408b2c1b 100644 --- a/extension/content.css +++ b/extension/content.css @@ -1,7 +1,9 @@ -/* gstack browse — ref overlay + status pill styles */ +/* gstack browse — ref overlay + status pill styles + * Design system: DESIGN.md (amber accent, zinc neutrals) + */ #gstack-ref-overlays { - font-family: 'SF Mono', 'Fira Code', monospace !important; + font-family: 'JetBrains Mono', 'SF Mono', 'Fira Code', monospace !important; } /* Connection status pill — bottom-right corner */ @@ -14,13 +16,13 @@ align-items: center; gap: 6px; padding: 6px 12px; - background: rgba(10, 10, 10, 0.85); + background: rgba(12, 12, 12, 0.85); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); - border: 1px solid rgba(74, 222, 128, 0.3); - border-radius: 20px; + border: 1px solid rgba(245, 158, 11, 0.25); + border-radius: 9999px; color: #e0e0e0; - font-family: 'SF Mono', 'Fira Code', 'Cascadia Code', monospace; + font-family: 'JetBrains Mono', 'SF Mono', 'Fira Code', 'Cascadia Code', monospace; font-size: 11px; font-weight: 500; letter-spacing: 0.02em; @@ -38,8 +40,8 @@ width: 6px; height: 6px; border-radius: 50%; - background: #4ade80; - box-shadow: 0 0 6px rgba(74, 222, 128, 0.5); + background: #F59E0B; + box-shadow: 0 0 6px rgba(245, 158, 11, 0.5); flex-shrink: 0; } @@ -56,7 +58,7 @@ font-size: 10px; font-weight: 700; padding: 1px 4px; - border-radius: 3px; + border-radius: 4px; line-height: 14px; pointer-events: none; z-index: 2147483647; @@ -69,9 +71,9 @@ right: 12px; width: 220px; max-height: 300px; - background: rgba(10, 10, 10, 0.95); - border: 1px solid #333; - border-radius: 6px; + background: rgba(12, 12, 12, 0.95); + border: 1px solid #262626; + border-radius: 8px; overflow: hidden; pointer-events: auto; box-shadow: 0 4px 24px rgba(0, 0, 0, 0.5); @@ -80,9 +82,9 @@ .gstack-ref-panel-header { padding: 6px 10px; - background: #0f0f0f; - border-bottom: 1px solid #222; - color: #fff; + background: #141414; + border-bottom: 1px solid #262626; + color: #FAFAFA; font-weight: 600; font-size: 11px; } @@ -94,20 +96,20 @@ .gstack-ref-panel-row { padding: 3px 10px; - border-bottom: 1px solid #1a1a1a; + border-bottom: 1px solid #1f1f1f; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .gstack-ref-panel-id { - color: #4ade80; + color: #FBBF24; font-weight: 600; margin-right: 4px; } .gstack-ref-panel-role { - color: #888; + color: #A1A1AA; margin-right: 4px; } @@ -117,6 +119,6 @@ .gstack-ref-panel-more { padding: 4px 10px; - color: #666; + color: #52525B; font-style: italic; } diff --git a/extension/icons/icon-128.png b/extension/icons/icon-128.png index 7deb432e..bad5e886 100644 Binary files a/extension/icons/icon-128.png and b/extension/icons/icon-128.png differ diff --git a/extension/icons/icon-16.png b/extension/icons/icon-16.png index 273c0afc..e0f7b060 100644 Binary files a/extension/icons/icon-16.png and b/extension/icons/icon-16.png differ diff --git a/extension/icons/icon-48.png b/extension/icons/icon-48.png index 1678c43f..ee223d32 100644 Binary files a/extension/icons/icon-48.png and b/extension/icons/icon-48.png differ diff --git a/extension/popup.html b/extension/popup.html index f6a95583..e9959915 100644 --- a/extension/popup.html +++ b/extension/popup.html @@ -6,7 +6,7 @@ * { margin: 0; padding: 0; box-sizing: border-box; } body { width: 240px; - background: #0a0a0a; + background: #0C0C0C; color: #e0e0e0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif; font-size: 13px; @@ -15,29 +15,29 @@ h1 { font-size: 16px; font-weight: 700; - color: #fff; + color: #FAFAFA; margin-bottom: 16px; letter-spacing: -0.3px; } label { display: block; font-size: 12px; - color: #888; + color: #A1A1AA; margin-bottom: 4px; } input { width: 100%; padding: 8px; - background: #1a1a1a; - border: 1px solid #333; - border-radius: 4px; - color: #fff; - font-family: 'SF Mono', 'Fira Code', monospace; + background: #141414; + border: 1px solid #262626; + border-radius: 8px; + color: #FAFAFA; + font-family: 'JetBrains Mono', 'SF Mono', 'Fira Code', monospace; font-size: 13px; outline: none; - transition: border-color 0.15s; + transition: border-color 150ms; } - input:focus { border-color: #4ade80; } + input:focus { border-color: #F59E0B; } .status { margin: 12px 0; display: flex; @@ -48,35 +48,35 @@ width: 8px; height: 8px; border-radius: 50%; - background: #555; + background: #3f3f46; flex-shrink: 0; } - .dot.connected { background: #4ade80; } - .dot.error { background: #f87171; } + .dot.connected { background: #22C55E; } + .dot.error { background: #EF4444; } .dot.reconnecting { - background: #fbbf24; - animation: pulse 1.5s ease-in-out infinite; + background: #F59E0B; + animation: pulse 2s ease-in-out infinite; } @keyframes pulse { 0%, 100% { opacity: 0.4; } 50% { opacity: 1; } } - .status-text { color: #888; font-size: 12px; } - .status-text.connected { color: #4ade80; } - .details { color: #666; font-size: 11px; margin-top: 2px; } + .status-text { color: #A1A1AA; font-size: 12px; } + .status-text.connected { color: #22C55E; } + .details { color: #52525B; font-size: 11px; margin-top: 2px; } button { width: 100%; margin-top: 12px; padding: 8px; - background: #0a2a14; - border: 1px solid #4ade80; - border-radius: 4px; - color: #4ade80; + background: rgba(245, 158, 11, 0.1); + border: 1px solid #F59E0B; + border-radius: 8px; + color: #FBBF24; font-size: 13px; cursor: pointer; - transition: all 0.15s; + transition: all 150ms; } - button:hover { background: #0f3a1c; } + button:hover { background: rgba(245, 158, 11, 0.2); }