@sugar-crash-studios/vibe-forge 0.4.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 (201) hide show
  1. package/.claude/commands/clear-attention.md +63 -0
  2. package/.claude/commands/compact-context.md +52 -0
  3. package/.claude/commands/configure-vcs.md +102 -0
  4. package/.claude/commands/forge.md +171 -0
  5. package/.claude/commands/need-help.md +77 -0
  6. package/.claude/commands/update-status.md +64 -0
  7. package/.claude/commands/worker-loop.md +106 -0
  8. package/.claude/hooks/worker-loop.js +198 -0
  9. package/.claude/scripts/setup-worker-loop.sh +45 -0
  10. package/.claude/settings.local.json +46 -0
  11. package/LICENSE +21 -0
  12. package/README.md +238 -0
  13. package/agents/aegis/personality.md +294 -0
  14. package/agents/anvil/personality.md +276 -0
  15. package/agents/architect/personality.md +258 -0
  16. package/agents/crucible/personality.md +360 -0
  17. package/agents/ember/personality.md +291 -0
  18. package/agents/forge-master/capabilities.md +144 -0
  19. package/agents/forge-master/context-template.md +128 -0
  20. package/agents/forge-master/personality.md +138 -0
  21. package/agents/furnace/personality.md +340 -0
  22. package/agents/herald/personality.md +247 -0
  23. package/agents/loki/personality.md +108 -0
  24. package/agents/oracle/personality.md +283 -0
  25. package/agents/pixel/personality.md +113 -0
  26. package/agents/planning-hub/personality.md +320 -0
  27. package/agents/scribe/personality.md +251 -0
  28. package/agents/temper/personality.md +218 -0
  29. package/bin/cli.js +375 -0
  30. package/bin/dashboard/api/agents.js +333 -0
  31. package/bin/dashboard/api/dispatch.js +483 -0
  32. package/bin/dashboard/api/tasks.js +416 -0
  33. package/bin/dashboard/frontend/index.html +13 -0
  34. package/bin/dashboard/frontend/package.json +16 -0
  35. package/bin/dashboard/frontend/src/App.svelte +222 -0
  36. package/bin/dashboard/frontend/src/app.css +1777 -0
  37. package/bin/dashboard/frontend/src/lib/components/AgentCard.svelte +60 -0
  38. package/bin/dashboard/frontend/src/lib/components/AgentsPanel.svelte +57 -0
  39. package/bin/dashboard/frontend/src/lib/components/DispatchModal.svelte +180 -0
  40. package/bin/dashboard/frontend/src/lib/components/Footer.svelte +33 -0
  41. package/bin/dashboard/frontend/src/lib/components/Header.svelte +84 -0
  42. package/bin/dashboard/frontend/src/lib/components/IssueCard.svelte +33 -0
  43. package/bin/dashboard/frontend/src/lib/components/IssuesPanel.svelte +73 -0
  44. package/bin/dashboard/frontend/src/lib/components/KeyboardShortcutsModal.svelte +108 -0
  45. package/bin/dashboard/frontend/src/lib/components/MobileTabs.svelte +52 -0
  46. package/bin/dashboard/frontend/src/lib/components/NotificationCard.svelte +60 -0
  47. package/bin/dashboard/frontend/src/lib/components/NotificationsPanel.svelte +44 -0
  48. package/bin/dashboard/frontend/src/lib/components/TaskCard.svelte +63 -0
  49. package/bin/dashboard/frontend/src/lib/components/TasksPanel.svelte +82 -0
  50. package/bin/dashboard/frontend/src/lib/components/Toast.svelte +45 -0
  51. package/bin/dashboard/frontend/src/lib/stores/agents.js +34 -0
  52. package/bin/dashboard/frontend/src/lib/stores/issues.js +54 -0
  53. package/bin/dashboard/frontend/src/lib/stores/notifications.js +48 -0
  54. package/bin/dashboard/frontend/src/lib/stores/tasks.js +63 -0
  55. package/bin/dashboard/frontend/src/lib/stores/theme.js +33 -0
  56. package/bin/dashboard/frontend/src/lib/stores/toast.js +35 -0
  57. package/bin/dashboard/frontend/src/lib/stores/ui.js +25 -0
  58. package/bin/dashboard/frontend/src/lib/stores/voice.js +275 -0
  59. package/bin/dashboard/frontend/src/lib/stores/websocket.js +295 -0
  60. package/bin/dashboard/frontend/src/lib/utils/api.js +101 -0
  61. package/bin/dashboard/frontend/src/lib/utils/formatters.js +54 -0
  62. package/bin/dashboard/frontend/src/main.js +9 -0
  63. package/bin/dashboard/frontend/svelte.config.js +5 -0
  64. package/bin/dashboard/frontend/vite.config.js +20 -0
  65. package/bin/dashboard/public/assets/index-DnfVj9Ce.css +1 -0
  66. package/bin/dashboard/public/assets/index-Ze5h0kXQ.js +2 -0
  67. package/bin/dashboard/public/index.html +14 -0
  68. package/bin/dashboard/server.js +566 -0
  69. package/bin/forge-daemon.sh +463 -0
  70. package/bin/forge-setup.sh +645 -0
  71. package/bin/forge-spawn.sh +164 -0
  72. package/bin/forge.cmd +83 -0
  73. package/bin/forge.sh +533 -0
  74. package/bin/lib/agents.sh +177 -0
  75. package/bin/lib/colors.sh +44 -0
  76. package/bin/lib/config.sh +347 -0
  77. package/bin/lib/constants.sh +241 -0
  78. package/bin/lib/daemon/display.sh +128 -0
  79. package/bin/lib/daemon/notifications.sh +263 -0
  80. package/bin/lib/daemon/routing.sh +77 -0
  81. package/bin/lib/daemon/state.sh +115 -0
  82. package/bin/lib/daemon/sync.sh +95 -0
  83. package/bin/lib/database.sh +310 -0
  84. package/bin/lib/heimdall-setup.js +113 -0
  85. package/bin/lib/heimdall.js +265 -0
  86. package/bin/lib/json.sh +264 -0
  87. package/bin/lib/terminal.js +451 -0
  88. package/bin/lib/util.sh +126 -0
  89. package/bin/lib/vcs.js +349 -0
  90. package/config/agent-manifest.yaml +203 -0
  91. package/config/agents.json +168 -0
  92. package/config/task-template.md +159 -0
  93. package/config/task-types.yaml +106 -0
  94. package/context/agent-status/aegis.json +7 -0
  95. package/context/agent-status/anvil.json +7 -0
  96. package/context/agent-status/architect.json +7 -0
  97. package/context/agent-status/crucible.json +7 -0
  98. package/context/agent-status/ember.json +7 -0
  99. package/context/agent-status/furnace.json +7 -0
  100. package/context/agent-status/loki.json +7 -0
  101. package/context/agent-status/oracle.json +7 -0
  102. package/context/agent-status/pixel.json +7 -0
  103. package/context/agent-status/planning-hub.json +7 -0
  104. package/context/agent-status/scribe.json +7 -0
  105. package/context/agent-status/temper.json +7 -0
  106. package/context/feature-brainstorm.md +426 -0
  107. package/context/forge-state.yaml +19 -0
  108. package/context/modern-conventions.md +129 -0
  109. package/context/project-context-template.md +122 -0
  110. package/context/project-context.md +122 -0
  111. package/docs/TODO.md +150 -0
  112. package/docs/agents.md +409 -0
  113. package/docs/architecture/decisions/ADR-001-daemon-modularization.md +122 -0
  114. package/docs/architecture/vibe-lab-integration.md +684 -0
  115. package/docs/architecture.md +194 -0
  116. package/docs/bmad-gap-analysis-2026-03-31.md +444 -0
  117. package/docs/cleanup-workflow.md +329 -0
  118. package/docs/commands.md +451 -0
  119. package/docs/dashboard-mockup.html +989 -0
  120. package/docs/getting-started.md +261 -0
  121. package/docs/integration/forge-ownership-policy.md +112 -0
  122. package/docs/npm-publishing.md +132 -0
  123. package/docs/roadmap-2026.md +519 -0
  124. package/docs/security.md +144 -0
  125. package/docs/wireframes/dashboard-mvp.md +1164 -0
  126. package/docs/workflows/README.md +32 -0
  127. package/docs/workflows/azure-devops.md +108 -0
  128. package/docs/workflows/bitbucket.md +104 -0
  129. package/docs/workflows/git-only.md +130 -0
  130. package/docs/workflows/gitea.md +168 -0
  131. package/docs/workflows/github.md +103 -0
  132. package/docs/workflows/gitlab.md +105 -0
  133. package/docs/workflows.md +454 -0
  134. package/package.json +73 -0
  135. package/tasks/completed/ARCH-001-duplicate-agent-config.md +121 -0
  136. package/tasks/completed/ARCH-002-mixed-bash-node-implementation.md +88 -0
  137. package/tasks/completed/ARCH-003-worker-loop-hook-duplication.md +77 -0
  138. package/tasks/completed/ARCH-009-test-organization.md +78 -0
  139. package/tasks/completed/ARCH-011-jq-vs-nodejs-json.md +94 -0
  140. package/tasks/completed/ARCH-012-tmp-files-in-root.md +71 -0
  141. package/tasks/completed/ARCH-013-exit-code-constants.md +65 -0
  142. package/tasks/completed/ARCH-014-sed-incompatibility.md +96 -0
  143. package/tasks/completed/ARCH-015-docs-todo-tracking.md +83 -0
  144. package/tasks/completed/BUG-dash-001-tasks-filter-error.md +31 -0
  145. package/tasks/completed/BUG-dash-002-agents-unknown.md +41 -0
  146. package/tasks/completed/CLEAN-001.md +38 -0
  147. package/tasks/completed/CLEAN-002.md +43 -0
  148. package/tasks/completed/CLEAN-003.md +47 -0
  149. package/tasks/completed/CLEAN-004.md +56 -0
  150. package/tasks/completed/CLEAN-005.md +75 -0
  151. package/tasks/completed/CLEAN-006.md +47 -0
  152. package/tasks/completed/CLEAN-007.md +34 -0
  153. package/tasks/completed/CLEAN-008.md +49 -0
  154. package/tasks/completed/CLEAN-012.md +58 -0
  155. package/tasks/completed/CLEAN-013.md +45 -0
  156. package/tasks/completed/FEATURE-001a-dashboard-wireframes.md +162 -0
  157. package/tasks/completed/IMPL-007a-daemon-notifications-module.md +82 -0
  158. package/tasks/completed/IMPL-007b-daemon-sync-module.md +71 -0
  159. package/tasks/completed/IMPL-007c-daemon-state-module.md +80 -0
  160. package/tasks/completed/IMPL-007d-daemon-routing-module.md +77 -0
  161. package/tasks/completed/IMPL-007e-daemon-display-module.md +77 -0
  162. package/tasks/completed/IMPL-007f-daemon-integration.md +124 -0
  163. package/tasks/completed/PLAT-1-heimdall.md +420 -0
  164. package/tasks/completed/SEC-001-sql-injection-fix.md +58 -0
  165. package/tasks/completed/SEC-002-notification-injection-fix.md +45 -0
  166. package/tasks/completed/SEC-003-eval-injection-fix.md +54 -0
  167. package/tasks/completed/SEC-004-pid-race-condition-fix.md +49 -0
  168. package/tasks/completed/SEC-005-worker-loop-path-fix.md +51 -0
  169. package/tasks/completed/SEC-006-eval-agent-names.md +55 -0
  170. package/tasks/completed/SEC-007-spawn-escaping.md +67 -0
  171. package/tasks/completed/TASK-DASH-001-server-infrastructure.md +185 -0
  172. package/tasks/completed/TASK-anvil-001-dashboard-frontend.md +133 -0
  173. package/tasks/completed/review-bmad-aegis.md +89 -0
  174. package/tasks/completed/review-bmad-anvil.md +80 -0
  175. package/tasks/completed/review-bmad-crucible.md +81 -0
  176. package/tasks/completed/review-bmad-ember.md +90 -0
  177. package/tasks/completed/review-bmad-furnace.md +79 -0
  178. package/tasks/completed/review-bmad-pixel.md +82 -0
  179. package/tasks/completed/review-bmad-scribe.md +92 -0
  180. package/tasks/completed/review-bmad-sentinel.md +83 -0
  181. package/tasks/pending/ARCH-004-git-bash-detection-duplication.md +72 -0
  182. package/tasks/pending/ARCH-005-missing-src-directory.md +95 -0
  183. package/tasks/pending/ARCH-006-task-template-location.md +64 -0
  184. package/tasks/pending/ARCH-008-forge-master-vs-hub.md +81 -0
  185. package/tasks/pending/ARCH-010-missing-index-files.md +84 -0
  186. package/tasks/pending/CLEAN-009.md +31 -0
  187. package/tasks/pending/CLEAN-010.md +30 -0
  188. package/tasks/pending/CLEAN-011.md +30 -0
  189. package/tasks/pending/CLEAN-014.md +32 -0
  190. package/tasks/pending/DESIGN-dash-001-layout-review.md +45 -0
  191. package/tasks/pending/FEATURE-001-dashboard-mvp.md +268 -0
  192. package/tasks/review/ARCH-007-daemon-monolith.md +162 -0
  193. package/tasks/review/bmad-review-aegis.md +349 -0
  194. package/tasks/review/bmad-review-anvil.md +259 -0
  195. package/tasks/review/bmad-review-crucible.md +277 -0
  196. package/tasks/review/bmad-review-ember.md +307 -0
  197. package/tasks/review/bmad-review-furnace.md +285 -0
  198. package/tasks/review/bmad-review-pixel.md +329 -0
  199. package/tasks/review/bmad-review-scribe.md +361 -0
  200. package/tasks/review/bmad-review-sentinel.md +242 -0
  201. package/tasks/review/task-001.md +78 -0
@@ -0,0 +1,1777 @@
1
+ /* ===================================================================
2
+ VIBE FORGE DASHBOARD - STYLES (Svelte Version)
3
+ Based on Pixel's UX Specification
4
+ =================================================================== */
5
+
6
+ /* ===================================================================
7
+ CSS CUSTOM PROPERTIES (Dark Mode Default)
8
+ =================================================================== */
9
+ :root {
10
+ /* Background Colors - Dark Mode */
11
+ --bg-primary: #0D1117;
12
+ --bg-secondary: #161B22;
13
+ --bg-tertiary: #21262D;
14
+ --bg-hover: #30363D;
15
+ --bg-active: #484F58;
16
+
17
+ /* Border Colors */
18
+ --border-default: #30363D;
19
+ --border-muted: #21262D;
20
+
21
+ /* Text Colors */
22
+ --text-primary: #F0F6FC;
23
+ --text-secondary: #8B949E;
24
+ --text-muted: #6E7681;
25
+ --text-link: #58A6FF;
26
+
27
+ /* Accent Colors */
28
+ --accent-primary: #238636;
29
+ --accent-secondary: #1F6FEB;
30
+
31
+ /* Status Colors */
32
+ --danger: #F85149;
33
+ --warning: #D29922;
34
+ --success: #3FB950;
35
+ --info: #58A6FF;
36
+
37
+ /* Agent Colors */
38
+ --agent-hub: #A371F7;
39
+ --agent-anvil: #58A6FF;
40
+ --agent-furnace: #F0883E;
41
+ --agent-crucible: #3FB950;
42
+ --agent-scribe: #56D4DD;
43
+ --agent-sentinel: #D29922;
44
+ --agent-ember: #F85149;
45
+ --agent-architect: #DB61A2;
46
+ --agent-aegis: #E3B341;
47
+ --agent-pixel: #F778BA;
48
+
49
+ /* Priority Colors */
50
+ --priority-critical: #F85149;
51
+ --priority-high: #F0883E;
52
+ --priority-medium: #D29922;
53
+ --priority-low: #58A6FF;
54
+
55
+ /* Issue Category Colors */
56
+ --issue-doc: #A371F7;
57
+ --issue-test: #F85149;
58
+ --issue-sec: #F85149;
59
+ --issue-cov: #D29922;
60
+ --issue-todo: #58A6FF;
61
+ --issue-review: #F0883E;
62
+
63
+ /* Animation Durations */
64
+ --transition-fast: 150ms;
65
+ --transition-normal: 200ms;
66
+ --transition-slow: 300ms;
67
+
68
+ /* Spacing */
69
+ --spacing-xs: 4px;
70
+ --spacing-sm: 8px;
71
+ --spacing-md: 16px;
72
+ --spacing-lg: 24px;
73
+ --spacing-xl: 32px;
74
+
75
+ /* Border Radius */
76
+ --radius-sm: 4px;
77
+ --radius-md: 8px;
78
+ --radius-lg: 12px;
79
+
80
+ /* Shadows */
81
+ --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
82
+ --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.4);
83
+ --shadow-lg: 0 10px 20px rgba(0, 0, 0, 0.5);
84
+
85
+ /* Typography */
86
+ --font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, sans-serif;
87
+ --font-mono: 'SF Mono', 'Consolas', 'Liberation Mono', Menlo, monospace;
88
+ --font-size-xs: 0.75rem;
89
+ --font-size-sm: 0.875rem;
90
+ --font-size-md: 1rem;
91
+ --font-size-lg: 1.125rem;
92
+ --font-size-xl: 1.25rem;
93
+
94
+ /* Layout */
95
+ --header-height: 60px;
96
+ --footer-height: 32px;
97
+ --mobile-tab-height: 56px;
98
+ }
99
+
100
+ /* ===================================================================
101
+ LIGHT MODE THEME
102
+ =================================================================== */
103
+ [data-theme="light"] {
104
+ --bg-primary: #FFFFFF;
105
+ --bg-secondary: #F6F8FA;
106
+ --bg-tertiary: #FFFFFF;
107
+ --bg-hover: #F3F4F6;
108
+ --bg-active: #EAEEF2;
109
+
110
+ --border-default: #D0D7DE;
111
+ --border-muted: #D8DEE4;
112
+
113
+ --text-primary: #1F2328;
114
+ --text-secondary: #656D76;
115
+ --text-muted: #8C959F;
116
+ --text-link: #0969DA;
117
+
118
+ --accent-primary: #1A7F37;
119
+ --accent-secondary: #0969DA;
120
+
121
+ --danger: #CF222E;
122
+ --warning: #9A6700;
123
+ --success: #1A7F37;
124
+ --info: #0969DA;
125
+
126
+ --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.1);
127
+ --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1);
128
+ --shadow-lg: 0 10px 20px rgba(0, 0, 0, 0.15);
129
+ }
130
+
131
+ /* ===================================================================
132
+ RESET AND BASE STYLES
133
+ =================================================================== */
134
+ *, *::before, *::after {
135
+ box-sizing: border-box;
136
+ margin: 0;
137
+ padding: 0;
138
+ }
139
+
140
+ html {
141
+ font-size: 16px;
142
+ scroll-behavior: smooth;
143
+ }
144
+
145
+ body {
146
+ font-family: var(--font-sans);
147
+ font-size: var(--font-size-md);
148
+ line-height: 1.5;
149
+ color: var(--text-primary);
150
+ background-color: var(--bg-primary);
151
+ min-height: 100vh;
152
+ display: flex;
153
+ flex-direction: column;
154
+ overflow-x: hidden;
155
+ }
156
+
157
+ #app {
158
+ display: flex;
159
+ flex-direction: column;
160
+ min-height: 100vh;
161
+ }
162
+
163
+ /* Theme transition for smooth switching */
164
+ body, .panel, .header, .footer, .modal-content, .card, .btn {
165
+ transition: background-color var(--transition-normal) ease,
166
+ color var(--transition-normal) ease,
167
+ border-color var(--transition-normal) ease;
168
+ }
169
+
170
+ /* ===================================================================
171
+ SKIP LINKS (Accessibility)
172
+ =================================================================== */
173
+ .skip-link {
174
+ position: absolute;
175
+ top: -100px;
176
+ left: 0;
177
+ background: var(--accent-secondary);
178
+ color: var(--text-primary);
179
+ padding: var(--spacing-sm) var(--spacing-md);
180
+ z-index: 1000;
181
+ text-decoration: none;
182
+ border-radius: var(--radius-sm);
183
+ }
184
+
185
+ .skip-link:focus {
186
+ top: var(--spacing-sm);
187
+ left: var(--spacing-sm);
188
+ }
189
+
190
+ /* ===================================================================
191
+ CONNECTION BANNER
192
+ =================================================================== */
193
+ .connection-banner {
194
+ position: fixed;
195
+ top: 0;
196
+ left: 0;
197
+ right: 0;
198
+ background: var(--warning);
199
+ color: #000;
200
+ padding: var(--spacing-sm) var(--spacing-md);
201
+ display: flex;
202
+ align-items: center;
203
+ justify-content: center;
204
+ gap: var(--spacing-md);
205
+ z-index: 1000;
206
+ font-weight: 500;
207
+ }
208
+
209
+ .banner-icon {
210
+ width: 24px;
211
+ height: 24px;
212
+ background: #000;
213
+ color: var(--warning);
214
+ border-radius: 50%;
215
+ display: flex;
216
+ align-items: center;
217
+ justify-content: center;
218
+ font-weight: bold;
219
+ }
220
+
221
+ .banner-retry {
222
+ background: rgba(0, 0, 0, 0.2);
223
+ border: 1px solid rgba(0, 0, 0, 0.3);
224
+ color: #000;
225
+ padding: var(--spacing-xs) var(--spacing-md);
226
+ border-radius: var(--radius-sm);
227
+ cursor: pointer;
228
+ font-weight: 500;
229
+ }
230
+
231
+ .banner-retry:hover {
232
+ background: rgba(0, 0, 0, 0.3);
233
+ }
234
+
235
+ /* ===================================================================
236
+ HEADER
237
+ =================================================================== */
238
+ .header {
239
+ position: sticky;
240
+ top: 0;
241
+ height: var(--header-height);
242
+ background: var(--bg-secondary);
243
+ border-bottom: 1px solid var(--border-default);
244
+ display: flex;
245
+ align-items: center;
246
+ justify-content: space-between;
247
+ padding: 0 var(--spacing-lg);
248
+ z-index: 100;
249
+ }
250
+
251
+ .header-left {
252
+ display: flex;
253
+ align-items: center;
254
+ }
255
+
256
+ .logo-btn {
257
+ display: flex;
258
+ align-items: center;
259
+ gap: var(--spacing-sm);
260
+ background: none;
261
+ border: none;
262
+ color: var(--text-primary);
263
+ cursor: pointer;
264
+ padding: var(--spacing-sm);
265
+ border-radius: var(--radius-sm);
266
+ }
267
+
268
+ .logo-btn:hover {
269
+ background: var(--bg-hover);
270
+ }
271
+
272
+ .logo-btn:focus-visible {
273
+ outline: 2px solid var(--accent-secondary);
274
+ outline-offset: 2px;
275
+ }
276
+
277
+ .logo-icon {
278
+ font-size: 1.5rem;
279
+ }
280
+
281
+ .logo-text {
282
+ font-size: var(--font-size-lg);
283
+ font-weight: 600;
284
+ letter-spacing: 0.5px;
285
+ }
286
+
287
+ .header-right {
288
+ display: flex;
289
+ align-items: center;
290
+ gap: var(--spacing-sm);
291
+ }
292
+
293
+ .header-btn {
294
+ width: 40px;
295
+ height: 40px;
296
+ display: flex;
297
+ align-items: center;
298
+ justify-content: center;
299
+ background: none;
300
+ border: none;
301
+ color: var(--text-secondary);
302
+ cursor: pointer;
303
+ border-radius: var(--radius-sm);
304
+ }
305
+
306
+ .header-btn:hover {
307
+ background: var(--bg-hover);
308
+ color: var(--text-primary);
309
+ }
310
+
311
+ .header-btn:focus-visible {
312
+ outline: 2px solid var(--accent-secondary);
313
+ outline-offset: 2px;
314
+ }
315
+
316
+ .header-btn .icon {
317
+ width: 20px;
318
+ height: 20px;
319
+ }
320
+
321
+ /* Theme toggle icons */
322
+ [data-theme="dark"] .sun-icon { display: block; }
323
+ [data-theme="dark"] .moon-icon { display: none; }
324
+ [data-theme="light"] .sun-icon { display: none; }
325
+ [data-theme="light"] .moon-icon { display: block; }
326
+
327
+ #theme-toggle {
328
+ transition: transform var(--transition-normal) ease;
329
+ }
330
+
331
+ #theme-toggle:active {
332
+ transform: rotate(180deg);
333
+ }
334
+
335
+ /* Voice toggle */
336
+ #voice-toggle {
337
+ transition: color var(--transition-normal) ease;
338
+ }
339
+
340
+ #voice-toggle.active {
341
+ color: var(--accent-secondary);
342
+ }
343
+
344
+ #voice-toggle.speaking {
345
+ color: var(--accent-primary);
346
+ animation: voice-pulse 1s ease-in-out infinite;
347
+ }
348
+
349
+ @keyframes voice-pulse {
350
+ 0%, 100% { opacity: 1; }
351
+ 50% { opacity: 0.4; }
352
+ }
353
+
354
+ /* ===================================================================
355
+ MAIN CONTENT AREA
356
+ =================================================================== */
357
+ .main {
358
+ flex: 1;
359
+ padding: var(--spacing-lg);
360
+ display: flex;
361
+ flex-direction: column;
362
+ gap: var(--spacing-lg);
363
+ max-width: 1800px;
364
+ margin: 0 auto;
365
+ width: 100%;
366
+ min-height: calc(100vh - var(--header-height) - var(--footer-height));
367
+ }
368
+
369
+ /* ===================================================================
370
+ PANELS LAYOUT
371
+ =================================================================== */
372
+ .panels-top {
373
+ display: grid;
374
+ grid-template-columns: 4fr 3fr 3fr;
375
+ gap: var(--spacing-lg);
376
+ flex: 0.6;
377
+ min-height: 0;
378
+ }
379
+
380
+ .panel {
381
+ background: var(--bg-secondary);
382
+ border: 1px solid var(--border-default);
383
+ border-radius: var(--radius-md);
384
+ display: flex;
385
+ flex-direction: column;
386
+ overflow: hidden;
387
+ }
388
+
389
+ .panel:focus {
390
+ outline: none;
391
+ }
392
+
393
+ .panel:focus-visible {
394
+ outline: 2px solid var(--accent-secondary);
395
+ outline-offset: 2px;
396
+ }
397
+
398
+ .panel-header {
399
+ display: flex;
400
+ align-items: center;
401
+ justify-content: space-between;
402
+ padding: var(--spacing-md);
403
+ border-bottom: 1px solid var(--border-muted);
404
+ flex-shrink: 0;
405
+ }
406
+
407
+ .panel-title {
408
+ font-size: var(--font-size-sm);
409
+ font-weight: 600;
410
+ text-transform: uppercase;
411
+ letter-spacing: 0.5px;
412
+ color: var(--text-primary);
413
+ }
414
+
415
+ .panel-subtitle {
416
+ font-weight: 400;
417
+ color: var(--text-muted);
418
+ text-transform: none;
419
+ }
420
+
421
+ .panel-actions {
422
+ display: flex;
423
+ align-items: center;
424
+ gap: var(--spacing-xs);
425
+ }
426
+
427
+ .panel-refresh,
428
+ .panel-collapse,
429
+ .panel-clear {
430
+ width: 32px;
431
+ height: 32px;
432
+ display: flex;
433
+ align-items: center;
434
+ justify-content: center;
435
+ background: none;
436
+ border: none;
437
+ color: var(--text-secondary);
438
+ cursor: pointer;
439
+ border-radius: var(--radius-sm);
440
+ }
441
+
442
+ .panel-clear {
443
+ width: auto;
444
+ padding: 0 var(--spacing-sm);
445
+ font-size: var(--font-size-xs);
446
+ }
447
+
448
+ .panel-refresh:hover,
449
+ .panel-collapse:hover,
450
+ .panel-clear:hover {
451
+ background: var(--bg-hover);
452
+ color: var(--text-primary);
453
+ }
454
+
455
+ .panel-refresh:focus-visible,
456
+ .panel-collapse:focus-visible,
457
+ .panel-clear:focus-visible {
458
+ outline: 2px solid var(--accent-secondary);
459
+ outline-offset: 2px;
460
+ }
461
+
462
+ .panel-refresh .icon,
463
+ .panel-collapse .icon {
464
+ width: 16px;
465
+ height: 16px;
466
+ }
467
+
468
+ .panel-refresh.loading .icon {
469
+ animation: spin 1s linear infinite;
470
+ }
471
+
472
+ @keyframes spin {
473
+ from { transform: rotate(0deg); }
474
+ to { transform: rotate(360deg); }
475
+ }
476
+
477
+ .panel-content {
478
+ flex: 1;
479
+ overflow-y: auto;
480
+ padding: var(--spacing-md);
481
+ display: flex;
482
+ flex-direction: column;
483
+ gap: var(--spacing-sm);
484
+ }
485
+
486
+ /* Issues Panel */
487
+ .issues-panel {
488
+ flex: 0.4;
489
+ }
490
+
491
+ .issues-panel.collapsed .panel-content,
492
+ .issues-panel.collapsed .empty-state,
493
+ .issues-panel.collapsed .loading-state,
494
+ .issues-panel.collapsed .error-state {
495
+ display: none;
496
+ }
497
+
498
+ .issues-panel.collapsed {
499
+ flex: 0;
500
+ }
501
+
502
+ .issues-panel .panel-collapse .icon {
503
+ transition: transform var(--transition-normal) ease;
504
+ }
505
+
506
+ .issues-panel.collapsed .panel-collapse .icon {
507
+ transform: rotate(180deg);
508
+ }
509
+
510
+ /* ===================================================================
511
+ TASKS PANEL SPECIFIC
512
+ =================================================================== */
513
+ .tasks-filters {
514
+ display: flex;
515
+ gap: var(--spacing-xs);
516
+ padding: var(--spacing-sm) var(--spacing-md);
517
+ border-bottom: 1px solid var(--border-muted);
518
+ flex-shrink: 0;
519
+ overflow-x: auto;
520
+ }
521
+
522
+ .filter-tab {
523
+ padding: var(--spacing-xs) var(--spacing-sm);
524
+ background: none;
525
+ border: none;
526
+ color: var(--text-secondary);
527
+ font-size: var(--font-size-sm);
528
+ cursor: pointer;
529
+ border-radius: var(--radius-sm);
530
+ white-space: nowrap;
531
+ display: flex;
532
+ align-items: center;
533
+ gap: var(--spacing-xs);
534
+ }
535
+
536
+ .filter-tab:hover {
537
+ background: var(--bg-hover);
538
+ color: var(--text-primary);
539
+ }
540
+
541
+ .filter-tab:focus-visible {
542
+ outline: 2px solid var(--accent-secondary);
543
+ outline-offset: 2px;
544
+ }
545
+
546
+ .filter-tab.active {
547
+ background: var(--bg-tertiary);
548
+ color: var(--text-primary);
549
+ font-weight: 500;
550
+ }
551
+
552
+ .filter-count {
553
+ background: var(--bg-hover);
554
+ padding: 2px 6px;
555
+ border-radius: 10px;
556
+ font-size: var(--font-size-xs);
557
+ min-width: 20px;
558
+ text-align: center;
559
+ }
560
+
561
+ .filter-tab.active .filter-count {
562
+ background: var(--accent-secondary);
563
+ color: #fff;
564
+ }
565
+
566
+ /* ===================================================================
567
+ CARDS - TASK, AGENT, NOTIFICATION, ISSUE
568
+ =================================================================== */
569
+ .card {
570
+ background: var(--bg-tertiary);
571
+ border: 1px solid var(--border-muted);
572
+ border-radius: var(--radius-md);
573
+ padding: var(--spacing-md);
574
+ cursor: pointer;
575
+ transition: background var(--transition-fast) ease,
576
+ border-color var(--transition-fast) ease,
577
+ transform var(--transition-fast) ease;
578
+ }
579
+
580
+ .card:hover {
581
+ background: var(--bg-hover);
582
+ border-color: var(--border-default);
583
+ }
584
+
585
+ .card:focus-visible {
586
+ outline: 2px solid var(--accent-secondary);
587
+ outline-offset: 2px;
588
+ }
589
+
590
+ .card.selected {
591
+ border-color: var(--accent-secondary);
592
+ background: var(--bg-hover);
593
+ }
594
+
595
+ /* Task Card */
596
+ .task-card {
597
+ display: flex;
598
+ flex-direction: column;
599
+ gap: var(--spacing-sm);
600
+ }
601
+
602
+ .task-card-header {
603
+ display: flex;
604
+ align-items: center;
605
+ gap: var(--spacing-sm);
606
+ }
607
+
608
+ .priority-dot {
609
+ width: 8px;
610
+ height: 8px;
611
+ border-radius: 50%;
612
+ flex-shrink: 0;
613
+ }
614
+
615
+ .priority-dot.critical { background: var(--priority-critical); }
616
+ .priority-dot.high { background: var(--priority-high); }
617
+ .priority-dot.medium { background: var(--priority-medium); }
618
+ .priority-dot.low { background: var(--priority-low); }
619
+
620
+ .task-id {
621
+ font-family: var(--font-mono);
622
+ font-size: var(--font-size-xs);
623
+ color: var(--text-muted);
624
+ }
625
+
626
+ .task-title {
627
+ font-size: var(--font-size-sm);
628
+ font-weight: 500;
629
+ color: var(--text-primary);
630
+ overflow: hidden;
631
+ text-overflow: ellipsis;
632
+ white-space: nowrap;
633
+ }
634
+
635
+ .task-meta {
636
+ display: flex;
637
+ align-items: center;
638
+ gap: var(--spacing-sm);
639
+ font-size: var(--font-size-xs);
640
+ color: var(--text-muted);
641
+ }
642
+
643
+ .task-agent {
644
+ display: flex;
645
+ align-items: center;
646
+ gap: var(--spacing-xs);
647
+ }
648
+
649
+ .agent-badge {
650
+ padding: 2px 6px;
651
+ border-radius: var(--radius-sm);
652
+ font-size: var(--font-size-xs);
653
+ font-weight: 500;
654
+ }
655
+
656
+ /* Agent-specific badge colors */
657
+ .agent-badge.hub { background: rgba(163, 113, 247, 0.2); color: var(--agent-hub); }
658
+ .agent-badge.anvil { background: rgba(88, 166, 255, 0.2); color: var(--agent-anvil); }
659
+ .agent-badge.furnace { background: rgba(240, 136, 62, 0.2); color: var(--agent-furnace); }
660
+ .agent-badge.crucible { background: rgba(63, 185, 80, 0.2); color: var(--agent-crucible); }
661
+ .agent-badge.scribe { background: rgba(86, 212, 221, 0.2); color: var(--agent-scribe); }
662
+ .agent-badge.sentinel { background: rgba(210, 153, 34, 0.2); color: var(--agent-sentinel); }
663
+ .agent-badge.ember { background: rgba(248, 81, 73, 0.2); color: var(--agent-ember); }
664
+ .agent-badge.architect { background: rgba(219, 97, 162, 0.2); color: var(--agent-architect); }
665
+ .agent-badge.aegis { background: rgba(227, 179, 65, 0.2); color: var(--agent-aegis); }
666
+ .agent-badge.pixel { background: rgba(247, 120, 186, 0.2); color: var(--agent-pixel); }
667
+
668
+ /* Task Card Expanded State */
669
+ .task-card.expanded {
670
+ background: var(--bg-hover);
671
+ }
672
+
673
+ .task-expanded-content {
674
+ margin-top: var(--spacing-sm);
675
+ padding-top: var(--spacing-sm);
676
+ border-top: 1px solid var(--border-muted);
677
+ display: none;
678
+ }
679
+
680
+ .task-card.expanded .task-expanded-content {
681
+ display: block;
682
+ }
683
+
684
+ .task-description {
685
+ font-size: var(--font-size-sm);
686
+ color: var(--text-secondary);
687
+ margin-bottom: var(--spacing-sm);
688
+ }
689
+
690
+ .task-actions {
691
+ display: flex;
692
+ gap: var(--spacing-sm);
693
+ margin-top: var(--spacing-sm);
694
+ }
695
+
696
+ /* Agent Card */
697
+ .agent-card {
698
+ display: flex;
699
+ align-items: flex-start;
700
+ gap: var(--spacing-md);
701
+ }
702
+
703
+ .agent-avatar {
704
+ width: 40px;
705
+ height: 40px;
706
+ border-radius: 50%;
707
+ display: flex;
708
+ align-items: center;
709
+ justify-content: center;
710
+ font-weight: 600;
711
+ font-size: var(--font-size-md);
712
+ flex-shrink: 0;
713
+ }
714
+
715
+ .agent-avatar.hub { background: rgba(163, 113, 247, 0.2); color: var(--agent-hub); }
716
+ .agent-avatar.anvil { background: rgba(88, 166, 255, 0.2); color: var(--agent-anvil); }
717
+ .agent-avatar.furnace { background: rgba(240, 136, 62, 0.2); color: var(--agent-furnace); }
718
+ .agent-avatar.crucible { background: rgba(63, 185, 80, 0.2); color: var(--agent-crucible); }
719
+ .agent-avatar.scribe { background: rgba(86, 212, 221, 0.2); color: var(--agent-scribe); }
720
+ .agent-avatar.sentinel { background: rgba(210, 153, 34, 0.2); color: var(--agent-sentinel); }
721
+ .agent-avatar.ember { background: rgba(248, 81, 73, 0.2); color: var(--agent-ember); }
722
+ .agent-avatar.architect { background: rgba(219, 97, 162, 0.2); color: var(--agent-architect); }
723
+ .agent-avatar.aegis { background: rgba(227, 179, 65, 0.2); color: var(--agent-aegis); }
724
+ .agent-avatar.pixel { background: rgba(247, 120, 186, 0.2); color: var(--agent-pixel); }
725
+
726
+ .agent-info {
727
+ flex: 1;
728
+ min-width: 0;
729
+ }
730
+
731
+ .agent-name {
732
+ font-weight: 600;
733
+ font-size: var(--font-size-sm);
734
+ color: var(--text-primary);
735
+ }
736
+
737
+ .agent-status {
738
+ display: flex;
739
+ align-items: center;
740
+ gap: var(--spacing-xs);
741
+ font-size: var(--font-size-xs);
742
+ color: var(--text-secondary);
743
+ margin-top: 2px;
744
+ }
745
+
746
+ .status-indicator {
747
+ width: 8px;
748
+ height: 8px;
749
+ border-radius: 50%;
750
+ }
751
+
752
+ .status-indicator.idle { background: var(--success); }
753
+ .status-indicator.working { background: var(--info); animation: pulse 2s infinite; }
754
+ .status-indicator.blocked { background: var(--warning); }
755
+ .status-indicator.error { background: var(--danger); }
756
+ .status-indicator.offline { background: var(--text-muted); }
757
+
758
+ @keyframes pulse {
759
+ 0%, 100% { opacity: 1; }
760
+ 50% { opacity: 0.5; }
761
+ }
762
+
763
+ .agent-task {
764
+ font-family: var(--font-mono);
765
+ font-size: var(--font-size-xs);
766
+ color: var(--text-muted);
767
+ margin-top: var(--spacing-xs);
768
+ }
769
+
770
+ .agent-progress {
771
+ margin-top: var(--spacing-xs);
772
+ height: 4px;
773
+ background: var(--bg-primary);
774
+ border-radius: 2px;
775
+ overflow: hidden;
776
+ }
777
+
778
+ .agent-progress-bar {
779
+ height: 100%;
780
+ background: var(--info);
781
+ border-radius: 2px;
782
+ transition: width var(--transition-normal) ease;
783
+ }
784
+
785
+ /* Notification Card */
786
+ .notification-card {
787
+ display: flex;
788
+ gap: var(--spacing-sm);
789
+ padding: var(--spacing-sm) var(--spacing-md);
790
+ }
791
+
792
+ .notification-icon {
793
+ width: 20px;
794
+ height: 20px;
795
+ border-radius: 50%;
796
+ display: flex;
797
+ align-items: center;
798
+ justify-content: center;
799
+ font-size: var(--font-size-xs);
800
+ flex-shrink: 0;
801
+ }
802
+
803
+ .notification-icon.success { background: rgba(63, 185, 80, 0.2); color: var(--success); }
804
+ .notification-icon.info { background: rgba(88, 166, 255, 0.2); color: var(--info); }
805
+ .notification-icon.warning { background: rgba(210, 153, 34, 0.2); color: var(--warning); }
806
+ .notification-icon.attention { background: rgba(240, 136, 62, 0.2); color: var(--agent-furnace); }
807
+ .notification-icon.error { background: rgba(248, 81, 73, 0.2); color: var(--danger); }
808
+
809
+ .notification-content {
810
+ flex: 1;
811
+ min-width: 0;
812
+ }
813
+
814
+ .notification-title {
815
+ font-size: var(--font-size-sm);
816
+ font-weight: 500;
817
+ color: var(--text-primary);
818
+ }
819
+
820
+ .notification-desc {
821
+ font-size: var(--font-size-xs);
822
+ color: var(--text-secondary);
823
+ margin-top: 2px;
824
+ }
825
+
826
+ .notification-time {
827
+ font-size: var(--font-size-xs);
828
+ color: var(--text-muted);
829
+ margin-top: var(--spacing-xs);
830
+ }
831
+
832
+ .notification-actions {
833
+ display: flex;
834
+ gap: var(--spacing-sm);
835
+ margin-top: var(--spacing-sm);
836
+ }
837
+
838
+ .notification-dismiss {
839
+ background: none;
840
+ border: none;
841
+ color: var(--text-muted);
842
+ font-size: var(--font-size-xs);
843
+ cursor: pointer;
844
+ padding: 2px 6px;
845
+ border-radius: var(--radius-sm);
846
+ }
847
+
848
+ .notification-dismiss:hover {
849
+ background: var(--bg-hover);
850
+ color: var(--text-secondary);
851
+ }
852
+
853
+ /* Notification group header */
854
+ .notification-group-header {
855
+ font-size: var(--font-size-xs);
856
+ font-weight: 600;
857
+ color: var(--text-muted);
858
+ text-transform: uppercase;
859
+ letter-spacing: 0.5px;
860
+ padding: var(--spacing-xs) 0;
861
+ margin-top: var(--spacing-sm);
862
+ }
863
+
864
+ .notification-group-header:first-child {
865
+ margin-top: 0;
866
+ }
867
+
868
+ /* Issue Card */
869
+ .issue-card {
870
+ display: flex;
871
+ align-items: flex-start;
872
+ gap: var(--spacing-md);
873
+ padding: var(--spacing-md);
874
+ }
875
+
876
+ .issue-category {
877
+ width: 40px;
878
+ height: 40px;
879
+ border-radius: var(--radius-sm);
880
+ display: flex;
881
+ align-items: center;
882
+ justify-content: center;
883
+ font-size: var(--font-size-md);
884
+ flex-shrink: 0;
885
+ }
886
+
887
+ .issue-category.doc { background: rgba(163, 113, 247, 0.2); color: var(--issue-doc); }
888
+ .issue-category.test,
889
+ .issue-category.sec { background: rgba(248, 81, 73, 0.2); color: var(--issue-test); }
890
+ .issue-category.cov { background: rgba(210, 153, 34, 0.2); color: var(--issue-cov); }
891
+ .issue-category.todo { background: rgba(88, 166, 255, 0.2); color: var(--issue-todo); }
892
+ .issue-category.review { background: rgba(240, 136, 62, 0.2); color: var(--issue-review); }
893
+
894
+ .issue-content {
895
+ flex: 1;
896
+ min-width: 0;
897
+ }
898
+
899
+ .issue-header {
900
+ display: flex;
901
+ align-items: center;
902
+ gap: var(--spacing-sm);
903
+ }
904
+
905
+ .issue-badge {
906
+ font-size: var(--font-size-xs);
907
+ font-weight: 600;
908
+ text-transform: uppercase;
909
+ padding: 2px 6px;
910
+ border-radius: var(--radius-sm);
911
+ }
912
+
913
+ .issue-badge.doc { background: rgba(163, 113, 247, 0.2); color: var(--issue-doc); }
914
+ .issue-badge.test { background: rgba(248, 81, 73, 0.2); color: var(--issue-test); }
915
+ .issue-badge.sec { background: rgba(248, 81, 73, 0.2); color: var(--issue-sec); }
916
+ .issue-badge.cov { background: rgba(210, 153, 34, 0.2); color: var(--issue-cov); }
917
+ .issue-badge.todo { background: rgba(88, 166, 255, 0.2); color: var(--issue-todo); }
918
+ .issue-badge.review { background: rgba(240, 136, 62, 0.2); color: var(--issue-review); }
919
+
920
+ .issue-title {
921
+ font-size: var(--font-size-sm);
922
+ font-weight: 500;
923
+ color: var(--text-primary);
924
+ }
925
+
926
+ .issue-details {
927
+ font-size: var(--font-size-xs);
928
+ color: var(--text-secondary);
929
+ margin-top: var(--spacing-xs);
930
+ }
931
+
932
+ .issue-meta {
933
+ font-size: var(--font-size-xs);
934
+ color: var(--text-muted);
935
+ margin-top: var(--spacing-xs);
936
+ }
937
+
938
+ .issue-dispatch {
939
+ flex-shrink: 0;
940
+ }
941
+
942
+ /* ===================================================================
943
+ BUTTONS
944
+ =================================================================== */
945
+ .btn {
946
+ position: relative;
947
+ display: inline-flex;
948
+ align-items: center;
949
+ justify-content: center;
950
+ gap: var(--spacing-xs);
951
+ padding: var(--spacing-sm) var(--spacing-md);
952
+ font-size: var(--font-size-sm);
953
+ font-weight: 500;
954
+ border-radius: var(--radius-sm);
955
+ cursor: pointer;
956
+ border: 1px solid transparent;
957
+ transition: background var(--transition-fast) ease,
958
+ border-color var(--transition-fast) ease,
959
+ color var(--transition-fast) ease;
960
+ }
961
+
962
+ .btn:focus-visible {
963
+ outline: 2px solid var(--accent-secondary);
964
+ outline-offset: 2px;
965
+ }
966
+
967
+ .btn:disabled {
968
+ opacity: 0.5;
969
+ cursor: not-allowed;
970
+ }
971
+
972
+ .btn-primary {
973
+ background: var(--accent-primary);
974
+ color: #fff;
975
+ border-color: var(--accent-primary);
976
+ }
977
+
978
+ .btn-primary:hover:not(:disabled) {
979
+ background: #2ea043;
980
+ border-color: #2ea043;
981
+ }
982
+
983
+ .btn-secondary {
984
+ background: var(--bg-tertiary);
985
+ color: var(--text-primary);
986
+ border-color: var(--border-default);
987
+ }
988
+
989
+ .btn-secondary:hover:not(:disabled) {
990
+ background: var(--bg-hover);
991
+ border-color: var(--text-muted);
992
+ }
993
+
994
+ .btn-dispatch {
995
+ background: transparent;
996
+ color: var(--accent-secondary);
997
+ border-color: var(--accent-secondary);
998
+ padding: var(--spacing-xs) var(--spacing-sm);
999
+ font-size: var(--font-size-xs);
1000
+ }
1001
+
1002
+ .btn-dispatch:hover:not(:disabled) {
1003
+ background: var(--accent-secondary);
1004
+ color: #fff;
1005
+ }
1006
+
1007
+ .btn-dispatch .btn-arrow {
1008
+ transition: transform var(--transition-fast) ease;
1009
+ }
1010
+
1011
+ .btn-dispatch:hover .btn-arrow {
1012
+ transform: translateX(2px);
1013
+ }
1014
+
1015
+ .btn-spinner {
1016
+ width: 14px;
1017
+ height: 14px;
1018
+ border: 2px solid transparent;
1019
+ border-top-color: currentColor;
1020
+ border-radius: 50%;
1021
+ animation: spin 0.8s linear infinite;
1022
+ }
1023
+
1024
+ .btn.loading .btn-text {
1025
+ visibility: hidden;
1026
+ }
1027
+
1028
+ .btn.loading .btn-spinner {
1029
+ display: block;
1030
+ position: absolute;
1031
+ }
1032
+
1033
+ /* ===================================================================
1034
+ EMPTY, LOADING, ERROR STATES
1035
+ =================================================================== */
1036
+ .empty-state,
1037
+ .loading-state,
1038
+ .error-state {
1039
+ display: flex;
1040
+ flex-direction: column;
1041
+ align-items: center;
1042
+ justify-content: center;
1043
+ padding: var(--spacing-xl);
1044
+ text-align: center;
1045
+ }
1046
+
1047
+ .empty-icon,
1048
+ .error-icon {
1049
+ font-size: 2.5rem;
1050
+ margin-bottom: var(--spacing-md);
1051
+ opacity: 0.7;
1052
+ }
1053
+
1054
+ .error-icon {
1055
+ width: 48px;
1056
+ height: 48px;
1057
+ background: rgba(248, 81, 73, 0.2);
1058
+ color: var(--danger);
1059
+ border-radius: 50%;
1060
+ display: flex;
1061
+ align-items: center;
1062
+ justify-content: center;
1063
+ font-weight: bold;
1064
+ }
1065
+
1066
+ .empty-title,
1067
+ .error-title {
1068
+ font-size: var(--font-size-md);
1069
+ font-weight: 600;
1070
+ color: var(--text-primary);
1071
+ margin-bottom: var(--spacing-xs);
1072
+ }
1073
+
1074
+ .empty-subtitle {
1075
+ font-size: var(--font-size-sm);
1076
+ color: var(--text-secondary);
1077
+ }
1078
+
1079
+ .error-message {
1080
+ font-size: var(--font-size-sm);
1081
+ color: var(--text-muted);
1082
+ margin-bottom: var(--spacing-md);
1083
+ }
1084
+
1085
+ .empty-state.celebration .empty-icon {
1086
+ animation: bounce 1s ease infinite;
1087
+ }
1088
+
1089
+ @keyframes bounce {
1090
+ 0%, 100% { transform: translateY(0); }
1091
+ 50% { transform: translateY(-10px); }
1092
+ }
1093
+
1094
+ /* Skeleton loading */
1095
+ .skeleton-card,
1096
+ .skeleton-issue {
1097
+ background: linear-gradient(
1098
+ 90deg,
1099
+ var(--bg-tertiary) 25%,
1100
+ var(--bg-hover) 50%,
1101
+ var(--bg-tertiary) 75%
1102
+ );
1103
+ background-size: 200% 100%;
1104
+ animation: shimmer 1.5s infinite;
1105
+ border-radius: var(--radius-md);
1106
+ }
1107
+
1108
+ .skeleton-card {
1109
+ height: 80px;
1110
+ }
1111
+
1112
+ .skeleton-issue {
1113
+ height: 100px;
1114
+ }
1115
+
1116
+ @keyframes shimmer {
1117
+ 0% { background-position: 200% 0; }
1118
+ 100% { background-position: -200% 0; }
1119
+ }
1120
+
1121
+ /* ===================================================================
1122
+ FOOTER
1123
+ =================================================================== */
1124
+ .footer {
1125
+ height: var(--footer-height);
1126
+ background: var(--bg-secondary);
1127
+ border-top: 1px solid var(--border-default);
1128
+ display: flex;
1129
+ align-items: center;
1130
+ justify-content: space-between;
1131
+ padding: 0 var(--spacing-lg);
1132
+ font-size: var(--font-size-xs);
1133
+ color: var(--text-muted);
1134
+ }
1135
+
1136
+ .footer-left,
1137
+ .footer-right {
1138
+ display: flex;
1139
+ align-items: center;
1140
+ gap: var(--spacing-sm);
1141
+ }
1142
+
1143
+ .connection-status {
1144
+ display: flex;
1145
+ align-items: center;
1146
+ gap: var(--spacing-xs);
1147
+ }
1148
+
1149
+ .status-dot {
1150
+ width: 8px;
1151
+ height: 8px;
1152
+ border-radius: 50%;
1153
+ background: var(--danger);
1154
+ }
1155
+
1156
+ .status-dot.connected {
1157
+ background: var(--success);
1158
+ animation: pulse 2s infinite;
1159
+ }
1160
+
1161
+ .status-dot.disconnected {
1162
+ background: var(--danger);
1163
+ }
1164
+
1165
+ .separator {
1166
+ color: var(--border-default);
1167
+ }
1168
+
1169
+ .keyboard-help-btn {
1170
+ width: 24px;
1171
+ height: 24px;
1172
+ display: flex;
1173
+ align-items: center;
1174
+ justify-content: center;
1175
+ background: var(--bg-tertiary);
1176
+ border: 1px solid var(--border-default);
1177
+ color: var(--text-muted);
1178
+ border-radius: var(--radius-sm);
1179
+ cursor: pointer;
1180
+ font-size: var(--font-size-xs);
1181
+ font-weight: 600;
1182
+ }
1183
+
1184
+ .keyboard-help-btn:hover {
1185
+ background: var(--bg-hover);
1186
+ color: var(--text-primary);
1187
+ }
1188
+
1189
+ .keyboard-help-btn:focus-visible {
1190
+ outline: 2px solid var(--accent-secondary);
1191
+ outline-offset: 2px;
1192
+ }
1193
+
1194
+ /* ===================================================================
1195
+ MODALS
1196
+ =================================================================== */
1197
+ .modal {
1198
+ position: fixed;
1199
+ inset: 0;
1200
+ z-index: 1000;
1201
+ display: flex;
1202
+ align-items: center;
1203
+ justify-content: center;
1204
+ padding: var(--spacing-lg);
1205
+ }
1206
+
1207
+ .modal-backdrop {
1208
+ position: absolute;
1209
+ inset: 0;
1210
+ background: rgba(0, 0, 0, 0.5);
1211
+ animation: fadeIn var(--transition-normal) ease;
1212
+ }
1213
+
1214
+ @keyframes fadeIn {
1215
+ from { opacity: 0; }
1216
+ to { opacity: 1; }
1217
+ }
1218
+
1219
+ .modal-content {
1220
+ position: relative;
1221
+ background: var(--bg-secondary);
1222
+ border: 1px solid var(--border-default);
1223
+ border-radius: var(--radius-lg);
1224
+ max-width: 500px;
1225
+ width: 100%;
1226
+ max-height: 90vh;
1227
+ overflow: auto;
1228
+ animation: slideIn var(--transition-normal) ease;
1229
+ box-shadow: var(--shadow-lg);
1230
+ }
1231
+
1232
+ @keyframes slideIn {
1233
+ from {
1234
+ opacity: 0;
1235
+ transform: translateY(-20px);
1236
+ }
1237
+ to {
1238
+ opacity: 1;
1239
+ transform: translateY(0);
1240
+ }
1241
+ }
1242
+
1243
+ .modal-header {
1244
+ display: flex;
1245
+ align-items: center;
1246
+ justify-content: space-between;
1247
+ padding: var(--spacing-md) var(--spacing-lg);
1248
+ border-bottom: 1px solid var(--border-muted);
1249
+ }
1250
+
1251
+ .modal-title {
1252
+ font-size: var(--font-size-lg);
1253
+ font-weight: 600;
1254
+ color: var(--text-primary);
1255
+ }
1256
+
1257
+ .modal-close {
1258
+ width: 32px;
1259
+ height: 32px;
1260
+ display: flex;
1261
+ align-items: center;
1262
+ justify-content: center;
1263
+ background: none;
1264
+ border: none;
1265
+ color: var(--text-muted);
1266
+ font-size: 1.5rem;
1267
+ cursor: pointer;
1268
+ border-radius: var(--radius-sm);
1269
+ }
1270
+
1271
+ .modal-close:hover {
1272
+ background: var(--bg-hover);
1273
+ color: var(--text-primary);
1274
+ }
1275
+
1276
+ .modal-close:focus-visible {
1277
+ outline: 2px solid var(--accent-secondary);
1278
+ outline-offset: 2px;
1279
+ }
1280
+
1281
+ .modal-body {
1282
+ padding: var(--spacing-lg);
1283
+ }
1284
+
1285
+ .modal-footer {
1286
+ display: flex;
1287
+ justify-content: flex-end;
1288
+ gap: var(--spacing-sm);
1289
+ padding: var(--spacing-md) var(--spacing-lg);
1290
+ border-top: 1px solid var(--border-muted);
1291
+ }
1292
+
1293
+ .modal-error {
1294
+ display: flex;
1295
+ align-items: center;
1296
+ gap: var(--spacing-sm);
1297
+ padding: var(--spacing-sm) var(--spacing-lg);
1298
+ background: rgba(248, 81, 73, 0.1);
1299
+ color: var(--danger);
1300
+ font-size: var(--font-size-sm);
1301
+ }
1302
+
1303
+ .modal-error .error-icon {
1304
+ width: 20px;
1305
+ height: 20px;
1306
+ font-size: var(--font-size-xs);
1307
+ margin-bottom: 0;
1308
+ }
1309
+
1310
+ /* Dispatch Modal Specific */
1311
+ .dispatch-info {
1312
+ background: var(--bg-tertiary);
1313
+ border-radius: var(--radius-md);
1314
+ padding: var(--spacing-md);
1315
+ margin-bottom: var(--spacing-md);
1316
+ }
1317
+
1318
+ .info-row {
1319
+ display: flex;
1320
+ gap: var(--spacing-sm);
1321
+ margin-bottom: var(--spacing-xs);
1322
+ }
1323
+
1324
+ .info-row:last-child {
1325
+ margin-bottom: 0;
1326
+ }
1327
+
1328
+ .info-label {
1329
+ font-size: var(--font-size-sm);
1330
+ color: var(--text-muted);
1331
+ min-width: 60px;
1332
+ }
1333
+
1334
+ .info-value {
1335
+ font-size: var(--font-size-sm);
1336
+ color: var(--text-primary);
1337
+ }
1338
+
1339
+ .dispatch-preview {
1340
+ margin-top: var(--spacing-md);
1341
+ }
1342
+
1343
+ .preview-label {
1344
+ font-size: var(--font-size-sm);
1345
+ color: var(--text-secondary);
1346
+ margin-bottom: var(--spacing-sm);
1347
+ }
1348
+
1349
+ .task-preview {
1350
+ background: var(--bg-tertiary);
1351
+ border: 1px solid var(--border-default);
1352
+ border-radius: var(--radius-md);
1353
+ padding: var(--spacing-md);
1354
+ }
1355
+
1356
+ .preview-id {
1357
+ font-family: var(--font-mono);
1358
+ font-size: var(--font-size-xs);
1359
+ color: var(--text-muted);
1360
+ margin-bottom: var(--spacing-xs);
1361
+ }
1362
+
1363
+ .preview-title {
1364
+ font-size: var(--font-size-sm);
1365
+ font-weight: 500;
1366
+ color: var(--text-primary);
1367
+ margin-bottom: var(--spacing-sm);
1368
+ }
1369
+
1370
+ .preview-meta {
1371
+ display: flex;
1372
+ gap: var(--spacing-md);
1373
+ font-size: var(--font-size-xs);
1374
+ color: var(--text-secondary);
1375
+ }
1376
+
1377
+ .preview-meta strong {
1378
+ color: var(--text-primary);
1379
+ }
1380
+
1381
+ /* Keyboard Shortcuts Modal */
1382
+ .keyboard-help {
1383
+ max-width: 550px;
1384
+ }
1385
+
1386
+ .shortcut-section {
1387
+ margin-bottom: var(--spacing-lg);
1388
+ }
1389
+
1390
+ .shortcut-section:last-child {
1391
+ margin-bottom: 0;
1392
+ }
1393
+
1394
+ .shortcut-section h4 {
1395
+ font-size: var(--font-size-sm);
1396
+ font-weight: 600;
1397
+ color: var(--text-primary);
1398
+ margin-bottom: var(--spacing-sm);
1399
+ padding-bottom: var(--spacing-xs);
1400
+ border-bottom: 1px solid var(--border-muted);
1401
+ }
1402
+
1403
+ .shortcut-list {
1404
+ display: flex;
1405
+ flex-direction: column;
1406
+ gap: var(--spacing-sm);
1407
+ }
1408
+
1409
+ .shortcut {
1410
+ display: flex;
1411
+ align-items: center;
1412
+ gap: var(--spacing-sm);
1413
+ font-size: var(--font-size-sm);
1414
+ color: var(--text-secondary);
1415
+ }
1416
+
1417
+ .shortcut span {
1418
+ flex: 1;
1419
+ }
1420
+
1421
+ kbd {
1422
+ display: inline-flex;
1423
+ align-items: center;
1424
+ justify-content: center;
1425
+ min-width: 24px;
1426
+ height: 24px;
1427
+ padding: 0 var(--spacing-xs);
1428
+ background: var(--bg-tertiary);
1429
+ border: 1px solid var(--border-default);
1430
+ border-radius: var(--radius-sm);
1431
+ font-family: var(--font-mono);
1432
+ font-size: var(--font-size-xs);
1433
+ color: var(--text-primary);
1434
+ box-shadow: 0 1px 0 var(--border-default);
1435
+ }
1436
+
1437
+ /* ===================================================================
1438
+ TOAST NOTIFICATIONS
1439
+ =================================================================== */
1440
+ .toast-container {
1441
+ position: fixed;
1442
+ bottom: calc(var(--footer-height) + var(--spacing-md));
1443
+ right: var(--spacing-md);
1444
+ display: flex;
1445
+ flex-direction: column;
1446
+ gap: var(--spacing-sm);
1447
+ z-index: 1001;
1448
+ max-width: 400px;
1449
+ }
1450
+
1451
+ .toast {
1452
+ background: var(--bg-secondary);
1453
+ border: 1px solid var(--border-default);
1454
+ border-radius: var(--radius-md);
1455
+ padding: var(--spacing-md);
1456
+ display: flex;
1457
+ align-items: flex-start;
1458
+ gap: var(--spacing-sm);
1459
+ box-shadow: var(--shadow-lg);
1460
+ animation: slideInRight var(--transition-normal) ease;
1461
+ }
1462
+
1463
+ @keyframes slideInRight {
1464
+ from {
1465
+ opacity: 0;
1466
+ transform: translateX(100%);
1467
+ }
1468
+ to {
1469
+ opacity: 1;
1470
+ transform: translateX(0);
1471
+ }
1472
+ }
1473
+
1474
+ .toast.removing {
1475
+ animation: slideOutRight var(--transition-normal) ease forwards;
1476
+ }
1477
+
1478
+ @keyframes slideOutRight {
1479
+ from {
1480
+ opacity: 1;
1481
+ transform: translateX(0);
1482
+ }
1483
+ to {
1484
+ opacity: 0;
1485
+ transform: translateX(100%);
1486
+ }
1487
+ }
1488
+
1489
+ .toast-icon {
1490
+ width: 20px;
1491
+ height: 20px;
1492
+ border-radius: 50%;
1493
+ display: flex;
1494
+ align-items: center;
1495
+ justify-content: center;
1496
+ font-size: var(--font-size-xs);
1497
+ flex-shrink: 0;
1498
+ }
1499
+
1500
+ .toast.success .toast-icon { background: rgba(63, 185, 80, 0.2); color: var(--success); }
1501
+ .toast.error .toast-icon { background: rgba(248, 81, 73, 0.2); color: var(--danger); }
1502
+ .toast.info .toast-icon { background: rgba(88, 166, 255, 0.2); color: var(--info); }
1503
+ .toast.warning .toast-icon { background: rgba(210, 153, 34, 0.2); color: var(--warning); }
1504
+
1505
+ .toast-content {
1506
+ flex: 1;
1507
+ }
1508
+
1509
+ .toast-title {
1510
+ font-size: var(--font-size-sm);
1511
+ font-weight: 600;
1512
+ color: var(--text-primary);
1513
+ }
1514
+
1515
+ .toast-message {
1516
+ font-size: var(--font-size-xs);
1517
+ color: var(--text-secondary);
1518
+ margin-top: 2px;
1519
+ }
1520
+
1521
+ .toast-actions {
1522
+ display: flex;
1523
+ gap: var(--spacing-sm);
1524
+ margin-top: var(--spacing-sm);
1525
+ }
1526
+
1527
+ .toast-action {
1528
+ background: none;
1529
+ border: none;
1530
+ color: var(--text-link);
1531
+ font-size: var(--font-size-xs);
1532
+ cursor: pointer;
1533
+ padding: 0;
1534
+ }
1535
+
1536
+ .toast-action:hover {
1537
+ text-decoration: underline;
1538
+ }
1539
+
1540
+ .toast-close {
1541
+ width: 20px;
1542
+ height: 20px;
1543
+ display: flex;
1544
+ align-items: center;
1545
+ justify-content: center;
1546
+ background: none;
1547
+ border: none;
1548
+ color: var(--text-muted);
1549
+ cursor: pointer;
1550
+ border-radius: var(--radius-sm);
1551
+ font-size: var(--font-size-md);
1552
+ }
1553
+
1554
+ .toast-close:hover {
1555
+ background: var(--bg-hover);
1556
+ color: var(--text-primary);
1557
+ }
1558
+
1559
+ /* ===================================================================
1560
+ MOBILE TABS (Bottom Navigation)
1561
+ =================================================================== */
1562
+ .mobile-tabs {
1563
+ display: none;
1564
+ position: fixed;
1565
+ bottom: 0;
1566
+ left: 0;
1567
+ right: 0;
1568
+ height: var(--mobile-tab-height);
1569
+ background: var(--bg-secondary);
1570
+ border-top: 1px solid var(--border-default);
1571
+ z-index: 100;
1572
+ }
1573
+
1574
+ .mobile-tab {
1575
+ flex: 1;
1576
+ display: flex;
1577
+ flex-direction: column;
1578
+ align-items: center;
1579
+ justify-content: center;
1580
+ gap: 2px;
1581
+ background: none;
1582
+ border: none;
1583
+ color: var(--text-muted);
1584
+ font-size: var(--font-size-xs);
1585
+ cursor: pointer;
1586
+ padding: var(--spacing-xs);
1587
+ }
1588
+
1589
+ .mobile-tab:hover {
1590
+ color: var(--text-secondary);
1591
+ }
1592
+
1593
+ .mobile-tab.active {
1594
+ color: var(--accent-secondary);
1595
+ }
1596
+
1597
+ .mobile-tab:focus-visible {
1598
+ outline: 2px solid var(--accent-secondary);
1599
+ outline-offset: -2px;
1600
+ }
1601
+
1602
+ .tab-icon {
1603
+ width: 20px;
1604
+ height: 20px;
1605
+ }
1606
+
1607
+ /* ===================================================================
1608
+ RESPONSIVE DESIGN
1609
+ =================================================================== */
1610
+
1611
+ /* Tablet: 768px - 1199px */
1612
+ @media (max-width: 1199px) {
1613
+ .panels-top {
1614
+ grid-template-columns: 1fr 1fr;
1615
+ }
1616
+
1617
+ .notifications-panel {
1618
+ grid-column: span 2;
1619
+ }
1620
+
1621
+ .logo-text {
1622
+ font-size: var(--font-size-md);
1623
+ }
1624
+ }
1625
+
1626
+ /* Mobile: < 768px */
1627
+ @media (max-width: 767px) {
1628
+ :root {
1629
+ --spacing-lg: 16px;
1630
+ }
1631
+
1632
+ .header {
1633
+ padding: 0 var(--spacing-md);
1634
+ }
1635
+
1636
+ .logo-text {
1637
+ display: none;
1638
+ }
1639
+
1640
+ .main {
1641
+ padding: var(--spacing-md);
1642
+ padding-bottom: calc(var(--mobile-tab-height) + var(--spacing-md));
1643
+ }
1644
+
1645
+ .panels-top {
1646
+ display: flex;
1647
+ flex-direction: column;
1648
+ }
1649
+
1650
+ .panel {
1651
+ display: none;
1652
+ }
1653
+
1654
+ .panel.mobile-active {
1655
+ display: flex;
1656
+ flex: 1;
1657
+ }
1658
+
1659
+ .issues-panel {
1660
+ display: flex;
1661
+ flex: none;
1662
+ max-height: 300px;
1663
+ }
1664
+
1665
+ .issues-panel.mobile-active {
1666
+ flex: 1;
1667
+ max-height: none;
1668
+ }
1669
+
1670
+ .mobile-tabs {
1671
+ display: flex;
1672
+ }
1673
+
1674
+ .footer {
1675
+ display: none;
1676
+ }
1677
+
1678
+ .toast-container {
1679
+ bottom: calc(var(--mobile-tab-height) + var(--spacing-md));
1680
+ left: var(--spacing-md);
1681
+ right: var(--spacing-md);
1682
+ max-width: none;
1683
+ }
1684
+
1685
+ .modal-content {
1686
+ margin: var(--spacing-md);
1687
+ max-height: calc(100vh - var(--spacing-xl) * 2);
1688
+ }
1689
+
1690
+ .shortcut {
1691
+ flex-wrap: wrap;
1692
+ }
1693
+
1694
+ .shortcut kbd {
1695
+ margin-right: var(--spacing-xs);
1696
+ }
1697
+ }
1698
+
1699
+ /* Small mobile: < 375px */
1700
+ @media (max-width: 374px) {
1701
+ .filter-tab {
1702
+ padding: var(--spacing-xs);
1703
+ font-size: var(--font-size-xs);
1704
+ }
1705
+
1706
+ .filter-count {
1707
+ display: none;
1708
+ }
1709
+
1710
+ .filter-tab.active .filter-count {
1711
+ display: inline-block;
1712
+ }
1713
+ }
1714
+
1715
+ /* ===================================================================
1716
+ UTILITIES
1717
+ =================================================================== */
1718
+ .sr-only {
1719
+ position: absolute;
1720
+ width: 1px;
1721
+ height: 1px;
1722
+ padding: 0;
1723
+ margin: -1px;
1724
+ overflow: hidden;
1725
+ clip: rect(0, 0, 0, 0);
1726
+ white-space: nowrap;
1727
+ border: 0;
1728
+ }
1729
+
1730
+ /* Focus visible only for keyboard navigation */
1731
+ :focus:not(:focus-visible) {
1732
+ outline: none;
1733
+ }
1734
+
1735
+ /* Scrollbar styling */
1736
+ ::-webkit-scrollbar {
1737
+ width: 8px;
1738
+ height: 8px;
1739
+ }
1740
+
1741
+ ::-webkit-scrollbar-track {
1742
+ background: var(--bg-primary);
1743
+ }
1744
+
1745
+ ::-webkit-scrollbar-thumb {
1746
+ background: var(--border-default);
1747
+ border-radius: 4px;
1748
+ }
1749
+
1750
+ ::-webkit-scrollbar-thumb:hover {
1751
+ background: var(--text-muted);
1752
+ }
1753
+
1754
+ /* Selection */
1755
+ ::selection {
1756
+ background: var(--accent-secondary);
1757
+ color: #fff;
1758
+ }
1759
+
1760
+ /* Print styles */
1761
+ @media print {
1762
+ .header,
1763
+ .footer,
1764
+ .mobile-tabs,
1765
+ .modal,
1766
+ .toast-container {
1767
+ display: none !important;
1768
+ }
1769
+
1770
+ .main {
1771
+ padding: 0;
1772
+ }
1773
+
1774
+ .panel {
1775
+ break-inside: avoid;
1776
+ }
1777
+ }