diff --git a/README.md b/README.md
index b8d3b0d..bf3aa05 100644
--- a/README.md
+++ b/README.md
@@ -18,7 +18,7 @@
> ๐ฌ **[See the live demo โ](https://marlburrow.github.io/pinchchat/)** โ interactive preview of the UI with tool call visualization, streaming, and more.
-
+
## โจ Features
diff --git a/docs/demo.gif b/docs/demo.gif
new file mode 100644
index 0000000..201d7f4
Binary files /dev/null and b/docs/demo.gif differ
diff --git a/docs/index.html b/docs/index.html
index e9279c6..a0a3cb7 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -600,37 +600,9 @@
โญ GitHub
-
-
-
-
+
+
+
@@ -879,122 +851,6 @@
entries.forEach(e => { if (e.isIntersecting) { e.target.classList.add('visible'); observer.unobserve(e.target); } });
}, { threshold: 0.15 });
rows.forEach(r => observer.observe(r));
-
- // โโ Demo animation โโ
- const chat = document.getElementById('demo-chat-area');
- const input = document.getElementById('demo-input-text');
-
- const scenario = [
- { type: 'date-sep', text: 'Today', delay: 0 },
- { type: 'input-type', text: 'What\'s the weather in Grenoble and check my latest emails?', delay: 600 },
- { type: 'input-send', delay: 800 },
- { type: 'user-msg', text: 'What\'s the weather in Grenoble and check my latest emails?', delay: 200 },
- { type: 'thinking', delay: 400 },
- { type: 'tool-badge', name: 'web_search', cls: 'demo-tool-web', icon: '๐', label: 'web_search', delay: 800 },
- { type: 'tool-expand', tool: 'web_search', params: '{ "query": "weather Grenoble today" }', result: 'โ๏ธ Grenoble: 14ยฐC, partly cloudy\nWind: 12 km/h NW ยท Humidity: 58%', delay: 600 },
- { type: 'tool-badge', name: 'exec', cls: 'demo-tool-exec', icon: 'โก', label: 'exec', delay: 500 },
- { type: 'tool-expand', tool: 'exec', params: '{ "command": "gmail unread 3" }', result: '1. [Urgent] Deploy review โ team@fasst.io\n2. Charlotte school โ photo day\n3. Newsletter โ This Week in AI', delay: 700 },
- { type: 'remove-thinking', delay: 100 },
- { type: 'assistant-msg', html: '๐ค๏ธ Grenoble โ 14ยฐC, partly cloudy. Clear tonight.
๐ง 3 unread:
1. [Urgent] Deploy review โ team@fasst.io
2. Charlotte\'s school โ photo day ๐ธ
3. This Week in AI
Want me to open any of these?', delay: 200 },
- { type: 'pause', delay: 4000 },
- { type: 'reset', delay: 0 },
- ];
-
- let thinkingEl = null, toolArea = null, currentBotMsg = null, bubbleEl = null;
-
- function scrollDown() { chat.scrollTop = chat.scrollHeight; }
-
- function typeText(el, text, cb) {
- let i = 0;
- el.textContent = '';
- const cursor = document.createElement('span');
- cursor.className = 'demo-cursor';
- el.appendChild(cursor);
- const iv = setInterval(() => {
- if (i < text.length) { el.insertBefore(document.createTextNode(text[i]), cursor); i++; }
- else { clearInterval(iv); if (cursor.parentNode) cursor.remove(); if (cb) cb(); }
- }, 28);
- }
-
- function createBotMsg() {
- const msg = document.createElement('div');
- msg.className = 'demo-msg';
- msg.innerHTML = '๐ค
';
- chat.appendChild(msg);
- currentBotMsg = msg.querySelector('.demo-msg-body');
- bubbleEl = msg.querySelector('.demo-bubble-bot');
- toolArea = document.createElement('div');
- bubbleEl.appendChild(toolArea);
- scrollDown();
- return currentBotMsg;
- }
-
- function runStep(idx) {
- if (idx >= scenario.length) return;
- const step = scenario[idx];
- const next = () => setTimeout(() => runStep(idx + 1), scenario[idx + 1]?.delay || 0);
-
- switch (step.type) {
- case 'date-sep': {
- const sep = document.createElement('div');
- sep.className = 'demo-date-sep';
- sep.innerHTML = '' + step.text + '';
- chat.appendChild(sep);
- scrollDown(); next(); break;
- }
- case 'input-type': typeText(input, step.text, next); break;
- case 'input-send': input.textContent = ''; next(); break;
- case 'user-msg': {
- const msg = document.createElement('div');
- msg.className = 'demo-msg demo-msg-user';
- msg.innerHTML = '๐ค
';
- chat.appendChild(msg);
- msg.querySelector('.demo-msg-text').textContent = step.text;
- scrollDown(); next(); break;
- }
- case 'thinking': {
- if (!currentBotMsg) createBotMsg();
- thinkingEl = document.createElement('div');
- thinkingEl.className = 'demo-thinking';
- thinkingEl.innerHTML = 'Thinking ';
- currentBotMsg.appendChild(thinkingEl);
- scrollDown(); next(); break;
- }
- case 'tool-badge': {
- if (!toolArea) createBotMsg();
- const badge = document.createElement('span');
- badge.className = 'demo-tool ' + step.cls;
- badge.innerHTML = step.icon + ' ' + step.label;
- toolArea.appendChild(badge);
- scrollDown(); next(); break;
- }
- case 'tool-expand': {
- const expand = document.createElement('div');
- expand.className = 'demo-tool-expand';
- expand.innerHTML = 'โถ ' + step.tool + '
Parameters:\n' + step.params + '\n\nResult:\n' + step.result + '
';
- toolArea.appendChild(expand);
- scrollDown(); next(); break;
- }
- case 'remove-thinking': if (thinkingEl) { thinkingEl.remove(); thinkingEl = null; } next(); break;
- case 'assistant-msg': {
- const d = document.createElement('div');
- d.className = 'demo-msg-text';
- d.innerHTML = step.html;
- bubbleEl.appendChild(d);
- scrollDown(); next(); break;
- }
- case 'pause': setTimeout(next, step.delay); break;
- case 'reset':
- setTimeout(() => {
- chat.innerHTML = ''; input.textContent = '';
- thinkingEl = null; toolArea = null; currentBotMsg = null; bubbleEl = null;
- runStep(0);
- }, 500);
- break;
- }
- }
-
- setTimeout(() => runStep(0), 1200);
})();