wop commited on
Commit
e6e185b
·
verified ·
1 Parent(s): e540ed7

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +88 -88
index.html CHANGED
@@ -6,7 +6,7 @@
6
  <title>Amber Chat Visualizer</title>
7
  <script src="https://cdn.tailwindcss.com"></script>
8
  <style>
9
- /* Custom Yellow Grayscale Palette */
10
  :root {
11
  --amber-50: #fffbeb;
12
  --amber-100: #fef3c7;
@@ -17,13 +17,13 @@
17
  --amber-600: #d97706;
18
  --amber-700: #b45309;
19
  --amber-800: #92400e;
20
- --amber-900: #78350f;
21
- --amber-950: #1a1405; /* Deep warm black */
22
  }
23
 
24
  body {
25
- background-color: var(--amber-950);
26
- color: var(--amber-200);
27
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
28
  }
29
 
@@ -65,18 +65,18 @@
65
  <body class="flex flex-col h-screen overflow-hidden">
66
 
67
  <!-- Header -->
68
- <header class="flex items-center justify-between px-6 py-4 border-b border-amber-900/50 bg-amber-950 shadow-lg">
69
  <div class="flex items-center space-x-3">
70
- <div class="bg-amber-500/20 p-2 rounded-lg">
71
- <svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 text-amber-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
72
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z" />
73
  </svg>
74
  </div>
75
- <h1 class="text-xl font-bold tracking-tight text-amber-400">Amber Chat <span class="text-amber-700 font-light">Visualizer</span></h1>
76
  </div>
77
- <div class="flex items-center gap-4 text-xs font-mono text-amber-700">
78
  <span class="hidden sm:inline">JSON + VISUAL SYNC</span>
79
- <button onclick="copyJson()" class="p-2 hover:bg-amber-500/10 rounded-full transition-colors text-amber-500">
80
  <svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
81
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 5H6a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2v-1M8 5a2 2 0 002 2h2a2 2 0 002-2M8 5a2 2 0 012-2h2a2 2 0 012 2m0 0h2a2 2 0 012 2v3m2 4H10m0 0l3-3m-3 3l3 3" />
82
  </svg>
@@ -88,27 +88,27 @@
88
  <main class="main-container flex-1 flex overflow-hidden">
89
 
90
  <!-- Editor Panel -->
91
- <section class="panel w-1/2 flex flex-col bg-black/40 border-r border-amber-900/30">
92
- <div class="px-4 py-2 bg-amber-950/80 border-b border-amber-900/30 flex justify-between items-center">
93
- <span class="text-[10px] font-mono uppercase tracking-widest text-amber-700">source.json</span>
94
  <span id="json-error" class="text-[10px] text-red-500 hidden">Invalid JSON</span>
95
  </div>
96
  <textarea id="json-editor"
97
- class="flex-1 p-6 bg-transparent text-amber-500 font-mono text-sm outline-none resize-none custom-scrollbar"
98
  spellcheck="false"></textarea>
99
  </section>
100
 
101
  <!-- Preview Panel -->
102
- <section id="chat-preview" class="panel w-1/2 overflow-y-auto p-6 md:p-12 bg-amber-950/20 custom-scrollbar">
103
  <!-- Bubbles injected here -->
104
  </section>
105
 
106
  </main>
107
 
108
  <!-- Footer -->
109
- <footer class="h-10 border-t border-amber-900/30 flex items-center justify-between px-6 bg-amber-950 text-[10px] uppercase tracking-widest text-amber-800">
110
  <div>Click text to edit visually</div>
111
- <div>Grayscale Yellow Tint Mode</div>
112
  </footer>
113
 
114
  <script>
@@ -120,7 +120,7 @@
120
  "messages": [
121
  { "role": "system", "content": "You are a helpful assistant." },
122
  { "role": "user", "content": "Tell me about this yellow theme." },
123
- { "role": "assistant", "content": "<think>The user is noticing the monochrome amber palette. I should explain that it's designed for focus and health.</think>This is a yellow-tint grayscale theme. By removing blue light and focusing on amber tones, it aims to be much easier on your eyes during long coding sessions." }
124
  ]
125
  };
126
 
@@ -161,84 +161,84 @@
161
  // Role label
162
  const label = document.createElement('div');
163
  label.contentEditable = true;
164
- label.className = `text-[10px] font-bold uppercase tracking-widest mb-1 px-1 outline-none ${isUser ? 'text-amber-400' : 'text-amber-700'}`;
165
  label.innerText = msg.role;
166
  label.onblur = (e) => updateData(index, 'role', e.target.innerText);
167
 
168
  // Bubble body
169
  const body = document.createElement('div');
170
  const bubbleClasses = isUser
171
- ? 'bg-amber-600 text-amber-950 rounded-br-none font-medium'
172
  : isSystem
173
- ? 'bg-amber-900/20 border border-amber-900/50 text-amber-600 italic text-center w-full max-w-none text-sm'
174
- : 'bg-amber-900/40 border border-amber-800/50 text-amber-100 rounded-bl-none';
175
 
176
- body.className = `max-w-[90%] md:max-w-[85%] rounded-2xl px-5 py-3 shadow-lg ${bubbleClasses}`;
177
 
178
  // Handle thought tags
179
  const content = msg.content || "";
180
- const thinkMatch = content.match(/<think>([\s\S]*?)<\/think>/);
181
- const thoughtText = thinkMatch ? thinkMatch[1] : "";
182
- const cleanText = content.replace(/<think>[\s\S]*?<\/think>/, '').trim();
183
-
184
- if (isAssistant || thoughtText) {
185
- const details = document.createElement('details');
186
- details.open = !!thoughtText;
187
- details.className = 'mb-3 bg-black/30 rounded-lg border border-amber-900/50 overflow-hidden';
188
-
189
- const summary = document.createElement('summary');
190
- summary.className = 'cursor-pointer p-2 text-[10px] font-bold text-amber-700 hover:bg-amber-500/5 flex items-center select-none outline-none';
191
- summary.innerHTML = `<span class="mr-1">▶</span> THOUGHT PROCESS`;
192
-
193
- const thoughtDiv = document.createElement('div');
194
- thoughtDiv.contentEditable = true;
195
- thoughtDiv.className = 'p-3 text-xs text-amber-500/70 border-t border-amber-900/50 outline-none leading-relaxed';
196
- thoughtDiv.innerText = thoughtText;
197
- thoughtDiv.onblur = (e) => updateData(index, 'thought', e.target.innerText);
198
-
199
- details.appendChild(summary);
200
- details.appendChild(thoughtDiv);
201
- body.appendChild(details);
202
- }
203
-
204
- const mainText = document.createElement('div');
205
- mainText.contentEditable = true;
206
- mainText.className = 'outline-none whitespace-pre-wrap leading-relaxed text-sm md:text-base';
207
- mainText.innerText = cleanText;
208
- mainText.onblur = (e) => updateData(index, 'content', e.target.innerText);
209
-
210
- body.appendChild(mainText);
211
- container.appendChild(label);
212
- container.appendChild(body);
213
- return container;
214
- }
215
-
216
- function updateData(index, field, value) {
217
- const msg = data.messages[index];
218
- if (field === 'role') {
219
- msg.role = value;
220
- } else if (field === 'thought') {
221
- const currentContent = msg.content || "";
222
- const cleanPart = currentContent.replace(/<think>[\s\S]*?<\/think>/, '').trim();
223
- msg.content = `<think>${value}</think>${cleanPart}`;
224
- } else if (field === 'content') {
225
- const currentContent = msg.content || "";
226
- const thinkMatch = currentContent.match(/<think>([\s\S]*?)<\/think>/);
227
- const thinkPart = thinkMatch ? `<think>${thinkMatch[1]}</think>` : "";
228
- msg.content = thinkPart + value;
229
- }
230
-
231
- jsonEditor.value = JSON.stringify(data, null, 2);
232
- }
233
-
234
- function copyJson() {
235
- jsonEditor.select();
236
- document.execCommand('copy');
237
- const btn = document.querySelector('button[onclick="copyJson()"]');
238
- const original = btn.innerHTML;
239
- btn.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5 text-green-500" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" /></svg>`;
240
- setTimeout(() => btn.innerHTML = original, 2000);
241
- }
242
- </script>
243
- </body>
244
  </html>
 
6
  <title>Amber Chat Visualizer</title>
7
  <script src="https://cdn.tailwindcss.com"></script>
8
  <style>
9
+ /* Softer Amber Palette */
10
  :root {
11
  --amber-50: #fffbeb;
12
  --amber-100: #fef3c7;
 
17
  --amber-600: #d97706;
18
  --amber-700: #b45309;
19
  --amber-800: #92400e;
20
+ --amber-900: #453a2a; /* Softer dark brown */
21
+ --amber-950: #30251a; /* Softer deep brown */
22
  }
23
 
24
  body {
25
+ background-color: #f8f5f0; /* Light cream background */
26
+ color: #5d4e37; /* Soft brown text */
27
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
28
  }
29
 
 
65
  <body class="flex flex-col h-screen overflow-hidden">
66
 
67
  <!-- Header -->
68
+ <header class="flex items-center justify-between px-6 py-4 border-b border-amber-200/50 bg-white shadow-sm">
69
  <div class="flex items-center space-x-3">
70
+ <div class="bg-amber-100 p-2 rounded-lg">
71
+ <svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 text-amber-600" fill="none" viewBox="0 0 24 24" stroke="currentColor">
72
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z" />
73
  </svg>
74
  </div>
75
+ <h1 class="text-xl font-bold tracking-tight text-amber-700">Amber Chat <span class="text-amber-500 font-light">Visualizer</span></h1>
76
  </div>
77
+ <div class="flex items-center gap-4 text-xs font-mono text-amber-600">
78
  <span class="hidden sm:inline">JSON + VISUAL SYNC</span>
79
+ <button onclick="copyJson()" class="p-2 hover:bg-amber-100 rounded-full transition-colors text-amber-600">
80
  <svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
81
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 5H6a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2v-1M8 5a2 2 0 002 2h2a2 2 0 002-2M8 5a2 2 0 012-2h2a2 2 0 012 2m0 0h2a2 2 0 012 2v3m2 4H10m0 0l3-3m-3 3l3 3" />
82
  </svg>
 
88
  <main class="main-container flex-1 flex overflow-hidden">
89
 
90
  <!-- Editor Panel -->
91
+ <section class="panel w-1/2 flex flex-col bg-white/60 border-r border-amber-200/30">
92
+ <div class="px-4 py-2 bg-white/80 border-b border-amber-200/30 flex justify-between items-center">
93
+ <span class="text-[10px] font-mono uppercase tracking-widest text-amber-600">source.json</span>
94
  <span id="json-error" class="text-[10px] text-red-500 hidden">Invalid JSON</span>
95
  </div>
96
  <textarea id="json-editor"
97
+ class="flex-1 p-6 bg-transparent text-amber-700 font-mono text-sm outline-none resize-none custom-scrollbar"
98
  spellcheck="false"></textarea>
99
  </section>
100
 
101
  <!-- Preview Panel -->
102
+ <section id="chat-preview" class="panel w-1/2 overflow-y-auto p-6 md:p-12 bg-amber-50/50 custom-scrollbar">
103
  <!-- Bubbles injected here -->
104
  </section>
105
 
106
  </main>
107
 
108
  <!-- Footer -->
109
+ <footer class="h-10 border-t border-amber-200/30 flex items-center justify-between px-6 bg-white text-[10px] uppercase tracking-widest text-amber-600">
110
  <div>Click text to edit visually</div>
111
+ <div>Soft Amber Mode</div>
112
  </footer>
113
 
114
  <script>
 
120
  "messages": [
121
  { "role": "system", "content": "You are a helpful assistant." },
122
  { "role": "user", "content": "Tell me about this yellow theme." },
123
+ { "role": "assistant", "content": "This is a soft amber theme. By using warmer tones and reducing contrast, it aims to be much easier on your eyes during long coding sessions." }
124
  ]
125
  };
126
 
 
161
  // Role label
162
  const label = document.createElement('div');
163
  label.contentEditable = true;
164
+ label.className = `text-[10px] font-bold uppercase tracking-widest mb-1 px-1 outline-none ${isUser ? 'text-amber-600' : 'text-amber-500'}`;
165
  label.innerText = msg.role;
166
  label.onblur = (e) => updateData(index, 'role', e.target.innerText);
167
 
168
  // Bubble body
169
  const body = document.createElement('div');
170
  const bubbleClasses = isUser
171
+ ? 'bg-amber-200 text-amber-900 rounded-br-none font-medium'
172
  : isSystem
173
+ ? 'bg-amber-100/50 border border-amber-200/50 text-amber-700 italic text-center w-full max-w-none text-sm'
174
+ : 'bg-white border border-amber-200/50 text-amber-800 rounded-bl-none';
175
 
176
+ body.className = `max-w-[90%] md:max-w-[85%] rounded-2xl px-5 py-3 shadow-sm ${bubbleClasses}`;
177
 
178
  // Handle thought tags
179
  const content = msg.content || "";
180
+ const thinkMatch = content.match([\s\S]?)</think>/);
181
+ const thoughtText = thinkMatch ? thinkMatch[1] : "";
182
+ const cleanText = content.replace(/[\s\S]?</think>/, '').trim();
183
+
184
+ if (isAssistant || thoughtText) {
185
+ const details = document.createElement('details');
186
+ details.open = !!thoughtText;
187
+ details.className = 'mb-3 bg-amber-50/50 rounded-lg border border-amber-200/50 overflow-hidden';
188
+
189
+ const summary = document.createElement('summary');
190
+ summary.className = 'cursor-pointer p-2 text-[10px] font-bold text-amber-600 hover:bg-amber-100/50 flex items-center select-none outline-none';
191
+ summary.innerHTML = `<span class="mr-1">▶</span> THOUGHT PROCESS`;
192
+
193
+ const thoughtDiv = document.createElement('div');
194
+ thoughtDiv.contentEditable = true;
195
+ thoughtDiv.className = 'p-3 text-xs text-amber-600/70 border-t border-amber-200/50 outline-none leading-relaxed';
196
+ thoughtDiv.innerText = thoughtText;
197
+ thoughtDiv.onblur = (e) => updateData(index, 'thought', e.target.innerText);
198
+
199
+ details.appendChild(summary);
200
+ details.appendChild(thoughtDiv);
201
+ body.appendChild(details);
202
+ }
203
+
204
+ const mainText = document.createElement('div');
205
+ mainText.contentEditable = true;
206
+ mainText.className = 'outline-none whitespace-pre-wrap leading-relaxed text-sm md:text-base';
207
+ mainText.innerText = cleanText;
208
+ mainText.onblur = (e) => updateData(index, 'content', e.target.innerText);
209
+
210
+ body.appendChild(mainText);
211
+ container.appendChild(label);
212
+ container.appendChild(body);
213
+ return container;
214
+ }
215
+
216
+ function updateData(index, field, value) {
217
+ const msg = data.messages[index];
218
+ if (field === 'role') {
219
+ msg.role = value;
220
+ } else if (field === 'thought') {
221
+ const currentContent = msg.content || "";
222
+ const cleanPart = currentContent.replace(/[\s\S]*?<\/think>/, '').trim();
223
+ msg.content = `${value}
224
+ ${cleanPart}`;
225
+ } else if (field === 'content') {
226
+ const currentContent = msg.content || "";
227
+ const thinkMatch = currentContent.match([\s\S]*?)</think>/);
228
+ const thinkPart = thinkMatch ? `${thinkMatch[1]}` : "";
229
+ msg.content = thinkPart + value;
230
+ }
231
+
232
+ jsonEditor.value = JSON.stringify(data, null, 2);
233
+ }
234
+
235
+ function copyJson() {
236
+ jsonEditor.select();
237
+ document.execCommand('copy');
238
+ const btn = document.querySelector('button[onclick="copyJson()"]');
239
+ const original = btn.innerHTML;
240
+ btn.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5 text-green-500" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" /></svg>`;
241
+ setTimeout(() => btn.innerHTML = original, 2000);
242
+ }
243
+ </script></body>
244
  </html>