Skip to content

Commit 47bbd07

Browse files
committed
ui(website): redesign feature tour
1 parent 5fa22e0 commit 47bbd07

5 files changed

Lines changed: 405 additions & 140 deletions

File tree

apps/website/index.html

Lines changed: 118 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<link rel="stylesheet" href="/src/style.css" />
1313
</head>
1414
<body>
15-
<!-- Hero -->
15+
<!-- Hero + Product Viewer -->
1616
<section class="hero">
1717
<div class="hero-content fade-in-load">
1818
<img src="/logo.png" alt="Codelegate logo" class="hero-logo" />
@@ -22,10 +22,123 @@ <h1 class="hero-title">Codelegate</h1>
2222
Full Keyboard Navigation, on Mac/Linux.
2323
</p>
2424

25-
<div class="screencast-placeholder hero-screencast">
26-
<div class="screencast-inner">
27-
<svg class="play-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>
28-
<span>Screencast coming soon</span>
25+
<!-- Product Viewer -->
26+
<div class="pv-container">
27+
<!-- Left Nav -->
28+
<nav class="pv-nav">
29+
<div class="pv-nav-items">
30+
<button class="pv-nav-item active" data-tour="overview" data-shortcut="O">
31+
<span class="pv-nav-icon">
32+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>
33+
</span>
34+
<span class="pv-nav-label">Overview</span>
35+
<span class="pv-nav-shortcut" aria-hidden="true">O</span>
36+
</button>
37+
<button class="pv-nav-item" data-tour="agents" data-shortcut="A">
38+
<span class="pv-nav-icon">
39+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="3" width="20" height="14" rx="2" ry="2"/><line x1="8" y1="21" x2="16" y2="21"/><line x1="12" y1="17" x2="12" y2="21"/></svg>
40+
</span>
41+
<span class="pv-nav-label">Agent Support</span>
42+
<span class="pv-nav-shortcut" aria-hidden="true">A</span>
43+
</button>
44+
<button class="pv-nav-item" data-tour="worktree" data-shortcut="G">
45+
<span class="pv-nav-icon">
46+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="18" cy="18" r="3"/><circle cx="6" cy="6" r="3"/><path d="M13 6h3a2 2 0 0 1 2 2v7"/><path d="M6 9v12"/></svg>
47+
</span>
48+
<span class="pv-nav-label">Git Worktree</span>
49+
<span class="pv-nav-shortcut" aria-hidden="true">G</span>
50+
</button>
51+
<button class="pv-nav-item" data-tour="keyboard" data-shortcut="K">
52+
<span class="pv-nav-icon">
53+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="4" width="20" height="16" rx="2"/><path d="M6 8h.01"/><path d="M10 8h.01"/><path d="M14 8h.01"/></svg>
54+
</span>
55+
<span class="pv-nav-label">Keyboard Navigation</span>
56+
<span class="pv-nav-shortcut" aria-hidden="true">K</span>
57+
</button>
58+
<button class="pv-nav-item" data-tour="tui" data-shortcut="T">
59+
<span class="pv-nav-icon">
60+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="4 17 10 11 4 5"/><line x1="12" y1="19" x2="20" y2="19"/></svg>
61+
</span>
62+
<span class="pv-nav-label">All TUI Tools</span>
63+
<span class="pv-nav-shortcut" aria-hidden="true">T</span>
64+
</button>
65+
</div>
66+
<span class="pv-nav-hint">Ctrl+Shift for Navigation</span>
67+
</nav>
68+
69+
<!-- Stage -->
70+
<div class="pv-stage">
71+
<!-- Overview -->
72+
<div class="pv-tour active" data-tour-panel="overview">
73+
<div class="pv-tour-media">
74+
<div class="screencast-placeholder pv-screencast">
75+
<div class="screencast-inner">
76+
<svg class="play-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>
77+
<span>Screencast coming soon</span>
78+
</div>
79+
</div>
80+
</div>
81+
</div>
82+
83+
<!-- Agent Support -->
84+
<div class="pv-tour" data-tour-panel="agents">
85+
<div class="pv-tour-media">
86+
<div class="screencast-placeholder pv-screencast">
87+
<div class="screencast-inner">
88+
<svg class="play-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>
89+
</div>
90+
</div>
91+
</div>
92+
<div class="pv-tour-text">
93+
<h2 class="pv-tour-headline">Supports Claude Code and Codex CLI</h2>
94+
<p class="pv-tour-description">Run multiple agents side by side, each in its own workspace.<br />Dedicated terminal and built-in Git pane per session.<br />Pick up right where you left off with automatic session restore.</p>
95+
</div>
96+
</div>
97+
98+
<!-- Git Worktree -->
99+
<div class="pv-tour" data-tour-panel="worktree">
100+
<div class="pv-tour-media">
101+
<div class="screencast-placeholder pv-screencast">
102+
<div class="screencast-inner">
103+
<svg class="play-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>
104+
</div>
105+
</div>
106+
</div>
107+
<div class="pv-tour-text">
108+
<h2 class="pv-tour-headline">Git Worktree Management</h2>
109+
<p class="pv-tour-description">Let multiple agents work on the same repo at the same time.<br />Each session gets its own isolated worktree so nothing conflicts.</p>
110+
</div>
111+
</div>
112+
113+
<!-- Keyboard Navigation -->
114+
<div class="pv-tour" data-tour-panel="keyboard">
115+
<div class="pv-tour-media">
116+
<div class="screencast-placeholder pv-screencast">
117+
<div class="screencast-inner">
118+
<svg class="play-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>
119+
</div>
120+
</div>
121+
</div>
122+
<div class="pv-tour-text">
123+
<h2 class="pv-tour-headline">Full Keyboard Navigation</h2>
124+
<p class="pv-tour-description">Every action is a shortcut away.<br />Switch sessions, review diffs, commit, and manage branches.<br />Without ever reaching for the mouse.</p>
125+
</div>
126+
</div>
127+
128+
<!-- All TUI Tools -->
129+
<div class="pv-tour" data-tour-panel="tui">
130+
<div class="pv-tour-media">
131+
<div class="screencast-placeholder pv-screencast">
132+
<div class="screencast-inner">
133+
<svg class="play-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>
134+
</div>
135+
</div>
136+
</div>
137+
<div class="pv-tour-text">
138+
<h2 class="pv-tour-headline">Use Whatever All TUI Tools You Like</h2>
139+
<p class="pv-tour-description">Every session comes with a real terminal.<br />Dev server, lazygit, even zellij/tmux.<br />If it runs in your terminal, it runs here. No compromises.</p>
140+
</div>
141+
</div>
29142
</div>
30143
</div>
31144

@@ -48,74 +161,6 @@ <h1 class="hero-title">Codelegate</h1>
48161
</div>
49162
</section>
50163

51-
<!-- Feature 1: Agent Support -->
52-
<section class="feature-section">
53-
<div class="feature-layout fade-up">
54-
<div class="feature-text">
55-
<h2 class="feature-headline">Supports Claude Code<br />and Codex CLI</h2>
56-
<p class="feature-description">Run multiple agents side by side, each in its own workspace with a dedicated terminal and built-in Git pane. Pick up right where you left off with automatic session restore.</p>
57-
</div>
58-
<div class="feature-media">
59-
<div class="screencast-placeholder feature-screencast">
60-
<div class="screencast-inner">
61-
<svg class="play-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>
62-
</div>
63-
</div>
64-
</div>
65-
</div>
66-
</section>
67-
68-
<!-- Feature 2: Git Worktree -->
69-
<section class="feature-section">
70-
<div class="feature-layout feature-layout--reversed fade-up">
71-
<div class="feature-text">
72-
<h2 class="feature-headline">Git Worktree<br />Management</h2>
73-
<p class="feature-description">Let multiple agents work on the same repo at the same time. Each session gets its own isolated worktree so nothing conflicts.</p>
74-
</div>
75-
<div class="feature-media">
76-
<div class="screencast-placeholder feature-screencast">
77-
<div class="screencast-inner">
78-
<svg class="play-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>
79-
</div>
80-
</div>
81-
</div>
82-
</div>
83-
</section>
84-
85-
<!-- Feature 3: Keyboard Navigation -->
86-
<section class="feature-section">
87-
<div class="feature-layout fade-up">
88-
<div class="feature-text">
89-
<h2 class="feature-headline">Full Keyboard<br />Navigation</h2>
90-
<p class="feature-description">Every action is a shortcut away. Switch sessions, review diffs, commit, and manage branches without ever reaching for the mouse.</p>
91-
</div>
92-
<div class="feature-media">
93-
<div class="screencast-placeholder feature-screencast">
94-
<div class="screencast-inner">
95-
<svg class="play-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>
96-
</div>
97-
</div>
98-
</div>
99-
</div>
100-
</section>
101-
102-
<!-- Feature 4: TUI Tools -->
103-
<section class="feature-section">
104-
<div class="feature-layout feature-layout--reversed fade-up">
105-
<div class="feature-text">
106-
<h2 class="feature-headline">Use Whatever TUI<br />Tools You Like</h2>
107-
<p class="feature-description">Every session comes with a real terminal. Dev server, lazygit, even zellij/tmux - if it runs in your terminal, it runs here. No compromises.</p>
108-
</div>
109-
<div class="feature-media">
110-
<div class="screencast-placeholder feature-screencast">
111-
<div class="screencast-inner">
112-
<svg class="play-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>
113-
</div>
114-
</div>
115-
</div>
116-
</div>
117-
</section>
118-
119164
<!-- Footer -->
120165
<footer class="footer">
121166
<p>&copy; 2025 Codelegate. Open source on <a href="https://github.com/brucehsu/codelegate" target="_blank" rel="noopener">GitHub</a>.</p>

apps/website/ref.mov

18.7 MB
Binary file not shown.

apps/website/ref.png

343 KB
Loading

apps/website/src/main.js

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// Scroll fade-in
12
const observer = new IntersectionObserver(
23
(entries) => {
34
entries.forEach((entry) => {
@@ -11,3 +12,89 @@ const observer = new IntersectionObserver(
1112
);
1213

1314
document.querySelectorAll(".fade-up").forEach((el) => observer.observe(el));
15+
16+
// Product Viewer - tab switching with keyboard shortcuts
17+
const pvNav = document.querySelector(".pv-nav");
18+
const navItems = document.querySelectorAll(".pv-nav-item");
19+
const panels = new Map();
20+
let activeTour = "overview";
21+
let isAnimating = false;
22+
23+
// Build shortcut -> tour key map (keyed by KeyCode e.g. "KeyG")
24+
const shortcutMap = {};
25+
navItems.forEach((btn) => {
26+
const key = btn.dataset.tour;
27+
panels.set(key, document.querySelector(`[data-tour-panel="${key}"]`));
28+
if (btn.dataset.shortcut) {
29+
shortcutMap["Key" + btn.dataset.shortcut.toUpperCase()] = key;
30+
}
31+
});
32+
33+
function switchTour(key) {
34+
if (key === activeTour || isAnimating) return;
35+
isAnimating = true;
36+
37+
const oldNav = document.querySelector(`.pv-nav-item[data-tour="${activeTour}"]`);
38+
const newNav = document.querySelector(`.pv-nav-item[data-tour="${key}"]`);
39+
const oldPanel = panels.get(activeTour);
40+
const newPanel = panels.get(key);
41+
42+
// Update nav
43+
oldNav.classList.remove("active");
44+
newNav.classList.add("active");
45+
46+
// Fade out old
47+
oldPanel.classList.remove("active");
48+
oldPanel.style.opacity = "0";
49+
oldPanel.style.transform = "translateY(-16px)";
50+
51+
// Prep new off-screen
52+
newPanel.style.transition = "none";
53+
newPanel.style.opacity = "0";
54+
newPanel.style.transform = "translateY(16px)";
55+
newPanel.offsetHeight;
56+
newPanel.style.transition = "";
57+
58+
// Activate new
59+
newPanel.classList.add("active");
60+
61+
requestAnimationFrame(() => {
62+
newPanel.style.opacity = "";
63+
newPanel.style.transform = "";
64+
65+
setTimeout(() => {
66+
oldPanel.style.opacity = "";
67+
oldPanel.style.transform = "";
68+
isAnimating = false;
69+
}, 400);
70+
});
71+
72+
activeTour = key;
73+
}
74+
75+
// Click handlers
76+
navItems.forEach((btn) => {
77+
btn.addEventListener("click", () => {
78+
switchTour(btn.dataset.tour);
79+
});
80+
});
81+
82+
// Ctrl+Shift held = show shortcut badges and allow navigation
83+
document.addEventListener("keydown", (e) => {
84+
if (e.ctrlKey && e.shiftKey) {
85+
pvNav.classList.add("show-shortcuts");
86+
87+
const tour = shortcutMap[e.code];
88+
if (tour) {
89+
e.preventDefault();
90+
switchTour(tour);
91+
}
92+
}
93+
});
94+
95+
document.addEventListener("keyup", (e) => {
96+
// Only hide when both Ctrl and Shift are released
97+
if (!e.ctrlKey || !e.shiftKey) {
98+
pvNav.classList.remove("show-shortcuts");
99+
}
100+
});

0 commit comments

Comments
 (0)