From 58fa88e21051da0e1946d1588bba0edb0e4e4e6d Mon Sep 17 00:00:00 2001 From: vraspar Date: Sat, 28 Mar 2026 15:33:15 -0700 Subject: [PATCH] =?UTF-8?q?feat(website):=20Paper=20redesign=20=E2=80=94?= =?UTF-8?q?=20warm=20Muji-inspired=20aesthetic?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Complete visual direction change from dark Phosphor to warm Paper theme: - New color palette: cream background (#faf9f6), sage accent (#5a7a64) - Sticky header nav with Docs, Blog, GitHub links - Dark code blocks on light page (the visual signature) - 4 feature cards in 2x2 grid (Git, FTS5, MCP, Trails) - Clean CSS architecture diagram (no ASCII) - Static code demos (removed terminal typing animation) - Mobile hamburger menu with slide-out panel - Scroll reveal with gentle fade-in (12px, 500ms) - Inter for headings, JetBrains Mono for code only - All WCAG AA+ contrast ratios - JS reduced from ~210 lines to 70 lines - Replaced terminal.js with main.js Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- website/README.md | 45 ++-- website/index.html | 261 +++++++++--------- website/main.js | 70 +++++ website/style.css | 638 ++++++++++++++++++++++++-------------------- website/terminal.js | 214 --------------- 5 files changed, 577 insertions(+), 651 deletions(-) create mode 100644 website/main.js delete mode 100644 website/terminal.js diff --git a/website/README.md b/website/README.md index d4926c0..ad4758e 100644 --- a/website/README.md +++ b/website/README.md @@ -2,26 +2,28 @@ Static landing page for the [Brain CLI](https://github.com/vraspar/brain) project. +## Design: "Paper" + +Warm, Muji-inspired minimalism with cream backgrounds and sage green accents. Dark code blocks on a light page create the visual signature. No terminal animations, no dark-mode template energy. + ## Stack -- Plain HTML + CSS + vanilla JavaScript +- Plain HTML + CSS + vanilla JavaScript (~70 lines) - No frameworks, no build step, no dependencies -- Google Fonts: JetBrains Mono + Inter +- Google Fonts: Inter + JetBrains Mono ## Files ``` website/ -├── index.html # The entire page -├── style.css # All styles -├── terminal.js # Terminal typing animation (~170 lines) -└── README.md # This file ++-- index.html # The page ++-- style.css # Paper theme ++-- main.js # Scroll reveal, nav, copy button ++-- README.md # This file ``` ## Local preview -Open `index.html` in a browser, or use any static server: - ```bash cd website npx serve . @@ -31,24 +33,17 @@ python3 -m http.server 8000 ## Deploy to GitHub Pages -### Option 1: From `website/` directory - -1. Go to **Settings → Pages** in the GitHub repo -2. Set source to **Deploy from a branch** +1. Go to Settings > Pages in the GitHub repo +2. Set source to Deploy from a branch 3. Select branch `main` and folder `/website` -4. Save — site deploys to `https://vraspar.github.io/brain/` - -### Option 2: Copy to `docs/` (if Pages requires it) - -```bash -cp -r website/ docs/website/ -git add docs/website/ -git commit -m "deploy: website to GitHub Pages" -git push -``` +4. Save -Then configure Pages to serve from `/docs/website`. +## Color palette -## Design +- Page background: `#faf9f6` (warm cream) +- Card background: `#f2f0ec` (warm gray) +- Accent: `#5a7a64` (muted sage) +- Code blocks: `#2c2c2c` (dark) +- Text: `#3d3d3d` (charcoal) -Based on the Phosphor design spec. Dark monochrome theme with green (#4ade80) accent. All color combinations pass WCAG AA, most pass AAA. +All color combinations pass WCAG AA. diff --git a/website/index.html b/website/index.html index 1fa8d5c..6cde3b5 100644 --- a/website/index.html +++ b/website/index.html @@ -3,110 +3,126 @@ - brain — CLI-first knowledge sharing for dev teams + brain — CLI-first knowledge sharing for dev teams - + - + - + - - -
-
-
brain
-

- A CLI for sharing knowledge across a dev team.
- Markdown in git. Searchable via FTS5.
- Accessible to AI agents through MCP. -

- -
- $ npm install -g @vraspar/brain@alpha - -
- -
-
- -
+ + + +
+ +
+
+

brain

+

+ Share what your team knows.
+ A CLI that stores knowledge as markdown in git, makes it searchable with FTS5, and exposes it to your AI agent through MCP. +

+ +
+ $ npm install -g @vraspar/brain@alpha + +
+ +
+
$ brain search "kubernetes"
+
+Found 3 results: +┌────────────────────────┬────────┬───────┬───────────┐ +│ Title │ Author │ Type │ Tags │ +├────────────────────────┼────────┼───────┼───────────┤ +│ K8s Deployment Guide │ bob │ guide │ k8s │ +│ CI Pipeline │ carol │ guide │ ci, k8s │ +│ Helm Chart Patterns │ alice │ skill │ helm, k8s │ +└────────────────────────┴────────┴───────┴───────────┘
+
+
+
+ -
+
-

How it works

- -
-
-
1. Start
-
-
# First person creates a brain
-
$ brain init --name "Acme Engineering"
-
-✅ Brain "Acme Engineering" is ready!
-
 
-
# Teammates join it
-
$ brain connect https://github.com/acme/brain-hub.git
-
+ + +
+
01 — Start
+
+
# First person creates a brain
+
$ brain init --name "Acme Engineering"
+
✓ Brain "Acme Engineering" is ready!
+
 
+
# Teammates join it
+
$ brain connect https://github.com/acme/brain-hub.git
+
-
-
2. Add knowledge
-
-
# Push a single guide
-
$ brain push ./guide.md
-
-✅ Pushed: Docker Multi-Stage Builds +
+
02 — Add knowledge
+
+
# Push a single guide
+
$ brain push ./guide.md
+
✓ Pushed: Docker Multi-Stage Builds Tags: docker (auto-detected)
-
 
-
# Or import docs from a repo
-
$ brain ingest https://github.com/acme/docs.git
-
-✅ Ingested 24 entries from acme/docs
-
+
 
+
# Or import docs from a repo
+
$ brain ingest https://github.com/acme/docs.git
+
✓ Ingested 24 entries from acme/docs
+
-
-
3. Discover
-
-
$ brain search "kubernetes"
-
-Found 3 results: -┌────────────────────────┬────────┬───────┬───────────┐ -│ Title │ Author │ Type │ Tags │ -├────────────────────────┼────────┼───────┼───────────┤ -│ K8s Deployment Guide │ bob │ guide │ k8s │ -│ CI Pipeline │ carol │ guide │ ci, k8s │ -│ Helm Chart Patterns │ alice │ skill │ helm, k8s │ -└────────────────────────┴────────┴───────┴───────────┘
-
+
+
03 — Discover
+
+
$ brain trail kubernetes
+
K8s Deployment Guide + → Helm Chart Patterns (tags: k8s) + → CI Pipeline (tags: k8s, ci)
-
+
-

Why brain?

+
@@ -121,27 +137,26 @@

FTS5 search

MCP-native

10 tools and 2 resources via Model Context Protocol. Your AI agent can search, read, edit, and publish entries. brain serve starts the server.

+
+

Knowledge trails

+

Auto-computed links between entries. brain trail <topic> follows connections across your team’s knowledge graph.

+
-

Also: repo ingest · freshness scoring · knowledge trails · Obsidian vault · 20 commands

- -

- Zero infrastructure. One command to start.
- brain connect https://github.com/acme/brain-hub.git -

+

Also: repo ingest · freshness scoring · Obsidian vault · interactive search · 20 commands · --format json

-
+
-

Works with your AI agent

+ -

Add to your MCP client config:

+

Add brain to your MCP client:

-
-
mcp.json
-
{ +
+
mcp.json
+
{ "mcpServers": { "brain": { "command": "brain", @@ -151,28 +166,25 @@

Works with your AI agent

}
-

10 tools: push_knowledge · search_knowledge · whats_new · get_entry · brain_stats · get_recommendations · update_entry · list_entries · explore_topic · retract_entry
2 resources: brain://digest · brain://stats

- -

Your agent can search team knowledge, publish findings, and check what's new.

- -

Claude · Copilot · Cursor · Windsurf

+

Works with Claude · Copilot · Cursor · Windsurf

+

10 tools · 2 resources · Your agent can search team knowledge, publish findings, and check what’s new.

-
+
-

Quick start

+ -
+
# Install
-
$ npm install -g @vraspar/brain@alpha
+
$ npm install -g @vraspar/brain@alpha
 
# Create a brain
-
$ brain init --name "My Team"
+
$ brain init --name "My Team"
 
# Or join an existing one
-
$ brain connect <url>
+
$ brain connect <url>

Requires Node.js 20+ and git.

@@ -180,40 +192,28 @@

Quick start

-
+
-

Under the hood

- -
-       brain push / brain search / brain digest
-                        │
-                 ┌──────▼──────┐
-                 │     CLI     │
-                 └──────┬──────┘
-                        │
-       ┌────────────────┼────────────────┐
-       ▼                ▼                ▼
-  ┌──────────┐   ┌────────────┐   ┌──────────┐
-  │ Git repo │   │ SQLite    │   │ Receipts │
-  │ (storage)│   │ FTS5      │   │ (analytics│
-  │          │   │ (search)   │   │          │
-  └──────────┘   └────────────┘   └──────────┘
-
- -
-
- Storage - Markdown + YAML frontmatter in a git repo + + +
+
+ Git repo + storage
-
- Search - FTS5 virtual table, rebuilt on sync + +
+ SQLite FTS5 + search
-
- Analytics - JSON receipts, eventually consistent + +
+ Receipts + analytics
+ +

Entries are markdown with YAML frontmatter, stored in a git repo. The search index is a local SQLite cache, rebuilt from source on every sync. Read receipts track who reads what.

@@ -222,15 +222,16 @@

Under the hood

- + diff --git a/website/main.js b/website/main.js new file mode 100644 index 0000000..1cf3180 --- /dev/null +++ b/website/main.js @@ -0,0 +1,70 @@ +(function () { + 'use strict'; + + var prefersReduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches; + + // Scroll reveal + var reveals = document.querySelectorAll('.reveal'); + if (reveals.length > 0 && !prefersReduced) { + var observer = new IntersectionObserver( + function (entries) { + entries.forEach(function (entry) { + if (entry.isIntersecting) { + entry.target.classList.add('visible'); + observer.unobserve(entry.target); + } + }); + }, + { threshold: 0.1 } + ); + reveals.forEach(function (el) { observer.observe(el); }); + } else { + reveals.forEach(function (el) { el.classList.add('visible'); }); + } + + // Nav border on scroll + var nav = document.querySelector('.site-nav'); + var sentinel = document.querySelector('.nav-sentinel'); + if (nav && sentinel) { + var navObserver = new IntersectionObserver( + function (entries) { + entries.forEach(function (entry) { + nav.classList.toggle('scrolled', !entry.isIntersecting); + }); + }, + { threshold: 0 } + ); + navObserver.observe(sentinel); + } + + // Mobile nav toggle + var toggle = document.querySelector('.nav-toggle'); + var mobileMenu = document.querySelector('.mobile-menu'); + if (toggle && mobileMenu) { + toggle.addEventListener('click', function () { + var open = toggle.classList.toggle('open'); + mobileMenu.classList.toggle('open', open); + mobileMenu.setAttribute('aria-hidden', String(!open)); + toggle.setAttribute('aria-expanded', String(open)); + }); + } + + // Copy button + var copyBtns = document.querySelectorAll('.copy-btn'); + copyBtns.forEach(function (btn) { + btn.addEventListener('click', function () { + var text = btn.getAttribute('data-copy'); + if (!text) return; + navigator.clipboard.writeText(text).then(function () { + btn.classList.add('copied'); + btn.innerHTML = + ''; + setTimeout(function () { + btn.classList.remove('copied'); + btn.innerHTML = + ''; + }, 2000); + }); + }); + }); +})(); diff --git a/website/style.css b/website/style.css index 571f811..a8fd414 100644 --- a/website/style.css +++ b/website/style.css @@ -1,30 +1,28 @@ :root { /* Background */ - --bg-primary: #0a0a0a; - --bg-surface: #141414; - --bg-elevated: #1a1a1a; - --border: #262626; - --border-focus: #333333; + --bg-page: #faf9f6; + --bg-card: #f2f0ec; + --bg-nav: rgba(250, 249, 246, 0.85); + --border: #e5e2dc; + --border-hover: #d1cdc5; /* Text */ - --text-primary: #fafafa; - --text-body: #d4d4d8; - --text-secondary: #a1a1aa; - --text-muted: #71717a; - - /* Accent (Phosphor Green) */ - --accent: #4ade80; - --accent-bright: #86efac; - --accent-dim: #166534; - --accent-glow: rgba(74, 222, 128, 0.1); - - /* Terminal */ - --term-bg: #0d0d0d; - --term-border: #2a2a2a; - --term-prompt: #4ade80; - --term-cursor: #4ade80; - --term-output: #d4d4d8; - --term-comment: #6b7280; + --text-heading: #1a1a1a; + --text-body: #3d3d3d; + --text-secondary: #6b6b6b; + --text-muted: #9a9a9a; + + /* Accent (Sage) */ + --accent: #5a7a64; + --accent-light: #7a9a84; + --accent-bg: #eef3ef; + + /* Code */ + --code-bg: #2c2c2c; + --code-text: #e8e8e8; + --code-prompt: #7ab086; + --code-comment: #808080; + --code-border: #3a3a3a; } *, @@ -43,9 +41,9 @@ html { body { font-family: 'Inter', system-ui, -apple-system, sans-serif; font-weight: 400; - line-height: 1.7; + line-height: 1.75; color: var(--text-body); - background-color: var(--bg-primary); + background-color: var(--bg-page); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } @@ -57,10 +55,10 @@ body { left: 1rem; padding: 0.5rem 1rem; background: var(--accent); - color: var(--bg-primary); + color: #fff; font-weight: 600; - border-radius: 4px; - z-index: 100; + border-radius: 8px; + z-index: 200; text-decoration: none; } @@ -70,7 +68,7 @@ body { /* Layout */ .container { - max-width: 1100px; + max-width: 960px; margin: 0 auto; padding: 0 1.5rem; } @@ -81,112 +79,234 @@ body { } } -@media (min-width: 1100px) { - .container { - padding: 0; - } -} - -section { - padding: 5rem 0; +/* Navigation */ +.nav-sentinel { + height: 0; + position: absolute; + top: 0; } -/* Typography */ -h1, h2, h3, h4 { - font-family: 'JetBrains Mono', 'Fira Code', 'Cascadia Code', monospace; - color: var(--text-primary); - letter-spacing: -0.02em; - line-height: 1.3; +.site-nav { + position: sticky; + top: 0; + z-index: 100; + background: var(--bg-nav); + backdrop-filter: blur(12px); + -webkit-backdrop-filter: blur(12px); + border-bottom: 1px solid transparent; + transition: border-color 200ms ease; + height: 56px; } -h1 { - font-size: 3.5rem; - font-weight: 700; +.site-nav.scrolled { + border-bottom-color: var(--border); } -h2 { - font-size: 1.75rem; - font-weight: 700; - margin-bottom: 2.5rem; - text-align: center; +.nav-inner { + display: flex; + align-items: center; + justify-content: space-between; + height: 56px; } -h3 { +.nav-wordmark { + font-family: 'JetBrains Mono', monospace; font-size: 1.1rem; font-weight: 600; + color: var(--accent); + text-decoration: none; +} + +.nav-wordmark:hover { + color: var(--accent-light); +} + +.nav-links { + display: flex; + gap: 2rem; +} + +.nav-links a { + font-size: 0.875rem; + color: var(--text-secondary); + text-decoration: none; + transition: color 150ms ease; +} + +.nav-links a:hover { + color: var(--text-heading); +} + +.nav-toggle { + display: none; + background: none; + border: none; + cursor: pointer; + padding: 4px; + width: 28px; + height: 28px; + flex-direction: column; + justify-content: center; + gap: 5px; +} + +.nav-toggle span { + display: block; + width: 20px; + height: 2px; + background: var(--text-secondary); + border-radius: 1px; + transition: transform 200ms ease, opacity 200ms ease; +} + +.nav-toggle.open span:nth-child(1) { + transform: translateY(7px) rotate(45deg); +} + +.nav-toggle.open span:nth-child(2) { + opacity: 0; } +.nav-toggle.open span:nth-child(3) { + transform: translateY(-7px) rotate(-45deg); +} + +/* Mobile menu */ +.mobile-menu { + display: none; + position: fixed; + top: 56px; + left: 0; + right: 0; + background: var(--bg-page); + border-bottom: 1px solid var(--border); + padding: 1.5rem; + z-index: 99; + flex-direction: column; + gap: 1rem; +} + +.mobile-menu.open { + display: flex; +} + +.mobile-menu a { + font-size: 1rem; + color: var(--text-body); + text-decoration: none; + padding: 0.5rem 0; +} + +/* Typography */ +h1, h2, h3 { + font-family: 'Inter', system-ui, sans-serif; + color: var(--text-heading); + line-height: 1.3; +} + +h1 { font-size: 2.75rem; font-weight: 600; letter-spacing: -0.03em; } +h2 { font-size: 1.75rem; font-weight: 600; letter-spacing: -0.02em; } +h3 { font-size: 1.15rem; font-weight: 600; letter-spacing: -0.01em; } + p { - max-width: 65ch; - margin-left: auto; - margin-right: auto; + max-width: 60ch; } a { color: var(--text-body); text-decoration: none; - transition: color 200ms ease; + transition: color 150ms ease; } a:hover { color: var(--accent); - text-decoration: underline; } a:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; - border-radius: 2px; + border-radius: 4px; +} + +code { + font-family: 'JetBrains Mono', monospace; + font-size: 0.875em; + background: var(--bg-card); + padding: 0.15em 0.4em; + border-radius: 4px; + color: var(--accent); +} + +/* Section */ +.section { + padding: 6rem 0 4rem; +} + +.section-label { + font-family: 'JetBrains Mono', monospace; + font-size: 0.75rem; + font-weight: 500; + letter-spacing: 0.05em; + text-transform: uppercase; + color: var(--text-muted); + margin-bottom: 2.5rem; +} + +.section-desc { + color: var(--text-body); + font-size: 1rem; + line-height: 1.75; + margin-bottom: 1.5rem; } /* Hero */ .hero { - padding: 6rem 0 4rem; - text-align: center; + padding: 8rem 0 4rem; } .hero-wordmark { font-family: 'JetBrains Mono', monospace; - font-size: 4rem; - font-weight: 700; + font-size: 2.75rem; + font-weight: 600; color: var(--accent); - margin-bottom: 1.5rem; letter-spacing: -0.03em; + margin-bottom: 1.5rem; } .hero-subtitle { - font-size: 1.15rem; - color: var(--text-secondary); - line-height: 1.8; + font-size: 1.25rem; + color: var(--text-heading); + line-height: 1.6; margin-bottom: 2.5rem; - margin-left: auto; - margin-right: auto; + max-width: 48ch; } -.hero-subtitle span { - color: var(--text-body); +.hero-detail { + color: var(--text-secondary); + font-size: 1.05rem; } -.install-block { +/* Install pill */ +.install-pill { display: inline-flex; align-items: center; gap: 0.75rem; - background: var(--term-bg); - border: 1px solid var(--term-border); - border-radius: 6px; - padding: 0.75rem 1.25rem; - margin-bottom: 3rem; - position: relative; + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: 999px; + padding: 0.5rem 1.25rem; + margin-bottom: 2.5rem; } -.install-block code { - font-family: 'JetBrains Mono', monospace; - font-size: 0.95rem; - color: var(--text-primary); +.install-pill code { + background: none; + padding: 0; + font-size: 0.875rem; + color: var(--text-heading); } -.install-block .prompt { - color: var(--term-prompt); +.install-pill .prompt { + color: var(--accent); } .copy-btn { @@ -195,293 +315,228 @@ a:focus-visible { cursor: pointer; padding: 4px; color: var(--text-muted); - transition: color 200ms ease; + transition: color 150ms ease; display: flex; align-items: center; } -.copy-btn:hover { - color: var(--accent); -} +.copy-btn:hover { color: var(--accent); } .copy-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; - border-radius: 2px; -} - -.copy-btn.copied { - color: var(--accent); -} - -.hero-links { - display: flex; - justify-content: center; - gap: 1.5rem; - margin-top: 2rem; + border-radius: 4px; } -.hero-links a { - color: var(--text-secondary); - font-size: 0.9rem; -} +.copy-btn.copied { color: var(--accent); } -/* Terminal window */ -.terminal { - background: var(--term-bg); - border: 1px solid var(--term-border); - border-radius: 6px; - padding: 1.5rem; +/* Code blocks (dark on light page) */ +.code-block { + background: var(--code-bg); + color: var(--code-text); + border: 1px solid var(--code-border); + border-radius: 8px; + padding: 1.25rem 1.5rem; font-family: 'JetBrains Mono', monospace; font-size: 0.85rem; - line-height: 1.5; + line-height: 1.6; overflow-x: auto; - text-align: left; - box-shadow: 0 0 60px var(--accent-glow); - transition: border-color 200ms ease; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06); position: relative; + white-space: pre; } -.terminal:hover { - border-color: var(--border-focus); -} - -.terminal-title { - position: absolute; - top: 0; - left: 0; - padding: 0.4rem 1rem; - font-size: 0.75rem; - color: var(--text-muted); - border-bottom: 1px solid var(--term-border); - border-right: 1px solid var(--term-border); - border-radius: 6px 0 6px 0; +.code-block--narrow { + max-width: 560px; } -.terminal .prompt { - color: var(--term-prompt); +.code-block .prompt { + color: var(--code-prompt); user-select: none; } -.terminal .command { - color: var(--text-primary); +.code-block .cmd { + color: var(--code-text); } -.terminal .output { - color: var(--term-output); +.code-block .code-output { + color: #c0c0c0; white-space: pre; } -.terminal .comment { - color: var(--term-comment); -} - -.terminal .cursor { - display: inline-block; - width: 0.55em; - height: 1.1em; - background: var(--term-cursor); - vertical-align: text-bottom; - animation: blink 1s step-end infinite; -} - -@keyframes blink { - 50% { opacity: 0; } +.code-block .comment { + color: var(--code-comment); } -.hero .terminal { - max-width: 700px; - margin: 0 auto; - min-height: 260px; +.code-file-label { + position: absolute; + top: 0; + left: 0; + padding: 0.35rem 0.85rem; + font-size: 0.7rem; + color: var(--code-comment); + border-bottom: 1px solid var(--code-border); + border-right: 1px solid var(--code-border); + border-radius: 8px 0 8px 0; } -/* How it works */ -.steps-grid { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 1.5rem; - margin-bottom: 1.5rem; +/* Steps */ +.step { + margin-bottom: 2.5rem; } -.step-full { - grid-column: 1 / -1; +.step-label { + font-family: 'Inter', sans-serif; + font-size: 1rem; + font-weight: 500; + color: var(--text-heading); + margin-bottom: 1rem; } -.step-label { +.step-num { font-family: 'JetBrains Mono', monospace; - font-size: 0.8rem; color: var(--accent); - margin-bottom: 0.75rem; font-weight: 600; } -/* Why Brain cards */ +/* Feature cards */ .cards-grid { display: grid; - grid-template-columns: repeat(3, 1fr); - gap: 1.5rem; - margin-bottom: 2.5rem; + grid-template-columns: 1fr 1fr; + gap: 1.25rem; + margin-bottom: 2rem; } .card { + background: var(--bg-card); border: 1px solid var(--border); - border-radius: 4px; - padding: 1.5rem; + border-radius: 12px; + padding: 2rem; transition: border-color 200ms ease; } .card:hover { - border-color: var(--accent); + border-color: var(--border-hover); } .card h3 { color: var(--accent); - font-family: 'JetBrains Mono', monospace; - font-size: 1rem; - font-weight: 600; margin-bottom: 0.75rem; } .card p { font-size: 0.93rem; + line-height: 1.65; color: var(--text-body); - line-height: 1.6; - margin-left: 0; - margin-right: 0; } -.section-also { - text-align: center; - font-family: 'JetBrains Mono', monospace; - font-size: 0.85rem; - color: var(--text-muted); - margin: 0 auto 2rem; -} - -.section-punch { - text-align: center; - color: var(--text-secondary); - font-size: 1rem; - margin-left: auto; - margin-right: auto; -} - -.section-punch strong { - color: var(--text-primary); +.card code { + background: rgba(0, 0, 0, 0.04); } -.section-punch code { +.also-line { font-family: 'JetBrains Mono', monospace; - color: var(--accent); - font-size: 0.9rem; + font-size: 0.8rem; + color: var(--text-muted); + text-align: center; } /* Agent integration */ -.agent-section .terminal { - max-width: 560px; - margin: 0 auto 2rem; -} - -.agent-tools { - text-align: center; +.agent-meta { font-family: 'JetBrains Mono', monospace; font-size: 0.85rem; - color: var(--text-secondary); - margin-bottom: 1.5rem; - margin-left: auto; - margin-right: auto; -} - -.agent-desc { - text-align: center; - color: var(--text-body); - margin-bottom: 1.5rem; - max-width: 50ch; - margin-left: auto; - margin-right: auto; -} - -.agent-clients { - text-align: center; - font-family: 'JetBrains Mono', monospace; - font-size: 0.9rem; color: var(--text-muted); - margin-left: auto; - margin-right: auto; + margin-bottom: 1rem; } /* Quick start */ -.quick-start .terminal { - max-width: 700px; - margin: 0 auto; -} - -.quick-start .prereqs { +.prereqs { margin-top: 1rem; font-size: 0.85rem; color: var(--text-muted); - text-align: center; } /* Architecture */ -.arch-pre { - font-family: 'JetBrains Mono', monospace; - font-size: 0.8rem; - line-height: 1.4; - color: var(--text-primary); - max-width: 600px; - margin: 0 auto 2rem; - overflow-x: auto; +.arch-flow { + display: flex; + align-items: center; + justify-content: center; + gap: 0; + margin-bottom: 2rem; + flex-wrap: wrap; } -.arch-pre .arch-accent { +.arch-box { + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: 12px; + padding: 1.25rem 1.5rem; + text-align: center; + display: flex; + flex-direction: column; + gap: 0.25rem; + min-width: 150px; +} + +.arch-name { + font-family: 'JetBrains Mono', monospace; + font-size: 0.85rem; + font-weight: 600; color: var(--accent); } -.arch-notes { - display: grid; - grid-template-columns: repeat(3, 1fr); - gap: 1.5rem; - max-width: 700px; - margin: 0 auto; +.arch-role { + font-size: 0.8rem; + color: var(--text-muted); } -.arch-note { - font-size: 0.85rem; - text-align: center; +.arch-arrow { + font-size: 1.25rem; + color: var(--text-muted); + padding: 0 1rem; } -.arch-note strong { - color: var(--text-primary); - font-family: 'JetBrains Mono', monospace; - font-weight: 600; - display: block; - margin-bottom: 0.25rem; - font-size: 0.8rem; +.arch-desc { + max-width: 55ch; + margin-left: auto; + margin-right: auto; + text-align: center; } /* Footer */ .site-footer { padding: 3rem 0; text-align: center; + border-top: 1px solid var(--border); +} + +.footer-meta { + font-size: 0.8rem; color: var(--text-muted); - font-size: 0.85rem; + margin-bottom: 0.5rem; } .footer-links { - margin-top: 0.5rem; + display: flex; + justify-content: center; + gap: 1.5rem; } .footer-links a { + font-size: 0.8rem; color: var(--text-muted); - margin: 0 0.5rem; +} + +.footer-links a:hover { + color: var(--accent); } /* Scroll reveal */ .reveal { opacity: 0; - transform: translateY(20px); - transition: opacity 400ms ease-out, transform 400ms ease-out; + transform: translateY(12px); + transition: opacity 500ms cubic-bezier(0.25, 0.1, 0.25, 1), + transform 500ms cubic-bezier(0.25, 0.1, 0.25, 1); } .reveal.visible { @@ -497,45 +552,64 @@ a:focus-visible { transition: none; } - .terminal .cursor { - animation: none; - opacity: 1; + html { + scroll-behavior: auto; } } /* Responsive */ @media (max-width: 768px) { - h1, .hero-wordmark { - font-size: 2.5rem; + .hero { + padding: 6rem 0 3rem; } - h2 { - font-size: 1.4rem; + .hero-wordmark { + font-size: 2rem; } - section { - padding: 3.5rem 0; + .hero-subtitle { + font-size: 1.1rem; } - .steps-grid { - grid-template-columns: 1fr; + .section { + padding: 4rem 0 2.5rem; + } + + .section-label { + margin-bottom: 1.5rem; } .cards-grid { grid-template-columns: 1fr; } - .arch-notes { - grid-template-columns: 1fr; + .code-block { + font-size: 0.78rem; + padding: 1rem 1.25rem; } - .arch-pre { - font-size: 0.7rem; - overflow-x: auto; + .nav-links { + display: none; } - .terminal { - font-size: 0.78rem; + .nav-toggle { + display: flex; + } + + .arch-flow { + flex-direction: column; + gap: 0; + } + + .arch-arrow { + transform: rotate(90deg); + padding: 0.5rem 0; + } + + .arch-box { + min-width: unset; + width: 100%; + max-width: 200px; } .container { @@ -543,8 +617,8 @@ a:focus-visible { } } -@media (min-width: 769px) and (max-width: 1024px) { +@media (min-width: 769px) and (max-width: 960px) { .cards-grid { - grid-template-columns: 1fr 1fr; + gap: 1rem; } } diff --git a/website/terminal.js b/website/terminal.js deleted file mode 100644 index c008bca..0000000 --- a/website/terminal.js +++ /dev/null @@ -1,214 +0,0 @@ -(function () { - 'use strict'; - - var TYPING_SPEED = 35; - var PAUSE_BETWEEN = 800; - - var DEMO_SEQUENCE = [ - { - command: 'brain ingest https://github.com/acme/docs.git', - output: - '🔍 Scanning https://github.com/acme/docs.git...\n' + - ' Found 32 documentation files\n' + - '\n' + - '✅ Ingested 24 entries from acme/docs\n' + - ' ⚠ 8 skipped (duplicate slug)', - pauseAfter: 2500, - }, - { - command: 'brain search "kubernetes"', - output: - 'Found 3 results:\n' + - '┌────────────────────────┬────────┬───────┬───────────┐\n' + - '│ Title │ Author │ Type │ Tags │\n' + - '├────────────────────────┼────────┼───────┼───────────┤\n' + - '│ K8s Deployment Guide │ bob │ guide │ k8s │\n' + - '│ CI Pipeline │ carol │ guide │ ci, k8s │\n' + - '│ Helm Chart Patterns │ alice │ skill │ helm, k8s │\n' + - '└────────────────────────┴────────┴───────┴───────────┘', - pauseAfter: 2500, - }, - { - command: 'brain push ./guide.md', - output: - '✅ Pushed: Docker Multi-Stage Builds\n' + - ' Tags: docker (auto-detected)', - pauseAfter: 2000, - }, - { - command: 'brain trail kubernetes', - output: - 'K8s Deployment Guide\n' + - ' → Helm Chart Patterns (tags: k8s)\n' + - ' → CI Pipeline (tags: k8s, ci)', - pauseAfter: 2500, - }, - ]; - - var terminal = document.getElementById('hero-terminal'); - if (!terminal) return; - - var prefersReduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches; - var isPaused = false; - var animationTimer = null; - - if (prefersReduced) { - showStaticDemos(); - return; - } - - terminal.addEventListener('mouseenter', function () { isPaused = true; }); - terminal.addEventListener('mouseleave', function () { isPaused = false; }); - - runSequence(); - - function showStaticDemos() { - var html = ''; - for (var i = 0; i < DEMO_SEQUENCE.length; i++) { - var step = DEMO_SEQUENCE[i]; - html += - '
$ ' + - escapeHtml(step.command) + - '
' + - escapeHtml(step.output) + - '
'; - if (i < DEMO_SEQUENCE.length - 1) html += '
 
'; - } - terminal.innerHTML = html; - } - - function runSequence() { - var stepIndex = 0; - - function nextStep() { - if (stepIndex >= DEMO_SEQUENCE.length) { - animationTimer = setTimeout(function () { - terminal.innerHTML = ''; - stepIndex = 0; - nextStep(); - }, 3000); - return; - } - - var step = DEMO_SEQUENCE[stepIndex]; - typeCommand(step.command, function () { - appendOutput(step.output); - stepIndex++; - animationTimer = setTimeout(function () { - waitForUnpause(nextStep); - }, step.pauseAfter); - }); - } - - nextStep(); - } - - function waitForUnpause(callback) { - if (!isPaused) { - callback(); - return; - } - var check = setInterval(function () { - if (!isPaused) { - clearInterval(check); - callback(); - } - }, 100); - } - - function typeCommand(text, callback) { - var lineEl = document.createElement('div'); - var promptSpan = document.createElement('span'); - promptSpan.className = 'prompt'; - promptSpan.textContent = '$ '; - lineEl.appendChild(promptSpan); - - var cmdSpan = document.createElement('span'); - cmdSpan.className = 'command'; - lineEl.appendChild(cmdSpan); - - var cursorSpan = document.createElement('span'); - cursorSpan.className = 'cursor'; - cursorSpan.innerHTML = ' '; - lineEl.appendChild(cursorSpan); - - terminal.appendChild(lineEl); - - var charIndex = 0; - - function typeNext() { - if (isPaused) { - animationTimer = setTimeout(typeNext, 100); - return; - } - if (charIndex < text.length) { - cmdSpan.textContent += text[charIndex]; - charIndex++; - animationTimer = setTimeout(typeNext, TYPING_SPEED); - } else { - cursorSpan.remove(); - animationTimer = setTimeout(callback, PAUSE_BETWEEN); - } - } - - typeNext(); - } - - function appendOutput(text) { - var outputEl = document.createElement('div'); - outputEl.className = 'output'; - outputEl.textContent = text; - outputEl.style.whiteSpace = 'pre'; - terminal.appendChild(outputEl); - - var spacer = document.createElement('div'); - spacer.innerHTML = ' '; - terminal.appendChild(spacer); - } - - function escapeHtml(str) { - return str - .replace(/&/g, '&') - .replace(//g, '>') - .replace(/\n/g, '\n'); - } - - // Scroll reveal - var reveals = document.querySelectorAll('.reveal'); - if (reveals.length > 0 && !prefersReduced) { - var observer = new IntersectionObserver( - function (entries) { - entries.forEach(function (entry) { - if (entry.isIntersecting) { - entry.target.classList.add('visible'); - observer.unobserve(entry.target); - } - }); - }, - { threshold: 0.15 } - ); - reveals.forEach(function (el) { observer.observe(el); }); - } else { - reveals.forEach(function (el) { el.classList.add('visible'); }); - } - - // Copy button - var copyBtns = document.querySelectorAll('.copy-btn'); - copyBtns.forEach(function (btn) { - btn.addEventListener('click', function () { - var text = btn.getAttribute('data-copy'); - if (!text) return; - navigator.clipboard.writeText(text).then(function () { - btn.classList.add('copied'); - btn.innerHTML = - ''; - setTimeout(function () { - btn.classList.remove('copied'); - btn.innerHTML = - ''; - }, 2000); - }); - }); - }); -})();