@mooncompany/uplink-chat 0.5.2 → 0.32.3

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 (215) hide show
  1. package/LICENSE +14 -1
  2. package/README.md +105 -3
  3. package/bin/uplink.js +3 -0
  4. package/middleware/error-handler.js +1 -0
  5. package/package.json +89 -5
  6. package/public/css/agents.1fd7567a.css +1499 -0
  7. package/public/css/app.bc7e7484.css +2819 -0
  8. package/public/css/artifacts.css +488 -0
  9. package/public/css/commands.css +77 -0
  10. package/public/css/connection.css +131 -0
  11. package/public/css/cron-panel.css +364 -0
  12. package/public/css/dashboard.css +233 -0
  13. package/public/css/developer.css +342 -0
  14. package/public/css/files.css +123 -0
  15. package/public/css/markdown.css +156 -0
  16. package/public/css/message-actions.css +285 -0
  17. package/public/css/mobile.css +614 -0
  18. package/public/css/panels-unified.css +485 -0
  19. package/public/css/premium.css +415 -0
  20. package/public/css/realtime.css +189 -0
  21. package/public/css/satellites.7fa72088.css +632 -0
  22. package/public/css/settings-redesign.css +1322 -0
  23. package/public/css/shortcuts.css +185 -0
  24. package/public/css/split-view.4bc23474.css +858 -0
  25. package/public/css/themes.css +387 -0
  26. package/public/css/timestamps.css +54 -0
  27. package/public/css/variables.css +81 -0
  28. package/public/dist/bundle.493af136.js +1 -0
  29. package/public/favicon-256.png +0 -0
  30. package/public/icon-192.png +0 -0
  31. package/public/icon-512.png +0 -0
  32. package/public/img/icons/icon-alert-triangle.svg +17 -0
  33. package/public/img/icons/icon-brain.svg +20 -0
  34. package/public/img/icons/icon-brand-python.svg +19 -0
  35. package/public/img/icons/icon-camera.svg +16 -0
  36. package/public/img/icons/icon-chart-bar.svg +18 -0
  37. package/public/img/icons/icon-check.svg +15 -0
  38. package/public/img/icons/icon-circle-check.svg +16 -0
  39. package/public/img/icons/icon-clipboard.svg +16 -0
  40. package/public/img/icons/icon-cloud.svg +15 -0
  41. package/public/img/icons/icon-confetti.svg +24 -0
  42. package/public/img/icons/icon-device-mobile.svg +17 -0
  43. package/public/img/icons/icon-diamond.svg +16 -0
  44. package/public/img/icons/icon-file-text.svg +19 -0
  45. package/public/img/icons/icon-file-type-css.svg +19 -0
  46. package/public/img/icons/icon-file-type-csv.svg +19 -0
  47. package/public/img/icons/icon-file-type-doc.svg +19 -0
  48. package/public/img/icons/icon-file-type-html.svg +23 -0
  49. package/public/img/icons/icon-file-type-js.svg +18 -0
  50. package/public/img/icons/icon-file-type-pdf.svg +20 -0
  51. package/public/img/icons/icon-file-zip.svg +22 -0
  52. package/public/img/icons/icon-file.svg +16 -0
  53. package/public/img/icons/icon-folder.svg +15 -0
  54. package/public/img/icons/icon-headphones.svg +17 -0
  55. package/public/img/icons/icon-hourglass.svg +18 -0
  56. package/public/img/icons/icon-keyboard.svg +22 -0
  57. package/public/img/icons/icon-link.svg +17 -0
  58. package/public/img/icons/icon-lock-open.svg +17 -0
  59. package/public/img/icons/icon-lock.svg +17 -0
  60. package/public/img/icons/icon-mail.svg +16 -0
  61. package/public/img/icons/icon-message-dots.svg +18 -0
  62. package/public/img/icons/icon-microphone-2.svg +16 -0
  63. package/public/img/icons/icon-microphone.svg +18 -0
  64. package/public/img/icons/icon-movie.svg +22 -0
  65. package/public/img/icons/icon-music.svg +18 -0
  66. package/public/img/icons/icon-palette.svg +18 -0
  67. package/public/img/icons/icon-paperclip.svg +15 -0
  68. package/public/img/icons/icon-pencil.svg +16 -0
  69. package/public/img/icons/icon-photo.svg +18 -0
  70. package/public/img/icons/icon-presentation.svg +19 -0
  71. package/public/img/icons/icon-robot.svg +23 -0
  72. package/public/img/icons/icon-rocket.svg +17 -0
  73. package/public/img/icons/icon-satellite.svg +20 -0
  74. package/public/img/icons/icon-settings.svg +16 -0
  75. package/public/img/icons/icon-shield-lock.svg +17 -0
  76. package/public/img/icons/icon-sparkles.svg +15 -0
  77. package/public/img/icons/icon-star-filled.svg +11 -0
  78. package/public/img/icons/icon-tool.svg +15 -0
  79. package/public/img/icons/icon-trash.svg +19 -0
  80. package/public/img/icons/icon-volume.svg +17 -0
  81. package/public/img/icons/icon-world.svg +19 -0
  82. package/public/img/icons/icon-x.svg +16 -0
  83. package/public/img/logo.svg +13 -0
  84. package/public/img/wordmark.svg +35 -0
  85. package/public/index.html +1195 -0
  86. package/public/js/agents-data.js +1 -0
  87. package/public/js/agents-ui.js +1 -0
  88. package/public/js/agents.js +1 -0
  89. package/public/js/app.js +1 -0
  90. package/public/js/appearance-settings.js +1 -0
  91. package/public/js/artifacts.js +1 -0
  92. package/public/js/audio-pcm-processor.js +1 -0
  93. package/public/js/audio-queue.js +1 -0
  94. package/public/js/bootstrap.js +1 -0
  95. package/public/js/chat.js +1 -0
  96. package/public/js/commands.js +1 -0
  97. package/public/js/connection-api.js +1 -0
  98. package/public/js/connection.js +1 -0
  99. package/public/js/context-tracker.js +1 -0
  100. package/public/js/core.js +1 -0
  101. package/public/js/cron-panel.js +1 -0
  102. package/public/js/dashboard.js +1 -0
  103. package/public/js/developer.js +1 -0
  104. package/public/js/encryption.js +1 -0
  105. package/public/js/errors.js +1 -0
  106. package/public/js/event-bus.js +1 -0
  107. package/public/js/fetch-utils.js +1 -0
  108. package/public/js/file-handler.js +1 -0
  109. package/public/js/files.js +1 -0
  110. package/public/js/gateway-chat.js +1 -0
  111. package/public/js/logger.js +1 -0
  112. package/public/js/markdown.js +1 -0
  113. package/public/js/message-actions.js +1 -0
  114. package/public/js/message-renderer.js +1 -0
  115. package/public/js/missed-messages.js +1 -0
  116. package/public/js/mobile-debug.js +1 -0
  117. package/public/js/notifications.js +1 -0
  118. package/public/js/offline-queue.js +1 -0
  119. package/public/js/onboarding.js +1 -0
  120. package/public/js/panels.js +1 -0
  121. package/public/js/premium.js +1 -0
  122. package/public/js/primary-header.js +1 -0
  123. package/public/js/realtime-voice.js +1 -0
  124. package/public/js/satellite-sync.js +1 -0
  125. package/public/js/satellite-ui.js +1 -0
  126. package/public/js/satellites.js +1 -0
  127. package/public/js/settings.js +1 -0
  128. package/public/js/shortcuts.js +1 -0
  129. package/public/js/split-chat.js +1 -0
  130. package/public/js/split-resize.js +1 -0
  131. package/public/js/splitview.js +1 -0
  132. package/public/js/storage.js +1 -0
  133. package/public/js/streaming-handler.js +1 -0
  134. package/public/js/stt-settings.js +1 -0
  135. package/public/js/themes.js +1 -0
  136. package/public/js/timestamps.js +1 -0
  137. package/public/js/tts-settings.js +1 -0
  138. package/public/js/ui.js +1 -0
  139. package/public/js/update-notifier.js +1 -0
  140. package/public/js/utils/constants.js +1 -0
  141. package/public/js/utils/icons.js +1 -0
  142. package/public/js/utils/sanitize.js +1 -0
  143. package/public/js/utils/sse-parser.js +1 -0
  144. package/public/js/vad.js +1 -0
  145. package/public/js/vendor/dompurify.min.js +2 -0
  146. package/public/js/voice-settings-v2.js +1 -0
  147. package/public/js/voice.js +1 -0
  148. package/public/manifest.json +66 -0
  149. package/public/moon_texture.jpg +0 -0
  150. package/public/sw.js +1 -0
  151. package/public/three.min.js +6 -0
  152. package/public/u-icon.png +0 -0
  153. package/server/channel.js +1 -0
  154. package/server/chat.js +1 -0
  155. package/server/config-store.js +1 -0
  156. package/server/config.js +1 -0
  157. package/server/context.js +1 -0
  158. package/server/gateway-api-proxy.js +1 -0
  159. package/server/gateway-commands.js +1 -0
  160. package/server/gateway-proxy.js +1 -0
  161. package/server/index.js +1 -0
  162. package/server/logger.js +1 -0
  163. package/server/message-store.js +1 -0
  164. package/server/middleware/auth.js +1 -0
  165. package/server/middleware.js +1 -0
  166. package/server/openclaw-discover.js +1 -0
  167. package/server/premium/index.js +1 -0
  168. package/server/premium/license.js +1 -0
  169. package/server/realtime/bridge.js +1 -0
  170. package/server/realtime/index.js +1 -0
  171. package/server/realtime/tts-stream.js +1 -0
  172. package/server/routes/agents.js +1 -0
  173. package/server/routes/artifacts.js +1 -0
  174. package/server/routes/chat.js +1 -0
  175. package/server/routes/config-settings.js +1 -0
  176. package/server/routes/config.js +1 -0
  177. package/server/routes/cron.js +1 -0
  178. package/server/routes/files.js +1 -0
  179. package/server/routes/index.js +1 -0
  180. package/server/routes/media.js +1 -0
  181. package/server/routes/missed-messages.js +1 -0
  182. package/server/routes/premium.js +1 -0
  183. package/server/routes/push.js +1 -0
  184. package/server/routes/satellite.js +1 -0
  185. package/server/routes/status.js +1 -0
  186. package/server/routes/stt.js +1 -0
  187. package/server/routes/voice.js +1 -0
  188. package/server/routes/webhooks.js +1 -0
  189. package/server/routes.js +1 -0
  190. package/server/runtime-config.js +1 -0
  191. package/server/share.js +1 -0
  192. package/server/stt/faster-whisper.js +1 -0
  193. package/server/stt/groq.js +1 -0
  194. package/server/stt/index.js +1 -0
  195. package/server/stt/openai.js +1 -0
  196. package/server/sync.js +1 -0
  197. package/server/tailscale-https.js +1 -0
  198. package/server/tts.js +1 -0
  199. package/server/update-checker.js +1 -0
  200. package/server/utils/filename.js +1 -0
  201. package/server/utils.js +1 -0
  202. package/server/watchdog.js +3 -0
  203. package/server/websocket/broadcast.js +1 -0
  204. package/server/websocket/connections.js +1 -0
  205. package/server/websocket/index.js +1 -0
  206. package/server/websocket/routing.js +1 -0
  207. package/server/websocket/sync.js +1 -0
  208. package/server.js +1 -0
  209. package/utils/detect-tool-usage.js +1 -0
  210. package/utils/errors.js +1 -0
  211. package/utils/html-escape.js +1 -0
  212. package/utils/id-sanitize.js +1 -0
  213. package/utils/response.js +1 -0
  214. package/utils/with-retry.js +1 -0
  215. package/index.js +0 -2
@@ -0,0 +1,1499 @@
1
+ /* Agent selector in satellite launch prompt */
2
+ .satellite-agent-field {
3
+ display: flex;
4
+ align-items: center;
5
+ gap: var(--space-2);
6
+ margin-bottom: var(--space-2);
7
+ }
8
+
9
+ .satellite-agent-label {
10
+ font-size: 11px;
11
+ color: var(--text-muted);
12
+ text-transform: uppercase;
13
+ letter-spacing: 0.05em;
14
+ white-space: nowrap;
15
+ }
16
+
17
+ .satellite-agent-select {
18
+ flex: 1;
19
+ padding: var(--space-2) var(--space-3);
20
+ border: 1px solid var(--border);
21
+ border-radius: var(--radius-md);
22
+ background: var(--bg-input);
23
+ color: var(--text);
24
+ font-size: var(--text-sm);
25
+ }
26
+
27
+ .satellite-agent-select:focus {
28
+ outline: none;
29
+ border-color: var(--accent);
30
+ }
31
+
32
+ /* Agent badge on satellite items */
33
+ .satellite-agent-badge {
34
+ font-size: 11px;
35
+ padding: 1px 4px;
36
+ border-radius: var(--radius-sm);
37
+ background: var(--accent-10);
38
+ color: var(--accent);
39
+ border: 1px solid var(--accent-20, rgba(255,255,255,0.1));
40
+ }
41
+
42
+ /* ============================================
43
+ NAV TABS (Sessions / Agents toggle)
44
+ ============================================ */
45
+
46
+ .satellite-nav-tabs {
47
+ display: flex;
48
+ gap: 0;
49
+ }
50
+
51
+ .satellite-nav-tab {
52
+ background: none;
53
+ border: none;
54
+ color: var(--text-muted);
55
+ font-family: var(--font-mono);
56
+ font-size: var(--text-xs);
57
+ letter-spacing: 0.5px;
58
+ text-transform: uppercase;
59
+ padding: var(--space-1) var(--space-3);
60
+ cursor: pointer;
61
+ border-bottom: 2px solid transparent;
62
+ transition: color 0.15s ease, border-color 0.15s ease;
63
+ }
64
+
65
+ .satellite-nav-tab:hover {
66
+ color: var(--text);
67
+ }
68
+
69
+ .satellite-nav-tab.active {
70
+ color: var(--accent);
71
+ border-bottom-color: var(--accent);
72
+ }
73
+
74
+ /* Tab content areas */
75
+ .satellite-tab-content {
76
+ display: flex;
77
+ flex-direction: column;
78
+ flex: 1;
79
+ overflow: hidden;
80
+ }
81
+
82
+ .agents-tab-content {
83
+ display: flex;
84
+ flex-direction: column;
85
+ flex: 1;
86
+ overflow-y: auto;
87
+ overflow-x: hidden;
88
+ }
89
+
90
+ /* ============================================
91
+ AGENTS MODULE STYLES
92
+ ============================================ */
93
+
94
+ /* Loading state */
95
+ .agents-loading {
96
+ display: flex;
97
+ align-items: center;
98
+ justify-content: center;
99
+ gap: var(--space-2);
100
+ padding: var(--space-6);
101
+ color: var(--text-muted);
102
+ font-size: var(--text-sm);
103
+ }
104
+
105
+ .agents-loading-dot {
106
+ width: 8px;
107
+ height: 8px;
108
+ border-radius: 50%;
109
+ background: var(--accent);
110
+ animation: pulse 1.2s ease-in-out infinite;
111
+ }
112
+
113
+ /* Empty state */
114
+ .agents-empty {
115
+ display: flex;
116
+ flex-direction: column;
117
+ align-items: center;
118
+ justify-content: center;
119
+ gap: var(--space-2);
120
+ padding: var(--space-6);
121
+ color: var(--text-muted);
122
+ }
123
+
124
+ .agents-empty-icon {
125
+ font-size: var(--text-3xl);
126
+ opacity: 0.5;
127
+ }
128
+
129
+ .agents-empty-text {
130
+ font-size: var(--text-sm);
131
+ }
132
+
133
+ /* List header */
134
+ .agents-list-header {
135
+ display: flex;
136
+ align-items: center;
137
+ justify-content: space-between;
138
+ padding: var(--space-2) var(--space-4);
139
+ border-bottom: 1px solid var(--white-05);
140
+ }
141
+
142
+ .agents-list-count {
143
+ font-size: var(--text-xs);
144
+ color: var(--text-muted);
145
+ text-transform: uppercase;
146
+ letter-spacing: 0.5px;
147
+ }
148
+
149
+ .agents-refresh-btn {
150
+ background: none;
151
+ border: none;
152
+ color: var(--text-muted);
153
+ cursor: pointer;
154
+ font-size: var(--text-base);
155
+ padding: var(--space-1);
156
+ border-radius: var(--radius-md);
157
+ transition: color 0.15s, background 0.15s;
158
+ }
159
+
160
+ .agents-refresh-btn:hover {
161
+ color: var(--text);
162
+ background: var(--white-05);
163
+ }
164
+
165
+ /* Agent list */
166
+ .agents-list {
167
+ flex: 1;
168
+ overflow-y: auto;
169
+ }
170
+
171
+ /* Agent item */
172
+ .agent-item {
173
+ display: flex;
174
+ align-items: center;
175
+ gap: var(--space-3);
176
+ padding: var(--space-3) var(--space-4);
177
+ cursor: pointer;
178
+ transition: background 0.15s;
179
+ border-bottom: 1px solid var(--white-05);
180
+ }
181
+
182
+ .agent-item:hover {
183
+ background: var(--white-05);
184
+ }
185
+
186
+ .agent-item:last-child {
187
+ border-bottom: none;
188
+ }
189
+
190
+ .agent-item-emoji {
191
+ font-size: var(--text-xl);
192
+ flex-shrink: 0;
193
+ }
194
+
195
+ .agent-item-avatar {
196
+ width: 32px;
197
+ height: 32px;
198
+ flex-shrink: 0;
199
+ display: flex;
200
+ align-items: center;
201
+ justify-content: center;
202
+ font-size: var(--text-xl);
203
+ }
204
+
205
+ .agent-list-avatar-img {
206
+ width: 32px;
207
+ height: 32px;
208
+ border-radius: 50%;
209
+ object-fit: cover;
210
+ }
211
+
212
+ .agent-item-info {
213
+ flex: 1;
214
+ min-width: 0;
215
+ }
216
+
217
+ .agent-item-name-row {
218
+ display: flex;
219
+ align-items: center;
220
+ gap: var(--space-2);
221
+ flex-wrap: wrap;
222
+ }
223
+
224
+ .agent-item-name {
225
+ font-size: var(--text-sm);
226
+ font-weight: 600;
227
+ color: var(--text);
228
+ white-space: nowrap;
229
+ overflow: hidden;
230
+ text-overflow: ellipsis;
231
+ }
232
+
233
+ .agent-item-theme {
234
+ font-size: var(--text-xs);
235
+ color: var(--text-secondary, var(--text-muted));
236
+ margin-top: 1px;
237
+ white-space: nowrap;
238
+ overflow: hidden;
239
+ text-overflow: ellipsis;
240
+ opacity: 0.7;
241
+ }
242
+
243
+ .agent-item-meta {
244
+ display: flex;
245
+ align-items: center;
246
+ gap: var(--space-1);
247
+ margin-top: 2px;
248
+ font-size: var(--text-xs);
249
+ color: var(--text-muted);
250
+ }
251
+
252
+ .agent-meta-sep {
253
+ opacity: 0.4;
254
+ }
255
+
256
+ .agent-item-chevron {
257
+ color: var(--text-muted);
258
+ font-size: var(--text-lg);
259
+ flex-shrink: 0;
260
+ opacity: 0.5;
261
+ }
262
+
263
+ /* Agent badges */
264
+ .agent-badge {
265
+ display: inline-block;
266
+ font-size: 10px;
267
+ padding: 1px 6px;
268
+ border-radius: var(--radius-full);
269
+ font-weight: 600;
270
+ text-transform: uppercase;
271
+ letter-spacing: 0.5px;
272
+ line-height: 1.4;
273
+ }
274
+
275
+ .agent-badge-default {
276
+ background: rgba(99, 102, 241, 0.2);
277
+ color: var(--accent);
278
+ }
279
+
280
+ .agent-badge-sandbox {
281
+ background: rgba(245, 158, 11, 0.2);
282
+ color: rgb(245, 158, 11);
283
+ }
284
+
285
+ .agent-badge-partial {
286
+ background: rgba(245, 158, 11, 0.1);
287
+ color: rgb(217, 147, 38);
288
+ }
289
+
290
+ .agent-badge-off {
291
+ background: var(--white-05);
292
+ color: var(--text-muted);
293
+ }
294
+
295
+ /* ============================================
296
+ AGENT DETAIL VIEW
297
+ ============================================ */
298
+
299
+ .agent-detail {
300
+ padding: 0;
301
+ }
302
+
303
+ /* Hero banner � 1:1 square avatar */
304
+ .agent-detail-hero {
305
+ position: relative;
306
+ width: 100%;
307
+ aspect-ratio: 1 / 1;
308
+ max-height: 400px;
309
+ overflow: hidden;
310
+ cursor: pointer;
311
+ background: var(--bg-input, #1a1a2e);
312
+ }
313
+
314
+ .agent-detail-hero-img {
315
+ width: 100%;
316
+ height: 100%;
317
+ object-fit: contain;
318
+ display: none;
319
+ background: var(--bg-input, #1a1a2e);
320
+ }
321
+
322
+ .agent-detail-hero-fallback {
323
+ font-size: 80px;
324
+ display: flex;
325
+ align-items: center;
326
+ justify-content: center;
327
+ width: 100%;
328
+ height: 100%;
329
+ background: linear-gradient(135deg, var(--bg-input, #1a1a2e) 0%, var(--accent-bg, rgba(120,90,255,0.15)) 100%);
330
+ }
331
+
332
+ .agent-detail-hero-overlay {
333
+ position: absolute;
334
+ inset: 0;
335
+ background: linear-gradient(transparent 50%, rgba(0,0,0,0.75) 100%);
336
+ display: flex;
337
+ flex-direction: column;
338
+ justify-content: space-between;
339
+ padding: var(--space-3) var(--space-4);
340
+ }
341
+
342
+ .agent-detail-hero-nav {
343
+ display: flex;
344
+ justify-content: space-between;
345
+ align-items: center;
346
+ }
347
+
348
+ .agent-detail-hero .agent-avatar-overlay {
349
+ position: absolute;
350
+ inset: 0;
351
+ background: rgba(0, 0, 0, 0.4);
352
+ display: flex;
353
+ align-items: center;
354
+ justify-content: center;
355
+ font-size: 24px;
356
+ opacity: 0;
357
+ transition: opacity 0.2s;
358
+ pointer-events: none;
359
+ border-radius: 0;
360
+ }
361
+
362
+ .agent-detail-hero:hover .agent-avatar-overlay {
363
+ opacity: 1;
364
+ }
365
+
366
+ .agent-avatar-remove {
367
+ position: absolute;
368
+ top: var(--space-2, 8px);
369
+ right: var(--space-2, 8px);
370
+ z-index: 10;
371
+ width: 28px;
372
+ height: 28px;
373
+ border: none;
374
+ border-radius: 50%;
375
+ background: rgba(0, 0, 0, 0.6);
376
+ color: #fff;
377
+ font-size: 14px;
378
+ cursor: pointer;
379
+ opacity: 0;
380
+ transition: opacity 0.2s, background 0.2s;
381
+ display: flex;
382
+ align-items: center;
383
+ justify-content: center;
384
+ padding: 0;
385
+ pointer-events: auto;
386
+ }
387
+
388
+ .agent-detail-hero:hover .agent-avatar-remove {
389
+ opacity: 1;
390
+ }
391
+
392
+ .agent-avatar-remove:hover {
393
+ background: var(--danger, #e74c3c);
394
+ }
395
+
396
+ .agent-detail-hero .agent-badge-default {
397
+ position: absolute;
398
+ bottom: var(--space-3);
399
+ right: var(--space-4);
400
+ }
401
+
402
+ .agent-detail-hero-info {
403
+ display: flex;
404
+ flex-direction: column;
405
+ gap: 2px;
406
+ }
407
+
408
+ .agent-detail-back {
409
+ background: rgba(0, 0, 0, 0.4);
410
+ border: 1px solid rgba(255, 255, 255, 0.15);
411
+ color: #fff;
412
+ cursor: pointer;
413
+ font-size: var(--text-sm);
414
+ padding: var(--space-1) var(--space-2);
415
+ border-radius: 6px;
416
+ transition: background 0.15s;
417
+ backdrop-filter: blur(4px);
418
+ }
419
+
420
+ .agent-detail-back:hover {
421
+ background: rgba(0, 0, 0, 0.6);
422
+ }
423
+
424
+ /* Danger zone � bottom of detail page */
425
+ .agent-detail-danger-zone {
426
+ padding: var(--space-4);
427
+ border-top: 1px solid var(--white-05);
428
+ display: flex;
429
+ justify-content: center;
430
+ }
431
+
432
+ .agent-detail-delete {
433
+ background: transparent;
434
+ border: 1px solid rgba(239, 68, 68, 0.4);
435
+ color: #ef4444;
436
+ cursor: pointer;
437
+ font-size: var(--text-sm);
438
+ padding: var(--space-2) var(--space-4);
439
+ border-radius: 6px;
440
+ transition: background 0.15s, border-color 0.15s;
441
+ width: 100%;
442
+ }
443
+
444
+ .agent-detail-delete:hover {
445
+ background: rgba(239, 68, 68, 0.1);
446
+ border-color: #ef4444;
447
+ }
448
+
449
+ .agent-detail-name {
450
+ display: block;
451
+ font-weight: 700;
452
+ font-size: var(--text-lg, 1.125rem);
453
+ color: #fff;
454
+ text-shadow: 0 1px 3px rgba(0,0,0,0.5);
455
+ }
456
+
457
+ .agent-detail-hero-info .agent-detail-id {
458
+ display: block;
459
+ font-size: var(--text-xs);
460
+ color: rgba(255,255,255,0.7);
461
+ font-family: var(--font-mono);
462
+ text-shadow: 0 1px 2px rgba(0,0,0,0.5);
463
+ }
464
+
465
+ .agent-detail-theme-block {
466
+ padding: var(--space-2) var(--space-4);
467
+ border-bottom: 1px solid var(--white-05);
468
+ }
469
+
470
+ .agent-detail-theme {
471
+ display: block;
472
+ font-size: var(--text-xs);
473
+ color: var(--text-muted);
474
+ font-style: italic;
475
+ line-height: 1.4;
476
+ }
477
+
478
+ /* Legacy agent avatar upload (for list view) */
479
+ .agent-avatar-upload {
480
+ position: relative;
481
+ width: 48px;
482
+ height: 48px;
483
+ min-width: 48px;
484
+ min-height: 48px;
485
+ max-width: 48px;
486
+ max-height: 48px;
487
+ border-radius: 50%;
488
+ cursor: pointer;
489
+ flex-shrink: 0;
490
+ overflow: hidden;
491
+ background: var(--bg-input);
492
+ display: flex;
493
+ align-items: center;
494
+ justify-content: center;
495
+ }
496
+
497
+ .agent-avatar-preview {
498
+ width: 48px;
499
+ height: 48px;
500
+ object-fit: cover;
501
+ border-radius: 50%;
502
+ display: none;
503
+ }
504
+
505
+ .agent-avatar-fallback {
506
+ font-size: var(--text-2xl);
507
+ display: flex;
508
+ align-items: center;
509
+ justify-content: center;
510
+ width: 100%;
511
+ height: 100%;
512
+ }
513
+
514
+ .agent-avatar-upload .agent-avatar-overlay {
515
+ position: absolute;
516
+ inset: 0;
517
+ background: rgba(0, 0, 0, 0.5);
518
+ display: flex;
519
+ align-items: center;
520
+ justify-content: center;
521
+ font-size: 16px;
522
+ opacity: 0;
523
+ transition: opacity 0.2s;
524
+ border-radius: 50%;
525
+ pointer-events: none;
526
+ }
527
+
528
+ .agent-avatar-upload:hover .agent-avatar-overlay {
529
+ opacity: 1;
530
+ }
531
+
532
+ .agent-detail-id {
533
+ display: block;
534
+ font-size: var(--text-xs);
535
+ color: var(--text-muted);
536
+ font-family: var(--font-mono);
537
+ }
538
+
539
+ /* Sections */
540
+ .agent-section {
541
+ border-bottom: 1px solid var(--white-05);
542
+ }
543
+
544
+ .agent-section:last-child {
545
+ border-bottom: none;
546
+ }
547
+
548
+ .agent-section-header {
549
+ padding: var(--space-2) var(--space-4);
550
+ background: var(--black-10);
551
+ }
552
+
553
+ .agent-section-title {
554
+ font-family: var(--font-mono);
555
+ font-size: var(--text-xs);
556
+ color: var(--text-muted);
557
+ text-transform: uppercase;
558
+ letter-spacing: 0.5px;
559
+ }
560
+
561
+ .agent-section-body {
562
+ padding: var(--space-2) var(--space-4);
563
+ }
564
+
565
+ /* Detail rows */
566
+ .agent-detail-row {
567
+ display: flex;
568
+ align-items: flex-start;
569
+ gap: var(--space-3);
570
+ padding: var(--space-1) 0;
571
+ }
572
+
573
+ .agent-detail-label {
574
+ font-size: var(--text-xs);
575
+ color: var(--text-muted);
576
+ min-width: 90px;
577
+ flex-shrink: 0;
578
+ padding-top: 2px;
579
+ }
580
+
581
+ .agent-detail-value {
582
+ font-size: var(--text-sm);
583
+ color: var(--text);
584
+ word-break: break-all;
585
+ }
586
+
587
+ .agent-detail-mono {
588
+ font-family: var(--font-mono);
589
+ font-size: var(--text-xs);
590
+ }
591
+
592
+ .agent-detail-muted {
593
+ color: var(--text-muted);
594
+ font-style: italic;
595
+ }
596
+
597
+ .agent-detail-inherited {
598
+ color: var(--text-muted);
599
+ font-size: 10px;
600
+ font-style: italic;
601
+ font-family: var(--font-sans, sans-serif);
602
+ }
603
+
604
+ /* In split view, hide satellite's own header (use side-panel header for consistency) */
605
+ .side-panel-content .satellite-nav-header {
606
+ display: none !important;
607
+ }
608
+
609
+ /* Show inline tabs when satellite nav header is hidden in split view */
610
+ .side-panel-content .satellite-nav-tabs-inline {
611
+ display: flex !important;
612
+ gap: 0;
613
+ padding: 0 var(--space-4);
614
+ border-bottom: 1px solid var(--border);
615
+ flex-shrink: 0;
616
+ }
617
+
618
+ /* Navigator inside side-panel: fill the space, remove fixed positioning */
619
+ .side-panel-content .satellite-navigator {
620
+ position: static;
621
+ width: 100%;
622
+ max-width: none;
623
+ max-height: none;
624
+ height: 100%;
625
+ border: none;
626
+ border-radius: 0;
627
+ box-shadow: none;
628
+ z-index: auto;
629
+ }
630
+
631
+ .side-panel-content .satellite-navigator.visible {
632
+ display: flex !important;
633
+ }
634
+
635
+ /* Tool tags */
636
+ .agent-tool-tags {
637
+ display: flex;
638
+ flex-wrap: wrap;
639
+ gap: 4px;
640
+ }
641
+
642
+ .agent-tool-tag {
643
+ display: inline-block;
644
+ font-size: 10px;
645
+ padding: 2px 6px;
646
+ border-radius: var(--radius-md);
647
+ background: var(--white-05);
648
+ color: var(--text-muted);
649
+ font-family: var(--font-mono);
650
+ }
651
+
652
+ .agent-tool-allow {
653
+ background: rgba(34, 197, 94, 0.15);
654
+ color: rgb(34, 197, 94);
655
+ }
656
+
657
+ .agent-tool-deny {
658
+ background: rgba(239, 68, 68, 0.15);
659
+ color: rgb(239, 68, 68);
660
+ }
661
+
662
+ /* Section header with edit button */
663
+ .agent-section-header {
664
+ display: flex;
665
+ align-items: center;
666
+ justify-content: space-between;
667
+ }
668
+
669
+ .agent-section-actions {
670
+ display: flex;
671
+ gap: 6px;
672
+ }
673
+
674
+ .agent-section-btn {
675
+ font-size: 10px;
676
+ padding: 2px 8px;
677
+ border-radius: var(--radius-md);
678
+ border: 1px solid var(--border);
679
+ background: transparent;
680
+ color: var(--text-muted);
681
+ cursor: pointer;
682
+ font-family: var(--font-mono);
683
+ text-transform: uppercase;
684
+ letter-spacing: 0.5px;
685
+ transition: all 0.15s ease;
686
+ }
687
+
688
+ .agent-section-btn:hover {
689
+ color: var(--text-primary);
690
+ border-color: var(--text-muted);
691
+ }
692
+
693
+ .agent-section-edit:hover {
694
+ color: var(--accent);
695
+ border-color: var(--accent);
696
+ }
697
+
698
+ .agent-section-save {
699
+ background: var(--accent);
700
+ color: var(--bg);
701
+ border-color: var(--accent);
702
+ }
703
+
704
+ .agent-section-save:hover {
705
+ opacity: 0.9;
706
+ }
707
+
708
+ .agent-section-cancel:hover {
709
+ color: var(--text-primary);
710
+ }
711
+
712
+ /* Edit form fields */
713
+ .agent-edit-field {
714
+ margin-bottom: 10px;
715
+ }
716
+
717
+ .agent-edit-field:last-child {
718
+ margin-bottom: 0;
719
+ }
720
+
721
+ .agent-edit-label {
722
+ display: block;
723
+ font-size: 10px;
724
+ color: var(--text-muted);
725
+ text-transform: uppercase;
726
+ letter-spacing: 0.5px;
727
+ margin-bottom: 4px;
728
+ font-family: var(--font-mono);
729
+ }
730
+
731
+ .agent-edit-hint {
732
+ text-transform: none;
733
+ letter-spacing: 0;
734
+ opacity: 0.6;
735
+ }
736
+
737
+ .agent-edit-input,
738
+ .agent-edit-select,
739
+ .agent-edit-textarea {
740
+ width: 100%;
741
+ padding: 6px 8px;
742
+ border: 1px solid var(--border);
743
+ border-radius: var(--radius-md);
744
+ background: var(--black-20);
745
+ color: var(--text-primary);
746
+ font-size: 12px;
747
+ font-family: var(--font-mono);
748
+ outline: none;
749
+ transition: border-color 0.15s ease;
750
+ }
751
+
752
+ .agent-edit-input:focus,
753
+ .agent-edit-select:focus,
754
+ .agent-edit-textarea:focus {
755
+ border-color: var(--accent);
756
+ }
757
+
758
+ .agent-edit-input-short {
759
+ width: 80px;
760
+ }
761
+
762
+ .agent-edit-select {
763
+ cursor: pointer;
764
+ }
765
+
766
+ .agent-edit-textarea {
767
+ resize: vertical;
768
+ min-height: 60px;
769
+ }
770
+
771
+ /* Tool groups editor */
772
+ .agent-tools-grid {
773
+ margin-top: 8px;
774
+ }
775
+
776
+ .agent-tool-group {
777
+ margin-bottom: 8px;
778
+ border: 1px solid var(--white-05);
779
+ border-radius: var(--radius-md);
780
+ overflow: hidden;
781
+ }
782
+
783
+ .agent-tool-group-label {
784
+ display: flex;
785
+ align-items: center;
786
+ gap: 6px;
787
+ padding: 6px 8px;
788
+ background: var(--black-20);
789
+ cursor: pointer;
790
+ font-size: 12px;
791
+ color: var(--text-primary);
792
+ }
793
+
794
+ .agent-tool-group-label:hover {
795
+ background: var(--white-05);
796
+ }
797
+
798
+ .agent-tool-group-hint {
799
+ font-size: 9px;
800
+ color: var(--text-muted);
801
+ margin-left: auto;
802
+ font-family: var(--font-mono);
803
+ }
804
+
805
+ .agent-tool-group-items {
806
+ display: flex;
807
+ flex-wrap: wrap;
808
+ gap: 2px;
809
+ padding: 4px 8px 6px;
810
+ }
811
+
812
+ .agent-tool-item-label {
813
+ display: flex;
814
+ align-items: center;
815
+ gap: 4px;
816
+ font-size: 11px;
817
+ color: var(--text-muted);
818
+ cursor: pointer;
819
+ padding: 2px 4px;
820
+ border-radius: 3px;
821
+ }
822
+
823
+ .agent-tool-item-label:hover {
824
+ color: var(--text-primary);
825
+ background: var(--white-05);
826
+ }
827
+
828
+ .agent-tool-group-check,
829
+ .agent-tool-item-check {
830
+ accent-color: var(--accent);
831
+ }
832
+
833
+ /* Agent list actions (create button) */
834
+ .agents-list-actions {
835
+ padding: 8px 12px;
836
+ }
837
+
838
+ .agents-create-btn {
839
+ width: 100%;
840
+ padding: 8px 12px;
841
+ border: 1px dashed var(--border);
842
+ border-radius: var(--radius-md);
843
+ background: transparent;
844
+ color: var(--text-muted);
845
+ font-size: 12px;
846
+ font-family: var(--font-mono);
847
+ cursor: pointer;
848
+ transition: all 0.15s ease;
849
+ }
850
+
851
+ .agents-create-btn:hover {
852
+ border-color: var(--accent);
853
+ color: var(--accent);
854
+ background: var(--white-05);
855
+ }
856
+
857
+ .agents-create-submit {
858
+ border-style: solid;
859
+ background: var(--accent);
860
+ color: var(--bg);
861
+ border-color: var(--accent);
862
+ }
863
+
864
+ .agents-create-submit:hover {
865
+ opacity: 0.9;
866
+ color: var(--bg);
867
+ border-color: var(--accent);
868
+ }
869
+
870
+ /* Create form */
871
+ .agent-create-title {
872
+ font-size: 16px;
873
+ font-weight: 600;
874
+ color: var(--text-primary);
875
+ padding: 0 12px 4px;
876
+ }
877
+
878
+ .agent-create-warning {
879
+ font-size: 11px;
880
+ color: var(--text-muted);
881
+ padding: 6px 12px;
882
+ margin: 0 12px 8px;
883
+ background: rgba(234, 179, 8, 0.1);
884
+ border: 1px solid rgba(234, 179, 8, 0.25);
885
+ border-radius: var(--radius-md);
886
+ }
887
+
888
+ /* Delete button in detail header */
889
+ .agent-detail-delete {
890
+ font-size: 10px;
891
+ padding: 3px 8px;
892
+ border-radius: var(--radius-md);
893
+ border: 1px solid rgba(239, 68, 68, 0.4);
894
+ background: transparent;
895
+ color: rgb(239, 68, 68);
896
+ cursor: pointer;
897
+ font-family: var(--font-mono);
898
+ text-transform: uppercase;
899
+ letter-spacing: 0.5px;
900
+ transition: all 0.15s ease;
901
+ }
902
+
903
+ .agent-detail-delete:hover {
904
+ background: rgba(239, 68, 68, 0.15);
905
+ border-color: rgb(239, 68, 68);
906
+ }
907
+
908
+ /* Delete confirmation overlay */
909
+ .agent-confirm-overlay {
910
+ position: absolute;
911
+ top: 0;
912
+ left: 0;
913
+ right: 0;
914
+ bottom: 0;
915
+ background: var(--black-80);
916
+ display: flex;
917
+ align-items: center;
918
+ justify-content: center;
919
+ z-index: 10;
920
+ padding: 20px;
921
+ }
922
+
923
+ .agent-confirm-dialog {
924
+ background: var(--bg-secondary);
925
+ border: 1px solid var(--border);
926
+ border-radius: var(--radius-xl);
927
+ padding: 16px;
928
+ max-width: 320px;
929
+ width: 100%;
930
+ }
931
+
932
+ .agent-confirm-title {
933
+ font-size: 14px;
934
+ font-weight: 600;
935
+ color: var(--text-primary);
936
+ margin-bottom: 8px;
937
+ }
938
+
939
+ .agent-confirm-body {
940
+ font-size: 12px;
941
+ color: var(--text-muted);
942
+ margin-bottom: 12px;
943
+ line-height: 1.4;
944
+ }
945
+
946
+ .agent-confirm-actions {
947
+ display: flex;
948
+ gap: 8px;
949
+ justify-content: flex-end;
950
+ }
951
+
952
+ .agent-confirm-delete {
953
+ background: rgb(239, 68, 68) !important;
954
+ color: white !important;
955
+ border-color: rgb(239, 68, 68) !important;
956
+ }
957
+
958
+ .agent-confirm-delete:hover {
959
+ opacity: 0.9;
960
+ }
961
+
962
+ /* Restart overlay */
963
+ .agent-restart-overlay {
964
+ display: flex;
965
+ align-items: center;
966
+ justify-content: center;
967
+ height: 200px;
968
+ }
969
+
970
+ .agent-restart-content {
971
+ text-align: center;
972
+ }
973
+
974
+ .agent-restart-title {
975
+ font-size: 14px;
976
+ font-weight: 600;
977
+ color: var(--accent);
978
+ margin-top: 12px;
979
+ }
980
+
981
+ .agent-restart-sub {
982
+ font-size: 11px;
983
+ color: var(--text-muted);
984
+ margin-top: 4px;
985
+ }
986
+
987
+ /* Raw JSON section */
988
+ .agent-raw-toggle {
989
+ cursor: pointer;
990
+ }
991
+
992
+ .agent-raw-toggle:hover .agent-section-title {
993
+ color: var(--text-primary);
994
+ }
995
+
996
+ .agent-raw-chevron {
997
+ color: var(--text-muted);
998
+ font-size: 12px;
999
+ transition: transform 0.15s ease;
1000
+ }
1001
+
1002
+ .agent-raw-json {
1003
+ font-family: var(--font-mono);
1004
+ font-size: 10px;
1005
+ line-height: 1.5;
1006
+ color: var(--text-muted);
1007
+ background: var(--black-20);
1008
+ border: 1px solid var(--white-05);
1009
+ border-radius: var(--radius-md);
1010
+ padding: 8px;
1011
+ margin: 0;
1012
+ overflow-x: auto;
1013
+ white-space: pre;
1014
+ max-height: 300px;
1015
+ overflow-y: auto;
1016
+ }
1017
+
1018
+ .agent-raw-copy {
1019
+ margin-top: 6px;
1020
+ font-size: 10px;
1021
+ padding: 3px 8px;
1022
+ border-radius: var(--radius-md);
1023
+ border: 1px solid var(--border);
1024
+ background: transparent;
1025
+ color: var(--text-muted);
1026
+ cursor: pointer;
1027
+ font-family: var(--font-mono);
1028
+ }
1029
+
1030
+ .agent-raw-copy:hover {
1031
+ color: var(--accent);
1032
+ border-color: var(--accent);
1033
+ }
1034
+
1035
+ /* Tool presets */
1036
+ .agent-preset-bar {
1037
+ display: flex;
1038
+ flex-wrap: wrap;
1039
+ gap: 4px;
1040
+ }
1041
+
1042
+ .agent-preset-btn {
1043
+ font-size: 10px;
1044
+ padding: 3px 8px;
1045
+ border-radius: var(--radius-md);
1046
+ border: 1px solid var(--border);
1047
+ background: transparent;
1048
+ color: var(--text-muted);
1049
+ cursor: pointer;
1050
+ font-family: var(--font-mono);
1051
+ transition: all 0.15s ease;
1052
+ }
1053
+
1054
+ .agent-preset-btn:hover {
1055
+ border-color: var(--accent);
1056
+ color: var(--accent);
1057
+ }
1058
+
1059
+ .agent-preset-btn.active {
1060
+ background: var(--accent);
1061
+ color: var(--bg);
1062
+ border-color: var(--accent);
1063
+ }
1064
+
1065
+ /* Binding / routing editor */
1066
+ .agent-binding-info {
1067
+ font-size: 11px;
1068
+ color: var(--text-muted);
1069
+ line-height: 1.4;
1070
+ margin-bottom: 8px;
1071
+ }
1072
+
1073
+ .agent-binding-info em {
1074
+ color: var(--accent);
1075
+ font-style: normal;
1076
+ }
1077
+
1078
+ .agent-bindings-list {
1079
+ display: flex;
1080
+ flex-direction: column;
1081
+ gap: 8px;
1082
+ }
1083
+
1084
+ .agent-bindings-empty {
1085
+ font-size: 11px;
1086
+ padding: 8px 0;
1087
+ }
1088
+
1089
+ .agent-binding-row {
1090
+ display: flex;
1091
+ gap: 6px;
1092
+ align-items: flex-start;
1093
+ padding: 8px;
1094
+ background: var(--black-20);
1095
+ border: 1px solid var(--white-05);
1096
+ border-radius: var(--radius-md);
1097
+ }
1098
+
1099
+ .agent-binding-fields {
1100
+ flex: 1;
1101
+ display: grid;
1102
+ grid-template-columns: 1fr 1fr;
1103
+ gap: 6px;
1104
+ }
1105
+
1106
+ .agent-binding-fields .agent-edit-field {
1107
+ margin-bottom: 0;
1108
+ }
1109
+
1110
+ .agent-binding-fields .agent-edit-label {
1111
+ font-size: 9px;
1112
+ margin-bottom: 2px;
1113
+ }
1114
+
1115
+ .agent-binding-fields .agent-edit-input,
1116
+ .agent-binding-fields .agent-edit-select {
1117
+ font-size: 11px;
1118
+ padding: 4px 6px;
1119
+ }
1120
+
1121
+ .agent-binding-remove {
1122
+ flex-shrink: 0;
1123
+ width: 24px;
1124
+ height: 24px;
1125
+ display: flex;
1126
+ align-items: center;
1127
+ justify-content: center;
1128
+ border: 1px solid rgba(239, 68, 68, 0.3);
1129
+ background: transparent;
1130
+ color: rgba(239, 68, 68, 0.6);
1131
+ border-radius: var(--radius-md);
1132
+ cursor: pointer;
1133
+ font-size: 12px;
1134
+ margin-top: 14px;
1135
+ transition: all 0.15s ease;
1136
+ }
1137
+
1138
+ .agent-binding-remove:hover {
1139
+ background: rgba(239, 68, 68, 0.15);
1140
+ color: rgb(239, 68, 68);
1141
+ border-color: rgb(239, 68, 68);
1142
+ }
1143
+
1144
+ .agent-binding-add {
1145
+ margin-top: 8px;
1146
+ font-size: 11px;
1147
+ padding: 6px 12px;
1148
+ border: 1px dashed var(--border);
1149
+ background: transparent;
1150
+ color: var(--text-muted);
1151
+ border-radius: var(--radius-md);
1152
+ cursor: pointer;
1153
+ font-family: var(--font-mono);
1154
+ width: 100%;
1155
+ transition: all 0.15s ease;
1156
+ }
1157
+
1158
+ .agent-binding-add:hover {
1159
+ border-color: var(--accent);
1160
+ color: var(--accent);
1161
+ }
1162
+
1163
+ /* ============================================
1164
+ SWITCH OVERLAY
1165
+ ============================================ */
1166
+
1167
+ .satellite-switch-overlay {
1168
+ position: absolute;
1169
+ top: 0;
1170
+ left: 0;
1171
+ right: 0;
1172
+ bottom: 0;
1173
+ background: var(--black-80);
1174
+ display: flex;
1175
+ align-items: center;
1176
+ justify-content: center;
1177
+ z-index: 100;
1178
+ animation: fadeIn 0.15s ease;
1179
+ backdrop-filter: blur(2px);
1180
+ }
1181
+
1182
+ .satellite-switch-spinner {
1183
+ display: flex;
1184
+ flex-direction: column;
1185
+ align-items: center;
1186
+ gap: 8px;
1187
+ color: var(--text);
1188
+ font-size: 14px;
1189
+ }
1190
+
1191
+ .satellite-switch-spinner span:first-child {
1192
+ font-size: 32px;
1193
+ animation: satellitePulse 1s ease-in-out infinite;
1194
+ }
1195
+
1196
+ @keyframes satellitePulse {
1197
+ 0%, 100% { transform: scale(1); opacity: 1; }
1198
+ 50% { transform: scale(1.1); opacity: 0.7; }
1199
+ }
1200
+
1201
+ /* Input area disabled state during switch */
1202
+ .input-area.switching-satellite,
1203
+ .chat-input.switching-satellite {
1204
+ pointer-events: none;
1205
+ opacity: 0.5;
1206
+ transition: opacity 0.15s ease;
1207
+ }
1208
+
1209
+ /* ============================================
1210
+ PENDING DELETE STATE
1211
+ ============================================ */
1212
+
1213
+ .satellite-item.pending-delete {
1214
+ background: rgba(239, 68, 68, 0.15) !important;
1215
+ border-color: var(--error) !important;
1216
+ animation: pendingPulse 1s ease-in-out infinite;
1217
+ }
1218
+
1219
+ .satellite-item.pending-delete .satellite-item-delete {
1220
+ background: var(--error);
1221
+ color: white;
1222
+ border-radius: var(--radius-md);
1223
+ }
1224
+
1225
+ @keyframes pendingPulse {
1226
+ 0%, 100% { opacity: 1; }
1227
+ 50% { opacity: 0.7; }
1228
+ }
1229
+
1230
+ /* ============================================
1231
+ ANIMATIONS
1232
+ ============================================ */
1233
+
1234
+ @keyframes fadeIn {
1235
+ from { opacity: 0; }
1236
+ to { opacity: 1; }
1237
+ }
1238
+
1239
+ @keyframes pulse {
1240
+ 0%, 100% { opacity: 1; }
1241
+ 50% { opacity: 0.5; }
1242
+ }
1243
+
1244
+ @keyframes blink {
1245
+ 0%, 100% { opacity: 1; }
1246
+ 50% { opacity: 0.3; }
1247
+ }
1248
+
1249
+ /* ============================================
1250
+ MOBILE (< 480px)
1251
+ ============================================ */
1252
+
1253
+ @media (max-width: 480px) {
1254
+ .satellite-navigator {
1255
+ bottom: 140px;
1256
+ left: var(--space-4);
1257
+ right: var(--space-4);
1258
+ width: auto;
1259
+ }
1260
+ }
1261
+
1262
+ /* Accessibility: Respect reduced motion preference (M-09) */
1263
+ @media (prefers-reduced-motion: reduce) {
1264
+ *,
1265
+ *::before,
1266
+ *::after {
1267
+ animation-duration: 0.01ms !important;
1268
+ animation-iteration-count: 1 !important;
1269
+ transition-duration: 0.01ms !important;
1270
+ }
1271
+ }
1272
+
1273
+ /* === SHORTCUTS === */
1274
+
1275
+ /* ============================================
1276
+ KEYBOARD SHORTCUTS PANEL STYLES
1277
+ ============================================ */
1278
+
1279
+ .shortcuts-panel {
1280
+ position: fixed;
1281
+ top: 0;
1282
+ left: 0;
1283
+ right: 0;
1284
+ bottom: 0;
1285
+ background: rgba(0, 0, 0, 0.85);
1286
+ display: none;
1287
+ align-items: center;
1288
+ justify-content: center;
1289
+ z-index: var(--z-overlay);
1290
+ padding: var(--space-5);
1291
+ }
1292
+
1293
+ .shortcuts-panel.visible {
1294
+ display: flex;
1295
+ }
1296
+
1297
+ .shortcuts-panel-header {
1298
+ display: flex;
1299
+ align-items: center;
1300
+ justify-content: space-between;
1301
+ padding: var(--space-5) var(--space-6);
1302
+ border-bottom: 1px solid var(--border);
1303
+ }
1304
+
1305
+ .shortcuts-panel-header h3 {
1306
+ font-size: var(--text-lg);
1307
+ font-weight: 500;
1308
+ color: var(--text);
1309
+ margin: 0;
1310
+ }
1311
+
1312
+ .shortcuts-close {
1313
+ background: none;
1314
+ border: none;
1315
+ color: var(--text-muted);
1316
+ font-size: var(--text-2xl);
1317
+ cursor: pointer;
1318
+ min-width: 44px;
1319
+ min-height: 44px;
1320
+ display: flex;
1321
+ align-items: center;
1322
+ justify-content: center;
1323
+ line-height: 1;
1324
+ border-radius: var(--radius-md);
1325
+ }
1326
+
1327
+ .shortcuts-close:hover {
1328
+ color: var(--text);
1329
+ }
1330
+
1331
+ .shortcuts-panel > .shortcuts-panel-header,
1332
+ .shortcuts-panel > .shortcuts-list,
1333
+ .shortcuts-panel > .shortcuts-footer {
1334
+ /* Direct children styling */
1335
+ }
1336
+
1337
+ .shortcuts-panel-inner {
1338
+ background: var(--bg-secondary);
1339
+ border: 1px solid var(--border);
1340
+ border-radius: var(--radius-xl);
1341
+ width: 100%;
1342
+ max-width: 450px;
1343
+ max-height: 80vh;
1344
+ overflow: hidden;
1345
+ display: flex;
1346
+ flex-direction: column;
1347
+ }
1348
+
1349
+ .shortcuts-list {
1350
+ flex: 1;
1351
+ overflow-y: auto;
1352
+ padding: var(--space-3) 0;
1353
+ }
1354
+
1355
+ .shortcut-row {
1356
+ display: flex;
1357
+ align-items: center;
1358
+ justify-content: space-between;
1359
+ padding: var(--space-3) var(--space-6);
1360
+ transition: background 0.15s;
1361
+ }
1362
+
1363
+ .shortcut-row:hover {
1364
+ background: rgba(0, 240, 255, 0.05);
1365
+ }
1366
+
1367
+ .shortcut-desc {
1368
+ font-size: var(--text-base);
1369
+ color: var(--text);
1370
+ }
1371
+
1372
+ .shortcut-key {
1373
+ font-family: var(--font-mono);
1374
+ font-size: var(--text-sm);
1375
+ background: var(--bg-input);
1376
+ border: 1px solid var(--border);
1377
+ border-radius: var(--radius-md);
1378
+ padding: var(--space-1) var(--space-2);
1379
+ color: var(--accent);
1380
+ min-width: 60px;
1381
+ text-align: center;
1382
+ cursor: pointer;
1383
+ transition: all 0.15s ease;
1384
+ }
1385
+
1386
+ .shortcut-key:hover {
1387
+ border-color: var(--accent);
1388
+ background: rgba(0, 240, 255, 0.1);
1389
+ }
1390
+
1391
+ .shortcut-key.editing {
1392
+ border-color: var(--accent);
1393
+ background: rgba(0, 240, 255, 0.2);
1394
+ animation: pulse-border 1s infinite;
1395
+ color: var(--text);
1396
+ }
1397
+
1398
+ @keyframes pulse-border {
1399
+ 0%, 100% { border-color: var(--accent); }
1400
+ 50% { border-color: transparent; }
1401
+ }
1402
+
1403
+ .shortcuts-hint {
1404
+ padding: 0 var(--space-6);
1405
+ margin: 0 0 var(--space-2) 0;
1406
+ font-size: var(--text-xs);
1407
+ color: var(--text-muted);
1408
+ }
1409
+
1410
+ .shortcuts-footer {
1411
+ padding: var(--space-4) var(--space-6);
1412
+ border-top: 1px solid var(--border);
1413
+ display: flex;
1414
+ justify-content: flex-end;
1415
+ }
1416
+
1417
+ .shortcuts-reset {
1418
+ background: transparent;
1419
+ border: 1px solid var(--border);
1420
+ border-radius: var(--radius-md);
1421
+ padding: var(--space-2) var(--space-4);
1422
+ color: var(--text-muted);
1423
+ font-size: var(--text-sm);
1424
+ cursor: pointer;
1425
+ transition: all 0.15s;
1426
+ }
1427
+
1428
+ .shortcuts-reset:hover {
1429
+ border-color: var(--text-muted);
1430
+ color: var(--text);
1431
+ }
1432
+
1433
+ /* Settings button style */
1434
+ .setting-btn {
1435
+ background: var(--bg-input);
1436
+ border: 1px solid var(--border);
1437
+ border-radius: var(--radius-md);
1438
+ padding: var(--space-2) var(--space-4);
1439
+ color: var(--text-muted);
1440
+ font-size: var(--text-sm);
1441
+ cursor: pointer;
1442
+ transition: all 0.15s;
1443
+ }
1444
+
1445
+ .setting-btn:hover {
1446
+ border-color: var(--accent);
1447
+ color: var(--accent);
1448
+ }
1449
+
1450
+ /* Accessibility: Respect reduced motion preference (M-09) */
1451
+ @media (prefers-reduced-motion: reduce) {
1452
+ *,
1453
+ *::before,
1454
+ *::after {
1455
+ animation-duration: 0.01ms !important;
1456
+ animation-iteration-count: 1 !important;
1457
+ transition-duration: 0.01ms !important;
1458
+ }
1459
+ }
1460
+
1461
+ /* === TIMESTAMPS === */
1462
+
1463
+ /* ============================================
1464
+ TIMESTAMPS STYLES
1465
+ Small light text under message content
1466
+ ============================================ */
1467
+
1468
+ /* Timestamp inside message bubble */
1469
+ .message-timestamp {
1470
+ display: none;
1471
+ font-size: 0.65rem;
1472
+ font-family: var(--font-mono);
1473
+ color: var(--text-dim);
1474
+ margin-top: 6px;
1475
+ opacity: 0.5;
1476
+ user-select: none;
1477
+ line-height: 1;
1478
+ }
1479
+
1480
+ /* Show when enabled */
1481
+ .message.show-timestamp .message-timestamp {
1482
+ display: block;
1483
+ }
1484
+
1485
+ /* Slightly brighter on hover */
1486
+ .message:hover .message-timestamp {
1487
+ opacity: 0.8;
1488
+ }
1489
+
1490
+ /* Right-align for user messages */
1491
+ .message.user .message-timestamp {
1492
+ text-align: right;
1493
+ }
1494
+
1495
+ /* Left-align for assistant messages */
1496
+ .message.assistant .message-timestamp {
1497
+ text-align: left;
1498
+ }
1499
+