OcDash Deploy commited on
Commit
df24ee6
·
1 Parent(s): 0c7a9f0

Update dashboard to match workspace UI design

Browse files
Files changed (1) hide show
  1. index.html +775 -17
index.html CHANGED
@@ -1,18 +1,776 @@
1
- <!doctype html>
2
- <html lang="en" style="background-color: var(--v2-background-bg-deep, #fafafa)">
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1, interactive-widget=resizes-content, viewport-fit=cover" />
6
- <title>OcDash</title>
7
- <link rel="icon" type="image/png" href="/favicon-96x96-v3.png" sizes="96x96" />
8
- <link rel="icon" type="image/svg+xml" href="/favicon-v3.svg" />
9
- <link rel="shortcut icon" href="/favicon-v3.ico" />
10
- <meta name="theme-color" content="#fafafa" />
11
- <script type="module" crossorigin src="/assets/index-BntqT9Ye.js"></script>
12
- <link rel="stylesheet" crossorigin href="/assets/index-BXs0wIyU.css">
13
- </head>
14
- <body class="antialiased overscroll-none overflow-hidden bg-v2-background-bg-deep">
15
- <noscript>You need to enable JavaScript to run this app.</noscript>
16
- <div id="root" class="flex flex-col h-dvh bg-v2-background-bg-deep"></div>
17
- </body>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  </html>
 
1
+ <!DOCTYPE html>
2
+ <html lang="en" class="">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <title>OpenCode Workspace</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <style>
9
+ :root {
10
+ --v2-background-bg-deep: #fafafa;
11
+ --v2-background-bg-base: #ffffff;
12
+ --v2-background-bg-layer-01: #f2f2f2;
13
+ --v2-background-bg-layer-02: #ebebeb;
14
+ --v2-background-bg-layer-03: #e0e0e0;
15
+ --v2-background-bg-layer-04: #d4d4d4;
16
+ --v2-text-text-base: #1a1a1a;
17
+ --v2-text-text-muted: #777777;
18
+ --v2-text-text-faint: #b3b3b3;
19
+ --v2-text-text-inverse: #ffffff;
20
+ --v2-icon-icon-base: #1a1a1a;
21
+ --v2-icon-icon-muted: #777777;
22
+ --v2-icon-icon-accent: #0066ff;
23
+ --v2-border-border-muted: #e5e5e5;
24
+ --v2-border-border-base: #d9d9d9;
25
+ --v2-overlay-simple-overlay-hover: rgba(0,0,0,0.04);
26
+ --v2-elevation-raised: 0 1px 3px rgba(0,0,0,0.1);
27
+ --v2-elevation-floating: 0 4px 16px rgba(0,0,0,0.12);
28
+ --color-bg-project-card: #ffffff;
29
+ --color-bg-project-card-hover: #fafafa;
30
+ }
31
+ .dark {
32
+ --v2-background-bg-deep: #0e0e0e;
33
+ --v2-background-bg-base: #181818;
34
+ --v2-background-bg-layer-01: #1f1f1f;
35
+ --v2-background-bg-layer-02: #262626;
36
+ --v2-background-bg-layer-03: #303030;
37
+ --v2-background-bg-layer-04: #3a3a3a;
38
+ --v2-text-text-base: #e8e8e8;
39
+ --v2-text-text-muted: #999999;
40
+ --v2-text-text-faint: #666666;
41
+ --v2-text-text-inverse: #0e0e0e;
42
+ --v2-icon-icon-base: #e8e8e8;
43
+ --v2-icon-icon-muted: #999999;
44
+ --v2-icon-icon-accent: #3b82f6;
45
+ --v2-border-border-muted: #2a2a2a;
46
+ --v2-border-border-base: #333333;
47
+ --v2-overlay-simple-overlay-hover: rgba(255,255,255,0.06);
48
+ --v2-elevation-raised: 0 1px 3px rgba(0,0,0,0.4);
49
+ --v2-elevation-floating: 0 4px 16px rgba(0,0,0,0.5);
50
+ --color-bg-project-card: #1f1f1f;
51
+ --color-bg-project-card-hover: #262626;
52
+ }
53
+ * { margin: 0; padding: 0; box-sizing: border-box; }
54
+ body {
55
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
56
+ background: var(--v2-background-bg-deep);
57
+ color: var(--v2-text-text-base);
58
+ overflow: hidden;
59
+ height: 100vh;
60
+ }
61
+ .glow-input {
62
+ position: relative;
63
+ border-radius: 10px;
64
+ background: var(--v2-background-bg-base);
65
+ border: 1px solid var(--v2-border-border-muted);
66
+ transition: border-color 0.2s, box-shadow 0.2s;
67
+ }
68
+ .glow-input:focus-within {
69
+ border-color: var(--v2-icon-icon-accent);
70
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--v2-icon-icon-accent) 15%, transparent);
71
+ }
72
+ .glow-input textarea {
73
+ width: 100%;
74
+ border: none;
75
+ background: transparent;
76
+ color: var(--v2-text-text-base);
77
+ outline: none;
78
+ resize: none;
79
+ font-size: 13px;
80
+ line-height: 1.5;
81
+ padding: 8px 10px;
82
+ font-family: inherit;
83
+ }
84
+ .glow-input textarea::placeholder {
85
+ color: var(--v2-text-text-faint);
86
+ }
87
+ .session-tab {
88
+ display: flex;
89
+ align-items: center;
90
+ gap: 6px;
91
+ padding: 6px 10px;
92
+ border-radius: 6px;
93
+ cursor: default;
94
+ font-size: 13px;
95
+ color: var(--v2-text-text-muted);
96
+ transition: background 0.12s, color 0.12s;
97
+ }
98
+ .session-tab:hover {
99
+ background: var(--v2-overlay-simple-overlay-hover);
100
+ color: var(--v2-text-text-base);
101
+ }
102
+ .session-tab.active {
103
+ background: var(--v2-background-bg-layer-02);
104
+ color: var(--v2-text-text-base);
105
+ font-weight: 530;
106
+ }
107
+ .project-card {
108
+ background: var(--color-bg-project-card);
109
+ border: 1px solid var(--v2-border-border-muted);
110
+ border-radius: 10px;
111
+ padding: 14px;
112
+ cursor: default;
113
+ transition: background 0.15s, border-color 0.15s;
114
+ }
115
+ .project-card:hover {
116
+ background: var(--color-bg-project-card-hover);
117
+ border-color: var(--v2-border-border-base);
118
+ }
119
+ .nav-icon-btn {
120
+ display: flex;
121
+ align-items: center;
122
+ justify-content: center;
123
+ width: 28px;
124
+ height: 28px;
125
+ border-radius: 6px;
126
+ border: none;
127
+ background: transparent;
128
+ color: var(--v2-icon-icon-muted);
129
+ cursor: pointer;
130
+ transition: background 0.12s, color 0.12s;
131
+ }
132
+ .nav-icon-btn:hover {
133
+ background: var(--v2-overlay-simple-overlay-hover);
134
+ color: var(--v2-icon-icon-base);
135
+ }
136
+ .scrollable::-webkit-scrollbar { width: 4px; }
137
+ .scrollable::-webkit-scrollbar-track { background: transparent; }
138
+ .scrollable::-webkit-scrollbar-thumb { background: var(--v2-border-border-base); border-radius: 4px; }
139
+ .scrollable::-webkit-scrollbar-thumb:hover { background: var(--v2-text-text-faint); }
140
+ .modal-overlay {
141
+ position: fixed; inset: 0; z-index: 100;
142
+ background: rgba(0,0,0,0.4);
143
+ display: flex; align-items: center; justify-content: center;
144
+ opacity: 0; pointer-events: none;
145
+ transition: opacity 0.2s;
146
+ }
147
+ .modal-overlay.open { opacity: 1; pointer-events: auto; }
148
+ .modal-content {
149
+ background: var(--v2-background-bg-base);
150
+ border: 1px solid var(--v2-border-border-muted);
151
+ border-radius: 14px;
152
+ box-shadow: var(--v2-elevation-floating);
153
+ max-width: 640px;
154
+ width: 90vw;
155
+ max-height: 80vh;
156
+ overflow-y: auto;
157
+ transform: scale(0.95);
158
+ transition: transform 0.2s;
159
+ }
160
+ .modal-overlay.open .modal-content { transform: scale(1); }
161
+ .cmd-palette {
162
+ position: fixed; top: 80px; left: 50%; transform: translateX(-50%);
163
+ z-index: 200;
164
+ width: 620px;
165
+ max-width: calc(100vw - 40px);
166
+ background: var(--v2-background-bg-base);
167
+ border: 1px solid var(--v2-border-border-muted);
168
+ border-radius: 14px;
169
+ box-shadow: var(--v2-elevation-floating);
170
+ display: none;
171
+ overflow: hidden;
172
+ }
173
+ .cmd-palette.open { display: block; }
174
+ .cmd-palette input {
175
+ width: 100%;
176
+ border: none;
177
+ background: transparent;
178
+ padding: 14px 16px;
179
+ font-size: 14px;
180
+ color: var(--v2-text-text-base);
181
+ outline: none;
182
+ font-family: inherit;
183
+ }
184
+ .cmd-palette input::placeholder { color: var(--v2-text-text-faint); }
185
+ .mode-btn {
186
+ padding: 4px 10px;
187
+ border-radius: 6px;
188
+ border: none;
189
+ font-size: 12px;
190
+ font-weight: 530;
191
+ cursor: pointer;
192
+ background: transparent;
193
+ color: var(--v2-text-text-muted);
194
+ transition: background 0.12s, color 0.12s;
195
+ }
196
+ .mode-btn:hover { background: var(--v2-overlay-simple-overlay-hover); color: var(--v2-text-text-base); }
197
+ .mode-btn.active { background: var(--v2-background-bg-layer-02); color: var(--v2-text-text-base); }
198
+ .model-select {
199
+ appearance: none;
200
+ border: none;
201
+ background: transparent;
202
+ font-size: 12px;
203
+ color: var(--v2-text-text-muted);
204
+ cursor: pointer;
205
+ outline: none;
206
+ padding: 2px 4px;
207
+ border-radius: 4px;
208
+ font-family: inherit;
209
+ }
210
+ .model-select:hover { background: var(--v2-overlay-simple-overlay-hover); }
211
+ .msg-bubble {
212
+ padding: 8px 12px;
213
+ border-radius: 8px;
214
+ font-size: 13px;
215
+ line-height: 1.5;
216
+ max-width: 85%;
217
+ }
218
+ .msg-bubble.user {
219
+ background: var(--v2-background-bg-layer-02);
220
+ color: var(--v2-text-text-base);
221
+ align-self: flex-end;
222
+ border-bottom-right-radius: 4px;
223
+ }
224
+ .msg-bubble.assistant {
225
+ background: transparent;
226
+ color: var(--v2-text-text-base);
227
+ align-self: flex-start;
228
+ }
229
+ .msg-bubble.assistant .typing-dots span {
230
+ display: inline-block;
231
+ width: 5px; height: 5px;
232
+ border-radius: 50%;
233
+ background: var(--v2-text-text-muted);
234
+ margin: 0 2px;
235
+ animation: dotPulse 1.4s infinite both;
236
+ }
237
+ .msg-bubble.assistant .typing-dots span:nth-child(2) { animation-delay: 0.2s; }
238
+ .msg-bubble.assistant .typing-dots span:nth-child(3) { animation-delay: 0.4s; }
239
+ @keyframes dotPulse {
240
+ 0%, 80%, 100% { opacity: 0.3; transform: scale(0.8); }
241
+ 40% { opacity: 1; transform: scale(1); }
242
+ }
243
+ .card-status-dot {
244
+ width: 8px; height: 8px; border-radius: 50%; display: inline-block;
245
+ }
246
+ .card-status-dot.online { background: #22c55e; }
247
+ .card-status-dot.offline { background: #ef4444; }
248
+ .card-status-dot.idle { background: #f59e0b; }
249
+ .card-tag {
250
+ display: inline-flex;
251
+ align-items: center;
252
+ padding: 2px 8px;
253
+ border-radius: 4px;
254
+ font-size: 11px;
255
+ font-weight: 500;
256
+ background: var(--v2-background-bg-layer-01);
257
+ color: var(--v2-text-text-muted);
258
+ }
259
+ svg.icon { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
260
+ svg.icon-lg { width: 18px; height: 18px; }
261
+ svg.icon-sm { width: 14px; height: 14px; }
262
+ .toggle-dark { cursor: pointer; }
263
+ </style>
264
+ </head>
265
+ <body>
266
+ <svg style="display:none" xmlns="http://www.w3.org/2000/svg">
267
+ <symbol id="icon-chevron-down" viewBox="0 0 16 16"><path d="M4 6l4 4 4-4"/></symbol>
268
+ <symbol id="icon-chevron-right" viewBox="0 0 16 16"><path d="M6 4l4 4-4 4"/></symbol>
269
+ <symbol id="icon-search" viewBox="0 0 16 16"><circle cx="6.5" cy="6.5" r="3.5"/><path d="M10.5 10.5L14 14"/></symbol>
270
+ <symbol id="icon-settings" viewBox="0 0 16 16"><circle cx="8" cy="8" r="1.5"/><path d="M8 2v1.5M8 12.5V14M2 8h1.5M12.5 8H14M3.5 3.5l1 1M11.5 11.5l1 1M3.5 12.5l1-1M11.5 4.5l1-1"/></symbol>
271
+ <symbol id="icon-help" viewBox="0 0 16 16"><circle cx="8" cy="8" r="6"/><path d="M6 6c0-1.1.9-2 2-2s2 .9 2 2c0 1.5-2 2-2 3.5V11"/><circle cx="8" cy="12.5" r="0.5" fill="currentColor"/></symbol>
272
+ <symbol id="icon-folder" viewBox="0 0 16 16"><path d="M1.5 4.5v8a1 1 0 001 1h11a1 1 0 001-1V6a1 1 0 00-1-1H8.5l-1.5-2h-5a1 1 0 00-1 1z"/></symbol>
273
+ <symbol id="icon-plus" viewBox="0 0 16 16"><path d="M8 3v10M3 8h10"/></symbol>
274
+ <symbol id="icon-close" viewBox="0 0 16 16"><path d="M4 4l8 8M12 4l-8 8"/></symbol>
275
+ <symbol id="icon-send" viewBox="0 0 16 16"><path d="M2 8l12-6-4 6 4 6-12-6z"/></symbol>
276
+ <symbol id="icon-edit" viewBox="0 0 16 16"><path d="M11 2l3 3-8 8H3v-3z"/></symbol>
277
+ <symbol id="icon-trash" viewBox="0 0 16 16"><path d="M2 4h12M5 4V2.5a.5.5 0 01.5-.5h5a.5.5 0 01.5.5V4M3 4l1 10h8l1-10"/></symbol>
278
+ <symbol id="icon-copy" viewBox="0 0 16 16"><rect x="4" y="4" width="10" height="10" rx="1"/><path d="M2 12V2h10"/></symbol>
279
+ <symbol id="icon-check" viewBox="0 0 16 16"><path d="M3 8l3 4 7-8"/></symbol>
280
+ <symbol id="icon-archive" viewBox="0 0 16 16"><path d="M1.5 4.5h13M2.5 4.5V13a1 1 0 001 1h9a1 1 0 001-1V4.5M5 7.5h6"/></symbol>
281
+ <symbol id="icon-asterisk" viewBox="0 0 16 16"><path d="M8 2v12M2 8h12M3.5 3.5l9 9M12.5 3.5l-9 9"/></symbol>
282
+ <symbol id="icon-sun" viewBox="0 0 16 16"><circle cx="8" cy="8" r="3"/><path d="M8 1v2M8 13v2M1 8h2M13 8h2M3.5 3.5l1.5 1.5M11 11l1.5 1.5M3.5 12.5L5 11M11 5l1.5-1.5"/></symbol>
283
+ <symbol id="icon-moon" viewBox="0 0 16 16"><path d="M13.5 8.5A5.5 5.5 0 017.5 3a5.5 5.5 0 106 5.5z"/></symbol>
284
+ <symbol id="icon-stop" viewBox="0 0 16 16"><rect x="4" y="4" width="8" height="8" rx="1"/></symbol>
285
+ <symbol id="icon-history" viewBox="0 0 16 16"><circle cx="8" cy="8" r="6"/><path d="M8 5v3l2 1"/></symbol>
286
+ <symbol id="icon-globe" viewBox="0 0 16 16"><circle cx="8" cy="8" r="6"/><path d="M2 8h12M8 2a6 6 0 010 12"/></symbol>
287
+ <symbol id="icon-box" viewBox="0 0 16 16"><path d="M2 5l6-3 6 3v6l-6 3-6-3z"/><path d="M2 5l6 3 6-3M8 8v6"/></symbol>
288
+ <symbol id="icon-sparkles" viewBox="0 0 16 16"><path d="M5 2l.5 2.5L8 5l-2.5.5L5 8l-.5-2.5L2 5l2.5-.5z"/><path d="M11 4l.3 1.7L13 6l-1.7.3L11 8l-.3-1.7L9 6l1.7-.3z"/><path d="M9 11l.3 1.3L11 13l-1.7.3L9 14l-.3-1.7L7 13l1.7-.3z"/></symbol>
289
+ </svg>
290
+
291
+ <!-- MAIN LAYOUT -->
292
+ <div class="flex flex-col h-screen">
293
+ <!-- TOP BAR -->
294
+ <header class="h-9 shrink-0 flex items-center justify-between px-3 border-b" style="border-color:var(--v2-border-border-muted);background:var(--v2-background-bg-base);-webkit-app-region:drag">
295
+ <div class="flex items-center gap-2" style="-webkit-app-region:no-drag">
296
+ <svg class="icon icon-lg" style="color:var(--v2-icon-icon-accent)"><use href="#icon-box"/></svg>
297
+ <span class="text-[12px] font-semibold tracking-tight" style="color:var(--v2-text-text-muted)">OcDash</span>
298
+ </div>
299
+ <div class="flex items-center gap-2" style="-webkit-app-region:no-drag">
300
+ <div class="relative flex items-center">
301
+ <svg class="icon-sm absolute left-2 pointer-events-none" style="color:var(--v2-text-text-faint)"><use href="#icon-search"/></svg>
302
+ <input type="text" placeholder="Search sessions, projects, or commands (Ctrl+K)"
303
+ class="h-7 w-[280px] rounded-[6px] border-none bg-transparent pl-7 pr-3 text-[12px] outline-none"
304
+ style="color:var(--v2-text-text-base);background:var(--v2-background-bg-layer-02/60)"
305
+ onfocus="this.style.background='var(--v2-background-bg-layer-02)'"
306
+ onblur="this.style.background='var(--v2-background-bg-layer-02/60)'"
307
+ onkeydown="if(event.key==='Escape')this.blur();if(event.key==='Enter')openCommandPalette()"/>
308
+ </div>
309
+ <button class="nav-icon-btn" onclick="toggleDark()" title="Toggle theme">
310
+ <svg class="icon"><use href="#icon-sun" id="theme-icon"/></svg>
311
+ </button>
312
+ <span class="w-px h-4" style="background:var(--v2-border-border-muted)"></span>
313
+ </div>
314
+ </header>
315
+
316
+ <!-- MAIN BODY -->
317
+ <div class="flex flex-1 min-h-0 overflow-hidden">
318
+ <!-- LEFT NAV BAR -->
319
+ <nav class="w-10 shrink-0 flex flex-col items-center py-3 gap-2 border-r" style="background:var(--v2-background-bg-base);border-color:var(--v2-border-border-muted)">
320
+ <button class="nav-icon-btn" onclick="openSettings()" title="Settings (Ctrl+,)">
321
+ <svg class="icon icon-lg"><use href="#icon-settings"/></svg>
322
+ </button>
323
+ <button class="nav-icon-btn" onclick="openHelp()" title="Help">
324
+ <svg class="icon icon-lg"><use href="#icon-help"/></svg>
325
+ </button>
326
+ </nav>
327
+
328
+ <!-- LEFT PANEL: SESSIONS + CHAT (420px) -->
329
+ <div class="w-[420px] shrink-0 flex flex-col border-r" style="border-color:var(--v2-border-border-muted);background:var(--v2-background-bg-base)">
330
+ <!-- Session tabs -->
331
+ <div class="flex items-center gap-0.5 px-3 pt-2 pb-1 border-b" style="border-color:var(--v2-border-border-muted)">
332
+ <div class="session-tab active">
333
+ <svg class="icon-sm"><use href="#icon-sparkles"/></svg>
334
+ <span>Current</span>
335
+ </div>
336
+ <div class="session-tab">
337
+ <svg class="icon-sm"><use href="#icon-history"/></svg>
338
+ <span>Yesterday</span>
339
+ </div>
340
+ <div class="session-tab">
341
+ <svg class="icon-sm"><use href="#icon-archive"/></svg>
342
+ <span>Older</span>
343
+ </div>
344
+ <div class="flex-1"></div>
345
+ <button class="nav-icon-btn" onclick="alert('Archive')" title="Archive session">
346
+ <svg class="icon-sm"><use href="#icon-archive"/></svg>
347
+ </button>
348
+ </div>
349
+
350
+ <!-- Session list -->
351
+ <div class="flex flex-col px-2 py-2 gap-px border-b" style="border-color:var(--v2-border-border-muted);max-height:180px;overflow-y:auto" class="scrollable">
352
+ <div class="session-tab active">
353
+ <span class="w-5 h-5 rounded flex items-center justify-center text-[10px] font-bold shrink-0" style="background:var(--v2-background-bg-layer-03)">AE</span>
354
+ <span class="truncate">Fix endpoint routing</span>
355
+ <span class="ml-auto text-[11px]" style="color:var(--v2-text-text-faint)">2h</span>
356
+ </div>
357
+ <div class="session-tab">
358
+ <span class="w-5 h-5 rounded flex items-center justify-center text-[10px] font-bold shrink-0" style="background:var(--v2-background-bg-layer-03)">W2</span>
359
+ <span class="truncate">Refactor auth middleware</span>
360
+ <span class="ml-auto text-[11px]" style="color:var(--v2-text-text-faint)">5h</span>
361
+ </div>
362
+ <div class="session-tab">
363
+ <span class="w-5 h-5 rounded flex items-center justify-center text-[10px] font-bold shrink-0" style="background:var(--v2-background-bg-layer-03)">AS</span>
364
+ <span class="truncate">Deploy Astro site</span>
365
+ <span class="ml-auto text-[11px]" style="color:var(--v2-text-text-faint)">1d</span>
366
+ </div>
367
+ <div class="session-tab">
368
+ <span class="w-5 h-5 rounded flex items-center justify-center text-[10px] font-bold shrink-0" style="background:var(--v2-background-bg-layer-03)">WD</span>
369
+ <span class="truncate">Database migration plan</span>
370
+ <span class="ml-auto text-[11px]" style="color:var(--v2-text-text-faint)">2d</span>
371
+ </div>
372
+ </div>
373
+
374
+ <!-- Chat messages -->
375
+ <div class="flex-1 overflow-y-auto px-3 py-3 flex flex-col gap-3 scrollable" id="chat-messages">
376
+ <div class="msg-bubble assistant">
377
+ <div class="flex items-center gap-2 mb-1">
378
+ <span class="w-5 h-5 rounded flex items-center justify-center text-[10px] font-bold shrink-0" style="background:var(--v2-icon-icon-accent);color:var(--v2-text-text-inverse)">OC</span>
379
+ <span class="text-[11px]" style="color:var(--v2-text-text-muted)">OpenCode</span>
380
+ </div>
381
+ <div>Hello! I'm your AI coding assistant. I can help you write, debug, and refactor code. What are you working on?</div>
382
+ </div>
383
+ <div class="msg-bubble user">
384
+ <div>Let's work on the dashboard project. I need to add user authentication</div>
385
+ </div>
386
+ <div class="msg-bubble assistant">
387
+ <div class="flex items-center gap-2 mb-1">
388
+ <span class="w-5 h-5 rounded flex items-center justify-center text-[10px] font-bold shrink-0" style="background:var(--v2-icon-icon-accent);color:var(--v2-text-text-inverse)">OC</span>
389
+ <span class="text-[11px]" style="color:var(--v2-text-text-muted)">OpenCode</span>
390
+ </div>
391
+ <div>Great! I'll help you implement authentication. First, let me check your project structure...</div>
392
+ </div>
393
+ <div class="msg-bubble assistant" id="typing-indicator" style="display:none">
394
+ <div class="flex items-center gap-2 mb-1">
395
+ <span class="w-5 h-5 rounded flex items-center justify-center text-[10px] font-bold shrink-0" style="background:var(--v2-icon-icon-accent);color:var(--v2-text-text-inverse)">OC</span>
396
+ <span class="text-[11px]" style="color:var(--v2-text-text-muted)">OpenCode</span>
397
+ </div>
398
+ <div class="typing-dots"><span></span><span></span><span></span></div>
399
+ </div>
400
+ </div>
401
+
402
+ <!-- Input area -->
403
+ <div class="px-3 pb-3 pt-2 border-t" style="border-color:var(--v2-border-border-muted)">
404
+ <div class="glow-input">
405
+ <textarea rows="2" placeholder="Ask OpenCode anything..." id="chat-input"
406
+ onkeydown="if(event.key==='Enter'&&!event.shiftKey){event.preventDefault();sendMessage()}"></textarea>
407
+ </div>
408
+ <div class="flex items-center justify-between mt-2">
409
+ <div class="flex items-center gap-1.5">
410
+ <button class="mode-btn active">Auto</button>
411
+ <button class="mode-btn">Ask</button>
412
+ <button class="mode-btn">Edit</button>
413
+ <button class="mode-btn">Agent</button>
414
+ </div>
415
+ <div class="flex items-center gap-2">
416
+ <select class="model-select">
417
+ <option>gpt-4o</option>
418
+ <option>claude-opus-4</option>
419
+ <option>claude-sonnet-4</option>
420
+ <option selected>deepseek-v4</option>
421
+ <option>llama-4</option>
422
+ </select>
423
+ <button class="nav-icon-btn" onclick="sendMessage()" title="Send">
424
+ <svg class="icon"><use href="#icon-send"/></svg>
425
+ </button>
426
+ </div>
427
+ </div>
428
+ </div>
429
+ </div>
430
+
431
+ <!-- RIGHT PANEL: PROJECT CARDS -->
432
+ <div class="flex-1 flex flex-col min-w-0 overflow-hidden" style="background:var(--v2-background-bg-deep)">
433
+ <div class="flex items-center justify-between px-5 py-3">
434
+ <h2 class="text-[14px] font-semibold" style="color:var(--v2-text-text-base)">Projects</h2>
435
+ <span class="text-[12px]" style="color:var(--v2-text-text-muted)">7 active</span>
436
+ </div>
437
+ <div class="flex-1 overflow-y-auto px-5 pb-5 scrollable">
438
+ <div class="grid grid-cols-2 xl:grid-cols-3 gap-3">
439
+ <!-- altamura-endpoints -->
440
+ <div class="project-card">
441
+ <div class="flex items-center gap-2 mb-2">
442
+ <span class="w-7 h-7 rounded-[6px] flex items-center justify-center text-[11px] font-bold shrink-0" style="background:#e0f2fe;color:#0369a1">AE</span>
443
+ <div class="min-w-0 flex-1">
444
+ <div class="text-[13px] font-medium truncate" style="color:var(--v2-text-text-base)">altamura-endpoints</div>
445
+ <div class="text-[11px] truncate" style="color:var(--v2-text-text-faint)">/home/user/altamura</div>
446
+ </div>
447
+ <span class="card-status-dot online"></span>
448
+ </div>
449
+ <div class="flex items-center gap-2 mb-2">
450
+ <span class="card-tag">typescript</span>
451
+ <span class="card-tag">api</span>
452
+ <span class="card-tag">express</span>
453
+ </div>
454
+ <div class="flex items-center gap-2 text-[11px]" style="color:var(--v2-text-text-muted)">
455
+ <svg class="icon-sm"><use href="#icon-edit"/></svg>
456
+ <span>Fix endpoint routing</span>
457
+ </div>
458
+ <div class="mt-2 text-[11px]" style="color:var(--v2-text-text-faint)">Updated 2 hours ago</div>
459
+ </div>
460
+
461
+ <!-- w2 -->
462
+ <div class="project-card">
463
+ <div class="flex items-center gap-2 mb-2">
464
+ <span class="w-7 h-7 rounded-[6px] flex items-center justify-center text-[11px] font-bold shrink-0" style="background:#f3e8ff;color:#7c3aed">W2</span>
465
+ <div class="min-w-0 flex-1">
466
+ <div class="text-[13px] font-medium truncate" style="color:var(--v2-text-text-base)">w2</div>
467
+ <div class="text-[11px] truncate" style="color:var(--v2-text-text-faint)">/home/user/w2</div>
468
+ </div>
469
+ <span class="card-status-dot online"></span>
470
+ </div>
471
+ <div class="flex items-center gap-2 mb-2">
472
+ <span class="card-tag">python</span>
473
+ <span class="card-tag">cli</span>
474
+ <span class="card-tag">auth</span>
475
+ </div>
476
+ <div class="flex items-center gap-2 text-[11px]" style="color:var(--v2-text-text-muted)">
477
+ <svg class="icon-sm"><use href="#icon-edit"/></svg>
478
+ <span>Refactor auth middleware</span>
479
+ </div>
480
+ <div class="mt-2 text-[11px]" style="color:var(--v2-text-text-faint)">Updated 5 hours ago</div>
481
+ </div>
482
+
483
+ <!-- astro -->
484
+ <div class="project-card">
485
+ <div class="flex items-center gap-2 mb-2">
486
+ <span class="w-7 h-7 rounded-[6px] flex items-center justify-center text-[11px] font-bold shrink-0" style="background:#fef3c7;color:#b45309">AS</span>
487
+ <div class="min-w-0 flex-1">
488
+ <div class="text-[13px] font-medium truncate" style="color:var(--v2-text-text-base)">astro</div>
489
+ <div class="text-[11px] truncate" style="color:var(--v2-text-text-faint)">/home/user/astro</div>
490
+ </div>
491
+ <span class="card-status-dot online"></span>
492
+ </div>
493
+ <div class="flex items-center gap-2 mb-2">
494
+ <span class="card-tag">astro</span>
495
+ <span class="card-tag">react</span>
496
+ <span class="card-tag">tailwind</span>
497
+ </div>
498
+ <div class="flex items-center gap-2 text-[11px]" style="color:var(--v2-text-text-muted)">
499
+ <svg class="icon-sm"><use href="#icon-edit"/></svg>
500
+ <span>Deploy Astro site</span>
501
+ </div>
502
+ <div class="mt-2 text-[11px]" style="color:var(--v2-text-text-faint)">Updated 1 day ago</div>
503
+ </div>
504
+
505
+ <!-- wd -->
506
+ <div class="project-card">
507
+ <div class="flex items-center gap-2 mb-2">
508
+ <span class="w-7 h-7 rounded-[6px] flex items-center justify-center text-[11px] font-bold shrink-0" style="background:#dbeafe;color:#2563eb">WD</span>
509
+ <div class="min-w-0 flex-1">
510
+ <div class="text-[13px] font-medium truncate" style="color:var(--v2-text-text-base)">wd</div>
511
+ <div class="text-[11px] truncate" style="color:var(--v2-text-text-faint)">/home/user/wd</div>
512
+ </div>
513
+ <span class="card-status-dot idle"></span>
514
+ </div>
515
+ <div class="flex items-center gap-2 mb-2">
516
+ <span class="card-tag">rust</span>
517
+ <span class="card-tag">database</span>
518
+ </div>
519
+ <div class="flex items-center gap-2 text-[11px]" style="color:var(--v2-text-text-muted)">
520
+ <svg class="icon-sm"><use href="#icon-edit"/></svg>
521
+ <span>Database migration plan</span>
522
+ </div>
523
+ <div class="mt-2 text-[11px]" style="color:var(--v2-text-text-faint)">Updated 2 days ago</div>
524
+ </div>
525
+
526
+ <!-- claude-engineer -->
527
+ <div class="project-card">
528
+ <div class="flex items-center gap-2 mb-2">
529
+ <span class="w-7 h-7 rounded-[6px] flex items-center justify-center text-[11px] font-bold shrink-0" style="background:#fce7f3;color:#be185d">CE</span>
530
+ <div class="min-w-0 flex-1">
531
+ <div class="text-[13px] font-medium truncate" style="color:var(--v2-text-text-base)">claude-engineer</div>
532
+ <div class="text-[11px] truncate" style="color:var(--v2-text-text-faint)">/home/user/claude-engineer</div>
533
+ </div>
534
+ <span class="card-status-dot offline"></span>
535
+ </div>
536
+ <div class="flex items-center gap-2 mb-2">
537
+ <span class="card-tag">typescript</span>
538
+ <span class="card-tag">ai</span>
539
+ <span class="card-tag">cli</span>
540
+ </div>
541
+ <div class="flex items-center gap-2 text-[11px]" style="color:var(--v2-text-text-muted)">
542
+ <svg class="icon-sm"><use href="#icon-edit"/></svg>
543
+ <span>API integration</span>
544
+ </div>
545
+ <div class="mt-2 text-[11px]" style="color:var(--v2-text-text-faint)">Updated 3 days ago</div>
546
+ </div>
547
+
548
+ <!-- OcDash -->
549
+ <div class="project-card" style="border-color:var(--v2-icon-icon-accent)">
550
+ <div class="flex items-center gap-2 mb-2">
551
+ <span class="w-7 h-7 rounded-[6px] flex items-center justify-center text-[11px] font-bold shrink-0" style="background:#ede9fe;color:#6d28d9">OD</span>
552
+ <div class="min-w-0 flex-1">
553
+ <div class="text-[13px] font-medium truncate" style="color:var(--v2-text-text-base)">ocdash-app</div>
554
+ <div class="text-[11px] truncate" style="color:var(--v2-text-text-faint)">/home/user/ocdash-app</div>
555
+ </div>
556
+ <span class="card-status-dot online"></span>
557
+ </div>
558
+ <div class="flex items-center gap-2 mb-2">
559
+ <span class="card-tag" style="background:color-mix(in srgb, var(--v2-icon-icon-accent) 12%, transparent);color:var(--v2-icon-icon-accent)">active</span>
560
+ <span class="card-tag">solidjs</span>
561
+ <span class="card-tag">dashboard</span>
562
+ </div>
563
+ <div class="flex items-center gap-2 text-[11px]" style="color:var(--v2-text-text-muted)">
564
+ <svg class="icon-sm"><use href="#icon-edit"/></svg>
565
+ <span>Build dashboard UI</span>
566
+ </div>
567
+ <div class="mt-2 text-[11px]" style="color:var(--v2-text-text-faint)">Updated just now</div>
568
+ </div>
569
+ </div>
570
+ </div>
571
+ </div>
572
+ </div>
573
+ </div>
574
+
575
+ <!-- Command Palette -->
576
+ <div class="cmd-palette" id="cmd-palette">
577
+ <input type="text" placeholder="Type a command or search..." id="cmd-input" autocomplete="off"
578
+ onkeydown="if(event.key==='Escape')closeCommandPalette()"/>
579
+ <div class="border-t px-3 py-2 flex flex-col" style="border-color:var(--v2-border-border-muted)" id="cmd-results">
580
+ <div class="flex items-center gap-2 px-2 py-1.5 rounded-[6px] text-[13px] cursor-default hover:bg-v2-overlay-simple-overlay-hover" style="color:var(--v2-text-text-base)" onclick="closeCommandPalette();openSettings()">
581
+ <svg class="icon-sm"><use href="#icon-settings"/></svg>
582
+ <span>Open Settings</span>
583
+ <span class="ml-auto text-[11px]" style="color:var(--v2-text-text-faint)">Ctrl+,</span>
584
+ </div>
585
+ <div class="flex items-center gap-2 px-2 py-1.5 rounded-[6px] text-[13px] cursor-default hover:bg-v2-overlay-simple-overlay-hover" style="color:var(--v2-text-text-base)" onclick="closeCommandPalette();toggleDark()">
586
+ <svg class="icon-sm"><use href="#icon-sun"/></svg>
587
+ <span>Toggle Theme</span>
588
+ </div>
589
+ <div class="flex items-center gap-2 px-2 py-1.5 rounded-[6px] text-[13px] cursor-default hover:bg-v2-overlay-simple-overlay-hover" style="color:var(--v2-text-text-base)" onclick="closeCommandPalette();openHelp()">
590
+ <svg class="icon-sm"><use href="#icon-help"/></svg>
591
+ <span>Help & Feedback</span>
592
+ </div>
593
+ </div>
594
+ </div>
595
+
596
+ <!-- Settings Modal -->
597
+ <div class="modal-overlay" id="settings-modal">
598
+ <div class="modal-content">
599
+ <div class="flex items-center justify-between px-5 py-4 border-b" style="border-color:var(--v2-border-border-muted)">
600
+ <h2 class="text-[15px] font-semibold">Settings</h2>
601
+ <button class="nav-icon-btn" onclick="closeSettings()"><svg class="icon"><use href="#icon-close"/></svg></button>
602
+ </div>
603
+ <div class="p-5 space-y-4">
604
+ <div>
605
+ <label class="block text-[13px] font-medium mb-1" style="color:var(--v2-text-text-base)">Theme</label>
606
+ <div class="flex gap-2">
607
+ <button class="mode-btn active" onclick="setTheme('light')">Light</button>
608
+ <button class="mode-btn" onclick="setTheme('dark')">Dark</button>
609
+ <button class="mode-btn" onclick="setTheme('system')">System</button>
610
+ </div>
611
+ </div>
612
+ <div>
613
+ <label class="block text-[13px] font-medium mb-1" style="color:var(--v2-text-text-base)">Default Model</label>
614
+ <select class="model-select w-full p-2 rounded-[6px] text-[13px]" style="background:var(--v2-background-bg-layer-01);color:var(--v2-text-text-base);border:1px solid var(--v2-border-border-muted)">
615
+ <option>deepseek-v4</option>
616
+ <option>gpt-4o</option>
617
+ <option>claude-opus-4</option>
618
+ <option>claude-sonnet-4</option>
619
+ <option>llama-4</option>
620
+ </select>
621
+ </div>
622
+ <div>
623
+ <label class="block text-[13px] font-medium mb-1" style="color:var(--v2-text-text-base)">API Keys</label>
624
+ <p class="text-[12px]" style="color:var(--v2-text-text-muted)">Configure your API keys in the OpenCode desktop app.</p>
625
+ </div>
626
+ </div>
627
+ <div class="flex justify-end px-5 py-3 border-t gap-2" style="border-color:var(--v2-border-border-muted)">
628
+ <button class="mode-btn active" onclick="closeSettings()">Close</button>
629
+ </div>
630
+ </div>
631
+ </div>
632
+
633
+ <!-- Help Modal -->
634
+ <div class="modal-overlay" id="help-modal">
635
+ <div class="modal-content">
636
+ <div class="flex items-center justify-between px-5 py-4 border-b" style="border-color:var(--v2-border-border-muted)">
637
+ <h2 class="text-[15px] font-semibold">Help & Feedback</h2>
638
+ <button class="nav-icon-btn" onclick="closeHelp()"><svg class="icon"><use href="#icon-close"/></svg></button>
639
+ </div>
640
+ <div class="p-5 space-y-4">
641
+ <div>
642
+ <h3 class="text-[13px] font-medium mb-1" style="color:var(--v2-text-text-base)">Keyboard Shortcuts</h3>
643
+ <div class="text-[12px] space-y-1" style="color:var(--v2-text-text-muted)">
644
+ <div><kbd class="px-1.5 py-0.5 rounded text-[11px]" style="background:var(--v2-background-bg-layer-01)">Ctrl+K</kbd> Command Palette</div>
645
+ <div><kbd class="px-1.5 py-0.5 rounded text-[11px]" style="background:var(--v2-background-bg-layer-01)">Ctrl+,</kbd> Settings</div>
646
+ <div><kbd class="px-1.5 py-0.5 rounded text-[11px]" style="background:var(--v2-background-bg-layer-01)">Enter</kbd> Send Message</div>
647
+ <div><kbd class="px-1.5 py-0.5 rounded text-[11px]" style="background:var(--v2-background-bg-layer-01)">Shift+Enter</kbd> New Line</div>
648
+ </div>
649
+ </div>
650
+ <div>
651
+ <h3 class="text-[13px] font-medium mb-1" style="color:var(--v2-text-text-base)">About OcDash</h3>
652
+ <p class="text-[12px]" style="color:var(--v2-text-text-muted)">OcDash is a web dashboard for OpenCode workspaces. View your projects, manage sessions, and interact with your AI coding assistant.</p>
653
+ </div>
654
+ <div>
655
+ <h3 class="text-[13px] font-medium mb-1" style="color:var(--v2-text-text-base)">Get Help</h3>
656
+ <p class="text-[12px]" style="color:var(--v2-text-text-muted)">Visit <a href="https://opencode.ai/desktop-feedback" target="_blank" style="color:var(--v2-icon-icon-accent)">opencode.ai/desktop-feedback</a> for support.</p>
657
+ </div>
658
+ </div>
659
+ <div class="flex justify-end px-5 py-3 border-t gap-2" style="border-color:var(--v2-border-border-muted)">
660
+ <button class="mode-btn active" onclick="closeHelp()">Close</button>
661
+ </div>
662
+ </div>
663
+ </div>
664
+
665
+ <script>
666
+ // Theme management
667
+ function getPreferredTheme() {
668
+ const stored = localStorage.getItem('ocdash-theme')
669
+ if (stored === 'dark' || stored === 'light') return stored
670
+ return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
671
+ }
672
+ function setTheme(mode) {
673
+ const html = document.documentElement
674
+ if (mode === 'system') {
675
+ localStorage.removeItem('ocdash-theme')
676
+ mode = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
677
+ } else {
678
+ localStorage.setItem('ocdash-theme', mode)
679
+ }
680
+ html.classList.toggle('dark', mode === 'dark')
681
+ const icon = document.getElementById('theme-icon')
682
+ if (icon) icon.setAttribute('href', mode === 'dark' ? '#icon-moon' : '#icon-sun')
683
+ }
684
+ function toggleDark() {
685
+ const isDark = document.documentElement.classList.contains('dark')
686
+ setTheme(isDark ? 'light' : 'dark')
687
+ }
688
+ setTheme(getPreferredTheme())
689
+
690
+ // Modals
691
+ function openSettings() { document.getElementById('settings-modal').classList.add('open') }
692
+ function closeSettings() { document.getElementById('settings-modal').classList.remove('open') }
693
+ function openHelp() { document.getElementById('help-modal').classList.add('open') }
694
+ function closeHelp() { document.getElementById('help-modal').classList.remove('open') }
695
+
696
+ // Close modals on overlay click
697
+ document.querySelectorAll('.modal-overlay').forEach(el => {
698
+ el.addEventListener('click', function(e) {
699
+ if (e.target === this) this.classList.remove('open')
700
+ })
701
+ })
702
+
703
+ // Command palette
704
+ function openCommandPalette() {
705
+ document.getElementById('cmd-palette').classList.add('open')
706
+ document.getElementById('cmd-input').focus()
707
+ }
708
+ function closeCommandPalette() {
709
+ document.getElementById('cmd-palette').classList.remove('open')
710
+ document.getElementById('cmd-input').blur()
711
+ }
712
+ document.addEventListener('keydown', function(e) {
713
+ if ((e.ctrlKey || e.metaKey) && e.key === 'k') {
714
+ e.preventDefault()
715
+ const palette = document.getElementById('cmd-palette')
716
+ if (palette.classList.contains('open')) closeCommandPalette()
717
+ else openCommandPalette()
718
+ }
719
+ })
720
+ // Close palette on click outside
721
+ document.getElementById('cmd-palette')?.addEventListener('click', function(e) {
722
+ if (e.target === this) closeCommandPalette()
723
+ })
724
+
725
+ // Chat
726
+ function sendMessage() {
727
+ const input = document.getElementById('chat-input')
728
+ const text = input.value.trim()
729
+ if (!text) return
730
+ const messages = document.getElementById('chat-messages')
731
+ const userMsg = document.createElement('div')
732
+ userMsg.className = 'msg-bubble user'
733
+ userMsg.textContent = text
734
+ messages.appendChild(userMsg)
735
+ input.value = ''
736
+ // Show typing indicator
737
+ const typing = document.getElementById('typing-indicator')
738
+ if (typing) typing.style.display = 'block'
739
+ messages.scrollTop = messages.scrollHeight
740
+ // Simulate response
741
+ setTimeout(() => {
742
+ if (typing) typing.style.display = 'none'
743
+ const assistantMsg = document.createElement('div')
744
+ assistantMsg.className = 'msg-bubble assistant'
745
+ const header = document.createElement('div')
746
+ header.className = 'flex items-center gap-2 mb-1'
747
+ header.innerHTML = '<span class="w-5 h-5 rounded flex items-center justify-center text-[10px] font-bold shrink-0" style="background:var(--v2-icon-icon-accent);color:var(--v2-text-text-inverse)">OC</span><span class="text-[11px]" style="color:var(--v2-text-text-muted)">OpenCode</span>'
748
+ const body = document.createElement('div')
749
+ body.textContent = "I'm analyzing your request. Let me work through this..."
750
+ assistantMsg.appendChild(header)
751
+ assistantMsg.appendChild(body)
752
+ messages.appendChild(assistantMsg)
753
+ messages.scrollTop = messages.scrollHeight
754
+ }, 800)
755
+ }
756
+
757
+ // Mode buttons
758
+ document.querySelectorAll('.mode-btn').forEach(btn => {
759
+ btn.addEventListener('click', function() {
760
+ const parent = this.parentElement
761
+ if (parent) {
762
+ parent.querySelectorAll('.mode-btn').forEach(b => b.classList.remove('active'))
763
+ }
764
+ this.classList.add('active')
765
+ })
766
+ })
767
+
768
+ console.log('OcDash v0.1 — OpenCode Workspace Dashboard')
769
+ </script>
770
+ <script>
771
+ if (window.__HF_TOKEN__) {
772
+ console.log('HF Space configured with token')
773
+ }
774
+ </script>
775
+ </body>
776
  </html>