@polderlabs/bizar 3.23.1 → 4.2.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 (361) hide show
  1. package/README.md +83 -16
  2. package/bizar-dash/.bizar/activity.log +3 -0
  3. package/bizar-dash/.bizar/graph/.graphify_analysis.json +1540 -0
  4. package/bizar-dash/.bizar/graph/.graphify_labels.json +1 -0
  5. package/bizar-dash/.bizar/graph/GRAPH_REPORT.md +404 -0
  6. package/bizar-dash/.bizar/graph/cache/ast/v0.8.46/0661b816358db84dfdb7f10443db8a61152fd20b3fee950caf8fbf32920a1790.json +1 -0
  7. package/bizar-dash/.bizar/graph/cache/ast/v0.8.46/16da06d774142a6e5d74829ad982531286a6193ef798de8f593db029e123ec32.json +1 -0
  8. package/bizar-dash/.bizar/graph/cache/ast/v0.8.46/27e5697c01254c69c64c5a33896669073b40afb5ba88375102ae77fa5404136d.json +1 -0
  9. package/bizar-dash/.bizar/graph/cache/ast/v0.8.46/532997898027254aa4c0932243dc71d2f55888181232b65974961934997dc85b.json +1 -0
  10. package/bizar-dash/.bizar/graph/cache/ast/v0.8.46/84e3451a64c7f99f0cd6a88b0748d7426780486f53ab4935b7476b28c08f8293.json +1 -0
  11. package/bizar-dash/.bizar/graph/cache/ast/v0.8.46/88e5ea5f3e78fa69353fe9e6a8d1a05391d54605e25600cb125531eb5a6432ff.json +1 -0
  12. package/bizar-dash/.bizar/graph/cache/stat-index.json +1 -0
  13. package/bizar-dash/.bizar/graph/graph.html +307 -0
  14. package/bizar-dash/.bizar/graph/graph.json +40267 -0
  15. package/bizar-dash/.bizar/graph/manifest.json +762 -0
  16. package/bizar-dash/.graphifyignore +40 -0
  17. package/bizar-dash/.obsidian/README.md +14 -0
  18. package/bizar-dash/.obsidian/daily/2026-06-25.md +9 -0
  19. package/bizar-dash/.obsidian/vault.json +7 -0
  20. package/bizar-dash/.od-skills/web-prototype-e1429c1737/SKILL.md +103 -0
  21. package/bizar-dash/.od-skills/web-prototype-e1429c1737/assets/template.html +338 -0
  22. package/bizar-dash/.od-skills/web-prototype-e1429c1737/example.html +81 -0
  23. package/bizar-dash/.od-skills/web-prototype-e1429c1737/open-design.json +172 -0
  24. package/bizar-dash/.od-skills/web-prototype-e1429c1737/references/checklist.md +44 -0
  25. package/bizar-dash/.od-skills/web-prototype-e1429c1737/references/layouts.md +247 -0
  26. package/bizar-dash/CHANGELOG.md +474 -0
  27. package/bizar-dash/DESIGN.md +136 -0
  28. package/bizar-dash/dist/assets/main-B3RgW6FS.js +331 -0
  29. package/bizar-dash/dist/assets/main-B3RgW6FS.js.map +1 -0
  30. package/bizar-dash/dist/assets/main-DlJ8wgLR.css +1 -0
  31. package/bizar-dash/dist/assets/mobile-CsZQAswA.css +1 -0
  32. package/bizar-dash/dist/assets/mobile-DbxIw8BG.js +2 -0
  33. package/bizar-dash/dist/assets/mobile-DbxIw8BG.js.map +1 -0
  34. package/bizar-dash/dist/assets/mobile-Dvq2d53Y.js +354 -0
  35. package/bizar-dash/dist/assets/mobile-Dvq2d53Y.js.map +1 -0
  36. package/bizar-dash/dist/index.html +40 -0
  37. package/bizar-dash/dist/mobile.html +22 -0
  38. package/bizar-dash/plans/debug-plan/comments.json +1 -0
  39. package/bizar-dash/plans/debug-plan/meta.json +10 -0
  40. package/bizar-dash/plans/debug-plan/plan.json +174 -0
  41. package/bizar-dash/scripts/smoke-bg-retry.mjs +246 -0
  42. package/bizar-dash/src/cli/dashboard-ports.mjs +488 -0
  43. package/bizar-dash/src/cli.mjs +522 -0
  44. package/bizar-dash/src/server/activity-log.mjs +174 -0
  45. package/bizar-dash/src/server/agents-store.mjs +465 -0
  46. package/bizar-dash/src/server/api.mjs +138 -0
  47. package/bizar-dash/src/server/artifact-template.html +810 -0
  48. package/bizar-dash/src/server/artifacts-store.mjs +733 -0
  49. package/bizar-dash/src/server/auth.mjs +381 -0
  50. package/bizar-dash/src/server/background-store.mjs +447 -0
  51. package/bizar-dash/src/server/bg-poller.mjs +305 -0
  52. package/bizar-dash/src/server/bg-retry.mjs +574 -0
  53. package/bizar-dash/src/server/browser.mjs +40 -0
  54. package/bizar-dash/src/server/diagnostics-store.mjs +148 -0
  55. package/bizar-dash/src/server/dialog-poller.mjs +105 -0
  56. package/bizar-dash/src/server/dialog-store.mjs +177 -0
  57. package/bizar-dash/src/server/glyphs/mdx-compiler.mjs +583 -0
  58. package/bizar-dash/src/server/lib/path-safe.mjs +283 -0
  59. package/bizar-dash/src/server/memory-git.mjs +329 -0
  60. package/bizar-dash/src/server/memory-lightrag.mjs +767 -0
  61. package/bizar-dash/src/server/memory-schema.mjs +145 -0
  62. package/bizar-dash/src/server/memory-secrets.mjs +84 -0
  63. package/bizar-dash/src/server/memory-store.mjs +471 -0
  64. package/bizar-dash/src/server/mod-security.mjs +398 -0
  65. package/bizar-dash/src/server/mods-loader.mjs +1067 -0
  66. package/bizar-dash/src/server/notifications-store.mjs +243 -0
  67. package/bizar-dash/src/server/obsidian-store.mjs +318 -0
  68. package/bizar-dash/src/server/opencode-runner.mjs +279 -0
  69. package/bizar-dash/src/server/pair-store.mjs +138 -0
  70. package/bizar-dash/src/server/projects-store.mjs +364 -0
  71. package/bizar-dash/src/server/providers-store.mjs +789 -0
  72. package/bizar-dash/src/server/routes/_shared.mjs +415 -0
  73. package/bizar-dash/src/server/routes/activity.mjs +110 -0
  74. package/bizar-dash/src/server/routes/agents.mjs +134 -0
  75. package/bizar-dash/src/server/routes/artifacts.mjs +279 -0
  76. package/bizar-dash/src/server/routes/auth.mjs +69 -0
  77. package/bizar-dash/src/server/routes/background.mjs +165 -0
  78. package/bizar-dash/src/server/routes/chat.mjs +485 -0
  79. package/bizar-dash/src/server/routes/config.mjs +129 -0
  80. package/bizar-dash/src/server/routes/diagnostics.mjs +50 -0
  81. package/bizar-dash/src/server/routes/dialogs.mjs +86 -0
  82. package/bizar-dash/src/server/routes/fs.mjs +429 -0
  83. package/bizar-dash/src/server/routes/history.mjs +78 -0
  84. package/bizar-dash/src/server/routes/memory.mjs +658 -0
  85. package/bizar-dash/src/server/routes/misc.mjs +89 -0
  86. package/bizar-dash/src/server/routes/mods.mjs +359 -0
  87. package/bizar-dash/src/server/routes/notifications.mjs +54 -0
  88. package/bizar-dash/src/server/routes/obsidian.mjs +239 -0
  89. package/bizar-dash/src/server/routes/opencode-sessions.mjs +55 -0
  90. package/bizar-dash/src/server/routes/overview.mjs +91 -0
  91. package/bizar-dash/src/server/routes/pair.mjs +67 -0
  92. package/bizar-dash/src/server/routes/projects.mjs +175 -0
  93. package/bizar-dash/src/server/routes/providers.mjs +47 -0
  94. package/bizar-dash/src/server/routes/schedules.mjs +104 -0
  95. package/bizar-dash/src/server/routes/settings.mjs +51 -0
  96. package/bizar-dash/src/server/routes/skills.mjs +76 -0
  97. package/bizar-dash/src/server/routes/tasks.mjs +468 -0
  98. package/bizar-dash/src/server/routes/themes.mjs +51 -0
  99. package/bizar-dash/src/server/routes-v2/auth.mjs +59 -0
  100. package/bizar-dash/src/server/routes-v2/events.mjs +107 -0
  101. package/bizar-dash/src/server/routes-v2/health.mjs +21 -0
  102. package/bizar-dash/src/server/routes-v2/index.mjs +90 -0
  103. package/bizar-dash/src/server/routes-v2/sessions.mjs +111 -0
  104. package/bizar-dash/src/server/schedules-runner.mjs +369 -0
  105. package/bizar-dash/src/server/schedules-store.mjs +268 -0
  106. package/bizar-dash/src/server/search-store.mjs +220 -0
  107. package/bizar-dash/src/server/serve-info.mjs +684 -0
  108. package/bizar-dash/src/server/server.mjs +796 -0
  109. package/bizar-dash/src/server/settings-store.mjs +45 -0
  110. package/bizar-dash/src/server/skills-store.mjs +300 -0
  111. package/bizar-dash/src/server/state.mjs +437 -0
  112. package/bizar-dash/src/server/tailscale-store.mjs +113 -0
  113. package/bizar-dash/src/server/task-delegator.mjs +824 -0
  114. package/bizar-dash/src/server/tasks-store.mjs +508 -0
  115. package/bizar-dash/src/server/tui.mjs +923 -0
  116. package/bizar-dash/src/server/update-store.mjs +168 -0
  117. package/bizar-dash/src/server/v2-auth-file.mjs +99 -0
  118. package/bizar-dash/src/server/v2-event-bus.mjs +128 -0
  119. package/bizar-dash/src/server/watcher.mjs +81 -0
  120. package/bizar-dash/src/server/yaml.mjs +238 -0
  121. package/bizar-dash/src/web/App.tsx +718 -0
  122. package/bizar-dash/src/web/MobileApp.tsx +408 -0
  123. package/bizar-dash/src/web/components/ArtifactCreateDialog.tsx +95 -0
  124. package/bizar-dash/src/web/components/ArtifactListDialog.tsx +55 -0
  125. package/bizar-dash/src/web/components/ArtifactViewer.tsx +143 -0
  126. package/bizar-dash/src/web/components/AuditDialog.tsx +79 -0
  127. package/bizar-dash/src/web/components/BgStatusBadge.tsx +32 -0
  128. package/bizar-dash/src/web/components/Button.tsx +56 -0
  129. package/bizar-dash/src/web/components/CanvasContextMenu.tsx +68 -0
  130. package/bizar-dash/src/web/components/Card.tsx +40 -0
  131. package/bizar-dash/src/web/components/CollapsibleSection.tsx +72 -0
  132. package/bizar-dash/src/web/components/CommandDialog.tsx +66 -0
  133. package/bizar-dash/src/web/components/EmptyState.tsx +30 -0
  134. package/bizar-dash/src/web/components/FileBrowser.tsx +633 -0
  135. package/bizar-dash/src/web/components/HelpDialog.tsx +55 -0
  136. package/bizar-dash/src/web/components/KillConfirmDialog.tsx +88 -0
  137. package/bizar-dash/src/web/components/Modal.tsx +215 -0
  138. package/bizar-dash/src/web/components/Notifications.tsx +241 -0
  139. package/bizar-dash/src/web/components/SearchModal.tsx +224 -0
  140. package/bizar-dash/src/web/components/Sidebar.tsx +66 -0
  141. package/bizar-dash/src/web/components/Spinner.tsx +19 -0
  142. package/bizar-dash/src/web/components/StatusBadge.tsx +25 -0
  143. package/bizar-dash/src/web/components/Tag.tsx +28 -0
  144. package/bizar-dash/src/web/components/Toast.tsx +150 -0
  145. package/bizar-dash/src/web/components/Topbar.tsx +368 -0
  146. package/bizar-dash/src/web/components/VisualPlanDialog.tsx +58 -0
  147. package/bizar-dash/src/web/components/chat/AgentChip.tsx +68 -0
  148. package/bizar-dash/src/web/components/chat/ChatBubble.tsx +60 -0
  149. package/bizar-dash/src/web/components/chat/ChatThread.tsx +88 -0
  150. package/bizar-dash/src/web/components/chat/ChatTopBar.tsx +50 -0
  151. package/bizar-dash/src/web/components/chat/Composer.tsx +164 -0
  152. package/bizar-dash/src/web/components/chat/ConfirmModal.tsx +54 -0
  153. package/bizar-dash/src/web/components/chat/EmptyState.tsx +21 -0
  154. package/bizar-dash/src/web/components/chat/FirstRunGreeting.tsx +18 -0
  155. package/bizar-dash/src/web/components/chat/FloatingComposer.tsx +32 -0
  156. package/bizar-dash/src/web/components/chat/InfoPanel.tsx +119 -0
  157. package/bizar-dash/src/web/components/chat/LoadingSkeleton.tsx +19 -0
  158. package/bizar-dash/src/web/components/chat/MessageBubble.tsx +60 -0
  159. package/bizar-dash/src/web/components/chat/SessionList.tsx +153 -0
  160. package/bizar-dash/src/web/components/chat/StreamingIndicator.tsx +9 -0
  161. package/bizar-dash/src/web/components/chat/SuggestionCards.tsx +55 -0
  162. package/bizar-dash/src/web/components/chat/WelcomeScreen.tsx +36 -0
  163. package/bizar-dash/src/web/components/chat/index.ts +20 -0
  164. package/bizar-dash/src/web/components/chat/useAutoGrowTextarea.ts +18 -0
  165. package/bizar-dash/src/web/components/chat/useChat.ts +219 -0
  166. package/bizar-dash/src/web/components/chat/useSlashCommands.ts +47 -0
  167. package/bizar-dash/src/web/index.html +37 -0
  168. package/bizar-dash/src/web/lib/api.ts +193 -0
  169. package/bizar-dash/src/web/lib/markdown.tsx +59 -0
  170. package/bizar-dash/src/web/lib/types.ts +668 -0
  171. package/bizar-dash/src/web/lib/utils.ts +114 -0
  172. package/bizar-dash/src/web/lib/ws.ts +176 -0
  173. package/bizar-dash/src/web/main.tsx +34 -0
  174. package/bizar-dash/src/web/mobile/MobileApp.tsx +278 -0
  175. package/bizar-dash/src/web/mobile/MobileBottomNav.tsx +38 -0
  176. package/bizar-dash/src/web/mobile/MobileTopbar.tsx +115 -0
  177. package/bizar-dash/src/web/mobile/components/MobileBottomSheet.tsx +182 -0
  178. package/bizar-dash/src/web/mobile/components/MobileListItem.tsx +64 -0
  179. package/bizar-dash/src/web/mobile/components/MobileModal.tsx +123 -0
  180. package/bizar-dash/src/web/mobile/views/MobileActivity.tsx +273 -0
  181. package/bizar-dash/src/web/mobile/views/MobileAgents.tsx +374 -0
  182. package/bizar-dash/src/web/mobile/views/MobileArtifactCanvas.tsx +439 -0
  183. package/bizar-dash/src/web/mobile/views/MobileArtifacts.tsx +143 -0
  184. package/bizar-dash/src/web/mobile/views/MobileChat.tsx +180 -0
  185. package/bizar-dash/src/web/mobile/views/MobileConfig.tsx +175 -0
  186. package/bizar-dash/src/web/mobile/views/MobileHistory.tsx +191 -0
  187. package/bizar-dash/src/web/mobile/views/MobileMods.tsx +149 -0
  188. package/bizar-dash/src/web/mobile/views/MobileMore.tsx +121 -0
  189. package/bizar-dash/src/web/mobile/views/MobileNotifications.tsx +137 -0
  190. package/bizar-dash/src/web/mobile/views/MobilePlans.tsx +26 -0
  191. package/bizar-dash/src/web/mobile/views/MobileSchedules.tsx +685 -0
  192. package/bizar-dash/src/web/mobile/views/MobileSearchModal.tsx +172 -0
  193. package/bizar-dash/src/web/mobile/views/MobileSettings.tsx +388 -0
  194. package/bizar-dash/src/web/mobile/views/MobileSkills.tsx +153 -0
  195. package/bizar-dash/src/web/mobile/views/MobileTasks.tsx +564 -0
  196. package/bizar-dash/src/web/mobile.html +20 -0
  197. package/bizar-dash/src/web/mobile.tsx +13 -0
  198. package/bizar-dash/src/web/styles/chat.css +198 -0
  199. package/bizar-dash/src/web/styles/glyphs.css +960 -0
  200. package/bizar-dash/src/web/styles/main.css +8855 -0
  201. package/bizar-dash/src/web/styles/mobile-chat.css +5 -0
  202. package/bizar-dash/src/web/styles/mobile.css +1960 -0
  203. package/bizar-dash/src/web/views/Activity.tsx +1203 -0
  204. package/bizar-dash/src/web/views/Agents.tsx +701 -0
  205. package/bizar-dash/src/web/views/Artifacts.tsx +1480 -0
  206. package/bizar-dash/src/web/views/BackgroundAgents.tsx +450 -0
  207. package/bizar-dash/src/web/views/Chat.tsx +190 -0
  208. package/bizar-dash/src/web/views/Config.tsx +2063 -0
  209. package/bizar-dash/src/web/views/History.tsx +335 -0
  210. package/bizar-dash/src/web/views/ModView.tsx +207 -0
  211. package/bizar-dash/src/web/views/Mods.tsx +693 -0
  212. package/bizar-dash/src/web/views/Overview.tsx +812 -0
  213. package/bizar-dash/src/web/views/Providers.tsx +302 -0
  214. package/bizar-dash/src/web/views/Schedules.tsx +802 -0
  215. package/bizar-dash/src/web/views/Settings.tsx +1787 -0
  216. package/bizar-dash/src/web/views/Skills.tsx +431 -0
  217. package/bizar-dash/src/web/views/Tasks.tsx +1523 -0
  218. package/bizar-dash/src/web/views/glyphs/GlyphRenderer.tsx +613 -0
  219. package/bizar-dash/src/web/views/glyphs/components.tsx +1098 -0
  220. package/bizar-dash/templates/mod/FORMAT.md +76 -0
  221. package/bizar-dash/templates/mod/hello-mod/README.md +19 -0
  222. package/bizar-dash/templates/mod/hello-mod/agents/greeter.md +8 -0
  223. package/bizar-dash/templates/mod/hello-mod/commands/hello.md +6 -0
  224. package/bizar-dash/templates/mod/hello-mod/mod.json +20 -0
  225. package/bizar-dash/templates/mod/hello-mod/routes/ping.mjs +9 -0
  226. package/bizar-dash/templates/mod/hello-mod/views/HelloView.tsx +10 -0
  227. package/bizar-dash/tests/dashboard-ports.test.mjs +138 -0
  228. package/bizar-dash/tests/graphify-mod-spawn.node.test.mjs +90 -0
  229. package/bizar-dash/tests/memory-cli.test.mjs +542 -0
  230. package/bizar-dash/tests/memory-config.test.mjs +422 -0
  231. package/bizar-dash/tests/memory-git.test.mjs +246 -0
  232. package/bizar-dash/tests/memory-lightrag.test.mjs +153 -0
  233. package/bizar-dash/tests/memory-protocol-drift.test.mjs +45 -0
  234. package/bizar-dash/tests/memory-schema.test.mjs +198 -0
  235. package/bizar-dash/tests/memory-secrets.test.mjs +121 -0
  236. package/bizar-dash/tests/memory-store.test.mjs +390 -0
  237. package/bizar-dash/tests/memory-sync.test.mjs +141 -0
  238. package/bizar-dash/tests/mod-instructions.node.test.mjs +188 -0
  239. package/bizar-dash/tests/mod-security.test.mjs +273 -0
  240. package/bizar-dash/tests/mod-upgrade.node.test.mjs +357 -0
  241. package/bizar-dash/tests/no-agent-browser.node.test.mjs +98 -0
  242. package/bizar-dash/tests/obsidian-back-compat.test.mjs +199 -0
  243. package/bizar-dash/tests/opencode-runner.test.mjs +172 -0
  244. package/bizar-dash/tests/path-safe.test.mjs +108 -0
  245. package/bizar-dash/tests/providers-store-backup-keys.node.test.mjs +333 -0
  246. package/bizar-dash/tests/smoke-v2.mjs +212 -0
  247. package/bizar-dash/tests/strip-thinking.test.mjs +175 -0
  248. package/bizar-dash/tests/submit-feedback.test.mjs +353 -0
  249. package/bizar-dash/tests/tmux-wrap.test.mjs +145 -0
  250. package/bizar-dash/tests/yaml.test.mjs +128 -0
  251. package/bizar-dash/tsconfig.json +23 -0
  252. package/bizar-dash/vite.config.ts +27 -0
  253. package/cli/atomic.mjs +73 -0
  254. package/cli/banner.mjs +1 -1
  255. package/cli/bin.mjs +44 -47
  256. package/cli/bootstrap.mjs +1 -1
  257. package/cli/copy.mjs +25 -16
  258. package/cli/dev-link.mjs +17 -1
  259. package/cli/doctor.mjs +4 -4
  260. package/cli/doctor.test.mjs +2 -2
  261. package/cli/init.mjs +135 -1
  262. package/cli/install.mjs +31 -39
  263. package/cli/memory-constants.mjs +59 -0
  264. package/cli/memory.mjs +1436 -0
  265. package/cli/service.mjs +5 -6
  266. package/cli/utils.mjs +6 -3
  267. package/config/AGENTS.md +7 -7
  268. package/config/agents/_shared/AGENT_BASELINE.md +59 -61
  269. package/config/opencode.json +13 -38
  270. package/config/skills/memory-protocol/SKILL.md +105 -0
  271. package/config/skills/obsidian/SKILL.md +270 -65
  272. package/install.sh +59 -19
  273. package/package.json +49 -14
  274. package/packages/sdk/LICENSE +21 -0
  275. package/packages/sdk/README.md +80 -0
  276. package/packages/sdk/src/client.ts +183 -0
  277. package/packages/sdk/src/errors.ts +120 -0
  278. package/packages/sdk/src/events.ts +153 -0
  279. package/packages/sdk/src/index.ts +63 -0
  280. package/packages/sdk/src/types.ts +176 -0
  281. package/packages/sdk/src/version.ts +4 -0
  282. package/packages/sdk/tests/client.test.ts +217 -0
  283. package/packages/sdk/tests/errors.test.ts +108 -0
  284. package/packages/sdk/tests/events.test.ts +139 -0
  285. package/packages/sdk/tests/fixtures/fetch-mock.ts +152 -0
  286. package/packages/sdk/tests/fixtures/sse-mock.ts +30 -0
  287. package/packages/sdk/tsconfig.json +25 -0
  288. package/packages/sdk/vitest.config.ts +9 -0
  289. package/plugins/bizar/LICENSE +21 -0
  290. package/plugins/bizar/README.md +448 -0
  291. package/plugins/bizar/dist/index.js +29901 -0
  292. package/plugins/bizar/index.ts +1491 -0
  293. package/plugins/bizar/scripts/check-forbidden-imports.sh +33 -0
  294. package/plugins/bizar/src/background-state.ts +551 -0
  295. package/plugins/bizar/src/background.ts +1250 -0
  296. package/plugins/bizar/src/commands-impl.ts +464 -0
  297. package/plugins/bizar/src/commands.ts +1168 -0
  298. package/plugins/bizar/src/dashboard-client.ts +233 -0
  299. package/plugins/bizar/src/event-stream.ts +606 -0
  300. package/plugins/bizar/src/fingerprint.ts +120 -0
  301. package/plugins/bizar/src/handoff.ts +79 -0
  302. package/plugins/bizar/src/http-client.ts +467 -0
  303. package/plugins/bizar/src/key-rotation.ts +218 -0
  304. package/plugins/bizar/src/logger.ts +144 -0
  305. package/plugins/bizar/src/loop.ts +176 -0
  306. package/plugins/bizar/src/opencode-runner.ts +390 -0
  307. package/plugins/bizar/src/options.ts +421 -0
  308. package/plugins/bizar/src/plan-fs.ts +323 -0
  309. package/plugins/bizar/src/reasoning-clean.ts +454 -0
  310. package/plugins/bizar/src/report.ts +178 -0
  311. package/plugins/bizar/src/research-prompt.ts +35 -0
  312. package/plugins/bizar/src/serve-info.ts +228 -0
  313. package/plugins/bizar/src/serve.ts +496 -0
  314. package/plugins/bizar/src/settings.ts +349 -0
  315. package/plugins/bizar/src/state.ts +298 -0
  316. package/plugins/bizar/src/tools/bg-collect.ts +104 -0
  317. package/plugins/bizar/src/tools/bg-get-comments.ts +239 -0
  318. package/plugins/bizar/src/tools/bg-kill.ts +87 -0
  319. package/plugins/bizar/src/tools/bg-spawn.ts +401 -0
  320. package/plugins/bizar/src/tools/bg-status.ts +99 -0
  321. package/plugins/bizar/src/tools/open-kb.ts +191 -0
  322. package/plugins/bizar/src/tools/plan-action.ts +767 -0
  323. package/plugins/bizar/src/tools/read-glyph-feedback.ts +170 -0
  324. package/plugins/bizar/src/tools/wait-for-feedback.ts +402 -0
  325. package/plugins/bizar/tests/attach-handler-bug.test.ts +169 -0
  326. package/plugins/bizar/tests/background-state.test.ts +277 -0
  327. package/plugins/bizar/tests/background.test.ts +402 -0
  328. package/plugins/bizar/tests/block.test.ts +195 -0
  329. package/plugins/bizar/tests/canonical-key-order.test.ts +75 -0
  330. package/plugins/bizar/tests/commands-impl.test.ts +442 -0
  331. package/plugins/bizar/tests/commands.test.ts +584 -0
  332. package/plugins/bizar/tests/config.test.ts +122 -0
  333. package/plugins/bizar/tests/dashboard-client.test.ts +159 -0
  334. package/plugins/bizar/tests/dispose.test.ts +336 -0
  335. package/plugins/bizar/tests/event-stream.test.ts +409 -0
  336. package/plugins/bizar/tests/event.test.ts +262 -0
  337. package/plugins/bizar/tests/fingerprint.test.ts +162 -0
  338. package/plugins/bizar/tests/http-client.test.ts +404 -0
  339. package/plugins/bizar/tests/init-helpers.test.ts +203 -0
  340. package/plugins/bizar/tests/integration/slash-command.test.ts +348 -0
  341. package/plugins/bizar/tests/integration/tool-routing.test.ts +314 -0
  342. package/plugins/bizar/tests/key-rotation.test.ts +396 -0
  343. package/plugins/bizar/tests/loop.test.ts +397 -0
  344. package/plugins/bizar/tests/options.test.ts +276 -0
  345. package/plugins/bizar/tests/reasoning-clean.test.ts +422 -0
  346. package/plugins/bizar/tests/serve.test.ts +339 -0
  347. package/plugins/bizar/tests/settings.test.ts +351 -0
  348. package/plugins/bizar/tests/stall-think.test.ts +750 -0
  349. package/plugins/bizar/tests/state.test.ts +276 -0
  350. package/plugins/bizar/tests/tools/bg-collect.test.ts +337 -0
  351. package/plugins/bizar/tests/tools/bg-get-comments.test.ts +485 -0
  352. package/plugins/bizar/tests/tools/bg-kill.test.ts +235 -0
  353. package/plugins/bizar/tests/tools/bg-spawn-delegation.test.ts +147 -0
  354. package/plugins/bizar/tests/tools/bg-spawn.test.ts +311 -0
  355. package/plugins/bizar/tests/tools/bg-status.test.ts +217 -0
  356. package/plugins/bizar/tests/tools/opencode-runner.test.ts +115 -0
  357. package/plugins/bizar/tests/tools/plan-action.test.ts +599 -0
  358. package/plugins/bizar/tests/tools/read-glyph-feedback.test.ts +253 -0
  359. package/plugins/bizar/tests/tools/wait-for-feedback.test.ts +390 -0
  360. package/plugins/bizar/tests/update-deadlock.test.ts +145 -0
  361. package/plugins/bizar/tsconfig.json +29 -0
@@ -0,0 +1,1960 @@
1
+ /* ─────────────────────────────────────────────────────────────────────
2
+ Bizar Dashboard — Mobile styles (v3.5.0)
3
+ Phone-first: 320px-768px wide. Bottom nav. Sticky composer.
4
+ ───────────────────────────────────────────────────────────────────── */
5
+
6
+ /* v3.21.x — Mobile chat stylesheet must be imported BEFORE all other
7
+ rules (CSS @import ordering rule). */
8
+ @import './mobile-chat.css';
9
+
10
+ /* ─── Theme tokens (mirror main.css) ─────────────────────────────── */
11
+ :root {
12
+ /* Surfaces */
13
+ --bg: #0b0e14;
14
+ --bg-elev: #12161f;
15
+ --bg-elev-2: #1a1f2b;
16
+ --bg-elev-3: #232a39;
17
+ --surface: var(--bg-elev);
18
+ --surface-2: var(--bg-elev-2);
19
+
20
+ /* Borders */
21
+ --border: #232a39;
22
+ --border-strong: #2d3648;
23
+
24
+ /* Text */
25
+ --text: #c9d1d9;
26
+ --text-muted: #6e7681;
27
+ --text-dim: #484f58;
28
+ --text-strong: #f0f6fc;
29
+
30
+ /* Accent (violet) */
31
+ --accent: #8b5cf6;
32
+ --accent-bg: rgba(139, 92, 246, 0.12);
33
+ --accent-border: rgba(139, 92, 246, 0.4);
34
+ --accent-2: #a78bfa;
35
+
36
+ /* Status */
37
+ --success: #3fb950;
38
+ --warning: #d29922;
39
+ --error: #f85149;
40
+ --info: #58a6ff;
41
+
42
+ /* Fonts */
43
+ --font-sans: 'Inter var', 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
44
+ --font-mono: 'JetBrains Mono', 'Fira Code', ui-monospace, monospace;
45
+
46
+ /* Mobile constants */
47
+ --mobile-tap-target: 44px;
48
+ --mobile-nav-height: 56px;
49
+ --mobile-topbar-height: 48px;
50
+ --mobile-padding: 16px;
51
+ --mobile-font-base: 16px;
52
+ }
53
+
54
+ /* ─── Reset ──────────────────────────────────────────────────────────── */
55
+ *,
56
+ *::before,
57
+ *::after {
58
+ box-sizing: border-box;
59
+ -webkit-tap-highlight-color: transparent;
60
+ -webkit-touch-callout: none;
61
+ touch-action: manipulation;
62
+ }
63
+
64
+ html,
65
+ body {
66
+ margin: 0;
67
+ padding: 0;
68
+ height: 100%;
69
+ overflow: hidden;
70
+ }
71
+
72
+ body {
73
+ font-family: var(--font-sans);
74
+ font-size: var(--mobile-font-base);
75
+ line-height: 1.5;
76
+ background: var(--bg);
77
+ color: var(--text);
78
+ -webkit-font-smoothing: antialiased;
79
+ overscroll-behavior: none;
80
+ }
81
+
82
+ button,
83
+ [role="button"],
84
+ a,
85
+ input,
86
+ select,
87
+ textarea {
88
+ touch-action: manipulation;
89
+ }
90
+
91
+ input,
92
+ textarea,
93
+ select {
94
+ user-select: text;
95
+ -webkit-user-select: text;
96
+ font-size: var(--mobile-font-base);
97
+ }
98
+
99
+ a {
100
+ color: var(--accent);
101
+ text-decoration: none;
102
+ }
103
+
104
+ code,
105
+ .mono {
106
+ font-family: var(--font-mono);
107
+ }
108
+
109
+ /* ─── App shell ──────────────────────────────────────────────────────── */
110
+ .mobile-app {
111
+ display: flex;
112
+ flex-direction: column;
113
+ height: 100vh;
114
+ height: 100dvh;
115
+ background: var(--bg);
116
+ color: var(--text);
117
+ font-family: var(--font-sans);
118
+ padding-top: env(safe-area-inset-top, 0);
119
+ padding-bottom: env(safe-area-inset-bottom, 0);
120
+ overscroll-behavior: none;
121
+ }
122
+
123
+ /* ─── Top bar ───────────────────────────────────────────────────────── */
124
+ .mobile-topbar {
125
+ height: var(--mobile-topbar-height);
126
+ flex-shrink: 0;
127
+ display: flex;
128
+ align-items: center;
129
+ justify-content: space-between;
130
+ padding: 0 var(--mobile-padding);
131
+ background: var(--surface);
132
+ border-bottom: 1px solid var(--border);
133
+ position: sticky;
134
+ top: 0;
135
+ z-index: 10;
136
+ }
137
+
138
+ .mobile-topbar-left {
139
+ display: flex;
140
+ align-items: center;
141
+ gap: 8px;
142
+ }
143
+
144
+ .mobile-logo {
145
+ font-size: 20px;
146
+ line-height: 1;
147
+ }
148
+
149
+ .mobile-title {
150
+ font-size: 16px;
151
+ font-weight: 600;
152
+ color: var(--text-strong);
153
+ }
154
+
155
+ .mobile-topbar-right {
156
+ display: flex;
157
+ align-items: center;
158
+ gap: 4px;
159
+ }
160
+
161
+ .mobile-icon-btn {
162
+ width: var(--mobile-tap-target);
163
+ height: var(--mobile-tap-target);
164
+ min-width: var(--mobile-tap-target);
165
+ min-height: var(--mobile-tap-target);
166
+ display: flex;
167
+ align-items: center;
168
+ justify-content: center;
169
+ background: transparent;
170
+ border: none;
171
+ border-radius: 8px;
172
+ color: var(--text-muted);
173
+ cursor: pointer;
174
+ transition: background 120ms ease, color 120ms ease;
175
+ padding: 0;
176
+ }
177
+
178
+ .mobile-icon-btn:hover {
179
+ background: var(--bg-elev-2);
180
+ color: var(--text);
181
+ }
182
+
183
+ .mobile-icon-btn:active {
184
+ background: var(--bg-elev-3);
185
+ }
186
+
187
+ .mobile-icon-btn-danger {
188
+ color: var(--error);
189
+ }
190
+
191
+ /* ─── Content area ───────────────────────────────────────────────────── */
192
+ .mobile-content {
193
+ flex: 1;
194
+ overflow-y: auto;
195
+ overflow-x: hidden;
196
+ -webkit-overflow-scrolling: touch;
197
+ padding: var(--mobile-padding);
198
+ padding-bottom: calc(var(--mobile-nav-height) + var(--mobile-padding) + env(safe-area-inset-bottom, 0));
199
+ }
200
+
201
+ .mobile-view {
202
+ max-width: 100%;
203
+ min-width: 0;
204
+ }
205
+
206
+ .mobile-view-footer {
207
+ padding: 24px 0;
208
+ text-align: center;
209
+ }
210
+
211
+ /* ─── Bottom nav ────────────────────────────────────────────────────── */
212
+ .mobile-bottom-nav {
213
+ position: fixed;
214
+ bottom: 0;
215
+ left: 0;
216
+ right: 0;
217
+ height: calc(var(--mobile-nav-height) + env(safe-area-inset-bottom, 0));
218
+ background: var(--surface);
219
+ border-top: 1px solid var(--border);
220
+ display: flex;
221
+ align-items: stretch;
222
+ padding-bottom: env(safe-area-inset-bottom, 0);
223
+ z-index: 50;
224
+ }
225
+
226
+ .mobile-nav-btn {
227
+ flex: 1;
228
+ display: flex;
229
+ flex-direction: column;
230
+ align-items: center;
231
+ justify-content: center;
232
+ gap: 2px;
233
+ background: transparent;
234
+ border: none;
235
+ color: var(--text-muted);
236
+ cursor: pointer;
237
+ min-height: var(--mobile-tap-target);
238
+ padding: 8px 4px;
239
+ transition: color 120ms ease;
240
+ }
241
+
242
+ .mobile-nav-btn-active {
243
+ color: var(--accent);
244
+ }
245
+
246
+ .mobile-nav-label {
247
+ font-size: 10px;
248
+ font-weight: 500;
249
+ }
250
+
251
+ /* ─── Loading ────────────────────────────────────────────────────────── */
252
+ .mobile-loading {
253
+ display: flex;
254
+ flex-direction: column;
255
+ align-items: center;
256
+ justify-content: center;
257
+ height: 100vh;
258
+ height: 100dvh;
259
+ gap: 12px;
260
+ color: var(--text-muted);
261
+ }
262
+
263
+ /* ─── Stats grid ─────────────────────────────────────────────────────── */
264
+ .mobile-stats {
265
+ display: grid;
266
+ grid-template-columns: 1fr 1fr;
267
+ gap: 12px;
268
+ margin-bottom: 20px;
269
+ }
270
+
271
+ .mobile-stat {
272
+ background: var(--surface);
273
+ border: 1px solid var(--border);
274
+ border-radius: 12px;
275
+ padding: 16px;
276
+ text-align: center;
277
+ }
278
+
279
+ .mobile-stat-value {
280
+ font-size: 28px;
281
+ font-weight: 700;
282
+ color: var(--accent);
283
+ line-height: 1;
284
+ }
285
+
286
+ .mobile-stat-label {
287
+ font-size: 12px;
288
+ color: var(--text-muted);
289
+ margin-top: 4px;
290
+ }
291
+
292
+ /* ─── Sections ───────────────────────────────────────────────────────── */
293
+ .mobile-section {
294
+ margin-bottom: 20px;
295
+ }
296
+
297
+ .mobile-section-title {
298
+ font-size: 12px;
299
+ font-weight: 600;
300
+ color: var(--text-muted);
301
+ text-transform: uppercase;
302
+ letter-spacing: 0.05em;
303
+ margin: 0 0 8px;
304
+ display: flex;
305
+ align-items: center;
306
+ gap: 6px;
307
+ }
308
+
309
+ /* ─── Cards ───────────────────────────────────────────────────────────── */
310
+ .mobile-card {
311
+ background: var(--surface);
312
+ border: 1px solid var(--border);
313
+ border-radius: 12px;
314
+ padding: 14px;
315
+ margin-bottom: 12px;
316
+ }
317
+
318
+ .mobile-card-list {
319
+ display: flex;
320
+ flex-direction: column;
321
+ gap: 6px;
322
+ }
323
+
324
+ /* ─── Agent card ─────────────────────────────────────────────────────── */
325
+ .mobile-agent-card {
326
+ display: flex;
327
+ align-items: center;
328
+ gap: 10px;
329
+ padding: 12px;
330
+ background: var(--surface);
331
+ border: 1px solid var(--border);
332
+ border-radius: 10px;
333
+ }
334
+
335
+ .mobile-agent-dot {
336
+ width: 8px;
337
+ height: 8px;
338
+ border-radius: 50%;
339
+ background: var(--text-dim);
340
+ flex-shrink: 0;
341
+ }
342
+
343
+ .mobile-agent-dot[data-status="working"],
344
+ .mobile-agent-dot[data-status="doing"] {
345
+ background: var(--success);
346
+ animation: pulse-dot 1.6s ease-in-out infinite;
347
+ }
348
+
349
+ .mobile-agent-dot[data-status="error"],
350
+ .mobile-agent-dot[data-status="stuck"] {
351
+ background: var(--error);
352
+ }
353
+
354
+ .mobile-agent-dot[data-status="idle"] {
355
+ background: var(--text-dim);
356
+ }
357
+
358
+ @keyframes pulse-dot {
359
+ 0%, 100% { opacity: 1; }
360
+ 50% { opacity: 0.4; }
361
+ }
362
+
363
+ .mobile-agent-info {
364
+ flex: 1;
365
+ min-width: 0;
366
+ }
367
+
368
+ .mobile-agent-name {
369
+ font-size: 14px;
370
+ font-weight: 500;
371
+ display: -webkit-box;
372
+ -webkit-box-orient: vertical;
373
+ -webkit-line-clamp: 2;
374
+ overflow: hidden;
375
+ white-space: normal;
376
+ overflow-wrap: anywhere;
377
+ }
378
+
379
+ .mobile-agent-meta {
380
+ font-size: 12px;
381
+ color: var(--text-muted);
382
+ display: block;
383
+ overflow-wrap: anywhere;
384
+ }
385
+
386
+ /* ─── Task card ──────────────────────────────────────────────────────── */
387
+ .mobile-task-card {
388
+ width: 100%;
389
+ padding: 12px;
390
+ background: var(--surface);
391
+ border: 1px solid var(--border);
392
+ border-radius: 10px;
393
+ display: flex;
394
+ align-items: center;
395
+ gap: 10px;
396
+ text-align: left;
397
+ }
398
+
399
+ .mobile-task-actions {
400
+ display: flex;
401
+ gap: 2px;
402
+ flex-shrink: 0;
403
+ }
404
+
405
+ .priority-dot {
406
+ width: 8px;
407
+ height: 8px;
408
+ border-radius: 50%;
409
+ flex-shrink: 0;
410
+ }
411
+
412
+ .task-content {
413
+ flex: 1;
414
+ min-width: 0;
415
+ }
416
+
417
+ .task-title {
418
+ font-size: 14px;
419
+ font-weight: 500;
420
+ display: -webkit-box;
421
+ -webkit-box-orient: vertical;
422
+ -webkit-line-clamp: 2;
423
+ overflow: hidden;
424
+ white-space: normal;
425
+ overflow-wrap: anywhere;
426
+ }
427
+
428
+ .task-meta {
429
+ font-size: 12px;
430
+ color: var(--text-muted);
431
+ display: block;
432
+ overflow-wrap: anywhere;
433
+ }
434
+
435
+ /* ─── Tasks toolbar ───────────────────────────────────────────────────── */
436
+ .mobile-tasks-toolbar {
437
+ display: flex;
438
+ flex-wrap: wrap;
439
+ gap: 8px;
440
+ align-items: center;
441
+ margin-bottom: 16px;
442
+ }
443
+
444
+ .mobile-search-input {
445
+ flex: 1;
446
+ height: var(--mobile-tap-target);
447
+ padding: 0 14px;
448
+ background: var(--surface);
449
+ border: 1px solid var(--border);
450
+ border-radius: 22px;
451
+ color: var(--text);
452
+ font-family: inherit;
453
+ font-size: var(--mobile-font-base);
454
+ outline: none;
455
+ }
456
+
457
+ .mobile-search-input:focus {
458
+ border-color: var(--accent);
459
+ }
460
+
461
+ .mobile-empty-inline {
462
+ font-size: 13px;
463
+ color: var(--text-muted);
464
+ padding: 4px 0;
465
+ }
466
+
467
+ .mobile-empty-compact {
468
+ padding: 24px 16px;
469
+ }
470
+
471
+ /* ─── Settings ───────────────────────────────────────────────────────── */
472
+ .mobile-setting-row {
473
+ display: flex;
474
+ justify-content: space-between;
475
+ align-items: center;
476
+ padding: 10px 0;
477
+ border-bottom: 1px solid var(--border);
478
+ }
479
+
480
+ .mobile-setting-row:last-child {
481
+ border-bottom: none;
482
+ }
483
+
484
+ .mobile-setting-label {
485
+ font-size: 14px;
486
+ color: var(--text);
487
+ }
488
+
489
+ .mobile-setting-value {
490
+ font-size: 14px;
491
+ color: var(--text-muted);
492
+ text-align: right;
493
+ }
494
+
495
+ /* ─── More tab list items ────────────────────────────────────────────── */
496
+ .mobile-list-item {
497
+ display: flex;
498
+ align-items: center;
499
+ gap: 12px;
500
+ padding: 12px;
501
+ background: var(--surface);
502
+ border: 1px solid var(--border);
503
+ border-radius: 10px;
504
+ }
505
+
506
+ .mobile-list-icon {
507
+ color: var(--text-muted);
508
+ flex-shrink: 0;
509
+ }
510
+
511
+ .mobile-list-content {
512
+ flex: 1;
513
+ min-width: 0;
514
+ }
515
+
516
+ .mobile-list-title {
517
+ font-size: 14px;
518
+ font-weight: 500;
519
+ display: -webkit-box;
520
+ -webkit-box-orient: vertical;
521
+ -webkit-line-clamp: 2;
522
+ overflow: hidden;
523
+ white-space: normal;
524
+ overflow-wrap: anywhere;
525
+ }
526
+
527
+ .mobile-list-meta {
528
+ font-size: 12px;
529
+ color: var(--text-muted);
530
+ display: block;
531
+ overflow-wrap: anywhere;
532
+ }
533
+
534
+ .mobile-list-badge {
535
+ font-size: 11px;
536
+ padding: 2px 8px;
537
+ border-radius: 12px;
538
+ background: var(--bg-elev-3);
539
+ color: var(--text-muted);
540
+ flex-shrink: 0;
541
+ }
542
+
543
+ .mobile-list-badge[data-status="working"],
544
+ .mobile-list-badge[data-status="doing"] {
545
+ background: rgba(63, 185, 80, 0.15);
546
+ color: var(--success);
547
+ }
548
+
549
+ .mobile-list-badge[data-status="error"],
550
+ .mobile-list-badge[data-status="stuck"] {
551
+ background: rgba(248, 81, 73, 0.15);
552
+ color: var(--error);
553
+ }
554
+
555
+ .badge-on {
556
+ background: rgba(63, 185, 80, 0.15);
557
+ color: var(--success);
558
+ }
559
+
560
+ .badge-off {
561
+ background: var(--bg-elev-3);
562
+ color: var(--text-dim);
563
+ }
564
+
565
+ .mobile-active-badge {
566
+ font-size: 11px;
567
+ padding: 2px 8px;
568
+ border-radius: 12px;
569
+ background: var(--accent-bg);
570
+ color: var(--accent);
571
+ flex-shrink: 0;
572
+ }
573
+
574
+ /* ─── Empty state ────────────────────────────────────────────────────── */
575
+ .mobile-empty {
576
+ text-align: center;
577
+ padding: 48px 20px;
578
+ color: var(--text-muted);
579
+ }
580
+
581
+ .mobile-empty svg {
582
+ margin-bottom: 12px;
583
+ opacity: 0.4;
584
+ }
585
+
586
+ .mobile-empty p {
587
+ margin: 0 0 6px;
588
+ }
589
+
590
+ .muted {
591
+ color: var(--text-muted);
592
+ font-size: 13px;
593
+ }
594
+
595
+ /* ─── Buttons ─────────────────────────────────────────────────────────── */
596
+ .mobile-btn {
597
+ min-height: var(--mobile-tap-target);
598
+ min-width: var(--mobile-tap-target);
599
+ padding: 12px 20px;
600
+ border-radius: 10px;
601
+ font-size: 15px;
602
+ font-weight: 500;
603
+ border: none;
604
+ background: var(--accent);
605
+ color: white;
606
+ cursor: pointer;
607
+ display: inline-flex;
608
+ align-items: center;
609
+ justify-content: center;
610
+ gap: 8px;
611
+ transition: opacity 120ms ease;
612
+ text-decoration: none;
613
+ }
614
+
615
+ .mobile-btn:active {
616
+ opacity: 0.7;
617
+ }
618
+
619
+ .mobile-btn-secondary {
620
+ background: var(--surface);
621
+ border: 1px solid var(--border);
622
+ color: var(--text);
623
+ }
624
+
625
+ .mobile-more-footer {
626
+ padding: 16px 0;
627
+ border-top: 1px solid var(--border);
628
+ margin-top: 8px;
629
+ }
630
+
631
+ .mobile-more-link {
632
+ display: flex;
633
+ align-items: center;
634
+ justify-content: center;
635
+ gap: 4px;
636
+ color: var(--accent);
637
+ font-size: 14px;
638
+ text-decoration: none;
639
+ min-height: var(--mobile-tap-target);
640
+ padding: 12px;
641
+ }
642
+
643
+ /* ─── Dark mode ───────────────────────────────────────────────────────── */
644
+ [data-theme="dark"] .mobile-app {
645
+ background: #0d1117;
646
+ }
647
+
648
+ /* ─── Light mode ──────────────────────────────────────────────────────── */
649
+ [data-theme="light"] {
650
+ --bg: #ffffff;
651
+ --bg-elev: #f6f8fa;
652
+ --bg-elev-2: #eaeef2;
653
+ --bg-elev-3: #d0d7de;
654
+ --surface: var(--bg-elev);
655
+ --surface-2: var(--bg-elev-2);
656
+ --border: #d0d7de;
657
+ --border-strong: #afb8c1;
658
+ --text: #1f2328;
659
+ --text-muted: #656d76;
660
+ --text-dim: #8c959f;
661
+ --text-strong: #1f2328;
662
+
663
+ /* v3.5.6 — Accent override. The :root block sets --accent: #8b5cf6
664
+ (a dark-mode violet) which looks harsh on a white background.
665
+ Match the desktop main.css light-mode value (#7c3aed) so the
666
+ mobile dashboard stays visually consistent with desktop. Without
667
+ this override, mobile light mode shows a too-bright purple accent
668
+ everywhere --accent is used (links, buttons, focus rings, etc.). */
669
+ --accent: #7c3aed;
670
+ --accent-2: #6d28d9;
671
+ --accent-bg: rgba(124, 58, 237, 0.08);
672
+ --accent-border: rgba(124, 58, 237, 0.3);
673
+ }
674
+
675
+ /* ═══════════════════════════════════════════════════════════════════════
676
+ NEW MOBILE STYLES (v3.6 — comprehensive mobile parity)
677
+ ═══════════════════════════════════════════════════════════════════════ */
678
+
679
+ /* ─── Bottom sheet ─────────────────────────────────────────────────── */
680
+ .mobile-sheet-overlay {
681
+ position: fixed;
682
+ inset: 0;
683
+ background: rgba(0, 0, 0, 0.6);
684
+ z-index: 100;
685
+ display: flex;
686
+ align-items: flex-end;
687
+ animation: sheet-fade-in 150ms ease;
688
+ }
689
+
690
+ @keyframes sheet-fade-in {
691
+ from { opacity: 0; }
692
+ to { opacity: 1; }
693
+ }
694
+
695
+ .mobile-sheet {
696
+ width: 100%;
697
+ background: var(--surface);
698
+ border-radius: 16px 16px 0 0;
699
+ max-height: 85vh;
700
+ overflow-y: auto;
701
+ overflow-x: hidden;
702
+ animation: sheet-slide-up 200ms cubic-bezier(0.32, 0.72, 0, 1);
703
+ display: flex;
704
+ flex-direction: column;
705
+ }
706
+
707
+ @keyframes sheet-slide-up {
708
+ from { transform: translateY(100%); }
709
+ to { transform: translateY(0); }
710
+ }
711
+
712
+ .mobile-sheet-handle {
713
+ width: 36px;
714
+ height: 4px;
715
+ background: var(--border-strong);
716
+ border-radius: 2px;
717
+ margin: 10px auto 0;
718
+ flex-shrink: 0;
719
+ }
720
+
721
+ .mobile-sheet-header {
722
+ display: flex;
723
+ align-items: center;
724
+ justify-content: space-between;
725
+ padding: 12px 16px 8px;
726
+ border-bottom: 1px solid var(--border);
727
+ flex-shrink: 0;
728
+ }
729
+
730
+ .mobile-sheet-title {
731
+ font-size: 16px;
732
+ font-weight: 600;
733
+ color: var(--text-strong);
734
+ margin: 0;
735
+ }
736
+
737
+ .mobile-sheet-content {
738
+ flex: 1;
739
+ overflow-y: auto;
740
+ padding: 12px 16px;
741
+ }
742
+
743
+ .mobile-sheet-actions {
744
+ padding: 12px 16px;
745
+ border-top: 1px solid var(--border);
746
+ flex-shrink: 0;
747
+ display: flex;
748
+ gap: 8px;
749
+ }
750
+
751
+ /* ─── Full-screen modal ────────────────────────────────────────────── */
752
+ .mobile-modal-overlay {
753
+ position: fixed;
754
+ inset: 0;
755
+ background: var(--bg);
756
+ z-index: 200;
757
+ display: flex;
758
+ flex-direction: column;
759
+ animation: modal-fade-in 150ms ease;
760
+ }
761
+
762
+ @keyframes modal-fade-in {
763
+ from { opacity: 0; }
764
+ to { opacity: 1; }
765
+ }
766
+
767
+ .mobile-modal {
768
+ flex: 1;
769
+ display: flex;
770
+ flex-direction: column;
771
+ overflow: hidden;
772
+ }
773
+
774
+ .mobile-modal-header {
775
+ display: flex;
776
+ align-items: center;
777
+ justify-content: space-between;
778
+ padding: 12px 16px;
779
+ border-bottom: 1px solid var(--border);
780
+ flex-shrink: 0;
781
+ }
782
+
783
+ .mobile-modal-title {
784
+ font-size: 18px;
785
+ font-weight: 600;
786
+ color: var(--text-strong);
787
+ margin: 0;
788
+ }
789
+
790
+ .mobile-modal-content {
791
+ flex: 1;
792
+ overflow-y: auto;
793
+ padding: 16px;
794
+ }
795
+
796
+ .mobile-modal-actions {
797
+ padding: 12px 16px;
798
+ border-top: 1px solid var(--border);
799
+ flex-shrink: 0;
800
+ display: flex;
801
+ gap: 8px;
802
+ }
803
+
804
+ /* ─── Search modal ─────────────────────────────────────────────────── */
805
+ .mobile-search-container {
806
+ display: flex;
807
+ flex-direction: column;
808
+ gap: 12px;
809
+ height: 100%;
810
+ }
811
+
812
+ .mobile-search-input-row {
813
+ display: flex;
814
+ align-items: center;
815
+ gap: 8px;
816
+ background: var(--surface);
817
+ border: 1px solid var(--border);
818
+ border-radius: 12px;
819
+ padding: 0 14px;
820
+ height: var(--mobile-tap-target);
821
+ }
822
+
823
+ .mobile-search-field {
824
+ flex: 1;
825
+ background: transparent;
826
+ border: none;
827
+ outline: none;
828
+ color: var(--text);
829
+ font-family: inherit;
830
+ font-size: var(--mobile-font-base);
831
+ }
832
+
833
+ .mobile-search-scopes {
834
+ display: flex;
835
+ gap: 6px;
836
+ flex-wrap: wrap;
837
+ }
838
+
839
+ .mobile-scope-chip {
840
+ min-height: var(--mobile-tap-target);
841
+ padding: 10px 14px;
842
+ border-radius: 16px;
843
+ font-size: 13px;
844
+ font-weight: 500;
845
+ background: var(--surface);
846
+ border: 1px solid var(--border);
847
+ color: var(--text-muted);
848
+ cursor: pointer;
849
+ transition: all 120ms ease;
850
+ }
851
+
852
+ .mobile-scope-chip.active {
853
+ background: var(--accent-bg);
854
+ border-color: var(--accent-border);
855
+ color: var(--accent);
856
+ }
857
+
858
+ .mobile-search-results {
859
+ flex: 1;
860
+ overflow-y: auto;
861
+ }
862
+
863
+ .mobile-search-group {
864
+ margin-bottom: 16px;
865
+ }
866
+
867
+ .mobile-search-group-title {
868
+ font-size: 11px;
869
+ font-weight: 600;
870
+ color: var(--text-muted);
871
+ text-transform: uppercase;
872
+ letter-spacing: 0.05em;
873
+ margin: 0 0 6px;
874
+ display: flex;
875
+ align-items: center;
876
+ gap: 4px;
877
+ }
878
+
879
+ .mobile-search-result-item {
880
+ padding: 10px 12px;
881
+ background: var(--surface);
882
+ border: 1px solid var(--border);
883
+ border-radius: 8px;
884
+ margin-bottom: 4px;
885
+ cursor: pointer;
886
+ }
887
+
888
+ .mobile-search-result-title {
889
+ font-size: 14px;
890
+ font-weight: 500;
891
+ display: block;
892
+ overflow-wrap: anywhere;
893
+ }
894
+
895
+ .mobile-search-result-meta {
896
+ font-size: 12px;
897
+ color: var(--text-muted);
898
+ display: block;
899
+ overflow-wrap: anywhere;
900
+ }
901
+
902
+ .mobile-search-loading {
903
+ text-align: center;
904
+ padding: 20px;
905
+ color: var(--text-muted);
906
+ font-size: 14px;
907
+ }
908
+
909
+ /* ─── Notifications ────────────────────────────────────────────────── */
910
+ .mobile-notif-btn {
911
+ position: relative;
912
+ }
913
+
914
+ .mobile-notif-badge {
915
+ position: absolute;
916
+ top: 4px;
917
+ right: 4px;
918
+ min-width: 16px;
919
+ height: 16px;
920
+ background: var(--error);
921
+ color: white;
922
+ font-size: 10px;
923
+ font-weight: 700;
924
+ border-radius: 8px;
925
+ display: flex;
926
+ align-items: center;
927
+ justify-content: center;
928
+ padding: 0 4px;
929
+ }
930
+
931
+ .mobile-notif-list {
932
+ display: flex;
933
+ flex-direction: column;
934
+ gap: 4px;
935
+ }
936
+
937
+ .mobile-notif-item {
938
+ width: 100%;
939
+ min-height: var(--mobile-tap-target);
940
+ display: flex;
941
+ align-items: flex-start;
942
+ gap: 12px;
943
+ padding: 12px;
944
+ background: var(--surface);
945
+ border: 1px solid var(--border);
946
+ border-radius: 10px;
947
+ cursor: pointer;
948
+ position: relative;
949
+ }
950
+
951
+ .mobile-notif-item.unread {
952
+ border-color: var(--accent-border);
953
+ }
954
+
955
+ .mobile-notif-icon {
956
+ width: 28px;
957
+ height: 28px;
958
+ border-radius: 50%;
959
+ display: flex;
960
+ align-items: center;
961
+ justify-content: center;
962
+ font-size: 14px;
963
+ flex-shrink: 0;
964
+ }
965
+
966
+ .mobile-notif-icon.severity-success { background: rgba(63, 185, 80, 0.15); color: var(--success); }
967
+ .mobile-notif-icon.severity-error { background: rgba(248, 81, 73, 0.15); color: var(--error); }
968
+ .mobile-notif-icon.severity-warning { background: rgba(210, 153, 34, 0.15); color: var(--warning); }
969
+ .mobile-notif-icon.severity-info { background: rgba(88, 166, 255, 0.15); color: var(--info); }
970
+
971
+ .mobile-notif-body {
972
+ flex: 1;
973
+ min-width: 0;
974
+ }
975
+
976
+ .mobile-notif-title {
977
+ font-size: 14px;
978
+ font-weight: 500;
979
+ display: block;
980
+ overflow-wrap: anywhere;
981
+ }
982
+
983
+ .mobile-notif-text {
984
+ font-size: 13px;
985
+ color: var(--text-muted);
986
+ display: block;
987
+ margin-top: 2px;
988
+ }
989
+
990
+ .mobile-notif-time {
991
+ font-size: 11px;
992
+ color: var(--text-dim);
993
+ display: block;
994
+ margin-top: 4px;
995
+ }
996
+
997
+ .mobile-notif-dot {
998
+ width: 8px;
999
+ height: 8px;
1000
+ border-radius: 50%;
1001
+ background: var(--accent);
1002
+ flex-shrink: 0;
1003
+ margin-top: 6px;
1004
+ }
1005
+
1006
+ /* ─── Project selector ─────────────────────────────────────────────── */
1007
+ .mobile-project-btn {
1008
+ display: flex;
1009
+ align-items: center;
1010
+ gap: 4px;
1011
+ background: transparent;
1012
+ border: none;
1013
+ color: var(--text-muted);
1014
+ cursor: pointer;
1015
+ min-height: var(--mobile-tap-target);
1016
+ min-width: var(--mobile-tap-target);
1017
+ padding: 10px 8px;
1018
+ border-radius: 6px;
1019
+ font-size: 14px;
1020
+ font-family: inherit;
1021
+ }
1022
+
1023
+ .mobile-project-btn:hover {
1024
+ background: var(--bg-elev-2);
1025
+ color: var(--text);
1026
+ }
1027
+
1028
+ .mobile-project-name {
1029
+ max-width: 120px;
1030
+ display: -webkit-box;
1031
+ -webkit-box-orient: vertical;
1032
+ -webkit-line-clamp: 2;
1033
+ overflow: hidden;
1034
+ white-space: normal;
1035
+ }
1036
+
1037
+ .mobile-project-list {
1038
+ display: flex;
1039
+ flex-direction: column;
1040
+ gap: 6px;
1041
+ }
1042
+
1043
+ .mobile-project-item {
1044
+ display: flex;
1045
+ align-items: center;
1046
+ gap: 12px;
1047
+ padding: 12px;
1048
+ background: var(--surface);
1049
+ border: 1px solid var(--border);
1050
+ border-radius: 10px;
1051
+ cursor: pointer;
1052
+ }
1053
+
1054
+ .mobile-project-item.active {
1055
+ border-color: var(--accent-border);
1056
+ }
1057
+
1058
+ .mobile-project-status {
1059
+ width: 8px;
1060
+ height: 8px;
1061
+ border-radius: 50%;
1062
+ background: var(--text-dim);
1063
+ flex-shrink: 0;
1064
+ }
1065
+
1066
+ .mobile-project-status[data-status="active"] { background: var(--success); }
1067
+ .mobile-project-status[data-status="error"] { background: var(--error); }
1068
+
1069
+ .mobile-project-info {
1070
+ flex: 1;
1071
+ min-width: 0;
1072
+ }
1073
+
1074
+ .mobile-project-item-name {
1075
+ font-size: 14px;
1076
+ font-weight: 500;
1077
+ display: block;
1078
+ }
1079
+
1080
+ .mobile-project-item-path {
1081
+ font-size: 11px;
1082
+ color: var(--text-muted);
1083
+ display: block;
1084
+ overflow-wrap: anywhere;
1085
+ font-family: var(--font-mono);
1086
+ }
1087
+
1088
+ /* ─── Back button ─────────────────────────────────────────────────── */
1089
+ .mobile-back-btn {
1090
+ position: fixed;
1091
+ top: calc(var(--mobile-topbar-height) + 8px);
1092
+ left: 12px;
1093
+ z-index: 60;
1094
+ background: var(--surface);
1095
+ border: 1px solid var(--border);
1096
+ color: var(--text);
1097
+ font-size: 13px;
1098
+ font-weight: 500;
1099
+ min-height: var(--mobile-tap-target);
1100
+ padding: 10px 14px;
1101
+ border-radius: 20px;
1102
+ cursor: pointer;
1103
+ display: flex;
1104
+ align-items: center;
1105
+ gap: 4px;
1106
+ box-shadow: 0 2px 8px rgba(0,0,0,0.3);
1107
+ }
1108
+
1109
+ /* ─── Kanban tabs ─────────────────────────────────────────────────── */
1110
+ .mobile-kanban-tabs {
1111
+ display: flex;
1112
+ gap: 4px;
1113
+ margin-bottom: 12px;
1114
+ overflow-x: auto;
1115
+ -webkit-overflow-scrolling: touch;
1116
+ }
1117
+
1118
+ .mobile-kanban-tab {
1119
+ min-height: var(--mobile-tap-target);
1120
+ padding: 10px 14px;
1121
+ border-radius: 20px;
1122
+ font-size: 13px;
1123
+ font-weight: 500;
1124
+ background: var(--surface);
1125
+ border: 1px solid var(--border);
1126
+ color: var(--text-muted);
1127
+ cursor: pointer;
1128
+ white-space: nowrap;
1129
+ transition: all 120ms ease;
1130
+ flex-shrink: 0;
1131
+ }
1132
+
1133
+ .mobile-kanban-tab.active {
1134
+ background: var(--accent-bg);
1135
+ border-color: var(--accent-border);
1136
+ color: var(--accent);
1137
+ }
1138
+
1139
+ .mobile-tasks-filters {
1140
+ display: flex;
1141
+ flex-wrap: wrap;
1142
+ gap: 8px;
1143
+ margin-bottom: 12px;
1144
+ }
1145
+
1146
+ .mobile-filter-select {
1147
+ min-height: var(--mobile-tap-target);
1148
+ padding: 0 10px;
1149
+ background: var(--surface);
1150
+ border: 1px solid var(--border);
1151
+ border-radius: 18px;
1152
+ color: var(--text);
1153
+ font-family: inherit;
1154
+ font-size: 13px;
1155
+ cursor: pointer;
1156
+ }
1157
+
1158
+ /* ─── FAB ─────────────────────────────────────────────────────────── */
1159
+ .mobile-fab {
1160
+ position: fixed;
1161
+ bottom: calc(var(--mobile-nav-height) + 80px + env(safe-area-inset-bottom, 0));
1162
+ right: 20px;
1163
+ width: 56px;
1164
+ height: 56px;
1165
+ border-radius: 50%;
1166
+ background: var(--accent);
1167
+ color: white;
1168
+ border: none;
1169
+ cursor: pointer;
1170
+ display: flex;
1171
+ align-items: center;
1172
+ justify-content: center;
1173
+ box-shadow: 0 4px 16px rgba(139, 92, 246, 0.4);
1174
+ z-index: 30;
1175
+ transition: transform 120ms ease, box-shadow 120ms ease;
1176
+ }
1177
+
1178
+ .mobile-fab:active {
1179
+ transform: scale(0.94);
1180
+ box-shadow: 0 2px 8px rgba(139, 92, 246, 0.3);
1181
+ }
1182
+
1183
+ /* ─── Task detail ────────────────────────────────────────────────── */
1184
+ .mobile-task-detail-actions {
1185
+ display: flex;
1186
+ gap: 8px;
1187
+ flex-wrap: wrap;
1188
+ }
1189
+
1190
+ .mobile-task-detail {
1191
+ display: flex;
1192
+ flex-direction: column;
1193
+ gap: 12px;
1194
+ }
1195
+
1196
+ .mobile-task-detail-header {
1197
+ display: flex;
1198
+ align-items: center;
1199
+ gap: 8px;
1200
+ }
1201
+
1202
+ .mobile-task-status-badge {
1203
+ font-size: 11px;
1204
+ font-weight: 600;
1205
+ padding: 3px 10px;
1206
+ border-radius: 12px;
1207
+ text-transform: capitalize;
1208
+ }
1209
+
1210
+ .mobile-task-status-badge.status-queued { background: rgba(88, 166, 255, 0.15); color: var(--info); }
1211
+ .mobile-task-status-badge.status-doing { background: rgba(63, 185, 80, 0.15); color: var(--success); }
1212
+ .mobile-task-status-badge.status-blocked { background: rgba(248, 81, 73, 0.15); color: var(--error); }
1213
+ .mobile-task-status-badge.status-done { background: rgba(63, 185, 80, 0.15); color: var(--success); }
1214
+
1215
+ .mobile-task-priority {
1216
+ font-size: 11px;
1217
+ font-weight: 600;
1218
+ padding: 3px 10px;
1219
+ border-radius: 12px;
1220
+ text-transform: capitalize;
1221
+ }
1222
+
1223
+ .mobile-task-priority.priority-high { background: rgba(248, 81, 73, 0.15); color: var(--error); }
1224
+ .mobile-task-priority.priority-normal { background: rgba(88, 166, 255, 0.15); color: var(--info); }
1225
+ .mobile-task-priority.priority-low { background: var(--bg-elev-3); color: var(--text-dim); }
1226
+
1227
+ .mobile-task-detail-title {
1228
+ font-size: 18px;
1229
+ font-weight: 600;
1230
+ color: var(--text-strong);
1231
+ margin: 0;
1232
+ }
1233
+
1234
+ .mobile-task-detail-desc {
1235
+ font-size: 14px;
1236
+ color: var(--text-muted);
1237
+ line-height: 1.5;
1238
+ margin: 0;
1239
+ overflow-wrap: anywhere;
1240
+ }
1241
+
1242
+ .mobile-task-detail-meta {
1243
+ display: flex;
1244
+ flex-direction: column;
1245
+ gap: 0;
1246
+ }
1247
+
1248
+ .mobile-task-detail-row {
1249
+ display: flex;
1250
+ justify-content: space-between;
1251
+ align-items: center;
1252
+ padding: 8px 0;
1253
+ border-bottom: 1px solid var(--border);
1254
+ font-size: 13px;
1255
+ }
1256
+
1257
+ .mobile-task-detail-row:last-child {
1258
+ border-bottom: none;
1259
+ }
1260
+
1261
+ .mobile-task-detail-row span:first-child {
1262
+ color: var(--text-muted);
1263
+ }
1264
+
1265
+ .mobile-task-detail-row span:last-child {
1266
+ color: var(--text);
1267
+ font-weight: 500;
1268
+ }
1269
+
1270
+ /* ─── Task form ───────────────────────────────────────────────────── */
1271
+ .mobile-task-form {
1272
+ display: flex;
1273
+ flex-direction: column;
1274
+ gap: 12px;
1275
+ }
1276
+
1277
+ .mobile-field-label {
1278
+ font-size: 12px;
1279
+ font-weight: 600;
1280
+ color: var(--text-muted);
1281
+ text-transform: uppercase;
1282
+ letter-spacing: 0.04em;
1283
+ margin-bottom: 4px;
1284
+ display: block;
1285
+ }
1286
+
1287
+ .mobile-input {
1288
+ width: 100%;
1289
+ min-height: var(--mobile-tap-target);
1290
+ padding: 10px 14px;
1291
+ background: var(--surface);
1292
+ border: 1px solid var(--border);
1293
+ border-radius: 10px;
1294
+ color: var(--text);
1295
+ font-family: inherit;
1296
+ font-size: var(--mobile-font-base);
1297
+ outline: none;
1298
+ transition: border-color 120ms ease;
1299
+ }
1300
+
1301
+ .mobile-input:focus {
1302
+ border-color: var(--accent);
1303
+ }
1304
+
1305
+ .mobile-input-sm {
1306
+ min-height: var(--mobile-tap-target);
1307
+ padding: 8px 12px;
1308
+ }
1309
+
1310
+ /* ─── Agent detail ────────────────────────────────────────────────── */
1311
+ .mobile-agent-detail {
1312
+ display: flex;
1313
+ flex-direction: column;
1314
+ gap: 12px;
1315
+ }
1316
+
1317
+ .mobile-agent-detail-status {
1318
+ display: flex;
1319
+ align-items: center;
1320
+ gap: 8px;
1321
+ }
1322
+
1323
+ .mobile-agent-detail-status-text {
1324
+ font-size: 14px;
1325
+ font-weight: 500;
1326
+ text-transform: capitalize;
1327
+ }
1328
+
1329
+ .mobile-agent-detail-desc {
1330
+ font-size: 14px;
1331
+ color: var(--text-muted);
1332
+ line-height: 1.5;
1333
+ margin: 0;
1334
+ overflow-wrap: anywhere;
1335
+ }
1336
+
1337
+ /* ─── Canvas ──────────────────────────────────────────────────────── */
1338
+ .mobile-view-canvas {
1339
+ padding-bottom: 80px;
1340
+ }
1341
+
1342
+ .mobile-canvas-bar {
1343
+ display: flex;
1344
+ align-items: center;
1345
+ justify-content: space-between;
1346
+ padding: 0 0 12px;
1347
+ border-bottom: 1px solid var(--border);
1348
+ margin-bottom: 12px;
1349
+ }
1350
+
1351
+ .mobile-canvas-meta {
1352
+ display: flex;
1353
+ flex-direction: column;
1354
+ gap: 2px;
1355
+ }
1356
+
1357
+ .mobile-canvas-title {
1358
+ font-size: 16px;
1359
+ font-weight: 600;
1360
+ color: var(--text-strong);
1361
+ }
1362
+
1363
+ .mobile-canvas-status {
1364
+ font-size: 11px;
1365
+ font-weight: 600;
1366
+ padding: 2px 8px;
1367
+ border-radius: 10px;
1368
+ text-transform: capitalize;
1369
+ }
1370
+
1371
+ .mobile-canvas-status[data-status="approved"],
1372
+ .mobile-canvas-status[data-status="done"] {
1373
+ background: rgba(63, 185, 80, 0.15);
1374
+ color: var(--success);
1375
+ }
1376
+
1377
+ .mobile-canvas-status[data-status="in-progress"],
1378
+ .mobile-canvas-status[data-status="doing"] {
1379
+ background: rgba(88, 166, 255, 0.15);
1380
+ color: var(--info);
1381
+ }
1382
+
1383
+ .mobile-canvas-status[data-status="draft"] {
1384
+ background: var(--bg-elev-3);
1385
+ color: var(--text-dim);
1386
+ }
1387
+
1388
+ .mobile-canvas-actions {
1389
+ display: flex;
1390
+ align-items: center;
1391
+ gap: 4px;
1392
+ }
1393
+
1394
+ .mobile-canvas-comment-count {
1395
+ position: absolute;
1396
+ top: 2px;
1397
+ right: 2px;
1398
+ background: var(--accent);
1399
+ color: white;
1400
+ font-size: 9px;
1401
+ font-weight: 700;
1402
+ border-radius: 6px;
1403
+ padding: 1px 4px;
1404
+ min-width: 14px;
1405
+ text-align: center;
1406
+ }
1407
+
1408
+ .mobile-canvas-elements {
1409
+ display: flex;
1410
+ flex-direction: column;
1411
+ gap: 10px;
1412
+ }
1413
+
1414
+ .mobile-canvas-element {
1415
+ background: var(--surface);
1416
+ border: 2px solid var(--border);
1417
+ border-radius: 12px;
1418
+ overflow: hidden;
1419
+ cursor: pointer;
1420
+ }
1421
+
1422
+ .mobile-canvas-element.selected {
1423
+ box-shadow: 0 0 0 2px var(--accent);
1424
+ }
1425
+
1426
+ .mobile-canvas-el-header {
1427
+ display: flex;
1428
+ align-items: center;
1429
+ gap: 6px;
1430
+ padding: 8px 12px;
1431
+ }
1432
+
1433
+ .mobile-canvas-el-type {
1434
+ font-size: 11px;
1435
+ font-weight: 600;
1436
+ text-transform: uppercase;
1437
+ }
1438
+
1439
+ .mobile-canvas-el-status {
1440
+ font-size: 10px;
1441
+ padding: 1px 6px;
1442
+ border-radius: 8px;
1443
+ background: var(--bg-elev-3);
1444
+ color: var(--text-muted);
1445
+ margin-left: auto;
1446
+ }
1447
+
1448
+ .mobile-canvas-el-title {
1449
+ font-size: 14px;
1450
+ font-weight: 600;
1451
+ padding: 8px 12px;
1452
+ color: var(--text-strong);
1453
+ }
1454
+
1455
+ .mobile-canvas-el-content {
1456
+ font-size: 13px;
1457
+ color: var(--text-muted);
1458
+ padding: 0 12px 8px;
1459
+ line-height: 1.4;
1460
+ }
1461
+
1462
+ .mobile-canvas-el-comments {
1463
+ display: flex;
1464
+ align-items: center;
1465
+ gap: 4px;
1466
+ padding: 6px 12px;
1467
+ border-top: 1px solid var(--border);
1468
+ font-size: 11px;
1469
+ color: var(--text-dim);
1470
+ }
1471
+
1472
+ .mobile-canvas-comments {
1473
+ margin-top: 16px;
1474
+ background: var(--surface);
1475
+ border: 1px solid var(--border);
1476
+ border-radius: 12px;
1477
+ overflow: hidden;
1478
+ }
1479
+
1480
+ .mobile-canvas-comments-header {
1481
+ display: flex;
1482
+ align-items: center;
1483
+ justify-content: space-between;
1484
+ padding: 12px;
1485
+ border-bottom: 1px solid var(--border);
1486
+ }
1487
+
1488
+ .mobile-canvas-comments-header h4 {
1489
+ margin: 0;
1490
+ font-size: 14px;
1491
+ font-weight: 600;
1492
+ }
1493
+
1494
+ .mobile-canvas-comment-list {
1495
+ max-height: 300px;
1496
+ overflow-y: auto;
1497
+ padding: 12px;
1498
+ }
1499
+
1500
+ .mobile-canvas-comment {
1501
+ margin-bottom: 12px;
1502
+ }
1503
+
1504
+ .mobile-canvas-comment-head {
1505
+ display: flex;
1506
+ align-items: center;
1507
+ gap: 8px;
1508
+ margin-bottom: 4px;
1509
+ }
1510
+
1511
+ .mobile-canvas-comment-head .mono {
1512
+ font-size: 11px;
1513
+ font-weight: 600;
1514
+ }
1515
+
1516
+ .mobile-canvas-comment-head .muted {
1517
+ font-size: 11px;
1518
+ color: var(--text-dim);
1519
+ margin-left: auto;
1520
+ }
1521
+
1522
+ .mobile-canvas-comment-text {
1523
+ font-size: 13px;
1524
+ color: var(--text-muted);
1525
+ line-height: 1.4;
1526
+ }
1527
+
1528
+ .mobile-canvas-comment-input {
1529
+ display: flex;
1530
+ gap: 8px;
1531
+ padding: 12px;
1532
+ border-top: 1px solid var(--border);
1533
+ }
1534
+
1535
+ .mobile-canvas-comment-input .mobile-input {
1536
+ flex: 1;
1537
+ }
1538
+
1539
+ /* ─── Activity enhancements ─────────────────────────────────────────── */
1540
+ .mobile-activity-header {
1541
+ display: flex;
1542
+ align-items: center;
1543
+ justify-content: space-between;
1544
+ margin-bottom: 8px;
1545
+ }
1546
+
1547
+ .mobile-event-item {
1548
+ display: flex;
1549
+ align-items: flex-start;
1550
+ gap: 10px;
1551
+ padding: 10px 12px;
1552
+ background: var(--surface);
1553
+ border: 1px solid var(--border);
1554
+ border-radius: 10px;
1555
+ margin-bottom: 4px;
1556
+ cursor: pointer;
1557
+ }
1558
+
1559
+ .mobile-event-kind {
1560
+ font-size: 10px;
1561
+ font-weight: 700;
1562
+ padding: 2px 8px;
1563
+ border-radius: 8px;
1564
+ background: var(--bg-elev-3);
1565
+ color: var(--text-muted);
1566
+ text-transform: uppercase;
1567
+ flex-shrink: 0;
1568
+ }
1569
+
1570
+ .mobile-event-msg {
1571
+ flex: 1;
1572
+ font-size: 13px;
1573
+ color: var(--text);
1574
+ overflow-wrap: anywhere;
1575
+ }
1576
+
1577
+ .mobile-event-time {
1578
+ font-size: 11px;
1579
+ color: var(--text-dim);
1580
+ flex-shrink: 0;
1581
+ }
1582
+
1583
+ /* ─── Submit hero ─────────────────────────────────────────────────── */
1584
+ .mobile-submit-hero {
1585
+ background: linear-gradient(135deg, var(--accent-bg) 0%, var(--bg-elev) 100%);
1586
+ border: 1px solid var(--accent-border);
1587
+ border-radius: 16px;
1588
+ padding: 16px;
1589
+ margin-bottom: 16px;
1590
+ }
1591
+
1592
+ .mobile-submit-input {
1593
+ width: 100%;
1594
+ background: var(--surface);
1595
+ border: 1px solid var(--border);
1596
+ border-radius: 12px;
1597
+ padding: 12px;
1598
+ color: var(--text);
1599
+ font-family: inherit;
1600
+ font-size: var(--mobile-font-base);
1601
+ resize: none;
1602
+ outline: none;
1603
+ margin-bottom: 12px;
1604
+ }
1605
+
1606
+ .mobile-submit-input:focus {
1607
+ border-color: var(--accent);
1608
+ }
1609
+
1610
+ .mobile-submit-actions {
1611
+ display: flex;
1612
+ flex-direction: column;
1613
+ gap: 10px;
1614
+ }
1615
+
1616
+ .mobile-submit-chips {
1617
+ display: flex;
1618
+ gap: 6px;
1619
+ flex-wrap: wrap;
1620
+ }
1621
+
1622
+ .mobile-submit-chip {
1623
+ min-height: var(--mobile-tap-target);
1624
+ padding: 10px 12px;
1625
+ border-radius: 16px;
1626
+ font-size: 12px;
1627
+ font-weight: 500;
1628
+ background: var(--surface);
1629
+ border: 1px solid var(--border);
1630
+ color: var(--text-muted);
1631
+ cursor: pointer;
1632
+ transition: all 120ms ease;
1633
+ }
1634
+
1635
+ .mobile-submit-chip:hover {
1636
+ border-color: var(--accent-border);
1637
+ color: var(--accent);
1638
+ }
1639
+
1640
+ /* ─── More nav ────────────────────────────────────────────────────── */
1641
+ .mobile-more-nav-item {
1642
+ display: flex;
1643
+ align-items: center;
1644
+ gap: 14px;
1645
+ padding: 14px 12px;
1646
+ background: var(--surface);
1647
+ border: 1px solid var(--border);
1648
+ border-radius: 12px;
1649
+ margin-bottom: 6px;
1650
+ cursor: pointer;
1651
+ transition: all 120ms ease;
1652
+ }
1653
+
1654
+ .mobile-more-nav-item:hover {
1655
+ border-color: var(--accent-border);
1656
+ background: var(--bg-elev-2);
1657
+ }
1658
+
1659
+ .mobile-more-nav-icon {
1660
+ width: 40px;
1661
+ height: 40px;
1662
+ border-radius: 10px;
1663
+ background: var(--bg-elev-2);
1664
+ color: var(--accent);
1665
+ display: flex;
1666
+ align-items: center;
1667
+ justify-content: center;
1668
+ flex-shrink: 0;
1669
+ }
1670
+
1671
+ .mobile-more-nav-content {
1672
+ flex: 1;
1673
+ min-width: 0;
1674
+ }
1675
+
1676
+ .mobile-more-nav-label {
1677
+ font-size: 15px;
1678
+ font-weight: 600;
1679
+ color: var(--text-strong);
1680
+ display: flex;
1681
+ align-items: center;
1682
+ gap: 8px;
1683
+ }
1684
+
1685
+ .mobile-more-nav-count {
1686
+ font-size: 11px;
1687
+ font-weight: 600;
1688
+ padding: 1px 7px;
1689
+ border-radius: 10px;
1690
+ background: var(--bg-elev-3);
1691
+ color: var(--text-muted);
1692
+ }
1693
+
1694
+ .mobile-more-nav-desc {
1695
+ font-size: 12px;
1696
+ color: var(--text-muted);
1697
+ display: block;
1698
+ margin-top: 2px;
1699
+ }
1700
+
1701
+ .mobile-more-nav-arrow {
1702
+ color: var(--text-dim);
1703
+ flex-shrink: 0;
1704
+ }
1705
+
1706
+ /* ─── Config ─────────────────────────────────────────────────────── */
1707
+ .mobile-config-list {
1708
+ display: flex;
1709
+ flex-direction: column;
1710
+ gap: 0;
1711
+ }
1712
+
1713
+ .mobile-config-row {
1714
+ display: flex;
1715
+ align-items: flex-start;
1716
+ flex-wrap: wrap;
1717
+ gap: 10px;
1718
+ padding: 10px 0;
1719
+ border-bottom: 1px solid var(--border);
1720
+ }
1721
+
1722
+ .mobile-config-row:last-child {
1723
+ border-bottom: none;
1724
+ }
1725
+
1726
+ .mobile-config-key {
1727
+ flex: 0 0 104px;
1728
+ display: flex;
1729
+ flex-direction: column;
1730
+ gap: 2px;
1731
+ }
1732
+
1733
+ .mobile-config-key .mono {
1734
+ font-size: 12px;
1735
+ font-weight: 500;
1736
+ color: var(--text);
1737
+ word-break: break-all;
1738
+ }
1739
+
1740
+ .mobile-config-type {
1741
+ font-size: 10px;
1742
+ color: var(--text-dim);
1743
+ text-transform: uppercase;
1744
+ }
1745
+
1746
+ .mobile-config-value {
1747
+ flex: 1;
1748
+ min-width: 0;
1749
+ }
1750
+
1751
+ .mobile-config-value .mobile-input {
1752
+ min-height: var(--mobile-tap-target);
1753
+ padding: 6px 10px;
1754
+ font-size: 13px;
1755
+ }
1756
+
1757
+ /* ─── Toggle switch ────────────────────────────────────────────────── */
1758
+ .mobile-toggle {
1759
+ position: relative;
1760
+ display: inline-flex;
1761
+ align-items: center;
1762
+ cursor: pointer;
1763
+ width: 44px;
1764
+ height: 24px;
1765
+ }
1766
+
1767
+ .mobile-toggle input {
1768
+ opacity: 0;
1769
+ width: 0;
1770
+ height: 0;
1771
+ position: absolute;
1772
+ }
1773
+
1774
+ .mobile-toggle-slider {
1775
+ position: absolute;
1776
+ inset: 0;
1777
+ background: var(--bg-elev-3);
1778
+ border-radius: 12px;
1779
+ transition: background 200ms ease;
1780
+ }
1781
+
1782
+ .mobile-toggle-slider::before {
1783
+ content: '';
1784
+ position: absolute;
1785
+ left: 2px;
1786
+ top: 2px;
1787
+ width: 20px;
1788
+ height: 20px;
1789
+ background: white;
1790
+ border-radius: 50%;
1791
+ transition: transform 200ms ease;
1792
+ }
1793
+
1794
+ .mobile-toggle input:checked + .mobile-toggle-slider {
1795
+ background: var(--accent);
1796
+ }
1797
+
1798
+ .mobile-toggle input:checked + .mobile-toggle-slider::before {
1799
+ transform: translateX(20px);
1800
+ }
1801
+
1802
+ /* ─── Theme buttons ────────────────────────────────────────────────── */
1803
+ .mobile-theme-btns {
1804
+ display: flex;
1805
+ gap: 6px;
1806
+ }
1807
+
1808
+ .mobile-theme-btn {
1809
+ display: flex;
1810
+ align-items: center;
1811
+ gap: 4px;
1812
+ min-height: var(--mobile-tap-target);
1813
+ padding: 10px 12px;
1814
+ border-radius: 16px;
1815
+ font-size: 12px;
1816
+ font-weight: 500;
1817
+ background: var(--surface);
1818
+ border: 1px solid var(--border);
1819
+ color: var(--text-muted);
1820
+ cursor: pointer;
1821
+ transition: all 120ms ease;
1822
+ }
1823
+
1824
+ .mobile-theme-btn.active {
1825
+ background: var(--accent-bg);
1826
+ border-color: var(--accent-border);
1827
+ color: var(--accent);
1828
+ }
1829
+
1830
+ /* ─── Accent swatches ─────────────────────────────────────────────── */
1831
+ .mobile-accent-swatches {
1832
+ display: flex;
1833
+ gap: 8px;
1834
+ flex-wrap: wrap;
1835
+ }
1836
+
1837
+ .mobile-accent-swatch {
1838
+ width: var(--mobile-tap-target);
1839
+ height: var(--mobile-tap-target);
1840
+ border-radius: 50%;
1841
+ border: 2px solid transparent;
1842
+ cursor: pointer;
1843
+ transition: transform 120ms ease;
1844
+ }
1845
+
1846
+ .mobile-accent-swatch:hover {
1847
+ transform: scale(1.1);
1848
+ }
1849
+
1850
+ .mobile-accent-swatch.active {
1851
+ border-color: white;
1852
+ box-shadow: 0 0 0 2px var(--accent);
1853
+ }
1854
+
1855
+ /* ─── Settings save bar ────────────────────────────────────────────── */
1856
+ .mobile-settings-save-bar {
1857
+ display: flex;
1858
+ align-items: center;
1859
+ justify-content: space-between;
1860
+ gap: 12px;
1861
+ flex-wrap: wrap;
1862
+ padding: 10px 16px;
1863
+ background: var(--warning);
1864
+ color: #000;
1865
+ font-size: 13px;
1866
+ font-weight: 500;
1867
+ margin: calc(-1 * var(--mobile-padding));
1868
+ margin-bottom: 12px;
1869
+ }
1870
+
1871
+ /* ─── List item interactive ──────────────────────────────────────── */
1872
+ .mobile-list-item-interactive {
1873
+ cursor: pointer;
1874
+ transition: all 120ms ease;
1875
+ }
1876
+
1877
+ .mobile-list-item-interactive:hover {
1878
+ border-color: var(--accent-border);
1879
+ background: var(--bg-elev-2);
1880
+ }
1881
+
1882
+ .mobile-list-item-interactive:active {
1883
+ opacity: 0.8;
1884
+ }
1885
+
1886
+ .mobile-list-status-dot {
1887
+ width: 8px;
1888
+ height: 8px;
1889
+ border-radius: 50%;
1890
+ flex-shrink: 0;
1891
+ }
1892
+
1893
+ .mobile-list-status-dot[data-status="working"],
1894
+ .mobile-list-status-dot[data-status="doing"] {
1895
+ background: var(--success);
1896
+ }
1897
+
1898
+ .mobile-list-status-dot[data-status="error"],
1899
+ .mobile-list-status-dot[data-status="stuck"] {
1900
+ background: var(--error);
1901
+ }
1902
+
1903
+ .mobile-list-status-dot[data-status="idle"] {
1904
+ background: var(--text-dim);
1905
+ }
1906
+
1907
+ .mobile-list-badge.badge-accent {
1908
+ background: var(--accent-bg);
1909
+ color: var(--accent);
1910
+ }
1911
+
1912
+ .mobile-list-badge.badge-warning {
1913
+ background: rgba(210, 153, 34, 0.15);
1914
+ color: var(--warning);
1915
+ }
1916
+
1917
+ /* ─── Danger button ─────────────────────────────────────────────── */
1918
+ .mobile-btn-danger {
1919
+ background: var(--error);
1920
+ color: white;
1921
+ }
1922
+
1923
+ .mobile-btn-danger:active {
1924
+ opacity: 0.8;
1925
+ }
1926
+
1927
+ .mobile-artifact-iframe {
1928
+ width: 100%;
1929
+ min-height: min(70dvh, 560px);
1930
+ border: 1px solid var(--border);
1931
+ border-radius: 12px;
1932
+ background: white;
1933
+ }
1934
+
1935
+ @media (max-width: 420px) {
1936
+ .mobile-config-key,
1937
+ .mobile-config-value {
1938
+ flex-basis: 100%;
1939
+ }
1940
+
1941
+ .mobile-task-detail-row {
1942
+ flex-direction: column;
1943
+ }
1944
+
1945
+ .mobile-task-detail-row span:first-child,
1946
+ .mobile-task-detail-row span:last-child {
1947
+ flex: none;
1948
+ text-align: left;
1949
+ }
1950
+ }
1951
+
1952
+ /* ─── Reduce motion ──────────────────────────────────────────────────── */
1953
+ @media (prefers-reduced-motion: reduce) {
1954
+ *,
1955
+ *::before,
1956
+ *::after {
1957
+ animation-duration: 0.01ms !important;
1958
+ transition-duration: 0.01ms !important;
1959
+ }
1960
+ }