webssh2_client 1.0.0-alpha.1 → 2.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -97,9 +97,255 @@ Supported URL parameters include:
97
97
  - `host` - SSH server hostname
98
98
  - `port` - SSH server port (default: 22)
99
99
  - `header` - Optional header text
100
- - `headerBackground` - Optional header background color
100
+ - `headerStyle` - Complete header styling with Tailwind CSS classes or CSS (recommended)
101
+ - `headerBackground` - Header background styling only (legacy, see Advanced Header Styling below)
101
102
  - `sshterm` - Terminal type (default: xterm-color)
102
103
 
104
+ #### Advanced Header Styling
105
+
106
+ WebSSH2 Client supports comprehensive header styling through two approaches: **enhanced headerStyle** (recommended) and **legacy headerBackground** (maintained for backward compatibility).
107
+
108
+ ##### Enhanced Header Styling (headerStyle)
109
+
110
+ The `headerStyle` parameter provides complete control over header appearance using Tailwind CSS classes or CSS properties:
111
+
112
+ **Basic Examples:**
113
+
114
+ ```
115
+ # Enhanced background with custom height and text
116
+ ?header=Production&headerStyle=bg-red-600%20h-10%20text-xl%20font-bold
117
+
118
+ # Gradient with custom styling
119
+ ?header=Staging&headerStyle=bg-gradient-to-r%20from-blue-500%20to-purple-500%20h-8%20text-lg
120
+
121
+ # Custom text colors and shadows
122
+ ?header=Development&headerStyle=bg-green-500%20text-black%20font-semibold%20shadow-lg
123
+ ```
124
+
125
+ **Advanced Styling Capabilities:**
126
+
127
+ **Backgrounds & Gradients:**
128
+
129
+ ```
130
+ # Multi-directional gradients
131
+ ?headerStyle=bg-gradient-to-br%20from-purple-600%20via-pink-500%20to-yellow-400%20h-12
132
+
133
+ # Solid colors with transparency
134
+ ?headerStyle=bg-blue-500%20h-8%20shadow-blue-500/50
135
+
136
+ # Complex gradient patterns
137
+ ?headerStyle=bg-gradient-to-r%20from-red-500%20via-yellow-500%20to-green-500%20h-10
138
+ ```
139
+
140
+ **Typography & Layout:**
141
+
142
+ ```
143
+ # Large headers with custom fonts
144
+ ?headerStyle=bg-slate-700%20h-16%20text-3xl%20font-black%20flex%20items-center%20justify-center
145
+
146
+ # Compact headers
147
+ ?headerStyle=bg-indigo-600%20h-5%20text-xs%20font-medium
148
+
149
+ # Custom text alignment and colors
150
+ ?headerStyle=bg-gradient-to-r%20from-cyan-400%20to-blue-500%20text-left%20text-yellow-100%20px-4
151
+ ```
152
+
153
+ **Borders & Effects:**
154
+
155
+ ```
156
+ # Styled borders
157
+ ?headerStyle=bg-purple-500%20border-2%20border-white%20border-dashed%20h-8
158
+
159
+ # Shadow effects
160
+ ?headerStyle=bg-green-500%20shadow-xl%20shadow-green-500/50%20rounded-lg%20h-10
161
+
162
+ # Rounded corners
163
+ ?headerStyle=bg-gradient-to-r%20from-pink-400%20to-rose-500%20rounded-xl%20h-12%20mx-2
164
+ ```
165
+
166
+ **Animations:**
167
+
168
+ ```
169
+ # Pulsing effect for alerts
170
+ ?headerStyle=bg-red-600%20animate-pulse%20h-8%20font-bold
171
+
172
+ # Bouncing for urgent notifications
173
+ ?headerStyle=bg-yellow-500%20animate-bounce%20h-10%20text-black%20font-semibold
174
+ ```
175
+
176
+ **Production Examples:**
177
+
178
+ ```
179
+ # Critical system warning
180
+ ?header=🚨%20PRODUCTION%20-%20CRITICAL%20🚨&headerStyle=bg-gradient-to-r%20from-red-600%20to-red-700%20h-12%20text-2xl%20font-bold%20animate-pulse%20shadow-lg
181
+
182
+ # Development environment
183
+ ?header=🛠️%20Development%20Environment&headerStyle=bg-gradient-to-r%20from-green-400%20to-emerald-600%20h-8%20text-white%20font-medium
184
+
185
+ # Staging deployment
186
+ ?header=🚀%20Staging%20Deployment&headerStyle=bg-gradient-to-r%20from-yellow-400%20to-orange-500%20h-10%20text-black%20font-semibold%20border-b-2%20border-orange-600
187
+
188
+ # Secure connection
189
+ ?header=🔐%20Encrypted%20Connection&headerStyle=bg-gradient-to-r%20from-emerald-500%20to-teal-600%20h-8%20text-white%20shadow-md
190
+ ```
191
+
192
+ ##### Legacy Header Styling (headerBackground)
193
+
194
+ For backward compatibility, the original `headerBackground` parameter is still supported:
195
+
196
+ **Basic Colors:**
197
+
198
+ ```
199
+ ?header=Production&headerBackground=red
200
+ ?header=Custom&headerBackground=%23ff6b35
201
+ ```
202
+
203
+ **Tailwind Classes:**
204
+
205
+ ```
206
+ ?header=Server%20Alpha&headerBackground=bg-blue-500
207
+ ?header=Critical%20System&headerBackground=bg-red-600
208
+ ```
209
+
210
+ **Simple Gradients:**
211
+
212
+ ```
213
+ ?header=Gradient%20Demo&headerBackground=bg-gradient-to-r%20from-blue-500%20to-purple-500
214
+ ```
215
+
216
+ ##### Header Styling Reference
217
+
218
+ **Essential Styling Categories:**
219
+
220
+ **🎨 Background Colors & Gradients**
221
+
222
+ ```
223
+ # Solid Colors
224
+ bg-red-600, bg-blue-500, bg-green-500, bg-yellow-500, bg-purple-500
225
+ bg-slate-700, bg-gray-800
226
+
227
+ # Gradients (Direction + Colors)
228
+ bg-gradient-to-r from-red-600 to-red-700
229
+ bg-gradient-to-br from-purple-500 via-pink-500 to-yellow-400
230
+ bg-gradient-to-tl from-blue-400 to-cyan-500
231
+ ```
232
+
233
+ **📝 Text Styling**
234
+
235
+ ```
236
+ # Sizes: text-xs, text-sm, text-base, text-lg, text-xl, text-2xl, text-3xl, text-4xl
237
+ # Weights: font-normal, font-medium, font-semibold, font-bold, font-black
238
+ # Colors: text-white, text-black, text-yellow-100, text-red-100, text-blue-100
239
+
240
+ # Examples
241
+ text-2xl font-bold text-white
242
+ text-sm font-medium text-black
243
+ text-4xl font-black text-yellow-100
244
+ ```
245
+
246
+ **📏 Header Heights**
247
+
248
+ ```
249
+ # Available: h-4, h-5, h-6, h-7, h-8, h-10, h-12, h-14, h-16
250
+ # Default was h-6 (24px), now customizable
251
+
252
+ h-8 # Compact header
253
+ h-12 # Standard header
254
+ h-16 # Prominent header
255
+ ```
256
+
257
+ **✨ Visual Effects**
258
+
259
+ ```
260
+ # Animations
261
+ animate-pulse # Pulsing effect for alerts
262
+ animate-bounce # Bouncing for urgent notifications
263
+
264
+ # Shadows
265
+ shadow-md, shadow-lg, shadow-xl
266
+
267
+ # Borders
268
+ border-2 border-white border-dashed
269
+ rounded-lg, rounded-xl
270
+ ```
271
+
272
+ **📍 Layout & Positioning**
273
+
274
+ ```
275
+ # Text Alignment
276
+ text-left, text-center, text-right
277
+
278
+ # Spacing
279
+ px-4, px-6 (horizontal padding)
280
+ py-2, py-3 (vertical padding)
281
+
282
+ # Flexbox (for complex layouts)
283
+ flex items-center justify-center
284
+ ```
285
+
286
+ **Common Use Cases:**
287
+
288
+ **🚨 Production/Critical Systems:**
289
+
290
+ ```
291
+ # Red gradient with large text and pulsing animation
292
+ bg-gradient-to-r from-red-600 to-red-700 h-12 text-2xl font-bold animate-pulse
293
+
294
+ # Solid red with white border
295
+ bg-red-600 border-2 border-white h-10 text-xl font-bold
296
+ ```
297
+
298
+ **🚀 Staging/Development:**
299
+
300
+ ```
301
+ # Yellow-orange gradient for staging
302
+ bg-gradient-to-r from-yellow-400 to-orange-500 h-10 text-black font-semibold
303
+
304
+ # Green for development
305
+ bg-gradient-to-r from-green-400 to-emerald-600 h-8 text-white font-medium
306
+ ```
307
+
308
+ **🔒 Secure/Special Connections:**
309
+
310
+ ```
311
+ # Blue gradient with shadow
312
+ bg-gradient-to-r from-blue-500 to-cyan-500 h-8 shadow-lg
313
+
314
+ # Purple with rounded corners
315
+ bg-purple-600 rounded-lg h-10 font-semibold
316
+ ```
317
+
318
+ **⚡ Quick Reference:**
319
+
320
+ - **Colors**: red, blue, green, yellow, purple, pink, cyan, emerald, slate, gray
321
+ - **Shades**: 400 (lighter), 500 (medium), 600 (darker), 700 (darkest common)
322
+ - **Text sizes**: xs, sm, base, lg, xl, 2xl, 3xl, 4xl
323
+ - **Heights**: 4-16 (h-4 = 16px, h-16 = 64px)
324
+ - **Combine freely**: `bg-blue-500 h-12 text-xl font-bold animate-pulse shadow-lg`
325
+
326
+ ##### Styling System Features
327
+
328
+ **Automatic Detection:**
329
+ The system automatically detects whether you're using:
330
+
331
+ - Tailwind CSS classes (applied as CSS classes)
332
+ - CSS color values (applied as inline styles)
333
+
334
+ **Complete Tailwind Support:**
335
+
336
+ - **Backgrounds:** Solid colors, gradients, transparency
337
+ - **Typography:** Font sizes, weights, colors, alignment
338
+ - **Layout:** Heights, padding, margins, flexbox
339
+ - **Borders:** Styles, colors, radius
340
+ - **Effects:** Shadows, animations
341
+ - **Bundle Optimized:** Curated safelist keeps CSS file size reasonable (~38KB)
342
+
343
+ **Backward Compatibility:**
344
+
345
+ - Existing `headerBackground` URLs continue to work
346
+ - Mixed usage supported (header + headerBackground or headerStyle)
347
+ - Graceful fallback to CSS for non-Tailwind values
348
+
103
349
  ### Configuration Object
104
350
 
105
351
  You can configure the client by setting `window.webssh2Config`:
@@ -1,149 +1,25 @@
1
- <!-- Version Version 1.0.0-alpha.1 - 2025-09-05T15:41:27.852Z - 200680b -->
1
+ <!-- Version Version 2.0.0-alpha.1 - 2025-09-07T02:20:37.207Z - 5a009ff -->
2
2
  <!-- webssh2-client -->
3
3
  <!-- /client/src/client.htm -->
4
4
  <!DOCTYPE html>
5
- <html lang="en" class="h-dvh">
5
+ <html lang="en" class="h-dvh bg-black">
6
6
  <head>
7
7
  <title>WebSSH2</title>
8
8
  <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover, interactive-widget=resizes-content">
9
9
  <link rel="icon" type="image/x-icon" href="./favicon.ico">
10
+ <style>
11
+ /* Prevent white flash during initial load */
12
+ html, body, #app {
13
+ background-color: #000 !important;
14
+ color: #f5f5f5 !important;
15
+ }
16
+ </style>
10
17
  <script type="module" crossorigin src="./webssh2.bundle.js"></script>
11
18
  <link rel="stylesheet" crossorigin href="./webssh2.css">
12
19
  </head>
13
20
  <body class="h-dvh overflow-hidden bg-black text-neutral-100">
14
- <dialog id="loginDialog" class="modal">
15
- <div class="modal-content relative bg-white text-slate-800 border border-neutral-300 rounded-md shadow-md p-6 w-80 sm:w-[28rem]">
16
- <h2 class="text-lg font-semibold text-slate-900 mb-2">WebSSH2 Login</h2>
17
- <form id="loginForm" class="space-y-3">
18
- <label for="hostInput" class="sr-only">Host</label>
19
- <input type="text" id="hostInput" name="host" placeholder="Host" required autocomplete="off" autocapitalize="off" spellcheck="false" enterkeyhint="next" class="block w-full rounded-md border border-slate-300 bg-white text-slate-900 placeholder-slate-400 px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
20
- <label for="portInput" class="sr-only">Port</label>
21
- <input type="text" id="portInput" name="port" placeholder="Port" value="22" autocomplete="off" autocapitalize="off" spellcheck="false" enterkeyhint="next" inputmode="numeric" pattern="[0-9]*" class="block w-full rounded-md border border-slate-300 bg-white text-slate-900 placeholder-slate-400 px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
22
- <label for="usernameInput" class="sr-only">Username</label>
23
- <input type="text" id="usernameInput" name="username" placeholder="Username" required autocomplete="username" autocapitalize="off" spellcheck="false" enterkeyhint="next" class="block w-full rounded-md border border-slate-300 bg-white text-slate-900 placeholder-slate-400 px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
24
-
25
- <!-- Password section - always visible -->
26
- <div class="password-wrapper relative w-full">
27
- <label for="passwordInput" class="sr-only">Password</label>
28
- <input type="password" id="passwordInput" name="password" placeholder="Password" autocomplete="current-password" autocapitalize="off" spellcheck="false" enterkeyhint="go" class="block w-full rounded-md border border-slate-300 bg-white text-slate-900 placeholder-slate-400 px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
29
- <span id="capsLockIcon" class="hidden absolute right-2 top-1/2 -translate-y-1/2 text-red-500 pointer-events-none">⇪</span>
30
- </div>
31
-
32
- <!-- Options row: Add SSH Key + Options -->
33
- <div class="flex items-center justify-between gap-2">
34
- <div class="private-key-toggle">
35
- <button type="button" id="privateKeyToggle" class="inline-flex items-center justify-center rounded-md border border-transparent px-3 py-2 text-sm font-medium bg-slate-600 text-white hover:bg-slate-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-slate-500 disabled:opacity-50 disabled:pointer-events-none shadow-sm">
36
- <i data-icon="key" class="icon-fw"></i> Add SSH Key
37
- </button>
38
- </div>
39
- <div>
40
- <button type="button" id="loginSettingsBtn" class="inline-flex items-center justify-center rounded-md border border-transparent px-3 py-2 text-sm font-medium bg-slate-700 text-white hover:bg-slate-800 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-slate-500 disabled:opacity-50 disabled:pointer-events-none shadow-sm" aria-label="Options" title="Options">
41
- <i data-icon="settings" class="icon-fw"></i> Options
42
- </button>
43
- </div>
44
- </div>
45
-
46
- <!-- Private key section (initially hidden) -->
47
- <div id="privateKeySection" class="hidden">
48
- <div class="private-key-input mt-2 p-3 rounded border border-neutral-300 bg-neutral-50 text-neutral-800">
49
- <label for="privateKeyText" class="sr-only">Private Key</label>
50
- <textarea id="privateKeyText" name="privateKey" autocomplete="off" autocapitalize="off" spellcheck="false"
51
- placeholder="Paste your private key here" rows="3" class="block w-full rounded-md border border-slate-300 bg-white text-slate-900 placeholder-slate-400 px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"></textarea>
52
- <div class="file-upload">
53
- <input type="file" id="privateKeyFile" class="sr-only">
54
- <label for="privateKeyFile" class="inline-flex items-center justify-center rounded-md border border-transparent px-3 py-2 text-sm font-medium bg-slate-600 text-white hover:bg-slate-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-slate-500 disabled:opacity-50 disabled:pointer-events-none shadow-sm">
55
- <i data-icon="upload" class="icon-fw"></i> Upload Key File
56
- </label>
57
- </div>
58
- <label for="passphraseInput" class="sr-only">Key Passphrase</label>
59
- <input type="password" id="passphraseInput" name="passphrase" autocomplete="off" autocapitalize="off" spellcheck="false" enterkeyhint="go"
60
- placeholder="Key password (if encrypted)" class="optional block w-full rounded-md border border-slate-300 bg-white text-slate-900 placeholder-slate-400 px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
61
- </div>
62
- </div>
63
-
64
- <div class="login-buttons mt-2">
65
- <button type="submit" class="inline-flex w-full items-center justify-center rounded-md border border-transparent px-3 py-2 text-sm font-medium bg-blue-600 text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none">Connect</button>
66
- </div>
67
- </form>
68
- </div>
69
- </dialog>
70
- <dialog id="errorDialog" class="modal">
71
- <div class="modal-content relative error-modal bg-red-50 border border-red-400 rounded-md shadow-md p-5 w-80 sm:w-96">
72
- <button type="button" autofocus class="close-button absolute top-2 right-2 text-neutral-400 hover:text-neutral-600 text-xl leading-none p-0 bg-transparent border-0">&times;</button>
73
- <h2 class="text-red-700">Error</h2>
74
- <p id="errorMessage"></p>
75
- </div>
76
- </dialog>
77
- <dialog id="promptDialog" class="modal">
78
- <div class="modal-content relative prompt-modal bg-white text-slate-800 border border-neutral-300 rounded-md shadow-md p-5 w-80 sm:w-96">
79
- <button type="button" autofocus class="close-button absolute top-2 right-2 text-neutral-400 hover:text-neutral-600 text-xl leading-none p-0 bg-transparent border-0">&times;</button>
80
- <h2 id="promptMessage">Authentication Required</h2>
81
- <form>
82
- <div id="promptInputContainer" class="mb-4 space-y-2"></div>
83
- <button type="submit" class="inline-flex items-center justify-center rounded-md border border-transparent px-3 py-2 text-sm font-medium bg-blue-600 text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none">Submit</button>
84
- </form>
85
- </div>
86
- </dialog>
87
- <dialog id="terminalSettingsDialog" class="modal">
88
- <div class="modal-content relative bg-white text-slate-800 border border-neutral-300 rounded-md shadow-md p-6 w-80 sm:w-[36rem]">
89
- <h2 class="text-lg font-semibold text-slate-900 mb-2">Terminal Settings</h2>
90
- <form id="terminalSettingsForm" class="space-y-2">
91
- <fieldset class="grid grid-cols-1 sm:grid-cols-[auto,1fr] gap-x-4 gap-y-3 items-center">
92
- <legend class="sr-only">Terminal Options</legend>
93
- <label for="fontSize" class="text-sm font-medium text-slate-700 sm:text-right pr-3 whitespace-nowrap">Font Size</label>
94
- <input type="number" id="fontSize" name="fontSize" min="8" max="72" required autocapitalize="off" spellcheck="false" class="block w-full rounded-md border border-slate-300 bg-white text-slate-900 placeholder-slate-400 px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
95
-
96
- <label for="fontFamily" class="text-sm font-medium text-slate-700 sm:text-right pr-3 whitespace-nowrap">Font Family</label>
97
- <input type="text" id="fontFamily" name="fontFamily" required autocapitalize="off" spellcheck="false" class="block w-full rounded-md border border-slate-300 bg-white text-slate-900 placeholder-slate-400 px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
98
-
99
- <label for="cursorBlink" class="text-sm font-medium text-slate-700 sm:text-right pr-3 whitespace-nowrap">Cursor Blink</label>
100
- <select id="cursorBlink" name="cursorBlink" class="block w-full rounded-md border border-slate-300 bg-white text-slate-900 px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
101
- <option value="true">On</option>
102
- <option value="false">Off</option>
103
- </select>
104
-
105
- <label for="scrollback" class="text-sm font-medium text-slate-700 sm:text-right pr-3 whitespace-nowrap">Scrollback</label>
106
- <input type="number" id="scrollback" name="scrollback" min="1" max="200000" required autocapitalize="off" spellcheck="false" class="block w-full rounded-md border border-slate-300 bg-white text-slate-900 placeholder-slate-400 px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
107
-
108
- <label for="tabStopWidth" class="text-sm font-medium text-slate-700 sm:text-right pr-3 whitespace-nowrap">Tab Stop Width</label>
109
- <input type="number" id="tabStopWidth" name="tabStopWidth" min="1" max="100" required autocapitalize="off" spellcheck="false" class="block w-full rounded-md border border-slate-300 bg-white text-slate-900 placeholder-slate-400 px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
110
-
111
- <label for="bellStyle" class="text-sm font-medium text-slate-700 sm:text-right pr-3 whitespace-nowrap">Bell Style</label>
112
- <select id="bellStyle" name="bellStyle" class="block w-full rounded-md border border-slate-300 bg-white text-slate-900 px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
113
- <option value="sound">Sound</option>
114
- <option value="none">None</option>
115
- </select>
116
- </fieldset>
117
- <div class="flex gap-2 pt-4 justify-end">
118
- <button type="submit" class="inline-flex items-center justify-center rounded-md border border-transparent px-3 py-2 text-sm font-medium bg-blue-600 text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none">Save</button>
119
- <button type="button" id="closeterminalSettingsBtn" class="inline-flex items-center justify-center rounded-md border border-transparent px-3 py-2 text-sm font-medium bg-slate-700 text-white hover:bg-slate-800 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-slate-500 disabled:opacity-50 disabled:pointer-events-none">Cancel</button>
120
- </div>
121
- </form>
122
- </div>
123
- </dialog>
124
- <div id="backdrop" class="backdrop hidden"></div>
125
- <button type="button" id="reconnectButton" class="hidden fixed left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 z-[1001] bg-blue-600 hover:bg-blue-700 text-white text-sm px-5 py-2 rounded shadow focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">Reconnect</button>
126
- <div class="box">
127
- <div id="header" class="hidden w-full text-center z-[99] h-6 leading-6 bg-green-600 text-white border-b border-neutral-200 shrink-0"></div>
128
- <div id="terminalContainer" class="terminal hidden flex-1 min-h-0 w-[calc(100%-1px)] max-w-[100vw] mx-auto p-[2px] pb-[env(safe-area-inset-bottom)] overscroll-contain touch-pan-y overflow-hidden"></div>
129
- <div id="bottomdiv" class="z-[99] h-6 flex items-center bg-neutral-800 text-neutral-100 border-t border-neutral-200 shrink-0">
130
- <div id="menu" class="relative group px-2">
131
- <button id="menuToggle" type="button" aria-controls="dropupContent" aria-expanded="false" class="inline-flex items-center gap-1 select-none">
132
- <i data-icon="menu" class="w-5 h-5 inline-block"></i> Menu
133
- </button>
134
- <div id="dropupContent" class="hidden group-hover:block absolute bottom-full left-0 min-w-56 bg-neutral-50 text-neutral-700 text-base shadow-md border border-neutral-200 z-[101]">
135
- <button type="button" id="clearLogBtn" class="hidden w-full text-left px-4 py-3 hover:bg-neutral-200 whitespace-nowrap inline-flex items-center gap-3"><i data-icon="trash-can" class="w-5 h-5 inline-block"></i> Clear Log</button>
136
- <button type="button" id="stopLogBtn" class="hidden w-full text-left px-4 py-3 hover:bg-neutral-200 whitespace-nowrap inline-flex items-center gap-3"><i data-icon="settings" class="animate-spin origin-center w-5 h-5 inline-block"></i> Stop Log</button>
137
- <button type="button" id="startLogBtn" class="w-full text-left px-4 py-3 hover:bg-neutral-200 whitespace-nowrap inline-flex items-center gap-3"><i data-icon="clipboard" class="w-5 h-5 inline-block"></i> Start Log</button>
138
- <button type="button" id="downloadLogBtn" class="hidden w-full text-left px-4 py-3 hover:bg-neutral-200 whitespace-nowrap inline-flex items-center gap-3"><i data-icon="download" class="w-5 h-5 inline-block"></i> Download Log</button>
139
- <button type="button" id="replayCredentialsBtn" class="w-full text-left px-4 py-3 hover:bg-neutral-200 whitespace-nowrap inline-flex items-center gap-3"><i data-icon="key" class="w-5 h-5 inline-block"></i> Credentials</button>
140
- <button type="button" id="reauthBtn" class="w-full text-left px-4 py-3 hover:bg-neutral-200 whitespace-nowrap inline-flex items-center gap-3"><i data-icon="key" class="w-5 h-5 inline-block"></i> Switch User</button>
141
- <button type="button" id="terminalSettingsBtn" class="w-full text-left px-4 py-3 hover:bg-neutral-200 whitespace-nowrap inline-flex items-center gap-3"><i data-icon="settings" class="w-5 h-5 inline-block"></i> Settings</button>
142
- </div>
143
- </div>
144
- <div id="footer" class="inline-block text-left px-[10px] border-l border-neutral-200"></div>
145
- <div id="status" role="status" aria-live="polite" aria-atomic="true" class="inline-block text-left px-[10px] z-[100] border-x border-neutral-200"></div>
146
- </div>
147
- </div>
21
+ <!-- SolidJS app will mount here -->
22
+ <!-- Static status element for testing (will be replaced by SolidJS app) -->
23
+ <div id="status" role="status" aria-live="polite" aria-atomic="true" class="hidden">Initializing...</div>
148
24
  </body>
149
25
  </html>