@hanzo/browser-extension 1.7.2

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.
Files changed (134) hide show
  1. package/.github/workflows/docs.yml +44 -0
  2. package/.github/workflows/release.yml +55 -0
  3. package/LICENSE +21 -0
  4. package/README.md +126 -0
  5. package/dist/browser-extension/README.md +43 -0
  6. package/dist/browser-extension/ai-worker.js +30 -0
  7. package/dist/browser-extension/background-firefox.js +617 -0
  8. package/dist/browser-extension/background.js +2737 -0
  9. package/dist/browser-extension/browser-control.js +683 -0
  10. package/dist/browser-extension/cdp-bridge-server.js +444 -0
  11. package/dist/browser-extension/chrome/ai-worker.js +571 -0
  12. package/dist/browser-extension/chrome/background.js +2737 -0
  13. package/dist/browser-extension/chrome/callback.html +17 -0
  14. package/dist/browser-extension/chrome/content-script.js +1270 -0
  15. package/dist/browser-extension/chrome/icon128.png +0 -0
  16. package/dist/browser-extension/chrome/icon16.png +0 -0
  17. package/dist/browser-extension/chrome/icon32.png +0 -0
  18. package/dist/browser-extension/chrome/icon48.png +0 -0
  19. package/dist/browser-extension/chrome/manifest.json +57 -0
  20. package/dist/browser-extension/chrome/popup.css +519 -0
  21. package/dist/browser-extension/chrome/popup.html +242 -0
  22. package/dist/browser-extension/chrome/popup.js +267 -0
  23. package/dist/browser-extension/chrome/sidebar.css +1176 -0
  24. package/dist/browser-extension/chrome/sidebar.html +280 -0
  25. package/dist/browser-extension/chrome/sidebar.js +778 -0
  26. package/dist/browser-extension/cli.js +233 -0
  27. package/dist/browser-extension/content-script.js +1270 -0
  28. package/dist/browser-extension/firefox/ai-worker.js +571 -0
  29. package/dist/browser-extension/firefox/background.js +617 -0
  30. package/dist/browser-extension/firefox/callback.html +17 -0
  31. package/dist/browser-extension/firefox/content-script.js +1270 -0
  32. package/dist/browser-extension/firefox/icon128.png +0 -0
  33. package/dist/browser-extension/firefox/icon16.png +0 -0
  34. package/dist/browser-extension/firefox/icon32.png +0 -0
  35. package/dist/browser-extension/firefox/icon48.png +0 -0
  36. package/dist/browser-extension/firefox/manifest.json +66 -0
  37. package/dist/browser-extension/firefox/popup.css +519 -0
  38. package/dist/browser-extension/firefox/popup.html +242 -0
  39. package/dist/browser-extension/firefox/popup.js +267 -0
  40. package/dist/browser-extension/firefox/sidebar.css +1176 -0
  41. package/dist/browser-extension/firefox/sidebar.html +280 -0
  42. package/dist/browser-extension/firefox/sidebar.js +778 -0
  43. package/dist/browser-extension/hanzo-browser-extension-firefox-1.1.0.zip +0 -0
  44. package/dist/browser-extension/icon128.png +0 -0
  45. package/dist/browser-extension/icon16.png +0 -0
  46. package/dist/browser-extension/icon32.png +0 -0
  47. package/dist/browser-extension/icon48.png +0 -0
  48. package/dist/browser-extension/manifest.json +57 -0
  49. package/dist/browser-extension/package.json +41 -0
  50. package/dist/browser-extension/popup.css +468 -0
  51. package/dist/browser-extension/popup.html +191 -0
  52. package/dist/browser-extension/popup.js +267 -0
  53. package/dist/browser-extension/safari/Info.plist +21 -0
  54. package/dist/browser-extension/safari/ai-worker.js +571 -0
  55. package/dist/browser-extension/safari/background.js +2737 -0
  56. package/dist/browser-extension/safari/callback.html +17 -0
  57. package/dist/browser-extension/safari/content-script.js +1270 -0
  58. package/dist/browser-extension/safari/icon128.png +0 -0
  59. package/dist/browser-extension/safari/icon16.png +0 -0
  60. package/dist/browser-extension/safari/icon32.png +0 -0
  61. package/dist/browser-extension/safari/icon48.png +0 -0
  62. package/dist/browser-extension/safari/popup.css +519 -0
  63. package/dist/browser-extension/safari/popup.html +242 -0
  64. package/dist/browser-extension/safari/popup.js +267 -0
  65. package/dist/browser-extension/safari/sidebar.css +1176 -0
  66. package/dist/browser-extension/safari/sidebar.html +280 -0
  67. package/dist/browser-extension/safari/sidebar.js +778 -0
  68. package/dist/browser-extension/sidebar.css +718 -0
  69. package/dist/browser-extension/sidebar.html +184 -0
  70. package/dist/browser-extension/sidebar.js +778 -0
  71. package/dist/browser-extension/webgpu-ai.js +495 -0
  72. package/dist/cdp-bridge-server.js +411 -0
  73. package/dist/safari/Hanzo AI/Hanzo AI.xcodeproj/project.pbxproj +1047 -0
  74. package/dist/safari/Hanzo AI/Hanzo AI.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  75. package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AccentColor.colorset/Contents.json +11 -0
  76. package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/Contents.json +98 -0
  77. package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/mac-icon-128@1x.png +0 -0
  78. package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/mac-icon-128@2x.png +0 -0
  79. package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/mac-icon-16@1x.png +0 -0
  80. package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/mac-icon-16@2x.png +0 -0
  81. package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/mac-icon-256@1x.png +0 -0
  82. package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/mac-icon-256@2x.png +0 -0
  83. package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/mac-icon-32@1x.png +0 -0
  84. package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/mac-icon-32@2x.png +0 -0
  85. package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/mac-icon-512@1x.png +0 -0
  86. package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/mac-icon-512@2x.png +0 -0
  87. package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/AppIcon.appiconset/universal-icon-1024@1x.png +0 -0
  88. package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/Contents.json +6 -0
  89. package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/LargeIcon.imageset/Contents.json +21 -0
  90. package/dist/safari/Hanzo AI/Shared (App)/Assets.xcassets/LargeIcon.imageset/icon128.png +0 -0
  91. package/dist/safari/Hanzo AI/Shared (App)/Resources/Base.lproj/Main.html +20 -0
  92. package/dist/safari/Hanzo AI/Shared (App)/Resources/Icon.png +0 -0
  93. package/dist/safari/Hanzo AI/Shared (App)/Resources/Script.js +24 -0
  94. package/dist/safari/Hanzo AI/Shared (App)/Resources/Style.css +61 -0
  95. package/dist/safari/Hanzo AI/Shared (App)/ViewController.swift +81 -0
  96. package/dist/safari/Hanzo AI/Shared (Extension)/SafariWebExtensionHandler.swift +42 -0
  97. package/dist/safari/Hanzo AI/iOS (App)/AppDelegate.swift +24 -0
  98. package/dist/safari/Hanzo AI/iOS (App)/Base.lproj/LaunchScreen.storyboard +36 -0
  99. package/dist/safari/Hanzo AI/iOS (App)/Base.lproj/Main.storyboard +38 -0
  100. package/dist/safari/Hanzo AI/iOS (App)/Info.plist +27 -0
  101. package/dist/safari/Hanzo AI/iOS (App)/SceneDelegate.swift +18 -0
  102. package/dist/safari/Hanzo AI/iOS (Extension)/Info.plist +13 -0
  103. package/dist/safari/Hanzo AI/macOS (App)/AppDelegate.swift +21 -0
  104. package/dist/safari/Hanzo AI/macOS (App)/Base.lproj/Main.storyboard +124 -0
  105. package/dist/safari/Hanzo AI/macOS (App)/Info.plist +8 -0
  106. package/dist/safari/Hanzo AI/macOS (Extension)/Info.plist +13 -0
  107. package/docs/_config.yml +13 -0
  108. package/docs/_layouts/default.html +435 -0
  109. package/docs/index.md +54 -0
  110. package/install-extension.sh +75 -0
  111. package/manifest.json +29 -0
  112. package/package.json +32 -0
  113. package/src/ai-worker.js +571 -0
  114. package/src/callback.html +17 -0
  115. package/src/chat-widget.tsx +93 -0
  116. package/src/icon128.png +0 -0
  117. package/src/icon16.png +0 -0
  118. package/src/icon32.png +0 -0
  119. package/src/icon48.png +0 -0
  120. package/src/manifest-firefox.json +66 -0
  121. package/src/manifest.json +57 -0
  122. package/src/package.json +41 -0
  123. package/src/popup.css +519 -0
  124. package/src/popup.html +242 -0
  125. package/src/popup.js +192 -0
  126. package/src/sidebar.css +1176 -0
  127. package/src/sidebar.html +280 -0
  128. package/src/sidebar.js +884 -0
  129. package/src/webgpu.d.ts +131 -0
  130. package/test/claude-integration.test.ts +251 -0
  131. package/test/server-frameworks-edge-cases.test.ts +145 -0
  132. package/test/server-frameworks.test.ts +395 -0
  133. package/test-cdp-connection.js +140 -0
  134. package/tsconfig.json +19 -0
@@ -0,0 +1,57 @@
1
+ {
2
+ "manifest_version": 3,
3
+ "name": "Hanzo AI",
4
+ "version": "1.7.2",
5
+ "description": "AI-powered dev assistant — click-to-code navigation, source maps, WebGPU AI, and MCP integration for Claude Code.",
6
+ "permissions": [
7
+ "activeTab",
8
+ "identity",
9
+ "sidePanel",
10
+ "storage",
11
+ "tabs",
12
+ "webNavigation",
13
+ "scripting",
14
+ "debugger"
15
+ ],
16
+ "host_permissions": [
17
+ "http://localhost/*",
18
+ "https://localhost/*",
19
+ "<all_urls>"
20
+ ],
21
+ "content_security_policy": {
22
+ "extension_pages": "script-src 'self' 'wasm-unsafe-eval'; object-src 'self';"
23
+ },
24
+ "content_scripts": [
25
+ {
26
+ "matches": ["<all_urls>"],
27
+ "js": ["content-script.js"],
28
+ "run_at": "document_idle"
29
+ }
30
+ ],
31
+ "background": {
32
+ "service_worker": "background.js",
33
+ "type": "module"
34
+ },
35
+ "action": {
36
+ "default_popup": "popup.html",
37
+ "default_icon": {
38
+ "16": "icon16.png",
39
+ "48": "icon48.png",
40
+ "128": "icon128.png"
41
+ }
42
+ },
43
+ "side_panel": {
44
+ "default_path": "sidebar.html"
45
+ },
46
+ "icons": {
47
+ "16": "icon16.png",
48
+ "48": "icon48.png",
49
+ "128": "icon128.png"
50
+ },
51
+ "web_accessible_resources": [
52
+ {
53
+ "resources": ["ai-worker.js", "models/*"],
54
+ "matches": ["<all_urls>"]
55
+ }
56
+ ]
57
+ }
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "@hanzo/browser-extension",
3
+ "version": "1.0.0",
4
+ "description": "Browser extension for click-to-code navigation with MCP integration",
5
+ "main": "cli.js",
6
+ "bin": {
7
+ "hanzo-browser-server": "./cli.js"
8
+ },
9
+ "scripts": {
10
+ "start": "node cli.js"
11
+ },
12
+ "files": [
13
+ "cli.js",
14
+ "browser-extension-server.js",
15
+ "content-script.js",
16
+ "manifest.json",
17
+ "README.md"
18
+ ],
19
+ "keywords": [
20
+ "mcp",
21
+ "browser",
22
+ "devtools",
23
+ "source-maps",
24
+ "react",
25
+ "vue",
26
+ "developer-tools"
27
+ ],
28
+ "dependencies": {
29
+ "ws": "^8.18.0",
30
+ "commander": "^11.0.0",
31
+ "chalk": "^5.3.0"
32
+ },
33
+ "devDependencies": {
34
+ "@types/ws": "^8.5.0",
35
+ "typescript": "^5.0.0",
36
+ "esbuild": "^0.25.0"
37
+ },
38
+ "peerDependencies": {
39
+ "@modelcontextprotocol/sdk": "^1.0.0"
40
+ }
41
+ }
@@ -0,0 +1,468 @@
1
+ /* Hanzo AI Browser Extension Popup — macOS Vibrancy Theme */
2
+
3
+ :root {
4
+ --bg: #0D0D0D;
5
+ --surface: rgba(18, 18, 18, 0.85);
6
+ --surface-light: rgba(30, 30, 30, 0.6);
7
+ --glass: rgba(24, 24, 24, 0.65);
8
+ --text: rgba(255, 255, 255, 0.92);
9
+ --text-dim: rgba(255, 255, 255, 0.45);
10
+ --text-faint: rgba(255, 255, 255, 0.25);
11
+ --border: rgba(255, 255, 255, 0.07);
12
+ --success: rgba(120, 200, 130, 0.9);
13
+ --warning: rgba(240, 200, 80, 0.9);
14
+ --error: rgba(220, 80, 80, 0.9);
15
+ --shimmer: linear-gradient(
16
+ 105deg,
17
+ transparent 40%,
18
+ rgba(255, 255, 255, 0.03) 45%,
19
+ rgba(255, 255, 255, 0.06) 50%,
20
+ rgba(255, 255, 255, 0.03) 55%,
21
+ transparent 60%
22
+ );
23
+ }
24
+
25
+ * {
26
+ margin: 0;
27
+ padding: 0;
28
+ box-sizing: border-box;
29
+ }
30
+
31
+ body {
32
+ width: 380px;
33
+ font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Inter', 'Segoe UI', sans-serif;
34
+ background: var(--bg);
35
+ color: var(--text);
36
+ font-size: 13px;
37
+ line-height: 1.5;
38
+ -webkit-font-smoothing: antialiased;
39
+ }
40
+
41
+ .container {
42
+ background: var(--surface);
43
+ backdrop-filter: blur(40px) saturate(1.2);
44
+ min-height: 500px;
45
+ }
46
+
47
+ /* Header */
48
+ header {
49
+ display: flex;
50
+ align-items: center;
51
+ gap: 12px;
52
+ padding: 16px;
53
+ border-bottom: 1px solid var(--border);
54
+ }
55
+
56
+ .logo {
57
+ width: 28px;
58
+ height: 28px;
59
+ opacity: 0.7;
60
+ transition: opacity 0.3s ease;
61
+ }
62
+
63
+ header:hover .logo { opacity: 0.9; }
64
+
65
+ h1 {
66
+ font-size: 16px;
67
+ font-weight: 500;
68
+ letter-spacing: -0.01em;
69
+ }
70
+
71
+ h2 {
72
+ font-size: 15px;
73
+ font-weight: 500;
74
+ margin-bottom: 8px;
75
+ }
76
+
77
+ h3 {
78
+ font-size: 11px;
79
+ font-weight: 600;
80
+ letter-spacing: 0.06em;
81
+ text-transform: uppercase;
82
+ color: var(--text-faint);
83
+ margin-bottom: 12px;
84
+ }
85
+
86
+ /* Sections */
87
+ .section {
88
+ padding: 20px;
89
+ animation: fadeIn 0.4s ease;
90
+ }
91
+
92
+ .section.hidden {
93
+ display: none;
94
+ }
95
+
96
+ @keyframes fadeIn {
97
+ from { opacity: 0; transform: translateY(4px); }
98
+ to { opacity: 1; transform: translateY(0); }
99
+ }
100
+
101
+ .subtitle {
102
+ color: var(--text-dim);
103
+ margin-bottom: 20px;
104
+ font-size: 13px;
105
+ }
106
+
107
+ /* Buttons */
108
+ .btn {
109
+ display: flex;
110
+ align-items: center;
111
+ justify-content: center;
112
+ gap: 8px;
113
+ width: 100%;
114
+ padding: 11px 16px;
115
+ border: none;
116
+ border-radius: 10px;
117
+ font-size: 13px;
118
+ font-weight: 500;
119
+ cursor: pointer;
120
+ transition: all 0.3s ease;
121
+ position: relative;
122
+ overflow: hidden;
123
+ }
124
+
125
+ .btn-primary {
126
+ background: rgba(255, 255, 255, 0.08);
127
+ color: var(--text);
128
+ border: 1px solid rgba(255, 255, 255, 0.12);
129
+ }
130
+
131
+ .btn-primary::after {
132
+ content: '';
133
+ position: absolute;
134
+ inset: 0;
135
+ background: var(--shimmer);
136
+ background-size: 300% 100%;
137
+ animation: shimmer 3s ease infinite;
138
+ pointer-events: none;
139
+ }
140
+
141
+ @keyframes shimmer {
142
+ 0% { background-position: 200% center; }
143
+ 100% { background-position: -100% center; }
144
+ }
145
+
146
+ .btn-primary:hover {
147
+ background: rgba(255, 255, 255, 0.12);
148
+ border-color: rgba(255, 255, 255, 0.18);
149
+ box-shadow: 0 2px 20px rgba(255, 255, 255, 0.04);
150
+ }
151
+
152
+ .btn-secondary {
153
+ background: rgba(255, 255, 255, 0.03);
154
+ color: var(--text-dim);
155
+ border: 1px solid var(--border);
156
+ }
157
+
158
+ .btn-secondary:hover {
159
+ background: rgba(255, 255, 255, 0.06);
160
+ color: var(--text);
161
+ }
162
+
163
+ .btn-icon {
164
+ width: 32px;
165
+ height: 32px;
166
+ padding: 0;
167
+ display: flex;
168
+ align-items: center;
169
+ justify-content: center;
170
+ background: transparent;
171
+ border: none;
172
+ border-radius: 8px;
173
+ color: var(--text-dim);
174
+ cursor: pointer;
175
+ transition: all 0.3s ease;
176
+ }
177
+
178
+ .btn-icon:hover {
179
+ background: rgba(255, 255, 255, 0.06);
180
+ color: var(--text);
181
+ }
182
+
183
+ .icon {
184
+ width: 18px;
185
+ height: 18px;
186
+ }
187
+
188
+ /* User Info */
189
+ .user-info {
190
+ display: flex;
191
+ align-items: center;
192
+ gap: 12px;
193
+ padding: 14px;
194
+ background: var(--glass);
195
+ backdrop-filter: blur(12px);
196
+ border: 1px solid rgba(255, 255, 255, 0.04);
197
+ border-radius: 10px;
198
+ }
199
+
200
+ .avatar {
201
+ width: 36px;
202
+ height: 36px;
203
+ border-radius: 50%;
204
+ background: rgba(255, 255, 255, 0.06);
205
+ border: 1px solid var(--border);
206
+ }
207
+
208
+ .user-info > div {
209
+ flex: 1;
210
+ }
211
+
212
+ .user-name {
213
+ font-weight: 500;
214
+ font-size: 13px;
215
+ }
216
+
217
+ .user-email {
218
+ font-size: 11px;
219
+ color: var(--text-dim);
220
+ }
221
+
222
+ /* Features */
223
+ .features {
224
+ display: flex;
225
+ flex-direction: column;
226
+ gap: 8px;
227
+ }
228
+
229
+ .feature-toggle label {
230
+ display: flex;
231
+ align-items: center;
232
+ gap: 12px;
233
+ padding: 12px;
234
+ background: var(--glass);
235
+ backdrop-filter: blur(8px);
236
+ border: 1px solid rgba(255, 255, 255, 0.04);
237
+ border-radius: 10px;
238
+ cursor: pointer;
239
+ transition: all 0.3s ease;
240
+ }
241
+
242
+ .feature-toggle label:hover {
243
+ background: rgba(255, 255, 255, 0.05);
244
+ border-color: var(--border);
245
+ }
246
+
247
+ .feature-toggle input {
248
+ display: none;
249
+ }
250
+
251
+ .toggle {
252
+ position: relative;
253
+ width: 40px;
254
+ height: 22px;
255
+ background: rgba(255, 255, 255, 0.08);
256
+ border-radius: 11px;
257
+ transition: background 0.3s ease;
258
+ flex-shrink: 0;
259
+ }
260
+
261
+ .toggle::after {
262
+ content: '';
263
+ position: absolute;
264
+ top: 2px;
265
+ left: 2px;
266
+ width: 18px;
267
+ height: 18px;
268
+ background: rgba(255, 255, 255, 0.4);
269
+ border-radius: 50%;
270
+ transition: all 0.3s ease;
271
+ }
272
+
273
+ input:checked + .toggle {
274
+ background: rgba(255, 255, 255, 0.18);
275
+ }
276
+
277
+ input:checked + .toggle::after {
278
+ transform: translateX(18px);
279
+ background: rgba(255, 255, 255, 0.85);
280
+ box-shadow: 0 0 8px rgba(255, 255, 255, 0.2);
281
+ }
282
+
283
+ .feature-info {
284
+ flex: 1;
285
+ }
286
+
287
+ .feature-info strong {
288
+ font-weight: 500;
289
+ font-size: 13px;
290
+ }
291
+
292
+ .feature-info small {
293
+ display: block;
294
+ color: var(--text-dim);
295
+ font-size: 11px;
296
+ }
297
+
298
+ /* Status */
299
+ .status {
300
+ display: flex;
301
+ flex-direction: column;
302
+ gap: 10px;
303
+ }
304
+
305
+ .status-item {
306
+ display: flex;
307
+ align-items: center;
308
+ gap: 8px;
309
+ font-size: 12px;
310
+ }
311
+
312
+ .status-dot {
313
+ width: 6px;
314
+ height: 6px;
315
+ border-radius: 50%;
316
+ background: rgba(255, 255, 255, 0.15);
317
+ transition: all 0.3s ease;
318
+ }
319
+
320
+ .status-dot.connected {
321
+ background: var(--success);
322
+ box-shadow: 0 0 8px rgba(120, 200, 130, 0.3);
323
+ }
324
+
325
+ .status-dot.warning {
326
+ background: var(--warning);
327
+ box-shadow: 0 0 8px rgba(240, 200, 80, 0.3);
328
+ }
329
+
330
+ .status-dot.error {
331
+ background: var(--error);
332
+ box-shadow: 0 0 8px rgba(220, 80, 80, 0.3);
333
+ }
334
+
335
+ .status-detail {
336
+ margin-left: auto;
337
+ font-size: 11px;
338
+ color: var(--text-dim);
339
+ }
340
+
341
+ /* Actions */
342
+ .actions {
343
+ display: flex;
344
+ gap: 10px;
345
+ }
346
+
347
+ .actions .btn {
348
+ flex: 1;
349
+ }
350
+
351
+ /* Guide */
352
+ .guide {
353
+ background: var(--glass);
354
+ backdrop-filter: blur(8px);
355
+ border: 1px solid rgba(255, 255, 255, 0.04);
356
+ padding: 14px;
357
+ border-radius: 10px;
358
+ }
359
+
360
+ .guide h3 {
361
+ margin-bottom: 8px;
362
+ }
363
+
364
+ .guide p {
365
+ font-size: 11px;
366
+ color: var(--text-dim);
367
+ margin-bottom: 4px;
368
+ }
369
+
370
+ kbd {
371
+ display: inline-block;
372
+ padding: 2px 6px;
373
+ background: rgba(255, 255, 255, 0.05);
374
+ border: 1px solid var(--border);
375
+ border-radius: 4px;
376
+ font-family: 'SF Mono', monospace;
377
+ font-size: 10px;
378
+ color: var(--text-dim);
379
+ }
380
+
381
+ /* Settings */
382
+ .settings-header {
383
+ display: flex;
384
+ align-items: center;
385
+ gap: 12px;
386
+ margin-bottom: 20px;
387
+ }
388
+
389
+ .settings-header h2 {
390
+ margin: 0;
391
+ }
392
+
393
+ .setting-group {
394
+ margin-bottom: 20px;
395
+ }
396
+
397
+ .setting-group label {
398
+ display: block;
399
+ margin-bottom: 10px;
400
+ color: var(--text-dim);
401
+ font-size: 12px;
402
+ }
403
+
404
+ .setting-group input[type="text"],
405
+ .setting-group input[type="number"],
406
+ .setting-group select {
407
+ width: 100%;
408
+ padding: 8px 12px;
409
+ background: rgba(255, 255, 255, 0.03);
410
+ border: 1px solid var(--border);
411
+ border-radius: 8px;
412
+ color: var(--text);
413
+ font-size: 13px;
414
+ margin-top: 4px;
415
+ transition: border-color 0.3s ease;
416
+ }
417
+
418
+ .setting-group input:focus,
419
+ .setting-group select:focus {
420
+ outline: none;
421
+ border-color: rgba(255, 255, 255, 0.15);
422
+ }
423
+
424
+ .setting-group input[type="checkbox"] {
425
+ margin-right: 8px;
426
+ accent-color: rgba(255, 255, 255, 0.5);
427
+ }
428
+
429
+ /* Utilities */
430
+ .divider {
431
+ height: 1px;
432
+ background: var(--border);
433
+ margin: 16px 0;
434
+ }
435
+
436
+ .help-text {
437
+ text-align: center;
438
+ font-size: 11px;
439
+ color: var(--text-dim);
440
+ margin-top: 16px;
441
+ }
442
+
443
+ .help-text a {
444
+ color: rgba(255, 255, 255, 0.55);
445
+ text-decoration: none;
446
+ transition: color 0.3s ease;
447
+ }
448
+
449
+ .help-text a:hover {
450
+ color: var(--text);
451
+ }
452
+
453
+ /* Animations */
454
+ @keyframes pulse {
455
+ 0% { opacity: 1; }
456
+ 50% { opacity: 0.4; }
457
+ 100% { opacity: 1; }
458
+ }
459
+
460
+ .status-dot.connecting {
461
+ animation: pulse 1.8s ease-in-out infinite;
462
+ }
463
+
464
+ /* Scrollbar */
465
+ ::-webkit-scrollbar { width: 4px; }
466
+ ::-webkit-scrollbar-track { background: transparent; }
467
+ ::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.08); border-radius: 2px; }
468
+ ::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, 0.14); }