@webship.co/workspace 0.0.0-stage → 1.0.0-alpha1

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 (311) hide show
  1. package/PLUGINS.md +249 -0
  2. package/README.md +379 -2
  3. package/WORKSPACES.md +69 -0
  4. package/actions/ai-items.js +293 -0
  5. package/actions/audio.js +48 -0
  6. package/actions/build-order.js +79 -0
  7. package/actions/checks.js +95 -0
  8. package/actions/claude-session.js +104 -0
  9. package/actions/commands-center.js +258 -0
  10. package/actions/composer.js +267 -0
  11. package/actions/ddev-addons.js +90 -0
  12. package/actions/ddev-mail.js +80 -0
  13. package/actions/ddev.js +237 -0
  14. package/actions/folders.js +165 -0
  15. package/actions/graphs.js +107 -0
  16. package/actions/images-svg.js +33 -0
  17. package/actions/images.js +145 -0
  18. package/actions/navigation.js +190 -0
  19. package/actions/node.js +222 -0
  20. package/actions/notes.js +55 -0
  21. package/actions/obsidian.js +59 -0
  22. package/actions/plugins.js +36 -0
  23. package/actions/project-make.js +28 -0
  24. package/actions/rag.js +202 -0
  25. package/actions/row-actions.js +262 -0
  26. package/actions/screens.js +270 -0
  27. package/actions/testing.js +121 -0
  28. package/actions/video-edit.js +54 -0
  29. package/ai-inventory.js +182 -0
  30. package/ai-items.js +202 -0
  31. package/assistant-cast.js +176 -0
  32. package/assistant-suggestions.js +91 -0
  33. package/assistant.js +484 -0
  34. package/audio-voice.js +528 -0
  35. package/auth-google.js +260 -0
  36. package/build-ai.js +52 -0
  37. package/build-order-page.js +191 -0
  38. package/build-order.js +313 -0
  39. package/builder-args.js +117 -0
  40. package/changelog.js +302 -0
  41. package/chat-threads.js +134 -0
  42. package/checks.js +105 -0
  43. package/claude-args.js +282 -0
  44. package/claude-sessions.js +129 -0
  45. package/command-author.js +117 -0
  46. package/command-block.js +20 -0
  47. package/commands/defaults.yml +159 -0
  48. package/commands-page.js +460 -0
  49. package/commands.js +568 -0
  50. package/cucumber.js +43 -0
  51. package/ddev-addons-page.js +124 -0
  52. package/ddev-addons.js +154 -0
  53. package/ddev-custom-commands.js +96 -0
  54. package/ddev-domains.js +84 -0
  55. package/ddev-import.js +93 -0
  56. package/ddev-mail-page.js +167 -0
  57. package/ddev-mail.js +110 -0
  58. package/ddev-options.js +145 -0
  59. package/ddev-snapshots.js +126 -0
  60. package/ddev.js +145 -0
  61. package/docs/DEVELOPER-GUIDE.md +224 -0
  62. package/docs/README.md +252 -0
  63. package/docs/REFERENCE.md +684 -0
  64. package/docs/USER-GUIDE.md +697 -0
  65. package/docs/screenshots/assistant/avatar-board.png +0 -0
  66. package/docs/screenshots/assistant/avatar-coffee.png +0 -0
  67. package/docs/screenshots/assistant/avatar-colours.png +0 -0
  68. package/docs/screenshots/assistant/avatar-icons.png +0 -0
  69. package/docs/screenshots/assistant/avatar-moves.png +0 -0
  70. package/docs/screenshots/assistant/avatar-pick-cookieman.png +0 -0
  71. package/docs/screenshots/assistant/avatar-settings-voices.png +0 -0
  72. package/docs/screenshots/assistant/avatar-status.png +0 -0
  73. package/docs/screenshots/create-card/create-card.png +0 -0
  74. package/docs/screenshots/create-card/start-ai.png +0 -0
  75. package/docs/screenshots/guide-clone-address.png +0 -0
  76. package/docs/screenshots/guide-clone-worktree-off.png +0 -0
  77. package/docs/screenshots/guide-clone-worktree-on.png +0 -0
  78. package/docs/screenshots/guide-ddev-menu.png +0 -0
  79. package/docs/screenshots/guide-domains.png +0 -0
  80. package/docs/screenshots/guide-home.png +0 -0
  81. package/docs/screenshots/guide-ide-menu.png +0 -0
  82. package/docs/screenshots/guide-remove-refusal.png +0 -0
  83. package/docs/screenshots/guide-rows-worktree.png +0 -0
  84. package/docs/screenshots/guide-screens.png +0 -0
  85. package/docs/screenshots/guide-settings.png +0 -0
  86. package/docs/screenshots/guide-workspace-page.png +0 -0
  87. package/docs/screenshots/home/card-settings.png +0 -0
  88. package/docs/screenshots/home/drag-reorder.png +0 -0
  89. package/docs/screenshots/home/edit-card.png +0 -0
  90. package/docs/screenshots/images/claude-code-image.png +0 -0
  91. package/docs/screenshots/images/edit-with-ai.png +0 -0
  92. package/docs/screenshots/images/gallery.png +0 -0
  93. package/docs/screenshots/images/generate-description.png +0 -0
  94. package/docs/screenshots/images/generate-plan.png +0 -0
  95. package/docs/screenshots/images/providers.png +0 -0
  96. package/docs/screenshots/images/svg-form.png +0 -0
  97. package/docs/screenshots/images/svg-result.png +0 -0
  98. package/docs/screenshots/images/upload.png +0 -0
  99. package/docs/screenshots/new-folder/2-form.png +0 -0
  100. package/docs/screenshots/new-folder/8-ddev-options.png +0 -0
  101. package/docs/screenshots/new-folder/files-folder.png +0 -0
  102. package/docs/screenshots/projects/ddev-custom-commands.png +0 -0
  103. package/docs/screenshots/projects/state-chip-stop.png +0 -0
  104. package/docs/screenshots/readme/dashboard-dark.png +0 -0
  105. package/docs/screenshots/readme/dashboard-light.png +0 -0
  106. package/docs/screenshots/readme/dev-dark.png +0 -0
  107. package/docs/screenshots/readme/dev-light.png +0 -0
  108. package/docs/screenshots/readme/docs-dark.png +0 -0
  109. package/docs/screenshots/readme/docs-light.png +0 -0
  110. package/docs/screenshots/readme/icons/ai.svg +4 -0
  111. package/docs/screenshots/readme/icons/code.svg +4 -0
  112. package/docs/screenshots/readme/icons/docs.svg +4 -0
  113. package/docs/screenshots/readme/icons/services.svg +4 -0
  114. package/docs/screenshots/readme/icons/sites.svg +4 -0
  115. package/docs/screenshots/readme/test-report-dark.png +0 -0
  116. package/docs/screenshots/readme/test-report-light.png +0 -0
  117. package/docs/screenshots/readme/test-scenarios.png +0 -0
  118. package/docs/screenshots/readme/test-steps.png +0 -0
  119. package/docs/screenshots/readme/videos-dark.png +0 -0
  120. package/docs/screenshots/readme/videos-light.png +0 -0
  121. package/docs/screenshots/screens-menu.png +0 -0
  122. package/docs/screenshots/screens-new.png +0 -0
  123. package/docs/screenshots/settings/auth-google-lists.png +0 -0
  124. package/docs/screenshots/settings/delete-1-row.png +0 -0
  125. package/docs/screenshots/settings/delete-2-confirm.png +0 -0
  126. package/docs/screenshots/settings/delete-3-type-name.png +0 -0
  127. package/docs/screenshots/settings/delete-4-type-yes.png +0 -0
  128. package/event-log.js +59 -0
  129. package/files-browser.js +247 -0
  130. package/folders.js +121 -0
  131. package/format.js +73 -0
  132. package/git-info.js +81 -0
  133. package/github-auth.js +62 -0
  134. package/graphs.js +104 -0
  135. package/html.js +10 -0
  136. package/icons.js +83 -0
  137. package/images-ai.js +447 -0
  138. package/images-create.js +226 -0
  139. package/images-page.js +417 -0
  140. package/images-records.js +39 -0
  141. package/images-render.js +36 -0
  142. package/images-svg-core.js +214 -0
  143. package/images-svg-sanitize.js +188 -0
  144. package/images-svg.js +241 -0
  145. package/images.js +270 -0
  146. package/jobs.js +430 -0
  147. package/linger.js +21 -0
  148. package/lists.js +292 -0
  149. package/media-info.js +136 -0
  150. package/navigation-page.js +264 -0
  151. package/navigation.js +394 -0
  152. package/notes.js +0 -0
  153. package/obsidian.js +405 -0
  154. package/package.json +47 -4
  155. package/palette-index.js +46 -0
  156. package/playwright.config.js +23 -0
  157. package/plugin-install.js +239 -0
  158. package/plugin-loader.js +448 -0
  159. package/plugin-manifest.js +83 -0
  160. package/plugin-settings.js +44 -0
  161. package/plugins/workspace-notes/index.js +59 -0
  162. package/plugins-page.js +103 -0
  163. package/project-make.js +241 -0
  164. package/project-name.js +210 -0
  165. package/public/assistant-avatar-moves.js +646 -0
  166. package/public/assistant-avatar-ui.js +1223 -0
  167. package/public/assistant-avatar.js +530 -0
  168. package/public/avatar/druplicon.vrm +0 -0
  169. package/public/css/base.css +260 -0
  170. package/public/css/components/ai-assistant.css +263 -0
  171. package/public/css/components/assistant-avatar.css +279 -0
  172. package/public/css/components/assistant-views.css +198 -0
  173. package/public/css/components/build-order.css +74 -0
  174. package/public/css/components/clone-as-a-git-worktree.css +30 -0
  175. package/public/css/components/command-palette.css +61 -0
  176. package/public/css/components/commands-center.css +139 -0
  177. package/public/css/components/confirm-dialog.css +40 -0
  178. package/public/css/components/create-card.css +8 -0
  179. package/public/css/components/ddev-menu.css +23 -0
  180. package/public/css/components/deep-chat.css +17 -0
  181. package/public/css/components/density.css +11 -0
  182. package/public/css/components/floating-assistant-workspace-pages.css +55 -0
  183. package/public/css/components/folders.css +5 -0
  184. package/public/css/components/full-height-left-assistant-sidebar-all-pages.css +39 -0
  185. package/public/css/components/full-height-right-actions-rail-pages-that-have-actions.css +267 -0
  186. package/public/css/components/grid-and-list.css +203 -0
  187. package/public/css/components/help-page.css +36 -0
  188. package/public/css/components/hero.css +16 -0
  189. package/public/css/components/images.css +70 -0
  190. package/public/css/components/layout-rhythm-and-spacing-polish.css +139 -0
  191. package/public/css/components/mic-on-any-field-that-wants-typing.css +416 -0
  192. package/public/css/components/modal-fit.css +113 -0
  193. package/public/css/components/page-width.css +23 -0
  194. package/public/css/components/plugins-page.css +9 -0
  195. package/public/css/components/project-cards.css +256 -0
  196. package/public/css/components/project-rows.css +390 -0
  197. package/public/css/components/reordering-the-workspace-cards.css +85 -0
  198. package/public/css/components/responsive-home-and-the-workspace-pages.css +457 -0
  199. package/public/css/components/running-commands-as-toasts.css +327 -0
  200. package/public/css/components/settings-editor-core-config-yml.css +828 -0
  201. package/public/css/components/short-results-as-a-toast-at-the-top.css +203 -0
  202. package/public/css/components/sound-player.css +84 -0
  203. package/public/css/components/suggest-agents-skills-commands.css +112 -0
  204. package/public/css/components/tab-modal.css +142 -0
  205. package/public/css/components/terminals.css +244 -0
  206. package/public/css/components/test-report-media-one-file-per-row-paged.css +144 -0
  207. package/public/css/components/top-toolbar-logo-breadcrumb.css +107 -0
  208. package/public/css/components/video-edit.css +6 -0
  209. package/public/css/components/web-ide-open-with.css +23 -0
  210. package/public/css/components/working-indicators.css +158 -0
  211. package/public/css/components/workspace-cards.css +79 -0
  212. package/public/favicon.ico +0 -0
  213. package/public/favicon.png +0 -0
  214. package/public/htmx.min.js +1 -0
  215. package/public/logo.png +0 -0
  216. package/public/media-player.js +215 -0
  217. package/public/mic.js +255 -0
  218. package/public/narration.js +110 -0
  219. package/public/palette.js +278 -0
  220. package/public/sortable.js +251 -0
  221. package/public/suggest.js +337 -0
  222. package/public/terminal.js +903 -0
  223. package/public/themes/default/theme.css +267 -0
  224. package/public/themes/ember/theme.css +180 -0
  225. package/public/themes/press/theme.css +290 -0
  226. package/public/themes/slate/theme.css +182 -0
  227. package/public/touch-icon.png +0 -0
  228. package/public/ui.js +2721 -0
  229. package/public/vendor/ace/LICENSE.txt +24 -0
  230. package/public/vendor/ace/ace.js +23 -0
  231. package/public/vendor/ace/ext-language_tools.js +8 -0
  232. package/public/vendor/ace/ext-searchbox.js +8 -0
  233. package/public/vendor/ace/mode-css.js +8 -0
  234. package/public/vendor/ace/mode-html.js +8 -0
  235. package/public/vendor/ace/mode-javascript.js +8 -0
  236. package/public/vendor/ace/mode-markdown.js +8 -0
  237. package/public/vendor/ace/mode-sh.js +8 -0
  238. package/public/vendor/ace/mode-yaml.js +8 -0
  239. package/public/vendor/ace/theme-textmate.js +8 -0
  240. package/public/vendor/ace/theme-tomorrow_night.js +8 -0
  241. package/public/vendor/ace/worker-yaml.js +1 -0
  242. package/public/vendor/deep-chat.LICENSE +21 -0
  243. package/public/vendor/deep-chat.bundle.js +1 -0
  244. package/public/vendor/fonts/dm-serif-text-LICENSE.txt +93 -0
  245. package/public/vendor/fonts/dm-serif-text-latin-400-italic.woff2 +0 -0
  246. package/public/vendor/fonts/dm-serif-text-latin-400-normal.woff2 +0 -0
  247. package/public/vendor/fonts/figtree-LICENSE.txt +93 -0
  248. package/public/vendor/fonts/figtree-latin-400-italic.woff2 +0 -0
  249. package/public/vendor/fonts/figtree-latin-400-normal.woff2 +0 -0
  250. package/public/vendor/fonts/figtree-latin-600-italic.woff2 +0 -0
  251. package/public/vendor/fonts/figtree-latin-600-normal.woff2 +0 -0
  252. package/public/vendor/fonts/jetbrains-mono-LICENSE.txt +93 -0
  253. package/public/vendor/fonts/jetbrains-mono-latin-400-normal.woff2 +0 -0
  254. package/public/vendor/fonts/ubuntu-mono-LICENSE.txt +98 -0
  255. package/public/vendor/fonts/ubuntu-mono-latin-wght-normal.woff2 +0 -0
  256. package/public/vendor/tabler-LICENSE.txt +21 -0
  257. package/public/vendor/tabler-sprite.svg +1 -0
  258. package/public/vendor/three/LICENSE +21 -0
  259. package/public/vendor/three/addons/loaders/GLTFLoader.js +4860 -0
  260. package/public/vendor/three/addons/utils/BufferGeometryUtils.js +1501 -0
  261. package/public/vendor/three/addons/utils/SkeletonUtils.js +496 -0
  262. package/public/vendor/three/three.core.min.js +6 -0
  263. package/public/vendor/three/three.module.min.js +6 -0
  264. package/public/vendor/three-vrm/LICENSE +22 -0
  265. package/public/vendor/three-vrm/three-vrm.module.min.js +983 -0
  266. package/public/vendor/uikit-icons.min.js +1 -0
  267. package/public/vendor/uikit.min.css +1 -0
  268. package/public/vendor/uikit.min.js +1 -0
  269. package/public/vendor/webship-icons/ui/bookmark-outlined.svg +1 -0
  270. package/public/vendor/webship-icons/ui/headset.svg +1 -0
  271. package/public/vendor/webship-icons/ui/menu.svg +1 -0
  272. package/public/vendor/webship-icons/ui/pause.svg +1 -0
  273. package/public/vendor/webship-icons/ui/play.svg +1 -0
  274. package/public/vendor/webship-icons/ui/share.svg +1 -0
  275. package/public/vendor/webship-icons/ui/sound-off.svg +1 -0
  276. package/public/vendor/webship-icons/ui/sound-on.svg +1 -0
  277. package/public/vendor/webship-icons/ui/stop.svg +1 -0
  278. package/public/vendor/xterm/addon-fit.js +2 -0
  279. package/public/vendor/xterm/addon-unicode11.js +2 -0
  280. package/public/vendor/xterm/addon-web-links.js +2 -0
  281. package/public/vendor/xterm/xterm.css +218 -0
  282. package/public/vendor/xterm/xterm.js +2 -0
  283. package/rag.js +169 -0
  284. package/reader.js +132 -0
  285. package/repo-blobs.js +66 -0
  286. package/report-pdf.js +337 -0
  287. package/row-layout.js +1440 -0
  288. package/screenrc +37 -0
  289. package/screens.js +1063 -0
  290. package/scripts/code-server-start.sh +190 -0
  291. package/scripts/images-claude-finish.js +107 -0
  292. package/scripts/screen-host.sh +114 -0
  293. package/scripts/screen-runner.js +362 -0
  294. package/scripts/screen-then.js +47 -0
  295. package/scripts/update.sh +350 -0
  296. package/server.js +8140 -0
  297. package/settings-file.js +423 -0
  298. package/speech.js +297 -0
  299. package/tab-modal.js +75 -0
  300. package/test-reports.js +260 -0
  301. package/themes.js +381 -0
  302. package/transcripts.js +168 -0
  303. package/urls.js +13 -0
  304. package/validate.js +18 -0
  305. package/version-check.js +94 -0
  306. package/video-edit.js +588 -0
  307. package/waiting.js +85 -0
  308. package/workspace-card-tools.js +41 -0
  309. package/workspace-delete.js +139 -0
  310. package/workspace-types.js +85 -0
  311. package/workspaces.js +557 -0
@@ -0,0 +1,139 @@
1
+ /* The Commands page (core/workspace-app/commands-page.js): the catalog, a command's own page, and its run form. */
2
+
3
+ .cc-tabs { display: flex; flex-wrap: wrap; gap: 0.375rem; }
4
+
5
+ .cc-command-head { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; margin-bottom: 0.5rem; }
6
+
7
+ .cc-dl { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 0.25rem 1rem; margin: 0 0 1rem; }
8
+ .cc-dl dt { color: var(--text-subtle); font-weight: 600; }
9
+ .cc-dl dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }
10
+
11
+ .cc-target,
12
+ .cc-options,
13
+ .cc-kind {
14
+ display: grid;
15
+ grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
16
+ gap: 0.5rem 0.75rem;
17
+ min-width: 0;
18
+ margin: 0 0 0.75rem;
19
+ padding: 0.5rem 0.75rem 0.75rem;
20
+ border: 1px solid var(--line);
21
+ border-radius: 0.5rem;
22
+ }
23
+ .cc-target legend,
24
+ .cc-options legend,
25
+ .cc-kind legend { padding: 0 0.25rem; }
26
+
27
+ .cc-form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); gap: 0.5rem 0.75rem; margin-bottom: 0.5rem; }
28
+ .cc-form-grid label,
29
+ .cc-target label,
30
+ .cc-options label,
31
+ .cc-kind label { display: flex; flex-direction: column; gap: 0.25rem; min-width: 0; }
32
+ .cc-form-grid .cc-inline,
33
+ .cc-kind .cc-inline { flex-direction: row; align-items: center; gap: 0.5rem; }
34
+ .cc-wide { grid-column: 1 / -1; }
35
+ .cc-code { font-family: var(--font-code); }
36
+
37
+ .cc-yaml { max-height: 28rem; overflow: auto; }
38
+ .cc-manage { margin: 0.75rem 0; }
39
+ .cc-new-other { margin-top: 1.5rem; padding-top: 1rem; border-top: 1px solid var(--line); }
40
+
41
+ @media (max-width: 40em) {
42
+ .cc-dl { grid-template-columns: minmax(0, 1fr); }
43
+ .cc-dl dd { margin-bottom: 0.375rem; }
44
+ }
45
+
46
+ /* A link inside a block of text has to be distinguishable from that text by something other than
47
+ colour: the command titles sit beside their description and file name, and brand blue against the
48
+ body ink is 1.52:1 — far under the 3:1 axe (and WCAG 1.4.1) asks for. Underlined, quietly, which is
49
+ the convention for a link in prose and the one cue that survives being colour-blind or printing it. */
50
+ .cmd-title a {
51
+ text-decoration: underline;
52
+ text-decoration-thickness: 1px;
53
+ text-underline-offset: 2px;
54
+ text-decoration-color: var(--line-strong);
55
+ }
56
+ .cmd-title a:hover { text-decoration-color: currentColor; }
57
+
58
+ /* ---------- Commands → Rail: the actions rail, arranged ----------
59
+ * The same shape as the Buttons pane, because it is the same question about a different strip of the
60
+ * screen: a list per group, drag by a handle, and a Hidden list at the end. */
61
+ .nav-scopes { display: flex; flex-wrap: wrap; gap: 0.25rem; }
62
+ .nav-groups { list-style: none; margin: 0; padding: 0; }
63
+
64
+ .nav-group {
65
+ border: 1px solid var(--line);
66
+ border-radius: 0.5rem;
67
+ padding: 0.5rem 0.75rem 0.75rem;
68
+ margin-bottom: 0.5rem;
69
+ background: var(--surface-card);
70
+ }
71
+ .nav-group-head { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.35rem; }
72
+ .nav-group-hidden { border-style: dashed; }
73
+
74
+ .nav-entries { list-style: none; margin: 0; padding: 0; min-height: 2rem; display: flex; flex-wrap: wrap; gap: 0.35rem; }
75
+ .nav-entry {
76
+ display: flex;
77
+ align-items: center;
78
+ gap: 0.35rem;
79
+ padding: 0.25rem 0.5rem;
80
+ border: 1px solid var(--line);
81
+ border-radius: 62.4375rem;
82
+ background: var(--surface);
83
+ font-size: 0.8125rem;
84
+ }
85
+ /* An empty group still takes a drop: a list with no height is a target nothing can be dragged into. */
86
+ .nav-entries:empty::after {
87
+ content: "drag an entry here";
88
+ color: var(--text-subtle);
89
+ font-size: 0.75rem;
90
+ padding: 0.35rem 0.25rem;
91
+ }
92
+
93
+ .nav-handle { cursor: grab; color: var(--line-strong); }
94
+ .nav-handle:active { cursor: grabbing; }
95
+ .nav-yours { font-size: 0.625rem; }
96
+ .nav-remove { padding: 0; color: var(--danger); }
97
+ .nav-save { position: sticky; bottom: 0; padding: 0.5rem 0; background: var(--surface); }
98
+ .nav-add { margin-top: 1rem; }
99
+
100
+ /* The navigation editor's two places: the top bar's three regions, then the sidebar's groups. */
101
+ .nav-place-head { display: flex; align-items: baseline; gap: 0.4rem; margin: 1rem 0 0.4rem; }
102
+ .nav-place-topbar { margin-bottom: 0.5rem; }
103
+ .nav-regions { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.5rem; }
104
+ @media (max-width: 47.9375em) { .nav-regions { grid-template-columns: 1fr; } }
105
+ .nav-region {
106
+ border: 1px dashed var(--line);
107
+ border-radius: 10px;
108
+ padding: 0.5rem;
109
+ background: var(--surface-muted);
110
+ }
111
+ html.dark .nav-region { background: transparent; }
112
+ .nav-region-label {
113
+ display: block;
114
+ font-size: 0.6875rem;
115
+ text-transform: uppercase;
116
+ letter-spacing: 1px;
117
+ color: var(--text-subtle);
118
+ margin-bottom: 0.35rem;
119
+ }
120
+
121
+ /* UIKit hardcodes .uk-form-label to a dark grey, and uikit.min.css is linked AFTER this stylesheet — so
122
+ a rule of ours at the same specificity loses the tie silently. On a dark card that label measured
123
+ 1.28:1, which is a WCAG AA failure nobody put there. Two classes out-specify it, in both halves of
124
+ the theme. */
125
+ html .uk-form-label { color: var(--text-subtle); }
126
+ html.dark .uk-form-label { color: var(--text-light); }
127
+
128
+ /* How much of an entry is shown, on the chip itself: icon + text, icon only, or text only. */
129
+ .nav-entry-show {
130
+ font-size: 0.625rem;
131
+ line-height: 1;
132
+ padding: 0.15rem 0.2rem;
133
+ border: 1px solid var(--line);
134
+ border-radius: 6px;
135
+ background: transparent;
136
+ color: var(--text-subtle);
137
+ max-width: 6.5rem;
138
+ }
139
+ .nav-entry-show:focus-visible { outline: 2px solid var(--brand-primary); outline-offset: 1px; }
@@ -0,0 +1,40 @@
1
+ /* The one confirm dialog every important action goes through. It is small on purpose: a question
2
+ with two answers, never a panel. Tokens only, so both themes and dark mode follow. */
3
+
4
+ #confirm-modal .uk-modal-dialog {
5
+ width: min(26rem, 92vw);
6
+ background: var(--surface-card);
7
+ color: var(--text-default);
8
+ border: 1px solid var(--line);
9
+ border-radius: 0.875rem;
10
+ box-shadow: var(--shadow-float);
11
+ }
12
+
13
+ /* "Wait!" is the alarm, so it is the loudest thing in the dialog — and the only one that shouts. */
14
+ #confirm-modal .uk-modal-title {
15
+ color: var(--danger-ink);
16
+ font-size: 1.5rem;
17
+ margin-bottom: 0.25rem;
18
+ }
19
+
20
+ #confirm-modal #confirm-text {
21
+ color: var(--text-default);
22
+ margin: 0 0 0.25rem;
23
+ }
24
+
25
+ /* What is about to happen, named. Empty when the button said nothing beyond its own label, and an
26
+ empty line of margin under the question reads as a rendering fault — so it collapses. */
27
+ #confirm-modal .confirm-what {
28
+ color: var(--text-subtle);
29
+ margin: 0;
30
+ word-break: break-word;
31
+ }
32
+ #confirm-modal .confirm-what:empty { display: none; }
33
+
34
+ /* No first and Yes last: the safe answer is the one under the thumb, and the one Escape gives. */
35
+ #confirm-modal .confirm-buttons {
36
+ display: flex;
37
+ justify-content: flex-end;
38
+ gap: 0.5rem;
39
+ margin: 1rem 0 0;
40
+ }
@@ -0,0 +1,8 @@
1
+ /* The build card: "What would you like to create?", the builder form, New folder, and Claude Code after the build. */
2
+ .create-head { gap: 0.75rem; flex-wrap: wrap; }
3
+ .build-form .build-ai-prompt { display: none; }
4
+ .build-form:has(input[name="ai_after"]:checked) .build-ai-prompt { display: block; }
5
+ /* A files workspace's create actions, as a row of buttons under the heading rather than tiles above the card. */
6
+ .create-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0.25rem 0 1.25rem; }
7
+ .create-head .action-btn.uk-button,
8
+ .create-actions .action-btn.uk-button { width: auto; display: inline-flex; align-items: center; gap: 0.4rem; padding: 0 0.9rem; line-height: 2rem; font-size: 0.875rem; }
@@ -0,0 +1,23 @@
1
+ /* A project's row menus: one narrow column, a long one's groups folded (ui.js), each entry on one line. */
2
+ .project-row .act-menu .uk-dropdown { min-width: 0; width: 18rem; max-height: min(34rem, 70vh); overflow-y: auto; padding: 0.5rem; }
3
+ .project-row .act-menu .uk-dropdown-nav > li > a { display: flex; align-items: center; gap: 0.5rem; padding: 0.3rem 0.5rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-decoration: none; }
4
+ /* A long entry ellipsises its text, never its icon. */
5
+ .project-row .act-menu .uk-dropdown-nav > li > a > .uk-icon { flex: none; }
6
+ .project-row .act-menu .uk-dropdown-nav > li[hidden] { display: none; }
7
+ .project-row .act-menu .uk-nav-header.ddev-fold { display: flex; align-items: center; justify-content: space-between; cursor: pointer; margin-top: 0.25rem; padding: 0.375rem 0.5rem; border-radius: 0.375rem; }
8
+ .project-row .act-menu .uk-nav-header.ddev-fold::after { content: ""; width: 0.4rem; height: 0.4rem; border-right: 2px solid currentColor; border-bottom: 2px solid currentColor; transform: rotate(-45deg); transition: transform 0.15s ease; }
9
+ .project-row .act-menu .uk-nav-header.ddev-fold[aria-expanded="true"]::after { transform: rotate(45deg); }
10
+ .project-row .act-menu .uk-nav-header.ddev-fold:hover { background: var(--subtle-brand); }
11
+ .project-row .act-menu .uk-nav-header.ddev-fold:focus-visible { outline: 2px solid var(--brand-primary); outline-offset: -2px; }
12
+
13
+ /* The list is a size container, so it is its own stacking layer, under the assistant panel (z 30). While a
14
+ menu inside it is open it rises above the panel and stays under the top bar (z 40). */
15
+ #webship-workspace-projects:has(.uk-dropdown.uk-open) { position: relative; z-index: 35; }
16
+ /* The folded menu is one column: the two-column layout split the groups and cut the entries. */
17
+ .act-menu-ddev .ddev-nav-columns { column-count: 1; }
18
+
19
+ /* COMPOSER and NODE drew two 20rem columns side by side, 640px wide; folded, one column is enough. */
20
+ .project-row .act-menu :is(.composer-columns, .node-columns) { display: block; }
21
+ .project-row .act-menu :is(.composer-columns, .node-columns) > ul + ul { border-left: 0; border-top: 1px solid var(--line); margin-top: 0.25rem; padding-top: 0.25rem; }
22
+ /* A long note in a menu wraps; it is a sentence, not an entry. */
23
+ .project-row .act-menu .uk-nav-header:not(.ddev-fold) { white-space: normal; text-transform: none; letter-spacing: 0; font-size: 0.75rem; line-height: 1.35; }
@@ -0,0 +1,17 @@
1
+ /* ---------- The assistant, as a deep-chat component ---------- */
2
+ /*
3
+ * deep-chat renders its own transcript and input inside a shadow root, so it is styled through the
4
+ * properties ui.js sets and through the few parts that live outside it: the intro template, the
5
+ * reply wrapper, and the command picker that ui.js moves into deep-chat's input toolbar.
6
+ */
7
+
8
+
9
+
10
+ /* The host element carries the brand face and the theme's own tokens INTO the shadow root:
11
+ * custom properties inherit across a shadow boundary, so every var() ui.js hands the component
12
+ * resolves against the page's theme and follows the light/dark toggle without a second config.
13
+ * Set on the host and not only inside, because deep-chat's own parts inherit from here. */
14
+ deep-chat {
15
+ font-family: var(--font-primary);
16
+ color: var(--text-default);
17
+ }
@@ -0,0 +1,11 @@
1
+ /* Project rows, comfortable or compact (ui.js, the density switch beside the page width).
2
+ *
3
+ * Compact keeps every button and folds away only the small caption under each ("36 commands", "linked",
4
+ * "locked"). The caption stays in the page for a screen reader and becomes the button's tooltip, so nothing
5
+ * is lost to a pointer or to assistive technology. Measured on the maintainer's Dev page: a card is 20 to 40px
6
+ * shorter, and three rows of buttons read as three rows of buttons rather than as buttons and notes. */
7
+ html[data-density="compact"] .act-with-status > .act-status {
8
+ position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden;
9
+ clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
10
+ }
11
+ html[data-density="compact"] .act-with-status { display: inline-flex; align-items: center; }
@@ -0,0 +1,55 @@
1
+ /* ---------- Floating assistant (workspace pages) ---------- */
2
+
3
+ .assistant-launcher {
4
+ position: fixed;
5
+ left:1.375rem;
6
+ bottom:1.375rem;
7
+ width:3.75rem;
8
+ height:3.75rem;
9
+ border-radius: 50%;
10
+ padding: 0;
11
+ font-size:1.75rem;
12
+ line-height:3.75rem;
13
+ z-index: 30;
14
+ box-shadow: 0 8px 22px rgba(30, 135, 240, .45);
15
+ }
16
+
17
+ .assistant-float {
18
+ display: none;
19
+ position: fixed;
20
+ left:1.375rem;
21
+ bottom:5.875rem;
22
+ width:min(31.25rem, calc(100vw - 2.75rem));
23
+ max-height:min(40rem, calc(100vh - 8.125rem));
24
+ overflow-y: auto;
25
+ z-index: 30;
26
+ box-shadow: 0 18px 44px rgba(0, 0, 0, .25);
27
+ border-radius:0.5rem;
28
+ }
29
+
30
+ .assistant-float.open { display: block; }
31
+
32
+ /* UIKit icons inside the round hero logo render white on the blue circle */
33
+ .logo { color: var(--text-inverse); }
34
+
35
+ /* Mic button while recording */
36
+ .mic-btn.listening {
37
+ background: var(--danger) !important;
38
+ color: var(--text-inverse) !important;
39
+ border-color: var(--danger) !important;
40
+ animation: mic-pulse 1.2s infinite;
41
+ }
42
+
43
+ @keyframes mic-pulse {
44
+ 50% { box-shadow: 0 0 0 6px rgba(240, 80, 110, .25); }
45
+ }
46
+
47
+ /* With the assistant open on a wide screen, shift the page content left so the widget never
48
+ * covers a button; collapsing it back to the launcher restores normal centring. Layout, not
49
+ * palette — it was in the default theme's file, so it only applied on one of the three themes. */
50
+ @media (min-width: 75em) {
51
+ body:has(.assistant-float.open) .page-body.webship-workspace-page {
52
+ margin-right: auto;
53
+ margin-left: 33.75rem;
54
+ }
55
+ }
@@ -0,0 +1,5 @@
1
+ /* New folder form: the Claude Code message only matters when Claude Code is what starts. */
2
+ .folder-new-form .folder-prompt { display: none; }
3
+ .folder-new-form:has(input[name="then"][value="claude"]:checked) .folder-prompt { display: block; }
4
+ .folder-new-form .folder-ddev-type { display: none; }
5
+ .folder-new-form:has(.folder-setup input:checked) .folder-ddev-type { display: block; }
@@ -0,0 +1,39 @@
1
+ /* ---------- Full-height left assistant sidebar (all pages) ---------- */
2
+
3
+ .assistant-side {
4
+ position: fixed;
5
+ top:4.0625rem;
6
+ left: 0;
7
+ bottom: 0;
8
+ width:25rem;
9
+ /* border-box, so the declared width IS the footprint. UIKit sets border-box on
10
+ its own components but not on a bare aside, so this was 424px wide against
11
+ the 400px margin on .app-content — a 24px overlap that only stayed invisible
12
+ because it landed in the container's own padding. */
13
+ box-sizing: border-box;
14
+ padding:1rem 0.5rem 1rem 1rem;
15
+ display: flex;
16
+ z-index: 30;
17
+ }
18
+
19
+ .assistant-side .assistant-panel {
20
+ display: flex;
21
+ flex-direction: column;
22
+ width: 100%;
23
+ min-height: 0;
24
+ }
25
+
26
+ .assistant-side .assistant-body {
27
+ flex: 1;
28
+ display: flex;
29
+ flex-direction: column;
30
+ min-height: 0;
31
+ }
32
+
33
+ .assistant-side .chat-log {
34
+ flex: 1;
35
+ max-height: none;
36
+ min-height: 0;
37
+ }
38
+
39
+ .app-content { margin-left:25rem; }
@@ -0,0 +1,267 @@
1
+ /* ---------- Full-height right actions rail (pages that have actions) ---------- */
2
+
3
+ /* Page actions used to sit in a row under the list, which on a long workspace put
4
+ them a hundred rows below the fold. Fixed on the right they stay reachable at
5
+ any scroll position, and the collapse gives the table back its width. */
6
+ .actions-side {
7
+ position: fixed;
8
+ top:4.0625rem;
9
+ right: 0;
10
+ bottom: 0;
11
+ width:15.5rem;
12
+ box-sizing: border-box; /* the declared width is the footprint */
13
+ padding:0 1rem 1rem 0.5rem;
14
+ display: flex;
15
+ flex-direction: column;
16
+ gap:0.625rem;
17
+ overflow-y: auto;
18
+ z-index: 30;
19
+ background: var(--surface);
20
+ border-left: 1px solid var(--line);
21
+ transition: width .18s ease;
22
+ }
23
+
24
+ .app-content.has-actions { margin-right:15.5rem; transition: margin-right .18s ease; }
25
+
26
+ .actions-toggle {
27
+ display: flex;
28
+ align-items: center;
29
+ gap:0.5rem;
30
+ background: none;
31
+ border: 1px solid var(--line);
32
+ border-radius:31.25rem;
33
+ padding:0.3125rem 0.75rem;
34
+ color: var(--text-subtle);
35
+ cursor: pointer;
36
+ font-size: .8125rem;
37
+ font-weight: 600;
38
+ align-self: flex-start;
39
+ }
40
+
41
+ .actions-toggle:hover { border-color: var(--brand-primary); color: var(--brand-primary); }
42
+ .actions-toggle-icon { transition: transform .18s ease; }
43
+
44
+ .actions-rail-inner { display: flex; flex-direction: column; gap:0.875rem; }
45
+ .actions-group { display: flex; flex-direction: column; gap:0.375rem; }
46
+
47
+ .actions-group-label {
48
+ font-size: .7rem;
49
+ font-weight: 700;
50
+ letter-spacing: .06em;
51
+ text-transform: uppercase;
52
+ /* No opacity on top of the token: --text-subtle is ALREADY the quiet one, and fading it again put
53
+ these labels at 4.4:1 on the dark rail — under the 4.5:1 a 11px bold label needs. Quiet is the
54
+ token's job; dimming it twice is how a colour that was checked stops being the colour rendered. */
55
+ color: var(--text-subtle);
56
+ }
57
+
58
+ /* Full-width, icon then label — a stacked rail reads as a list of actions, not a
59
+ toolbar of equal-weight buttons. */
60
+ .actions-side .action-btn {
61
+ display: flex;
62
+ align-items: center;
63
+ gap:0.5625rem;
64
+ width: 100%;
65
+ text-align: left;
66
+ padding:0 0.75rem;
67
+ line-height:2.125rem;
68
+ font-size: .82rem;
69
+ }
70
+
71
+ /* Collapsed: icons only, centred, labels hidden but still announced by title. */
72
+ html.actions-collapsed .actions-side { width:3.5rem; padding:0 0.5rem 1rem; }
73
+ html.actions-collapsed .app-content.has-actions { margin-right:3.5rem; }
74
+ html.actions-collapsed .actions-side .action-label,
75
+ html.actions-collapsed .actions-group-label { display: none; }
76
+ html.actions-collapsed .actions-toggle-icon { transform: rotate(180deg); }
77
+
78
+ /* Collapsed, an action is a square icon button: at 36px it is a comfortable
79
+ target, and square tiles in a column read as a toolbar, where the pill shape
80
+ of an expanded row would just look like a truncated button. */
81
+ html.actions-collapsed .actions-side .action-btn {
82
+ width:2.25rem;
83
+ height:2.25rem;
84
+ min-width:2.25rem;
85
+ padding: 0;
86
+ gap: 0;
87
+ line-height:2.25rem;
88
+ border-radius:0.5rem;
89
+ justify-content: center;
90
+ align-self: center;
91
+ }
92
+
93
+ html.actions-collapsed .actions-toggle {
94
+ align-self: center;
95
+ width:2.25rem;
96
+ height:2.25rem;
97
+ padding: 0;
98
+ border-radius:0.5rem;
99
+ justify-content: center;
100
+ }
101
+
102
+ /* No labels to separate the groups, so a hairline does it instead. */
103
+ html.actions-collapsed .actions-group + .actions-group {
104
+ border-top: 1px solid var(--line);
105
+ padding-top:0.625rem;
106
+ }
107
+
108
+ /* Workspace navigation, present on every page. Quieter than the page's own
109
+ actions — it is how you leave, not what you do here. */
110
+ .actions-nav .action-btn {
111
+ border-color: transparent;
112
+ background: transparent;
113
+ color: var(--text-subtle);
114
+ }
115
+
116
+ /* --link, not --brand-primary: Webship blue as TEXT on the dark rail tint is 3.4:1, and --link is the
117
+ one brand value the themes lighten in their dark half for exactly this reason. */
118
+ .actions-nav .action-btn:hover {
119
+ background: var(--subtle-brand);
120
+ color: var(--link);
121
+ }
122
+
123
+ /* The page you are on, so a column of nineteen icons still says where you are. */
124
+ .actions-nav .action-btn.is-current {
125
+ background: var(--subtle-brand);
126
+ color: var(--link);
127
+ font-weight: 600;
128
+ }
129
+
130
+ html.actions-collapsed .actions-nav .action-btn.is-current {
131
+ box-shadow: inset 2px 0 0 var(--brand-primary);
132
+ }
133
+
134
+ /* Nineteen workspaces plus the page's actions will outrun a short viewport, so
135
+ the rail scrolls its own content rather than the page. */
136
+ .actions-side { scrollbar-width: thin; }
137
+
138
+ /* Stack on tablets/phones: the rail becomes a normal block above the content. */
139
+ @media (max-width: 59.9375em) {
140
+ .actions-side,
141
+ html.actions-collapsed .actions-side {
142
+ position: static;
143
+ width: auto;
144
+ flex-direction: row;
145
+ flex-wrap: wrap;
146
+ align-items: center;
147
+ border-left: 0;
148
+ border-bottom: 1px solid var(--line);
149
+ padding:0.75rem 0.875rem;
150
+ }
151
+ .app-content.has-actions,
152
+ html.actions-collapsed .app-content.has-actions { margin-right: 0; }
153
+ html.actions-collapsed .actions-side .action-label,
154
+ html.actions-collapsed .actions-group-label { display: inline; }
155
+ .actions-rail-inner { flex-direction: row; flex-wrap: wrap; gap:0.625rem; }
156
+ .actions-side .action-btn { width: auto; }
157
+ .actions-toggle { display: none; }
158
+
159
+ /* Workspace navigation goes icon-only here. Twenty labelled links laid out
160
+ horizontally made the rail 893px tall on a 900px viewport — the whole first
161
+ screen before any content. The page's own actions keep their labels. */
162
+ .actions-nav { flex-direction: row; flex-wrap: wrap; gap:0.375rem; }
163
+ .actions-nav .actions-group-label,
164
+ html.actions-collapsed .actions-nav .actions-group-label,
165
+ .actions-nav .action-label,
166
+ html.actions-collapsed .actions-nav .action-label { display: none; }
167
+ .actions-nav .action-btn,
168
+ html.actions-collapsed .actions-nav .action-btn {
169
+ width:2.125rem;
170
+ min-width:2.125rem;
171
+ height:2.125rem;
172
+ padding: 0;
173
+ gap: 0;
174
+ justify-content: center;
175
+ border-radius:0.5rem;
176
+ border-color: var(--line);
177
+ }
178
+ }
179
+
180
+ /* The release this machine runs, last in the Go group. Quiet, and not a link: it is reference, read
181
+ when someone asks what you are on. The monospace is the same one a version has everywhere else in
182
+ this dashboard, and the row keeps the group's geometry so it lines up with the links above it —
183
+ collapsed, the tag icon is what is left, and the title still answers the question. */
184
+ .actions-nav .actions-version {
185
+ font-family: var(--font-code, ui-monospace, monospace);
186
+ font-size: .6875rem;
187
+ color: var(--text-subtle);
188
+ background: transparent;
189
+ border-color: transparent;
190
+ cursor: default;
191
+ box-shadow: none;
192
+ }
193
+ .actions-nav .actions-version:hover { background: transparent; color: var(--text-subtle); }
194
+
195
+ /* Unknown has to look deliberate rather than like a missing value, but still quiet. */
196
+ .actions-nav .actions-version.is-unknown { cursor: help; text-decoration: underline dotted; text-underline-offset: 2px; }
197
+
198
+ /* The toggle stays put: it is the one control that is needed exactly when the rail is long. */
199
+ .actions-head {
200
+ position: sticky;
201
+ top: 0;
202
+ z-index: 2;
203
+ padding: 1rem 0 0.5rem;
204
+ background: var(--surface);
205
+ }
206
+ html.actions-collapsed .actions-head { display: flex; justify-content: center; }
207
+
208
+ /* More below the fold? A soft fade at the foot says so, and goes once the end is in view. */
209
+ .actions-fade {
210
+ position: sticky;
211
+ bottom: -1rem;
212
+ flex: none;
213
+ height: 2rem;
214
+ margin: -1rem -1rem -1rem -0.5rem;
215
+ pointer-events: none;
216
+ background: linear-gradient(to bottom, transparent, var(--surface));
217
+ opacity: 0;
218
+ transition: opacity .15s ease;
219
+ }
220
+ .actions-side.can-scroll .actions-fade { opacity: 1; }
221
+
222
+ /* A group of one that repeats its own heading is just the tile; and collapsed, neighbouring singles
223
+ sit together rather than as islands each fenced by a hairline. */
224
+ .actions-group.is-repeat > .actions-group-label { display: none; }
225
+ html.actions-collapsed .actions-group.is-single + .actions-group.is-single:not(.actions-nav) {
226
+ border-top: 0;
227
+ padding-top: 0;
228
+ margin-top: -0.5rem;
229
+ }
230
+
231
+ /* Three states, three looks. Hover is a tint; the page you are on is a tint with the bar and a weight;
232
+ keyboard focus is a solid ring that no tint can hide. */
233
+ .actions-side .action-btn:focus-visible {
234
+ outline: 2px solid var(--brand-primary);
235
+ outline-offset: 2px;
236
+ box-shadow: none;
237
+ }
238
+ .actions-side .actions-toggle:focus-visible {
239
+ outline: 2px solid var(--brand-primary);
240
+ outline-offset: 2px;
241
+ }
242
+ .actions-nav .action-btn.is-current { box-shadow: inset 3px 0 0 var(--brand-primary); }
243
+
244
+ /* The tooltip is one element outside the rail, so the rail's scrolling cannot clip it. */
245
+ #rail-tip {
246
+ position: fixed;
247
+ z-index: 1100;
248
+ max-width: 20rem;
249
+ display: flex;
250
+ flex-direction: column;
251
+ gap: 0.125rem;
252
+ padding: 0.4rem 0.65rem;
253
+ border-radius: 0.5rem;
254
+ background: var(--ink);
255
+ color: var(--surface);
256
+ font-size: 0.8125rem;
257
+ line-height: 1.35;
258
+ pointer-events: none;
259
+ box-shadow: var(--shadow-float, 0 4px 14px rgb(0 0 0 / 20%));
260
+ }
261
+ #rail-tip strong { font-weight: 600; }
262
+ #rail-tip span { opacity: 0.85; }
263
+ #rail-tip[hidden] { display: none; }
264
+
265
+ @media (max-width: 59.9375em) {
266
+ .actions-head, .actions-fade { display: none; }
267
+ }