agentopia 1.0.0

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 (140) hide show
  1. package/.claude/settings.local.json +28 -0
  2. package/dist/app.d.ts +10 -0
  3. package/dist/app.d.ts.map +1 -0
  4. package/dist/app.js +121 -0
  5. package/dist/app.js.map +1 -0
  6. package/dist/config.d.ts +9 -0
  7. package/dist/config.d.ts.map +1 -0
  8. package/dist/config.js +19 -0
  9. package/dist/config.js.map +1 -0
  10. package/dist/db/database.d.ts +5 -0
  11. package/dist/db/database.d.ts.map +1 -0
  12. package/dist/db/database.js +39 -0
  13. package/dist/db/database.js.map +1 -0
  14. package/dist/db/schema.d.ts +3 -0
  15. package/dist/db/schema.d.ts.map +1 -0
  16. package/dist/db/schema.js +621 -0
  17. package/dist/db/schema.js.map +1 -0
  18. package/dist/index.d.ts +2 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +49 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/logger.d.ts +4 -0
  23. package/dist/logger.d.ts.map +1 -0
  24. package/dist/logger.js +9 -0
  25. package/dist/logger.js.map +1 -0
  26. package/dist/middleware/auth.d.ts +13 -0
  27. package/dist/middleware/auth.d.ts.map +1 -0
  28. package/dist/middleware/auth.js +733 -0
  29. package/dist/middleware/auth.js.map +1 -0
  30. package/dist/routes/agents.d.ts +3 -0
  31. package/dist/routes/agents.d.ts.map +1 -0
  32. package/dist/routes/agents.js +1058 -0
  33. package/dist/routes/agents.js.map +1 -0
  34. package/dist/routes/issues.d.ts +4 -0
  35. package/dist/routes/issues.d.ts.map +1 -0
  36. package/dist/routes/issues.js +946 -0
  37. package/dist/routes/issues.js.map +1 -0
  38. package/dist/routes/knowledge.d.ts +3 -0
  39. package/dist/routes/knowledge.d.ts.map +1 -0
  40. package/dist/routes/knowledge.js +117 -0
  41. package/dist/routes/knowledge.js.map +1 -0
  42. package/dist/routes/memories.d.ts +3 -0
  43. package/dist/routes/memories.d.ts.map +1 -0
  44. package/dist/routes/memories.js +115 -0
  45. package/dist/routes/memories.js.map +1 -0
  46. package/dist/routes/messages.d.ts +3 -0
  47. package/dist/routes/messages.d.ts.map +1 -0
  48. package/dist/routes/messages.js +130 -0
  49. package/dist/routes/messages.js.map +1 -0
  50. package/dist/routes/projects.d.ts +3 -0
  51. package/dist/routes/projects.d.ts.map +1 -0
  52. package/dist/routes/projects.js +754 -0
  53. package/dist/routes/projects.js.map +1 -0
  54. package/dist/routes/templates.d.ts +3 -0
  55. package/dist/routes/templates.d.ts.map +1 -0
  56. package/dist/routes/templates.js +117 -0
  57. package/dist/routes/templates.js.map +1 -0
  58. package/dist/routes/ui.d.ts +3 -0
  59. package/dist/routes/ui.d.ts.map +1 -0
  60. package/dist/routes/ui.js +38 -0
  61. package/dist/routes/ui.js.map +1 -0
  62. package/dist/services/agent-hierarchy.d.ts +14 -0
  63. package/dist/services/agent-hierarchy.d.ts.map +1 -0
  64. package/dist/services/agent-hierarchy.js +58 -0
  65. package/dist/services/agent-hierarchy.js.map +1 -0
  66. package/dist/services/agent-issue-batch.d.ts +17 -0
  67. package/dist/services/agent-issue-batch.d.ts.map +1 -0
  68. package/dist/services/agent-issue-batch.js +57 -0
  69. package/dist/services/agent-issue-batch.js.map +1 -0
  70. package/dist/services/controller.d.ts +4 -0
  71. package/dist/services/controller.d.ts.map +1 -0
  72. package/dist/services/controller.js +237 -0
  73. package/dist/services/controller.js.map +1 -0
  74. package/dist/services/langgraph-runner.d.ts +33 -0
  75. package/dist/services/langgraph-runner.d.ts.map +1 -0
  76. package/dist/services/langgraph-runner.js +478 -0
  77. package/dist/services/langgraph-runner.js.map +1 -0
  78. package/dist/services/orchestrator.d.ts +9 -0
  79. package/dist/services/orchestrator.d.ts.map +1 -0
  80. package/dist/services/orchestrator.js +116 -0
  81. package/dist/services/orchestrator.js.map +1 -0
  82. package/dist/services/pre-controller.d.ts +7 -0
  83. package/dist/services/pre-controller.d.ts.map +1 -0
  84. package/dist/services/pre-controller.js +101 -0
  85. package/dist/services/pre-controller.js.map +1 -0
  86. package/dist/services/process-manager.d.ts +67 -0
  87. package/dist/services/process-manager.d.ts.map +1 -0
  88. package/dist/services/process-manager.js +938 -0
  89. package/dist/services/process-manager.js.map +1 -0
  90. package/dist/services/project-permissions.d.ts +84 -0
  91. package/dist/services/project-permissions.d.ts.map +1 -0
  92. package/dist/services/project-permissions.js +129 -0
  93. package/dist/services/project-permissions.js.map +1 -0
  94. package/dist/services/scheduler.d.ts +6 -0
  95. package/dist/services/scheduler.d.ts.map +1 -0
  96. package/dist/services/scheduler.js +300 -0
  97. package/dist/services/scheduler.js.map +1 -0
  98. package/dist/services/system-prompt.d.ts +3 -0
  99. package/dist/services/system-prompt.d.ts.map +1 -0
  100. package/dist/services/system-prompt.js +285 -0
  101. package/dist/services/system-prompt.js.map +1 -0
  102. package/dist/services/terminal.d.ts +18 -0
  103. package/dist/services/terminal.d.ts.map +1 -0
  104. package/dist/services/terminal.js +222 -0
  105. package/dist/services/terminal.js.map +1 -0
  106. package/dist/services/websocket.d.ts +15 -0
  107. package/dist/services/websocket.d.ts.map +1 -0
  108. package/dist/services/websocket.js +204 -0
  109. package/dist/services/websocket.js.map +1 -0
  110. package/dist/types.d.ts +108 -0
  111. package/dist/types.d.ts.map +1 -0
  112. package/dist/types.js +3 -0
  113. package/dist/types.js.map +1 -0
  114. package/env.ini +18 -0
  115. package/package.json +38 -0
  116. package/project_id +0 -0
  117. package/public/admin-users.html +188 -0
  118. package/public/agent.html +199 -0
  119. package/public/css/issues.css +275 -0
  120. package/public/css/style.css +1299 -0
  121. package/public/index.html +166 -0
  122. package/public/issue.html +76 -0
  123. package/public/js/agent.js +19 -0
  124. package/public/js/common.js +735 -0
  125. package/public/js/dashboard.js +772 -0
  126. package/public/js/files-panel.js +703 -0
  127. package/public/js/interactive-terminal.js +201 -0
  128. package/public/js/issue-renderer.js +559 -0
  129. package/public/js/issue.js +57 -0
  130. package/public/js/project.js +2425 -0
  131. package/public/js/terminal.js +564 -0
  132. package/public/project.html +430 -0
  133. package/public/terminal.html +67 -0
  134. package/public/vendor/marked.js +74 -0
  135. package/public/vendor/xterm-addon-fit.js +2 -0
  136. package/public/vendor/xterm.css +209 -0
  137. package/public/vendor/xterm.js +2 -0
  138. package/send_message_and_update_issue.js +65 -0
  139. package/tsconfig.json +19 -0
  140. package/update_round2_and_create_round3.js +284 -0
@@ -0,0 +1,1299 @@
1
+ :root {
2
+ --bg: #fdf6e3;
3
+ --fg: #073642;
4
+ --header-bg: #eee8d5;
5
+ --drawer-bg: #eee8d5;
6
+ --border: #c9bba3;
7
+ --text-secondary: #586e75;
8
+ --accent: #268bd2;
9
+ --success: #859900;
10
+ --warning: #b58900;
11
+ --error: #dc322f;
12
+ --selected-bg: #e8dcc8;
13
+ }
14
+
15
+ * { margin: 0; padding: 0; box-sizing: border-box; }
16
+
17
+ body {
18
+ font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Fira Code', Menlo, monospace;
19
+ background: var(--bg);
20
+ color: var(--fg);
21
+ line-height: 1.5;
22
+ height: 100vh;
23
+ overflow-x: hidden;
24
+ }
25
+
26
+ a { color: var(--accent); text-decoration: none; }
27
+ a:hover { opacity: 0.8; }
28
+
29
+ .container { max-width: 1200px; margin: 0 auto; padding: 20px; }
30
+
31
+ /* Header */
32
+ header {
33
+ background: var(--header-bg);
34
+ border-bottom: 1px solid var(--border);
35
+ padding: 0 16px;
36
+ display: flex;
37
+ align-items: center;
38
+ height: 42px;
39
+ gap: 12px;
40
+ }
41
+
42
+ header h1 { font-size: 16px; font-weight: 600; letter-spacing: -0.02em; }
43
+ header h1 span { color: var(--accent); }
44
+
45
+ .header-right { margin-left: auto; display: flex; align-items: center; gap: 8px; }
46
+
47
+ /* User Menu */
48
+ .user-menu { position: relative; margin-left: auto; flex-shrink: 0; }
49
+ .user-menu-btn { background: none; border: 1px solid var(--border); border-radius: 50%; width: 30px; height: 30px; cursor: pointer; display: flex; align-items: center; justify-content: center; font-size: 13px; font-weight: 600; color: var(--fg); font-family: inherit; }
50
+ .user-menu-btn:hover { border-color: var(--accent); }
51
+ .user-menu-dropdown { display: none; position: absolute; right: 0; top: 36px; background: var(--header-bg); border: 1px solid var(--border); border-radius: 8px; box-shadow: 0 4px 16px rgba(0,0,0,0.3); min-width: 200px; z-index: 500; padding: 4px 0; }
52
+ .user-menu-dropdown.open { display: block; }
53
+ .user-menu-info { padding: 10px 14px; border-bottom: 1px solid var(--border); }
54
+ .user-menu-info .name { font-weight: 600; font-size: 13px; }
55
+ .user-menu-info .role { font-size: 11px; color: var(--text-secondary); text-transform: uppercase; }
56
+ .user-menu-dropdown a, .user-menu-dropdown button.menu-item { display: block; width: 100%; text-align: left; padding: 8px 14px; font-size: 13px; color: var(--fg); text-decoration: none; background: none; border: none; cursor: pointer; font-family: inherit; }
57
+ .user-menu-dropdown a:hover, .user-menu-dropdown button.menu-item:hover { background: var(--selected-bg); }
58
+ .user-menu-dropdown .divider { height: 1px; background: var(--border); margin: 4px 0; }
59
+
60
+ .breadcrumb { display: flex; gap: 8px; align-items: center; color: var(--text-secondary); font-size: 13px; }
61
+ .breadcrumb a { color: var(--text-secondary); }
62
+
63
+ /* Hamburger Menu Button */
64
+ .menu-btn {
65
+ background: none;
66
+ border: none;
67
+ padding: 6px 10px;
68
+ cursor: pointer;
69
+ display: flex;
70
+ flex-direction: column;
71
+ gap: 4px;
72
+ color: var(--fg);
73
+ height: 42px;
74
+ align-items: center;
75
+ justify-content: center;
76
+ }
77
+ .menu-btn:hover { opacity: 0.7; }
78
+ .menu-btn span {
79
+ display: block;
80
+ width: 18px;
81
+ height: 2px;
82
+ background: currentColor;
83
+ border-radius: 1px;
84
+ }
85
+
86
+ /* Overlay */
87
+ .overlay {
88
+ position: fixed;
89
+ top: 0; left: 0;
90
+ width: 100%; height: 100%;
91
+ background: rgba(0, 0, 0, 0.4);
92
+ z-index: 199;
93
+ opacity: 0;
94
+ visibility: hidden;
95
+ transition: all 0.3s;
96
+ }
97
+ .overlay.open { opacity: 1; visibility: visible; }
98
+
99
+ /* Drawer */
100
+ .drawer {
101
+ position: fixed;
102
+ top: 0; left: 0;
103
+ width: 280px;
104
+ max-width: 85vw;
105
+ height: 100%;
106
+ background: var(--drawer-bg);
107
+ border-right: 1px solid var(--border);
108
+ display: flex;
109
+ flex-direction: column;
110
+ transform: translateX(-100%);
111
+ transition: transform 0.3s;
112
+ z-index: 200;
113
+ box-shadow: 2px 0 10px rgba(0, 0, 0, 0.2);
114
+ overflow: hidden;
115
+ }
116
+ .drawer.open { transform: translateX(0); }
117
+
118
+ .drawer-header {
119
+ padding: 16px;
120
+ border-bottom: 1px solid var(--border);
121
+ display: flex;
122
+ justify-content: space-between;
123
+ align-items: center;
124
+ }
125
+ .drawer-header h3 { font-size: 16px; font-weight: bold; letter-spacing: -0.02em; }
126
+
127
+ .drawer-close {
128
+ background: none;
129
+ border: none;
130
+ font-size: 24px;
131
+ cursor: pointer;
132
+ color: inherit;
133
+ padding: 0 4px;
134
+ line-height: 1;
135
+ }
136
+ .drawer-close:hover { opacity: 0.7; }
137
+
138
+ .drawer-content { flex: 1; overflow-y: auto; }
139
+
140
+ .drawer-section { border-bottom: 1px solid var(--border); }
141
+
142
+ .drawer-section-header {
143
+ padding: 12px 16px;
144
+ font-size: 11px;
145
+ font-weight: bold;
146
+ text-transform: uppercase;
147
+ letter-spacing: 0.05em;
148
+ opacity: 0.5;
149
+ }
150
+
151
+ .drawer-link {
152
+ display: block;
153
+ padding: 10px 16px;
154
+ color: var(--accent);
155
+ text-decoration: none;
156
+ font-size: 13px;
157
+ }
158
+ .drawer-link:hover { opacity: 0.8; }
159
+
160
+ /* Settings in drawer */
161
+ .settings-section { padding: 12px 16px; }
162
+
163
+ .setting-group { margin-bottom: 14px; }
164
+ .setting-group:last-child { margin-bottom: 0; }
165
+ .setting-group label {
166
+ display: block;
167
+ margin-bottom: 6px;
168
+ font-size: 11px;
169
+ font-weight: bold;
170
+ text-transform: uppercase;
171
+ letter-spacing: 0.03em;
172
+ opacity: 0.6;
173
+ }
174
+ .setting-group select {
175
+ width: 100%;
176
+ padding: 6px 8px;
177
+ border: 1px solid var(--border);
178
+ border-radius: 4px;
179
+ font-size: 12px;
180
+ background: var(--bg);
181
+ color: inherit;
182
+ font-family: inherit;
183
+ }
184
+
185
+ /* Toggle switch */
186
+ .toggle-label {
187
+ display: flex !important;
188
+ align-items: center;
189
+ justify-content: space-between;
190
+ }
191
+ .toggle-switch {
192
+ position: relative;
193
+ width: 36px;
194
+ height: 20px;
195
+ border-radius: 10px;
196
+ border: 1px solid var(--border);
197
+ background: var(--border);
198
+ cursor: pointer;
199
+ padding: 0;
200
+ transition: background 0.2s;
201
+ }
202
+ .toggle-switch.on { background: var(--success); border-color: var(--success); }
203
+ .toggle-knob {
204
+ position: absolute;
205
+ top: 2px; left: 2px;
206
+ width: 14px; height: 14px;
207
+ border-radius: 50%;
208
+ background: white;
209
+ transition: transform 0.2s;
210
+ }
211
+ .toggle-switch.on .toggle-knob { transform: translateX(16px); }
212
+
213
+ /* Cards */
214
+ .card {
215
+ background: var(--header-bg);
216
+ border: 1px solid var(--border);
217
+ border-radius: 6px;
218
+ padding: 16px;
219
+ margin-bottom: 16px;
220
+ }
221
+ .card h2 { font-size: 16px; margin-bottom: 12px; }
222
+
223
+ .grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(350px, 1fr)); gap: 16px; }
224
+
225
+ /* Status badges */
226
+ .status-badge {
227
+ display: inline-block;
228
+ padding: 2px 8px;
229
+ border-radius: 12px;
230
+ font-size: 12px;
231
+ font-weight: 500;
232
+ }
233
+ .status-active, .status-running { background: rgba(63, 185, 80, 0.2); color: var(--success); }
234
+ .status-idle { background: rgba(139, 148, 158, 0.2); color: var(--text-secondary); }
235
+ .status-paused, .status-stopped, .status-warning { background: rgba(210, 153, 34, 0.2); color: var(--warning); }
236
+ .status-error { background: rgba(248, 81, 73, 0.2); color: var(--error); }
237
+ .status-completed { background: rgba(88, 166, 255, 0.2); color: var(--accent); }
238
+
239
+ .permission-badge {
240
+ display: inline-flex;
241
+ align-items: center;
242
+ justify-content: center;
243
+ padding: 2px 8px;
244
+ border-radius: 999px;
245
+ font-size: 10px;
246
+ font-weight: 700;
247
+ letter-spacing: 0.04em;
248
+ text-transform: uppercase;
249
+ border: 1px solid transparent;
250
+ }
251
+ .permission-owner {
252
+ background: rgba(133, 153, 0, 0.16);
253
+ color: var(--success);
254
+ border-color: rgba(133, 153, 0, 0.28);
255
+ }
256
+ .permission-shared {
257
+ background: rgba(38, 139, 210, 0.12);
258
+ color: var(--accent);
259
+ border-color: rgba(38, 139, 210, 0.28);
260
+ }
261
+ .permission-admin {
262
+ background: rgba(181, 137, 0, 0.14);
263
+ color: var(--warning);
264
+ border-color: rgba(181, 137, 0, 0.3);
265
+ }
266
+ .permission-debug {
267
+ background: rgba(88, 110, 117, 0.14);
268
+ color: var(--text-secondary);
269
+ border-color: rgba(88, 110, 117, 0.3);
270
+ }
271
+
272
+ .meta-chip {
273
+ display: inline-flex;
274
+ align-items: center;
275
+ gap: 6px;
276
+ padding: 4px 10px;
277
+ background: var(--bg);
278
+ border: 1px solid var(--border);
279
+ border-radius: 999px;
280
+ color: var(--fg);
281
+ font-size: 12px;
282
+ line-height: 1.2;
283
+ }
284
+ .meta-chip-label {
285
+ color: var(--text-secondary);
286
+ font-size: 10px;
287
+ text-transform: uppercase;
288
+ letter-spacing: 0.04em;
289
+ }
290
+ .meta-chip-secondary {
291
+ color: var(--text-secondary);
292
+ font-size: 11px;
293
+ }
294
+
295
+ /* Buttons */
296
+ .btn {
297
+ display: inline-block;
298
+ padding: 6px 16px;
299
+ border-radius: 6px;
300
+ border: 1px solid var(--border);
301
+ background: var(--selected-bg);
302
+ color: var(--fg);
303
+ cursor: pointer;
304
+ font-size: 14px;
305
+ font-family: inherit;
306
+ transition: background 0.15s;
307
+ }
308
+ .btn:hover { background: var(--border); text-decoration: none; }
309
+ .btn-primary { background: var(--accent); border-color: var(--accent); color: #fff; }
310
+ .btn-primary:hover { opacity: 0.85; }
311
+ .btn-danger { background: #da3633; border-color: #f85149; }
312
+ .btn-danger:hover { background: #f85149; }
313
+ .btn-sm { padding: 3px 10px; font-size: 12px; }
314
+ .usage-period-btn.active { background: var(--accent); border-color: var(--accent); color: #fff; }
315
+
316
+ /* Forms */
317
+ .form-group { margin-bottom: 12px; }
318
+ .form-group label { display: block; font-size: 14px; color: var(--text-secondary); margin-bottom: 4px; }
319
+ .form-group input, .form-group textarea, .form-group select {
320
+ width: 100%;
321
+ padding: 8px 12px;
322
+ background: var(--bg);
323
+ border: 1px solid var(--border);
324
+ border-radius: 6px;
325
+ color: var(--fg);
326
+ font-size: 14px;
327
+ font-family: inherit;
328
+ }
329
+ .form-group input:focus, .form-group textarea:focus, .form-group select:focus {
330
+ outline: none;
331
+ border-color: var(--accent);
332
+ }
333
+ .form-group textarea { resize: vertical; min-height: 80px; }
334
+
335
+ /* Agent list */
336
+ .agent-list { list-style: none; }
337
+ .agent-item {
338
+ display: flex;
339
+ align-items: center;
340
+ justify-content: space-between;
341
+ padding: 10px 0;
342
+ border-bottom: 1px solid var(--border);
343
+ }
344
+ .agent-item:last-child { border-bottom: none; }
345
+ .agent-info { flex: 1; }
346
+ .agent-name { font-weight: 600; }
347
+ .agent-role { font-size: 13px; color: var(--text-secondary); }
348
+
349
+ /* Messages */
350
+ .message-list { list-style: none; }
351
+ .message-item { padding: 8px 0; border-bottom: 1px solid var(--border); }
352
+ .message-item:last-child { border-bottom: none; }
353
+ .message-meta { font-size: 12px; color: var(--text-secondary); }
354
+ .message-unread { font-weight: 600; }
355
+
356
+ /* Terminal */
357
+ .terminal-container {
358
+ width: 100%;
359
+ height: 500px;
360
+ background: var(--bg);
361
+ border-radius: 6px;
362
+ overflow: hidden;
363
+ }
364
+
365
+ .workspace-card {
366
+ padding-top: 12px;
367
+ }
368
+
369
+ .workspace-tabs {
370
+ display: flex;
371
+ gap: 8px;
372
+ margin-bottom: 16px;
373
+ }
374
+
375
+ .workspace-tab {
376
+ appearance: none;
377
+ border: 1px solid var(--border);
378
+ border-radius: 999px;
379
+ background: var(--bg);
380
+ color: var(--text-secondary);
381
+ cursor: pointer;
382
+ font: inherit;
383
+ font-size: 12px;
384
+ padding: 6px 14px;
385
+ }
386
+
387
+ .workspace-tab.active {
388
+ background: var(--accent);
389
+ border-color: var(--accent);
390
+ color: #fff;
391
+ }
392
+
393
+ .workspace-panel[hidden] {
394
+ display: none !important;
395
+ }
396
+
397
+ .files-shell {
398
+ display: grid;
399
+ gap: 12px;
400
+ grid-template-columns: minmax(240px, 300px) minmax(0, 1fr);
401
+ min-height: 560px;
402
+ }
403
+
404
+ .file-browser-pane,
405
+ .file-editor-pane {
406
+ background: var(--bg);
407
+ border: 1px solid var(--border);
408
+ border-radius: 8px;
409
+ min-width: 0;
410
+ }
411
+
412
+ .file-browser-pane {
413
+ display: flex;
414
+ flex-direction: column;
415
+ overflow: hidden;
416
+ }
417
+
418
+ .file-browser-toolbar,
419
+ .file-editor-toolbar {
420
+ align-items: center;
421
+ border-bottom: 1px solid var(--border);
422
+ display: flex;
423
+ gap: 12px;
424
+ justify-content: space-between;
425
+ padding: 12px 14px;
426
+ }
427
+
428
+ .file-pane-label {
429
+ color: var(--text-secondary);
430
+ font-size: 10px;
431
+ font-weight: 600;
432
+ letter-spacing: 0.05em;
433
+ text-transform: uppercase;
434
+ }
435
+
436
+ .file-browser-root,
437
+ .file-current-path {
438
+ color: var(--fg);
439
+ font-size: 12px;
440
+ margin-top: 2px;
441
+ word-break: break-word;
442
+ }
443
+
444
+ .file-hidden-toggle {
445
+ align-items: center;
446
+ color: var(--text-secondary);
447
+ display: inline-flex;
448
+ gap: 6px;
449
+ font-size: 11px;
450
+ }
451
+
452
+ .file-browser-toolbar-main {
453
+ display: flex;
454
+ flex: 1;
455
+ flex-direction: column;
456
+ gap: 10px;
457
+ min-width: 0;
458
+ }
459
+
460
+ .file-toolbar-group {
461
+ min-width: 0;
462
+ }
463
+
464
+ .files-agent-select {
465
+ margin-top: 4px;
466
+ max-width: 100%;
467
+ min-width: 0;
468
+ padding: 7px 10px;
469
+ width: 100%;
470
+ }
471
+
472
+ .file-tree {
473
+ flex: 1;
474
+ overflow: auto;
475
+ padding: 10px 8px 12px;
476
+ }
477
+
478
+ .file-tree-item {
479
+ align-items: center;
480
+ border-radius: 6px;
481
+ color: var(--fg);
482
+ cursor: pointer;
483
+ display: flex;
484
+ gap: 8px;
485
+ margin-bottom: 2px;
486
+ padding: 5px 8px;
487
+ }
488
+
489
+ .file-tree-item:hover {
490
+ background: var(--selected-bg);
491
+ }
492
+
493
+ .file-tree-item.active {
494
+ background: color-mix(in srgb, var(--accent) 14%, var(--bg));
495
+ color: var(--accent);
496
+ }
497
+
498
+ .file-tree-item.loading {
499
+ color: var(--text-secondary);
500
+ }
501
+
502
+ .file-tree-spacer {
503
+ flex: 0 0 auto;
504
+ }
505
+
506
+ .file-tree-caret,
507
+ .file-tree-icon {
508
+ color: var(--text-secondary);
509
+ flex: 0 0 auto;
510
+ font-size: 12px;
511
+ text-align: center;
512
+ width: 12px;
513
+ }
514
+
515
+ .file-tree-item.active .file-tree-caret,
516
+ .file-tree-item.active .file-tree-icon {
517
+ color: inherit;
518
+ }
519
+
520
+ .file-tree-name {
521
+ flex: 1;
522
+ font-size: 12px;
523
+ min-width: 0;
524
+ overflow: hidden;
525
+ text-overflow: ellipsis;
526
+ white-space: nowrap;
527
+ }
528
+
529
+ .file-tree-action-btn {
530
+ background: none;
531
+ border: 1px solid var(--border-color, #ddd);
532
+ border-radius: 4px;
533
+ color: var(--text-secondary);
534
+ cursor: pointer;
535
+ flex: 0 0 auto;
536
+ font-size: 13px;
537
+ line-height: 1;
538
+ opacity: 0;
539
+ padding: 1px 4px;
540
+ }
541
+
542
+ .file-tree-item:hover .file-tree-action-btn {
543
+ opacity: 1;
544
+ }
545
+
546
+ .file-tree-action-btn:hover {
547
+ background: var(--selected-bg, #eee);
548
+ color: var(--accent, #0969da);
549
+ }
550
+
551
+ .file-upload-btn {
552
+ margin-left: 8px;
553
+ white-space: nowrap;
554
+ }
555
+
556
+ .file-tree-meta {
557
+ color: var(--text-secondary);
558
+ flex: 0 0 auto;
559
+ font-size: 10px;
560
+ }
561
+
562
+ .file-editor-pane {
563
+ display: flex;
564
+ flex-direction: column;
565
+ overflow: hidden;
566
+ }
567
+
568
+ .file-editor-meta {
569
+ flex: 1;
570
+ min-width: 0;
571
+ }
572
+
573
+ .file-editor-actions {
574
+ align-items: center;
575
+ display: inline-flex;
576
+ gap: 10px;
577
+ }
578
+
579
+ .file-save-hint {
580
+ color: var(--text-secondary);
581
+ font-size: 11px;
582
+ }
583
+
584
+ .file-editor-banner,
585
+ .file-panel-note,
586
+ .file-editor-status {
587
+ color: var(--text-secondary);
588
+ font-size: 12px;
589
+ padding: 10px 14px;
590
+ }
591
+
592
+ .file-panel-note {
593
+ background: rgba(181, 137, 0, 0.08);
594
+ border: 1px solid rgba(181, 137, 0, 0.2);
595
+ border-radius: 8px;
596
+ color: var(--warning);
597
+ margin-bottom: 12px;
598
+ }
599
+
600
+ .file-editor-banner {
601
+ background: rgba(38, 139, 210, 0.08);
602
+ border-bottom: 1px solid rgba(38, 139, 210, 0.14);
603
+ color: var(--accent);
604
+ }
605
+
606
+ .file-editor-banner.error {
607
+ background: rgba(220, 50, 47, 0.08);
608
+ border-bottom-color: rgba(220, 50, 47, 0.18);
609
+ color: var(--error);
610
+ }
611
+
612
+ .file-editor-banner.success {
613
+ background: rgba(133, 153, 0, 0.08);
614
+ border-bottom-color: rgba(133, 153, 0, 0.18);
615
+ color: var(--success);
616
+ }
617
+
618
+ .file-editor-surface {
619
+ flex: 1;
620
+ min-height: 360px;
621
+ position: relative;
622
+ }
623
+
624
+ .file-editor-surface .monaco-editor {
625
+ position: absolute;
626
+ inset: 0;
627
+ }
628
+
629
+ .file-mobile-browse {
630
+ display: none;
631
+ }
632
+
633
+ @media (max-width: 960px) {
634
+ .files-shell {
635
+ grid-template-columns: minmax(220px, 260px) minmax(0, 1fr);
636
+ }
637
+ }
638
+
639
+ @media (max-width: 800px) {
640
+ .files-shell {
641
+ grid-template-columns: 1fr;
642
+ min-height: 0;
643
+ }
644
+
645
+ .file-browser-toolbar {
646
+ align-items: flex-start;
647
+ flex-direction: column;
648
+ }
649
+
650
+ .file-hidden-toggle {
651
+ width: 100%;
652
+ }
653
+
654
+ .file-mobile-browse {
655
+ display: inline-block;
656
+ }
657
+
658
+ .files-shell.mobile-editor-focus .file-browser-pane {
659
+ display: none;
660
+ }
661
+
662
+ .files-shell.mobile-editor-focus .file-editor-pane {
663
+ display: flex;
664
+ }
665
+
666
+ .file-browser-pane {
667
+ min-height: 280px;
668
+ }
669
+ }
670
+
671
+ /* Info panel */
672
+ .info-panel { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
673
+ .info-panel dt { color: var(--text-secondary); font-size: 13px; }
674
+ .info-panel dd { font-size: 14px; margin-bottom: 8px; }
675
+
676
+ /* Utilities */
677
+ .flex { display: flex; gap: 12px; align-items: center; }
678
+ .flex-between { display: flex; justify-content: space-between; align-items: center; }
679
+ .mb-16 { margin-bottom: 16px; }
680
+ .mt-16 { margin-top: 16px; }
681
+
682
+ /* Modal */
683
+ .modal-overlay {
684
+ display: none;
685
+ position: fixed;
686
+ top: 0; left: 0; right: 0; bottom: 0;
687
+ background: rgba(0,0,0,0.5);
688
+ z-index: 100;
689
+ align-items: center;
690
+ justify-content: center;
691
+ }
692
+ .modal-overlay.active { display: flex; }
693
+ .modal {
694
+ background: var(--header-bg);
695
+ border: 1px solid var(--border);
696
+ border-radius: 8px;
697
+ padding: 20px;
698
+ min-width: 400px;
699
+ max-width: 600px;
700
+ max-height: 90vh;
701
+ overflow-y: auto;
702
+ }
703
+ .issue-panel-modal {
704
+ width: 80vw;
705
+ max-width: 800px;
706
+ max-height: 85vh;
707
+ overflow-y: auto;
708
+ position: relative;
709
+ }
710
+ .modal h3 { margin-bottom: 16px; }
711
+ .modal-actions { display: flex; gap: 8px; justify-content: flex-end; margin-top: 16px; }
712
+
713
+ /* Tabs */
714
+ .tab-bar { display: flex; border-bottom: 1px solid var(--border); margin-bottom: 16px; }
715
+ .tab {
716
+ padding: 8px 16px;
717
+ cursor: pointer;
718
+ border-bottom: 2px solid transparent;
719
+ color: var(--text-secondary);
720
+ font-size: 13px;
721
+ }
722
+ .tab.active { color: var(--fg); border-bottom-color: var(--accent); }
723
+
724
+ .empty-state { text-align: center; padding: 40px; color: var(--text-secondary); }
725
+
726
+ /* Thinking spinner — Claude Code style sparkle */
727
+ .thinking-spinner {
728
+ display: inline-block;
729
+ font-size: 14px;
730
+ animation: sparkle 1.5s ease-in-out infinite;
731
+ }
732
+ @keyframes sparkle {
733
+ 0%, 100% { opacity: 1; filter: hue-rotate(0deg) brightness(1); }
734
+ 25% { opacity: 0.4; filter: hue-rotate(40deg) brightness(1.3); }
735
+ 50% { opacity: 1; filter: hue-rotate(-30deg) brightness(1.1); }
736
+ 75% { opacity: 0.5; filter: hue-rotate(20deg) brightness(1.2); }
737
+ }
738
+
739
+ .thinking-bar {
740
+ display: flex;
741
+ align-items: center;
742
+ gap: 8px;
743
+ padding: 8px 12px;
744
+ font-size: 13px;
745
+ color: var(--accent);
746
+ animation: pulse-text 2s ease-in-out infinite;
747
+ }
748
+ @keyframes pulse-text {
749
+ 0%, 100% { opacity: 1; }
750
+ 50% { opacity: 0.4; }
751
+ }
752
+ @keyframes pulse {
753
+ 0%, 100% { opacity: 1; }
754
+ 50% { opacity: 0.3; }
755
+ }
756
+
757
+ /* Activity Summary Panel */
758
+ .activity-list {
759
+ display: flex;
760
+ flex-direction: column;
761
+ gap: 2px;
762
+ max-height: 340px;
763
+ overflow-y: auto;
764
+ }
765
+ .activity-item {
766
+ display: flex;
767
+ align-items: center;
768
+ gap: 8px;
769
+ padding: 5px 10px;
770
+ font-size: 12px;
771
+ border-radius: 4px;
772
+ background: var(--bg);
773
+ color: var(--fg);
774
+ line-height: 1.4;
775
+ }
776
+ .activity-item.active {
777
+ background: color-mix(in srgb, var(--accent) 10%, var(--bg));
778
+ color: var(--accent);
779
+ font-weight: 500;
780
+ }
781
+ .activity-icon {
782
+ flex-shrink: 0;
783
+ width: 18px;
784
+ text-align: center;
785
+ font-size: 13px;
786
+ }
787
+ .activity-item.active .activity-icon {
788
+ animation: sparkle 1.5s ease-in-out infinite;
789
+ }
790
+ .activity-text {
791
+ flex: 1;
792
+ overflow: hidden;
793
+ text-overflow: ellipsis;
794
+ white-space: nowrap;
795
+ }
796
+ .activity-text code {
797
+ font-size: 11px;
798
+ background: color-mix(in srgb, var(--border) 30%, var(--bg));
799
+ padding: 1px 4px;
800
+ border-radius: 3px;
801
+ }
802
+ .activity-time {
803
+ flex-shrink: 0;
804
+ font-size: 10px;
805
+ color: var(--text-secondary);
806
+ opacity: 0.7;
807
+ }
808
+
809
+ /* Dashboard Stats */
810
+ .dashboard-stats {
811
+ display: grid;
812
+ grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
813
+ gap: 12px;
814
+ margin-bottom: 20px;
815
+ }
816
+ .stat-card {
817
+ background: var(--header-bg);
818
+ border: 1px solid var(--border);
819
+ border-radius: 6px;
820
+ padding: 14px 16px;
821
+ text-align: center;
822
+ }
823
+ .stat-value {
824
+ font-size: 22px;
825
+ font-weight: 700;
826
+ color: var(--accent);
827
+ line-height: 1.2;
828
+ }
829
+ .stat-label {
830
+ font-size: 11px;
831
+ color: var(--text-secondary);
832
+ text-transform: uppercase;
833
+ letter-spacing: 0.03em;
834
+ margin-top: 4px;
835
+ }
836
+
837
+ /* Notifications Panel */
838
+ .notifications-panel {
839
+ background: var(--header-bg);
840
+ border: 1px solid var(--border);
841
+ border-radius: 6px;
842
+ margin-bottom: 20px;
843
+ overflow: hidden;
844
+ }
845
+ .notifications-header {
846
+ display: flex;
847
+ align-items: center;
848
+ gap: 8px;
849
+ padding: 8px 12px;
850
+ font-size: 13px;
851
+ font-weight: 600;
852
+ user-select: none;
853
+ }
854
+ .notif-filter-group {
855
+ display: flex;
856
+ gap: 2px;
857
+ margin-left: auto;
858
+ margin-right: 8px;
859
+ }
860
+ .notif-filter-btn {
861
+ background: transparent;
862
+ border: 1px solid var(--border);
863
+ color: var(--text-secondary);
864
+ font-size: 11px;
865
+ padding: 2px 10px;
866
+ cursor: pointer;
867
+ border-radius: 10px;
868
+ font-weight: 500;
869
+ transition: all 0.15s;
870
+ }
871
+ .notif-filter-btn:hover { color: var(--text-primary); border-color: var(--text-secondary); }
872
+ .notif-filter-btn.active {
873
+ background: var(--accent);
874
+ color: #fff;
875
+ border-color: var(--accent);
876
+ }
877
+ .notif-badge {
878
+ background: var(--error);
879
+ color: #fff;
880
+ font-size: 11px;
881
+ padding: 1px 8px;
882
+ border-radius: 10px;
883
+ font-weight: 600;
884
+ }
885
+ .notif-toggle {
886
+ font-size: 10px;
887
+ color: var(--text-secondary);
888
+ transition: transform 0.2s;
889
+ }
890
+ .notif-toggle.collapsed { transform: rotate(-90deg); }
891
+ .notifications-body {
892
+ border-top: 1px solid var(--border);
893
+ max-height: min(280px, 40vh);
894
+ overflow-y: auto;
895
+ }
896
+ .notifications-body.collapsed { display: none; }
897
+ .inbox-search-bar {
898
+ padding: 6px 12px;
899
+ border-top: 1px solid var(--border);
900
+ }
901
+ .inbox-search-input {
902
+ width: 100%;
903
+ box-sizing: border-box;
904
+ background: var(--bg);
905
+ border: 1px solid var(--border);
906
+ border-radius: 4px;
907
+ color: var(--text-primary);
908
+ font-size: 12px;
909
+ padding: 4px 8px;
910
+ outline: none;
911
+ }
912
+ .inbox-search-input:focus { border-color: var(--accent); }
913
+ .notif-item {
914
+ padding: 4px 12px;
915
+ border-bottom: 1px solid var(--border);
916
+ font-size: 12px;
917
+ display: flex;
918
+ align-items: center;
919
+ gap: 6px;
920
+ line-height: 1.3;
921
+ }
922
+ .notif-item:last-child { border-bottom: none; }
923
+ .notif-item.notif-action-required { background: rgba(181,137,0,0.08); }
924
+ .notif-item a { color: var(--accent); }
925
+ .notif-time {
926
+ font-size: 11px;
927
+ color: var(--text-secondary);
928
+ white-space: nowrap;
929
+ margin-left: auto;
930
+ flex-shrink: 0;
931
+ }
932
+ .notif-ack-btn {
933
+ flex-shrink: 0;
934
+ background: none;
935
+ border: 1px solid var(--border);
936
+ border-radius: 4px;
937
+ color: var(--text-secondary);
938
+ cursor: pointer;
939
+ font-size: 12px;
940
+ padding: 1px 6px;
941
+ opacity: 0.5;
942
+ transition: opacity 0.15s, color 0.15s;
943
+ }
944
+ .notif-ack-btn:hover {
945
+ opacity: 1;
946
+ color: var(--success);
947
+ border-color: var(--success);
948
+ }
949
+ .notif-icon {
950
+ flex-shrink: 0;
951
+ margin-top: 2px;
952
+ }
953
+ .notif-text {
954
+ flex: 1;
955
+ min-width: 0;
956
+ overflow: hidden;
957
+ text-overflow: ellipsis;
958
+ }
959
+ .last-activity {
960
+ font-size: 11px;
961
+ color: var(--text-secondary);
962
+ margin-top: 8px;
963
+ }
964
+
965
+ .project-card {
966
+ display: flex;
967
+ flex-direction: column;
968
+ gap: 10px;
969
+ }
970
+ .project-card-head {
971
+ display: flex;
972
+ justify-content: space-between;
973
+ gap: 12px;
974
+ align-items: flex-start;
975
+ }
976
+ .project-card-main {
977
+ min-width: 0;
978
+ display: flex;
979
+ flex-direction: column;
980
+ gap: 8px;
981
+ }
982
+ .project-card-title {
983
+ display: flex;
984
+ align-items: center;
985
+ flex-wrap: wrap;
986
+ gap: 6px;
987
+ font-size: 15px;
988
+ }
989
+ .project-card-tags {
990
+ display: flex;
991
+ flex-wrap: wrap;
992
+ gap: 6px;
993
+ }
994
+ .project-card-note {
995
+ display: flex;
996
+ align-items: center;
997
+ gap: 8px;
998
+ color: var(--text-secondary);
999
+ font-size: 12px;
1000
+ }
1001
+ .project-card-desc {
1002
+ color: var(--text-secondary);
1003
+ font-size: 13px;
1004
+ margin: 0;
1005
+ min-height: 38px;
1006
+ }
1007
+ .project-card-stats {
1008
+ display: flex;
1009
+ gap: 16px;
1010
+ font-size: 12px;
1011
+ flex-wrap: wrap;
1012
+ }
1013
+
1014
+ .project-header {
1015
+ display: flex;
1016
+ justify-content: space-between;
1017
+ gap: 16px;
1018
+ align-items: flex-start;
1019
+ }
1020
+ .project-header-main {
1021
+ min-width: 0;
1022
+ display: flex;
1023
+ flex-direction: column;
1024
+ gap: 10px;
1025
+ }
1026
+ .project-title-row {
1027
+ display: flex;
1028
+ align-items: center;
1029
+ flex-wrap: wrap;
1030
+ gap: 8px;
1031
+ }
1032
+ .project-access-row {
1033
+ display: flex;
1034
+ align-items: center;
1035
+ flex-wrap: wrap;
1036
+ gap: 8px;
1037
+ }
1038
+ .project-inline-note {
1039
+ color: var(--text-secondary);
1040
+ font-size: 12px;
1041
+ }
1042
+ .project-readonly-banner {
1043
+ padding: 10px 12px;
1044
+ background: rgba(38, 139, 210, 0.08);
1045
+ border: 1px solid rgba(38, 139, 210, 0.22);
1046
+ border-radius: 6px;
1047
+ color: var(--accent);
1048
+ font-size: 12px;
1049
+ }
1050
+
1051
+ .project-members-modal {
1052
+ width: min(720px, 94vw);
1053
+ max-width: 720px;
1054
+ }
1055
+ .project-members-header {
1056
+ display: flex;
1057
+ justify-content: space-between;
1058
+ align-items: flex-start;
1059
+ gap: 12px;
1060
+ margin-bottom: 16px;
1061
+ }
1062
+ .project-share-form {
1063
+ display: flex;
1064
+ gap: 12px;
1065
+ align-items: flex-end;
1066
+ margin-bottom: 16px;
1067
+ }
1068
+ .project-share-form .form-group {
1069
+ flex: 1;
1070
+ }
1071
+ .project-members-list {
1072
+ display: flex;
1073
+ flex-direction: column;
1074
+ gap: 10px;
1075
+ }
1076
+ .project-member-item {
1077
+ display: flex;
1078
+ justify-content: space-between;
1079
+ gap: 12px;
1080
+ align-items: center;
1081
+ padding: 12px 14px;
1082
+ background: var(--bg);
1083
+ border: 1px solid var(--border);
1084
+ border-radius: 8px;
1085
+ }
1086
+ .project-member-main {
1087
+ min-width: 0;
1088
+ display: flex;
1089
+ flex-direction: column;
1090
+ gap: 4px;
1091
+ }
1092
+ .project-member-name-row {
1093
+ display: flex;
1094
+ align-items: center;
1095
+ gap: 8px;
1096
+ flex-wrap: wrap;
1097
+ }
1098
+ .project-member-meta {
1099
+ color: var(--text-secondary);
1100
+ font-size: 12px;
1101
+ }
1102
+ .project-member-actions {
1103
+ flex-shrink: 0;
1104
+ }
1105
+ .project-member-static {
1106
+ color: var(--text-secondary);
1107
+ font-size: 12px;
1108
+ }
1109
+
1110
+ /* Quick Command Bar */
1111
+ .quick-cmd-bar {
1112
+ display: flex;
1113
+ flex-direction: column;
1114
+ gap: 4px;
1115
+ margin-top: 10px;
1116
+ border-top: 1px solid var(--border);
1117
+ padding-top: 10px;
1118
+ }
1119
+ .quick-cmd-row {
1120
+ display: flex;
1121
+ gap: 4px;
1122
+ }
1123
+ .quick-cmd-body {
1124
+ background: var(--bg);
1125
+ border: 1px solid var(--border);
1126
+ border-radius: 6px;
1127
+ padding: 6px 10px;
1128
+ font-size: 12px;
1129
+ color: var(--fg);
1130
+ outline: none;
1131
+ resize: vertical;
1132
+ font-family: inherit;
1133
+ min-height: 48px;
1134
+ max-height: 200px;
1135
+ overflow: hidden;
1136
+ transition: max-height 0.2s ease, opacity 0.2s ease, padding 0.15s ease;
1137
+ }
1138
+ .quick-cmd-body[data-collapsed] {
1139
+ max-height: 0;
1140
+ opacity: 0;
1141
+ padding: 0 10px;
1142
+ margin: 0;
1143
+ border-color: transparent;
1144
+ pointer-events: none;
1145
+ }
1146
+ .quick-cmd-body:focus {
1147
+ border-color: var(--accent);
1148
+ }
1149
+ .quick-cmd-body::placeholder {
1150
+ color: var(--text-secondary);
1151
+ opacity: 0.6;
1152
+ }
1153
+ .quick-cmd-input {
1154
+ flex: 1;
1155
+ background: var(--bg);
1156
+ border: 1px solid var(--border);
1157
+ border-radius: 6px;
1158
+ padding: 6px 10px;
1159
+ font-size: 12px;
1160
+ color: var(--fg);
1161
+ outline: none;
1162
+ }
1163
+ .quick-cmd-input:focus {
1164
+ border-color: var(--accent);
1165
+ }
1166
+ .quick-cmd-input::placeholder {
1167
+ color: var(--text-secondary);
1168
+ opacity: 0.6;
1169
+ }
1170
+ .quick-cmd-btn {
1171
+ background: var(--accent);
1172
+ color: #fff;
1173
+ border: none;
1174
+ border-radius: 6px;
1175
+ padding: 6px 10px;
1176
+ font-size: 12px;
1177
+ cursor: pointer;
1178
+ line-height: 1;
1179
+ }
1180
+ .quick-cmd-btn:hover {
1181
+ opacity: 0.85;
1182
+ }
1183
+ .quick-cmd-btn:disabled {
1184
+ opacity: 0.5;
1185
+ cursor: not-allowed;
1186
+ }
1187
+
1188
+ /* Collapsible inline text */
1189
+ .collapsible-text {
1190
+ display: inline-flex;
1191
+ align-items: flex-start;
1192
+ gap: 6px;
1193
+ max-width: 100%;
1194
+ min-width: 0;
1195
+ padding: 0;
1196
+ margin: 0;
1197
+ border: none;
1198
+ background: none;
1199
+ color: inherit;
1200
+ font: inherit;
1201
+ line-height: 1.45;
1202
+ text-align: left;
1203
+ vertical-align: top;
1204
+ }
1205
+ .collapsible-text.is-collapsible {
1206
+ cursor: pointer;
1207
+ }
1208
+ .collapsible-text__content {
1209
+ min-width: 0;
1210
+ max-width: 100%;
1211
+ }
1212
+ .collapsible-text.is-collapsible[data-expanded="false"] .collapsible-text__content {
1213
+ overflow: hidden;
1214
+ text-overflow: ellipsis;
1215
+ white-space: nowrap;
1216
+ }
1217
+ .collapsible-text.is-collapsible[data-expanded="true"] .collapsible-text__content {
1218
+ white-space: pre-wrap;
1219
+ word-break: break-word;
1220
+ }
1221
+ .collapsible-text__hint {
1222
+ flex-shrink: 0;
1223
+ padding: 1px 6px;
1224
+ border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent);
1225
+ border-radius: 999px;
1226
+ color: var(--accent);
1227
+ font-size: 10px;
1228
+ line-height: 1.35;
1229
+ opacity: 0.85;
1230
+ }
1231
+ .collapsible-text.is-collapsible:hover .collapsible-text__hint,
1232
+ .collapsible-text.is-collapsible:focus-visible .collapsible-text__hint {
1233
+ opacity: 1;
1234
+ }
1235
+ .collapsible-text.is-collapsible:focus-visible {
1236
+ outline: 1px solid color-mix(in srgb, var(--accent) 55%, transparent);
1237
+ outline-offset: 2px;
1238
+ border-radius: 4px;
1239
+ }
1240
+
1241
+ /* Scrollbar */
1242
+ ::-webkit-scrollbar { width: 6px; height: 6px; }
1243
+ ::-webkit-scrollbar-track { background: transparent; }
1244
+ ::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
1245
+ ::-webkit-scrollbar-thumb:hover { background: var(--text-secondary); }
1246
+
1247
+ /* Toast notifications */
1248
+ .toast-container { position: fixed; top: 16px; right: 16px; z-index: 10000; display: flex; flex-direction: column; gap: 8px; pointer-events: none; }
1249
+ .toast { pointer-events: auto; padding: 10px 16px; border-radius: 6px; font-size: 13px; color: #fff; box-shadow: 0 4px 12px rgba(0,0,0,0.3); cursor: pointer; animation: toast-in 0.25s ease-out, toast-out 0.3s ease-in forwards; animation-delay: 0s, 2.7s; max-width: 320px; word-break: break-word; }
1250
+ .toast-success { background: var(--success); }
1251
+ .toast-error { background: var(--error); }
1252
+ .toast-info { background: var(--accent); }
1253
+ @keyframes toast-in { from { opacity: 0; transform: translateX(40px); } to { opacity: 1; transform: translateX(0); } }
1254
+ @keyframes toast-out { from { opacity: 1; } to { opacity: 0; transform: translateY(-10px); } }
1255
+
1256
+ /* Loading spinner */
1257
+ .loading-spinner { display: flex; align-items: center; justify-content: center; gap: 8px; padding: 16px; color: var(--text-secondary); font-size: 13px; }
1258
+ .loading-spinner .spinner { width: 18px; height: 18px; border: 2px solid var(--border); border-top-color: var(--accent); border-radius: 50%; animation: spin 0.6s linear infinite; flex-shrink: 0; }
1259
+ .loading-spinner.small { padding: 8px; font-size: 12px; }
1260
+ .loading-spinner.small .spinner { width: 14px; height: 14px; }
1261
+ @keyframes spin { to { transform: rotate(360deg); } }
1262
+
1263
+ /* Error with retry */
1264
+ .error-retry { display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 16px; color: var(--text-secondary); font-size: 13px; text-align: center; }
1265
+ .error-retry .error-msg { color: var(--error); }
1266
+ .error-retry .retry-btn { padding: 4px 12px; font-size: 12px; border: 1px solid var(--border); border-radius: 4px; background: var(--header-bg); color: var(--fg); cursor: pointer; font-family: inherit; }
1267
+ .error-retry .retry-btn:hover { border-color: var(--accent); color: var(--accent); }
1268
+
1269
+ /* Notification badge pulse */
1270
+ @keyframes badge-pulse { 0% { transform: scale(1); } 50% { transform: scale(1.25); } 100% { transform: scale(1); } }
1271
+ .notif-badge.pulse { animation: badge-pulse 0.4s ease-in-out; }
1272
+
1273
+ /* ─── Responsive breakpoints ─── */
1274
+ @media (max-width: 768px) {
1275
+ .grid { grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); }
1276
+ .dashboard-stats { grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); }
1277
+ .notifications-body { max-height: 40vh; }
1278
+ header { gap: 8px; padding: 0 10px; }
1279
+ header .btn { font-size: 11px; padding: 3px 8px; }
1280
+ .breadcrumb { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1281
+ .modal { min-width: unset; width: 95vw; max-width: 95vw; }
1282
+ .issue-panel-modal { width: 95vw; max-width: 95vw; max-height: 90vh; padding: 16px; }
1283
+ .project-header { flex-direction: column; }
1284
+ .project-share-form { flex-direction: column; align-items: stretch; }
1285
+ .project-card-head { flex-direction: column; }
1286
+ }
1287
+ @media (max-width: 480px) {
1288
+ .grid { grid-template-columns: 1fr; }
1289
+ .dashboard-stats { grid-template-columns: repeat(2, 1fr); gap: 8px; }
1290
+ header { height: auto; min-height: 42px; flex-wrap: nowrap; padding: 6px 10px; }
1291
+ .header-right { gap: 4px; flex-shrink: 0; }
1292
+ .header-right .btn { display: none; }
1293
+ .user-menu { flex-shrink: 0; }
1294
+ .user-menu-btn { width: 28px; height: 28px; font-size: 12px; }
1295
+ .notifications-body { max-height: 50vh; }
1296
+ .issue-panel-modal { width: 100vw; max-width: 100vw; max-height: 95vh; border-radius: 4px; padding: 12px; }
1297
+ .project-card-stats { flex-direction: column; gap: 8px; }
1298
+ .project-member-item { flex-direction: column; align-items: flex-start; }
1299
+ }