@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,485 @@
1
+ /**
2
+ * Unified Panel System
3
+ * Shared styles for all panels (Settings, Activity, Satellites)
4
+ * Mobile: Full-page slide-in | Desktop: Floating panels
5
+ */
6
+
7
+ /* ==========================================================================
8
+ Panel Container
9
+ ========================================================================== */
10
+
11
+ /* Base panel styles - internal layout only, positioning handled by split-view or mobile.css */
12
+ .panel {
13
+ display: none;
14
+ flex-direction: column;
15
+ background: var(--bg);
16
+ overflow: hidden;
17
+ }
18
+
19
+ .panel.visible {
20
+ display: flex;
21
+ }
22
+
23
+ /* Desktop: panels render inside .side-panel-content via split-view.js
24
+ No positioning rules here - just fill the container */
25
+ @media (min-width: 1024px) {
26
+ .panel {
27
+ /* Inside side-panel, just fill the space */
28
+ width: 100%;
29
+ height: 100%;
30
+ max-height: 100%;
31
+ border: none;
32
+ border-radius: 0;
33
+ box-shadow: none;
34
+ background: var(--bg);
35
+ }
36
+
37
+ .panel.visible {
38
+ display: flex;
39
+ animation: panel-fade-in 0.2s ease-out;
40
+ }
41
+ }
42
+
43
+ @keyframes panel-fade-in {
44
+ from {
45
+ opacity: 0;
46
+ transform: scale(0.97);
47
+ }
48
+ to {
49
+ opacity: 1;
50
+ transform: scale(1);
51
+ }
52
+ }
53
+
54
+ /* Mobile: Full-page slide-in (< 1024px breakpoint to match split-view) */
55
+ @media (max-width: 1023px) {
56
+ .panel {
57
+ position: fixed !important;
58
+ inset: 0 !important;
59
+ width: 100% !important;
60
+ height: 100% !important;
61
+ max-width: 100% !important;
62
+ max-height: 100% !important;
63
+ border-radius: 0 !important;
64
+ transform: translateX(100%);
65
+ transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
66
+ background: var(--bg) !important;
67
+ z-index: var(--z-sticky) !important;
68
+ overflow-y: auto;
69
+ -webkit-overflow-scrolling: touch;
70
+ overscroll-behavior: contain;
71
+ }
72
+
73
+ .panel.visible {
74
+ display: flex !important;
75
+ flex-direction: column;
76
+ transform: translateX(0);
77
+ }
78
+ }
79
+
80
+ /* ==========================================================================
81
+ Panel Header
82
+ ========================================================================== */
83
+
84
+ .panel-header {
85
+ display: flex;
86
+ align-items: center;
87
+ justify-content: space-between;
88
+ padding: var(--space-4) var(--space-5);
89
+ border-bottom: 1px solid var(--border);
90
+ background: var(--bg);
91
+ position: sticky;
92
+ top: 0;
93
+ z-index: 1;
94
+ flex-shrink: 0;
95
+ }
96
+
97
+ .panel-title {
98
+ font-family: var(--font-mono);
99
+ font-size: var(--text-sm);
100
+ color: var(--accent);
101
+ letter-spacing: 1px;
102
+ text-transform: uppercase;
103
+ }
104
+
105
+ .panel-close {
106
+ min-width: 44px;
107
+ min-height: 44px;
108
+ display: flex;
109
+ align-items: center;
110
+ justify-content: center;
111
+ background: none;
112
+ border: none;
113
+ color: var(--text-muted);
114
+ font-size: var(--text-xl);
115
+ cursor: pointer;
116
+ border-radius: var(--radius-md);
117
+ transition: color 0.2s, background 0.2s;
118
+ }
119
+
120
+ .panel-close:hover {
121
+ color: var(--text);
122
+ background: var(--white-10);
123
+ }
124
+
125
+ .panel-close:focus-visible {
126
+ outline: 2px solid var(--accent);
127
+ outline-offset: 2px;
128
+ }
129
+
130
+ /* ==========================================================================
131
+ Panel Content
132
+ ========================================================================== */
133
+
134
+ .panel-content {
135
+ flex: 1;
136
+ overflow-y: auto;
137
+ padding: var(--space-4) var(--space-5);
138
+ -webkit-overflow-scrolling: touch;
139
+ }
140
+
141
+ /* Scrollbar styling for panel content */
142
+ .panel-content::-webkit-scrollbar {
143
+ width: 6px;
144
+ }
145
+
146
+ .panel-content::-webkit-scrollbar-track {
147
+ background: transparent;
148
+ }
149
+
150
+ .panel-content::-webkit-scrollbar-thumb {
151
+ background: var(--border);
152
+ border-radius: 3px;
153
+ }
154
+
155
+ .panel-content::-webkit-scrollbar-thumb:hover {
156
+ background: var(--text-muted);
157
+ }
158
+
159
+ /* ==========================================================================
160
+ Panel Row (Settings-style rows)
161
+ ========================================================================== */
162
+
163
+ .panel-row {
164
+ display: flex;
165
+ align-items: center;
166
+ justify-content: space-between;
167
+ gap: var(--space-4);
168
+ padding: var(--space-4) 0;
169
+ border-bottom: 1px solid var(--border);
170
+ }
171
+
172
+ .panel-row:last-child {
173
+ border-bottom: none;
174
+ }
175
+
176
+ .panel-row-info {
177
+ flex: 1;
178
+ min-width: 0; /* Allow text truncation */
179
+ }
180
+
181
+ .panel-row-label {
182
+ font-size: var(--text-base);
183
+ font-weight: 500;
184
+ color: var(--text);
185
+ }
186
+
187
+ .panel-row-desc {
188
+ font-size: var(--text-sm);
189
+ color: var(--text-muted);
190
+ margin-top: var(--space-1);
191
+ }
192
+
193
+ @media (max-width: 768px) {
194
+ .panel-row {
195
+ padding: var(--space-4) var(--space-5);
196
+ min-height: 60px;
197
+ margin: 0 calc(-1 * var(--space-5)); /* Extend to edges */
198
+ }
199
+ }
200
+
201
+ /* ==========================================================================
202
+ Panel Tabs
203
+ ========================================================================== */
204
+
205
+ .panel-tabs {
206
+ display: flex;
207
+ border-bottom: 1px solid var(--border);
208
+ padding: 0 var(--space-4);
209
+ flex-shrink: 0;
210
+ }
211
+
212
+ .panel-tab {
213
+ flex: 1;
214
+ padding: var(--space-3) var(--space-4);
215
+ background: none;
216
+ border: none;
217
+ border-bottom: 2px solid transparent;
218
+ color: var(--text-muted);
219
+ font-size: var(--text-sm);
220
+ font-weight: 500;
221
+ cursor: pointer;
222
+ transition: all 0.2s;
223
+ min-height: 44px; /* Touch-friendly */
224
+ }
225
+
226
+ .panel-tab:hover {
227
+ color: var(--text);
228
+ background: var(--white-05);
229
+ }
230
+
231
+ .panel-tab.active {
232
+ color: var(--accent);
233
+ border-bottom-color: var(--accent);
234
+ }
235
+
236
+ .panel-tab:focus-visible {
237
+ outline: 2px solid var(--accent);
238
+ outline-offset: -2px;
239
+ }
240
+
241
+ /* ==========================================================================
242
+ Panel List Items (Satellites-style)
243
+ ========================================================================== */
244
+
245
+ .panel-item {
246
+ display: flex;
247
+ align-items: center;
248
+ gap: var(--space-3);
249
+ padding: var(--space-3) var(--space-4);
250
+ margin: var(--space-1) 0;
251
+ border-radius: var(--radius-md);
252
+ cursor: pointer;
253
+ transition: background 0.2s;
254
+ border: 1px solid transparent;
255
+ min-height: 44px; /* Touch-friendly */
256
+ }
257
+
258
+ .panel-item:hover {
259
+ background: var(--white-05);
260
+ }
261
+
262
+ .panel-item.active {
263
+ background: rgba(99, 102, 241, 0.15);
264
+ border-color: var(--accent);
265
+ }
266
+
267
+ .panel-item:focus-visible {
268
+ outline: 2px solid var(--accent);
269
+ outline-offset: 2px;
270
+ }
271
+
272
+ .panel-item-icon {
273
+ font-size: var(--text-lg);
274
+ flex-shrink: 0;
275
+ }
276
+
277
+ .panel-item-name {
278
+ flex: 1;
279
+ font-size: var(--text-sm);
280
+ font-weight: 500;
281
+ color: var(--text);
282
+ min-width: 0; /* Allow text truncation */
283
+ overflow: hidden;
284
+ text-overflow: ellipsis;
285
+ white-space: nowrap;
286
+ }
287
+
288
+ .panel-item-badge {
289
+ font-size: var(--text-xs);
290
+ color: var(--text-muted);
291
+ background: var(--bg-input);
292
+ padding: 2px var(--space-2);
293
+ border-radius: var(--radius-full);
294
+ flex-shrink: 0;
295
+ }
296
+
297
+ .panel-item-status {
298
+ width: 8px;
299
+ height: 8px;
300
+ border-radius: 50%;
301
+ background: var(--success);
302
+ flex-shrink: 0;
303
+ }
304
+
305
+ .panel-item-status.offline {
306
+ background: var(--text-muted);
307
+ }
308
+
309
+ .panel-item-status.error {
310
+ background: var(--error);
311
+ }
312
+
313
+ /* ==========================================================================
314
+ Panel Actions (bottom area)
315
+ ========================================================================== */
316
+
317
+ .panel-actions {
318
+ padding: var(--space-4) var(--space-5);
319
+ border-top: 1px solid var(--border);
320
+ background: var(--bg);
321
+ flex-shrink: 0;
322
+ }
323
+
324
+ .panel-btn {
325
+ width: 100%;
326
+ padding: var(--space-3) var(--space-4);
327
+ background: var(--accent);
328
+ color: var(--text-inverse);
329
+ border: none;
330
+ border-radius: var(--radius-md);
331
+ font-size: var(--text-sm);
332
+ font-weight: 500;
333
+ cursor: pointer;
334
+ transition: background 0.2s, transform 0.1s;
335
+ min-height: 44px; /* Touch-friendly */
336
+ }
337
+
338
+ .panel-btn:hover {
339
+ background: var(--accent-hover);
340
+ transform: translateY(-1px);
341
+ }
342
+
343
+ .panel-btn:active {
344
+ transform: translateY(0);
345
+ }
346
+
347
+ .panel-btn:focus-visible {
348
+ outline: 2px solid var(--accent);
349
+ outline-offset: 2px;
350
+ }
351
+
352
+ .panel-btn.secondary {
353
+ background: transparent;
354
+ color: var(--text);
355
+ border: 1px solid var(--border);
356
+ }
357
+
358
+ .panel-btn.secondary:hover {
359
+ background: var(--white-05);
360
+ border-color: var(--text-muted);
361
+ }
362
+
363
+ .panel-btn + .panel-btn {
364
+ margin-top: var(--space-2);
365
+ }
366
+
367
+ /* Inline action buttons */
368
+ .panel-actions-inline {
369
+ display: flex;
370
+ gap: var(--space-2);
371
+ }
372
+
373
+ .panel-actions-inline .panel-btn {
374
+ flex: 1;
375
+ }
376
+
377
+ /* ==========================================================================
378
+ Panel Empty State
379
+ ========================================================================== */
380
+
381
+ .panel-empty {
382
+ display: flex;
383
+ flex-direction: column;
384
+ align-items: center;
385
+ justify-content: center;
386
+ padding: var(--space-8) var(--space-4);
387
+ text-align: center;
388
+ color: var(--text-muted);
389
+ }
390
+
391
+ .panel-empty-icon {
392
+ font-size: 2rem;
393
+ margin-bottom: var(--space-3);
394
+ opacity: 0.5;
395
+ }
396
+
397
+ .panel-empty-text {
398
+ font-size: var(--text-sm);
399
+ }
400
+
401
+ /* ==========================================================================
402
+ Panel Loading State
403
+ ========================================================================== */
404
+
405
+ .panel-loading {
406
+ display: flex;
407
+ align-items: center;
408
+ justify-content: center;
409
+ padding: var(--space-8);
410
+ }
411
+
412
+ .panel-loading::after {
413
+ content: '';
414
+ width: 24px;
415
+ height: 24px;
416
+ border: 2px solid var(--border);
417
+ border-top-color: var(--accent);
418
+ border-radius: 50%;
419
+ animation: panel-spin 0.8s linear infinite;
420
+ }
421
+
422
+ @keyframes panel-spin {
423
+ to {
424
+ transform: rotate(360deg);
425
+ }
426
+ }
427
+
428
+ /* ==========================================================================
429
+ Panel Section Headers
430
+ ========================================================================== */
431
+
432
+ .panel-section {
433
+ margin-top: var(--space-6);
434
+ }
435
+
436
+ .panel-section:first-child {
437
+ margin-top: 0;
438
+ }
439
+
440
+ .panel-section-title {
441
+ font-family: var(--font-mono);
442
+ font-size: var(--text-xs);
443
+ text-transform: uppercase;
444
+ letter-spacing: 0.5px;
445
+ color: var(--text-muted);
446
+ margin-bottom: var(--space-3);
447
+ padding: 0 var(--space-1);
448
+ }
449
+
450
+ /* ==========================================================================
451
+ Panel Divider
452
+ ========================================================================== */
453
+
454
+ .panel-divider {
455
+ height: 1px;
456
+ background: var(--border);
457
+ margin: var(--space-4) 0;
458
+ }
459
+
460
+ /* ==========================================================================
461
+ Responsive Adjustments
462
+ ========================================================================== */
463
+
464
+ /* Tablet adjustments (still mobile behavior until 1024px) */
465
+ @media (min-width: 481px) and (max-width: 1023px) {
466
+ .panel-content {
467
+ padding: var(--space-5) var(--space-6);
468
+ }
469
+ }
470
+
471
+ /* Reduced motion */
472
+ @media (prefers-reduced-motion: reduce) {
473
+ .panel {
474
+ transition: none;
475
+ }
476
+
477
+ .panel-btn {
478
+ transition: none;
479
+ }
480
+
481
+ .panel-loading::after {
482
+ animation: none;
483
+ }
484
+ }
485
+