Skip to content

Commit 2e61d81

Browse files
super3claude
andcommitted
Add interactive terminal demo with split panes and tab navigation
- Create split terminal simulation showing mdtail installation and usage - Show npm install command on right pane with realistic output - Display mdtail *.md with tab navigation between README.md and TODO.md - Match actual app layout with tab bar and navigation instructions - Use CSS overflow handling to prevent horizontal scrollbars - Auto-switch between tabs after 3 seconds to demonstrate navigation 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent cef4e13 commit 2e61d81

1 file changed

Lines changed: 384 additions & 0 deletions

File tree

demo.html

Lines changed: 384 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,384 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>mdtail - Split Terminal Demo</title>
7+
<style>
8+
* {
9+
margin: 0;
10+
padding: 0;
11+
box-sizing: border-box;
12+
}
13+
14+
body {
15+
background: #1e1e1e;
16+
font-family: 'Monaco', 'Menlo', 'Courier New', monospace;
17+
display: flex;
18+
justify-content: center;
19+
align-items: center;
20+
min-height: 100vh;
21+
padding: 20px;
22+
}
23+
24+
.terminal-container {
25+
background: #000;
26+
border-radius: 8px;
27+
box-shadow: 0 20px 60px rgba(0,0,0,0.5);
28+
overflow: hidden;
29+
width: 1200px;
30+
max-width: 100%;
31+
height: 600px;
32+
}
33+
34+
.terminal-header {
35+
background: linear-gradient(#504b45 0%, #3c3b37 100%);
36+
padding: 10px;
37+
display: flex;
38+
align-items: center;
39+
}
40+
41+
.terminal-controls {
42+
display: flex;
43+
gap: 8px;
44+
}
45+
46+
.terminal-control {
47+
width: 12px;
48+
height: 12px;
49+
border-radius: 50%;
50+
}
51+
52+
.close { background: #ff5f56; }
53+
.minimize { background: #ffbd2e; }
54+
.maximize { background: #27c93f; }
55+
56+
.terminal-title {
57+
flex: 1;
58+
text-align: center;
59+
color: #ccc;
60+
font-size: 14px;
61+
}
62+
63+
.terminal-split {
64+
display: flex;
65+
height: calc(100% - 40px);
66+
}
67+
68+
.terminal-pane {
69+
flex: 1;
70+
padding: 20px;
71+
color: #d4d4d4;
72+
font-size: 13px;
73+
line-height: 1.6;
74+
overflow-y: auto;
75+
overflow-x: hidden;
76+
position: relative;
77+
}
78+
79+
.terminal-left {
80+
border-right: 1px solid #333;
81+
background: #0c0c0c;
82+
}
83+
84+
.terminal-right {
85+
background: #000;
86+
}
87+
88+
.prompt {
89+
color: #569cd6;
90+
}
91+
92+
.command {
93+
color: #d4d4d4;
94+
}
95+
96+
.comment {
97+
color: #608b4e;
98+
}
99+
100+
.output {
101+
color: #d4d4d4;
102+
margin: 10px 0;
103+
}
104+
105+
.border {
106+
color: #764ba2;
107+
font-weight: bold;
108+
display: block;
109+
overflow: hidden;
110+
white-space: nowrap;
111+
}
112+
113+
.border::after {
114+
content: '══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════';
115+
display: inline-block;
116+
}
117+
118+
.divider {
119+
color: #666;
120+
display: block;
121+
overflow: hidden;
122+
white-space: nowrap;
123+
}
124+
125+
.divider::after {
126+
content: '──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────';
127+
display: inline-block;
128+
}
129+
130+
.filename {
131+
color: #667eea;
132+
text-align: center;
133+
font-weight: bold;
134+
text-transform: uppercase;
135+
}
136+
137+
.content {
138+
color: #d4d4d4;
139+
white-space: pre-wrap;
140+
font-family: inherit;
141+
}
142+
143+
.content h1 { color: #569cd6; margin: 10px 0; }
144+
.content h2 { color: #608b4e; margin: 10px 0; }
145+
.content li { margin-left: 20px; }
146+
147+
.typing {
148+
display: inline;
149+
border-right: 2px solid #0f0;
150+
animation: blink 1s infinite;
151+
}
152+
153+
@keyframes blink {
154+
0%, 50% { border-color: #0f0; }
155+
51%, 100% { border-color: transparent; }
156+
}
157+
158+
.hidden {
159+
display: none;
160+
}
161+
162+
.navigation {
163+
color: #569cd6;
164+
text-align: center;
165+
margin-top: 10px;
166+
}
167+
168+
.cursor {
169+
display: inline-block;
170+
width: 8px;
171+
height: 16px;
172+
background: #0f0;
173+
animation: blink 1s infinite;
174+
vertical-align: text-bottom;
175+
}
176+
177+
.tmux-status {
178+
position: absolute;
179+
bottom: 0;
180+
left: 0;
181+
right: 0;
182+
background: #222;
183+
color: #fff;
184+
padding: 2px 10px;
185+
font-size: 12px;
186+
display: flex;
187+
justify-content: space-between;
188+
}
189+
190+
.tmux-left {
191+
color: #0f0;
192+
}
193+
194+
.tmux-center {
195+
color: #569cd6;
196+
}
197+
198+
.tmux-right {
199+
color: #764ba2;
200+
}
201+
202+
@media (max-width: 768px) {
203+
.terminal-split {
204+
flex-direction: column;
205+
}
206+
.terminal-left {
207+
border-right: none;
208+
border-bottom: 1px solid #333;
209+
}
210+
}
211+
</style>
212+
</head>
213+
<body>
214+
<div class="terminal-container">
215+
<div class="terminal-header">
216+
<div class="terminal-controls">
217+
<div class="terminal-control close"></div>
218+
<div class="terminal-control minimize"></div>
219+
<div class="terminal-control maximize"></div>
220+
</div>
221+
<div class="terminal-title">Terminal - tmux session: mdtail-demo</div>
222+
</div>
223+
<div class="terminal-split">
224+
<!-- Left Pane - Command Line -->
225+
<div class="terminal-pane terminal-left" id="left-pane">
226+
<div id="left-content"></div>
227+
<div class="tmux-status">
228+
<span class="tmux-left">[0] 0:bash*</span>
229+
<span class="tmux-center">"mdtail-demo"</span>
230+
<span class="tmux-right">14:23</span>
231+
</div>
232+
</div>
233+
234+
<!-- Right Pane - mdtail -->
235+
<div class="terminal-pane terminal-right" id="right-pane">
236+
<div id="right-content"></div>
237+
<div class="tmux-status">
238+
<span class="tmux-left">[1] 1:mdtail</span>
239+
<span class="tmux-center">"mdtail-demo"</span>
240+
<span class="tmux-right">14:23</span>
241+
</div>
242+
</div>
243+
</div>
244+
</div>
245+
246+
<script>
247+
async function typeText(text, element, speed = 50) {
248+
for (let i = 0; i < text.length; i++) {
249+
element.innerHTML += text[i];
250+
await new Promise(r => setTimeout(r, speed));
251+
}
252+
}
253+
254+
async function runRightPane() {
255+
const container = document.getElementById('right-content');
256+
257+
// Initial prompt
258+
const prompt1 = document.createElement('span');
259+
prompt1.className = 'prompt';
260+
prompt1.innerHTML = '$ ';
261+
container.appendChild(prompt1);
262+
263+
await new Promise(r => setTimeout(r, 500));
264+
265+
// Type npm install command
266+
const npmCmd = document.createElement('span');
267+
npmCmd.className = 'command';
268+
container.appendChild(npmCmd);
269+
await typeText('npm install -g mdtail', npmCmd, 60);
270+
271+
await new Promise(r => setTimeout(r, 500));
272+
container.appendChild(document.createTextNode('\n'));
273+
274+
// Show npm installation output
275+
const npmOutput = document.createElement('div');
276+
npmOutput.className = 'output';
277+
npmOutput.style.color = '#888';
278+
npmOutput.textContent = 'added 1 package in 2s';
279+
container.appendChild(npmOutput);
280+
281+
await new Promise(r => setTimeout(r, 1000));
282+
283+
// Second prompt - no extra newline
284+
const prompt2 = document.createElement('span');
285+
prompt2.className = 'prompt';
286+
prompt2.innerHTML = '$ ';
287+
container.appendChild(prompt2);
288+
289+
await new Promise(r => setTimeout(r, 500));
290+
291+
// Type mdtail command
292+
const mdtailCmd = document.createElement('span');
293+
mdtailCmd.className = 'command';
294+
container.appendChild(mdtailCmd);
295+
await typeText('mdtail *.md', mdtailCmd, 60);
296+
297+
await new Promise(r => setTimeout(r, 500));
298+
container.appendChild(document.createTextNode('\n\n'));
299+
300+
// Show mdtail output with tabs
301+
showMdtailOutput();
302+
}
303+
304+
function showMdtailOutput() {
305+
const container = document.getElementById('right-content');
306+
const mdtailOutput = document.createElement('div');
307+
mdtailOutput.innerHTML = `
308+
<span class="border"></span>
309+
<div style="color: #d4d4d4; padding: 2px 0;">
310+
<span style="font-weight: bold; color: #fff;">[README.md]</span> │ TODO.md
311+
</div>
312+
<span class="divider"></span>
313+
314+
<div class="content" id="mdtail-content"># My Project
315+
316+
A simple demo application showcasing mdtail functionality.
317+
318+
## Quick Start
319+
320+
1. Install dependencies: npm install
321+
2. Run the app: npm start
322+
3. View docs: mdtail *.md
323+
324+
## Features
325+
326+
- Live markdown preview
327+
- File watching
328+
- Tab navigation</div>
329+
330+
<span class="border"></span>
331+
<div class="navigation">Tab 1 of 2 │ ← → Navigate │ Ctrl+C Exit</div>`;
332+
333+
container.appendChild(mdtailOutput);
334+
335+
// Simulate switching to TODO.md after 3 seconds
336+
setTimeout(() => {
337+
mdtailOutput.innerHTML = `
338+
<span class="border"></span>
339+
<div style="color: #d4d4d4; padding: 2px 0;">
340+
README.md │ <span style="font-weight: bold; color: #fff;">[TODO.md]</span>
341+
</div>
342+
<span class="divider"></span>
343+
344+
<div class="content" id="mdtail-content"># TODO List
345+
346+
## This Week
347+
- [x] Setup project
348+
- [x] Write documentation
349+
- [ ] Add tests
350+
- [ ] Deploy to production
351+
352+
## Next Sprint
353+
- [ ] User authentication
354+
- [ ] API integration
355+
- [ ] Performance optimization</div>
356+
357+
<span class="border"></span>
358+
<div class="navigation">Tab 2 of 2 │ ← → Navigate │ Ctrl+C Exit</div>`;
359+
}, 3000);
360+
}
361+
362+
async function runLeftPane() {
363+
const container = document.getElementById('left-content');
364+
365+
// Just show a prompt with cursor
366+
const prompt = document.createElement('span');
367+
prompt.className = 'prompt';
368+
prompt.innerHTML = '$ ';
369+
container.appendChild(prompt);
370+
371+
// Add blinking cursor
372+
const cursor = document.createElement('span');
373+
cursor.className = 'cursor';
374+
container.appendChild(cursor);
375+
}
376+
377+
// Start the demo
378+
window.addEventListener('load', () => {
379+
runLeftPane();
380+
runRightPane();
381+
});
382+
</script>
383+
</body>
384+
</html>

0 commit comments

Comments
 (0)