@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,203 @@
1
+ /* ---------- Grid or list, on the home page and inside a workspace ----------
2
+ *
3
+ * Two different questions wearing one control. The home page is a grid of small cards and the sensible
4
+ * choices are how many across; a workspace is a list of project rows, each carrying a dozen buttons,
5
+ * and the sensible default there is one to a row with the whole width to lay them out in.
6
+ *
7
+ * The state is on <html> — data-home-view and data-rows-view, written by the pre-paint script from the
8
+ * shared cookie — so a layout is never drawn one way and then rearranged.
9
+ */
10
+
11
+ .cards-head {
12
+ display: flex;
13
+ align-items: center;
14
+ justify-content: space-between;
15
+ gap: 0.75rem;
16
+ flex-wrap: wrap;
17
+ margin-bottom: 0.5rem;
18
+ }
19
+
20
+ /* The list is its own section, and on a workspace that builds projects it follows the Build form —
21
+ which ended flush against it: the form's last control and "Projects · how to lay them out" touched at
22
+ zero pixels, so one question ran straight into the next. A rule as well as the space, because they
23
+ are two different things to do rather than one thing with a gap in it. */
24
+ .build-form + #webship-workspace-projects,
25
+ .build-form + [id="webship-workspace-projects"] {
26
+ margin-top: 1.75rem;
27
+ padding-top: 1.5rem;
28
+ border-top: 1px solid var(--line);
29
+ }
30
+
31
+ /* The three controls sit together: how many across, and how wide the page is, are one question. */
32
+ .layout-controls { display: inline-flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
33
+
34
+ /* The switcher: one segmented control, so the options read as one question with several answers. */
35
+ .view-switcher {
36
+ display: inline-flex;
37
+ align-items: center;
38
+ border: 1px solid var(--line);
39
+ border-radius: 62.4375rem;
40
+ padding: 0.125rem;
41
+ background: var(--surface-card);
42
+ }
43
+
44
+ .view-pick,
45
+ .page-width-pick {
46
+ min-width: 2.125rem;
47
+ display: inline-flex;
48
+ align-items: center;
49
+ gap: 0.2rem;
50
+ min-width: 2rem;
51
+ height: 1.75rem;
52
+ padding: 0 0.5rem;
53
+ border: 0;
54
+ border-radius: 62.4375rem;
55
+ background: transparent;
56
+ color: var(--text-subtle);
57
+ cursor: pointer;
58
+ font-size: 0.75rem;
59
+ line-height: 1;
60
+ }
61
+
62
+ .view-pick:hover,
63
+ .page-width-pick:hover { color: var(--link); }
64
+ .view-pick.is-current,
65
+ .page-width-pick.is-current { background: var(--subtle-brand); color: var(--link); }
66
+ /* Drawn to Tabler's rules, so they sit with the sprite icons rather than beside them: the stroke is
67
+ stated once here, as .tabler-icon does for the 4,736 in the sprite. */
68
+ .view-mark { display: block; width: 1.125rem; height: 1.125rem; }
69
+ .view-pick .view-mark { opacity: .85; }
70
+ .view-pick.is-current .view-mark,
71
+ .page-width-pick.is-current .view-mark { opacity: 1; }
72
+
73
+ /* ---------- the home page's workspace cards ---------- */
74
+
75
+ /* UIKit's uk-child-width-* classes are what the grid ships with, so they are overridden rather than
76
+ removed: the markup keeps working with no JavaScript, and these take over when a choice is made.
77
+ !important is not needed — the attribute selector out-specifies the class. */
78
+ html[data-home-view="grid-1"] #workspace-cards > * { width: 100%; }
79
+
80
+ /* One across is a column of CARDS, not one card stretched across the window: a 1300px-wide card with
81
+ its name centred in the middle of it is a banner, and it would be the same shape as the list view
82
+ with none of its density. Capped and centred, so it still reads as the card it is. */
83
+ html[data-home-view="grid-1"] .workspace-card { max-width: 32rem; margin-inline: auto; }
84
+ html[data-home-view="grid-2"] #workspace-cards > * { width: 50%; }
85
+ html[data-home-view="grid-3"] #workspace-cards > * { width: 33.333%; }
86
+ html[data-home-view="grid-4"] #workspace-cards > * { width: 25%; }
87
+ html[data-home-view="grid-5"] #workspace-cards > * { width: 20%; }
88
+ html[data-home-view="grid-6"] #workspace-cards > * { width: 16.666%; }
89
+
90
+ /* Past four across the card is narrower than its own status label, so the label wraps instead of
91
+ dragging the card wider — the bug that put a horizontal scrollbar on this page once before. */
92
+ html[data-home-view="grid-5"] .workspace-card .uk-label,
93
+ html[data-home-view="grid-6"] .workspace-card .uk-label { white-space: normal; }
94
+
95
+ /* What uk-text-center and uk-display-block used to do, said here so the list view can undo it. */
96
+ .workspace-card { display: block; text-align: center; }
97
+
98
+ /* List: the card unfolds onto one line — icon, name, what it is, how many — so thirty workspaces can
99
+ be read down a column instead of scanned across a wall of tiles. */
100
+ html[data-home-view="list"] #workspace-cards > * { width: 100%; }
101
+ html[data-home-view="list"] .workspace-card {
102
+ display: flex;
103
+ align-items: center;
104
+ gap: 0.875rem;
105
+ text-align: left;
106
+ padding: 0.5rem 0.875rem;
107
+ }
108
+ html[data-home-view="list"] .workspace-card .icon { margin: 0; flex: none; }
109
+ html[data-home-view="list"] .workspace-card .uk-card-title { flex: none; width: 12rem; }
110
+ html[data-home-view="list"] .workspace-card .uk-text-meta { flex: 1; margin: 0; }
111
+ html[data-home-view="list"] .workspace-card .ws-card-handle { position: static; flex: none; }
112
+ html[data-home-view="list"] .workspace-card .uk-label { margin: 0; flex: none; }
113
+
114
+ /* ---------- a workspace's project rows ---------- */
115
+
116
+ /* List is the default and is what the rows already are, so only the grids need saying. A row in a grid
117
+ keeps everything it has — the buttons wrap instead of sitting on one line. */
118
+ html[data-rows-view^="grid"] #webship-workspace-projects .project-row { margin: 0; }
119
+ html[data-rows-view="grid-1"] #webship-workspace-projects,
120
+ html[data-rows-view="grid-2"] #webship-workspace-projects,
121
+ html[data-rows-view="grid-3"] #webship-workspace-projects {
122
+ display: grid;
123
+ gap: 0.75rem;
124
+ align-items: start;
125
+ }
126
+ /* Same for a workspace: one across is a column of cards down the middle of the page, which is what
127
+ makes it a different answer from the list rather than a second name for it. */
128
+ html[data-rows-view="grid-1"] #webship-workspace-projects { grid-template-columns: 1fr; }
129
+ html[data-rows-view="grid-1"] #webship-workspace-projects .project-row { max-width: 46rem; margin-inline: auto; width: 100%; }
130
+ html[data-rows-view="grid-2"] #webship-workspace-projects { grid-template-columns: repeat(2, minmax(0, 1fr)); }
131
+ html[data-rows-view="grid-3"] #webship-workspace-projects { grid-template-columns: repeat(3, minmax(0, 1fr)); }
132
+
133
+ /* The controls above the rows are not rows: they span the grid rather than becoming a cell in it. */
134
+ html[data-rows-view^="grid"] #webship-workspace-projects > :is(h3, p, .list-controls, .list-pager, .cards-head, .uk-alert) {
135
+ grid-column: 1 / -1;
136
+ }
137
+
138
+ /* Below the breakpoint where a workspace page stacks anyway, a multi-column grid of rows is a column
139
+ of slivers — so the grids collapse and the list is what is left. */
140
+ @media (max-width: 63.99em) {
141
+ html[data-rows-view="grid-2"] #webship-workspace-projects,
142
+ html[data-rows-view="grid-3"] #webship-workspace-projects { grid-template-columns: 1fr; }
143
+ html[data-home-view="grid-3"] #workspace-cards > *,
144
+ html[data-home-view="grid-4"] #workspace-cards > *,
145
+ html[data-home-view="grid-5"] #workspace-cards > *,
146
+ html[data-home-view="grid-6"] #workspace-cards > * { width: 50%; }
147
+ }
148
+
149
+ /* On a page with no list, the width control sits at the end of the heading row rather than in the
150
+ middle of it — the heading is what names the page, and this is a preference beside it. */
151
+ .page-heading .width-switcher { order: 9; margin-left: auto; }
152
+
153
+ /* The help page is a document, so its control goes at the top right on its own rather than beside a
154
+ heading it does not have. */
155
+ .help-head { justify-content: flex-end; margin-bottom: 0; }
156
+
157
+ /* The Screens page, in one, two or three columns.
158
+ *
159
+ * Both children SPAN the container first, and that is not decoration: #webship-workspace-projects is
160
+ * itself a grid — the same one the project rows are laid out in — so a single wrapper dropped into it
161
+ * becomes one cell. Without the span, the toolbar took the first column and the whole list the second,
162
+ * and half the page was empty. The list owns its own columns inside the width it is given. One is the default — see ui.js — and the grid is
163
+ `minmax(0, 1fr)` rather than plain `1fr` so a long session name cannot push a column wider than its
164
+ share: `dev--amd-website_starter-1-0-x-site-template--build` is one unbroken token, and a grid track sized
165
+ to its content is how a list of them ends up scrolling sideways. */
166
+ .screens-toolbar { grid-column: 1 / -1; }
167
+ .screens-list { grid-column: 1 / -1; display: grid; gap: 0; grid-template-columns: minmax(0, 1fr); }
168
+ .screens-list[data-cols="2"] { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 1rem; }
169
+ .screens-list[data-cols="3"] { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0 1rem; }
170
+
171
+ /* Below a laptop there is room for one, whatever was chosen on a wider screen. */
172
+ @media (max-width: 63.9375em) {
173
+ .screens-list[data-cols="2"],
174
+ .screens-list[data-cols="3"] { grid-template-columns: minmax(0, 1fr); }
175
+ }
176
+
177
+ .screens-cols { display: inline-flex; gap: .15rem; margin-right: .35rem; }
178
+
179
+ /* The Screens modal is as wide as what it is showing.
180
+ *
181
+ * It was a flat 1100px whatever was in it, so three columns of session cards came out at 338px each —
182
+ * narrower than the row of buttons inside them — while 463px of a 1563px window went unused. The width
183
+ * follows the column count now, and `min(…, 94vw)` is what keeps it inside the window: a fixed 1900px
184
+ * dialog on a 1440px laptop is a modal with its right-hand column off the screen.
185
+ *
186
+ * The numbers are what each card ends up with, measured rather than picked from a scale: 1146px at one
187
+ * column, 715 at two, 479 at three on a 1634px window — and the cap is what decides the last of those,
188
+ * not the 1900. A card narrower than that is what the page's own three-column view already renders at
189
+ * 412px, so this is the same trade, made where there is more room to give. */
190
+ #editor-modal[data-screens-cols] .uk-modal-dialog { width: min(94vw, 1200px); }
191
+ #editor-modal[data-screens-cols="2"] .uk-modal-dialog { width: min(94vw, 1500px); }
192
+ #editor-modal[data-screens-cols="3"] .uk-modal-dialog { width: min(94vw, 1900px); }
193
+
194
+ /* A session's glyph is a picture of the terminal it opens, scaled with the room the row has. It
195
+ dims when the session has ended and draws the eye, once, when one waits for an answer. */
196
+ .term-glyph { flex: none; width: clamp(3.5rem, 5vw, 5.5rem); height: auto; }
197
+ .screens-list[data-cols="3"] .term-glyph { width: 3.5rem; }
198
+ .screen-tile.is-dead .term-glyph { filter: grayscale(1); opacity: 0.5; }
199
+ .screen-tile.is-waiting .term-glyph-cursor { animation: term-glyph-blink 1.1s steps(2, start) infinite; }
200
+ @keyframes term-glyph-blink { to { visibility: hidden; } }
201
+ @media (prefers-reduced-motion: reduce) {
202
+ .screen-tile.is-waiting .term-glyph-cursor { animation: none; }
203
+ }
@@ -0,0 +1,36 @@
1
+ /* The guide: contents and search on the left, the text on the right. */
2
+ .help-layout { display: grid; grid-template-columns: 15rem minmax(0, 48rem); gap: 2rem; align-items: start; justify-content: center; }
3
+ .help-toc { position: sticky; top: 5rem; max-height: calc(100dvh - 6rem); overflow-y: auto; scrollbar-width: thin; font-size: 0.875rem; }
4
+ .help-find.uk-input { height: 2.25rem; border-radius: 0.5rem; margin-bottom: 0.75rem; }
5
+ .help-toc-label { margin: 0 0 0.25rem; font-size: 0.6875rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-subtle); }
6
+ .help-toc ul { list-style: none; margin: 0; padding: 0; }
7
+ .help-toc ul ul { padding-left: 0.75rem; font-size: 0.8125rem; }
8
+ .help-toc li[hidden] { display: none; }
9
+ .help-toc a { display: block; padding: 0.25rem 0.5rem; border-radius: 0.375rem; color: var(--text-default); text-decoration: none; }
10
+ .help-toc a:hover { background: var(--subtle-brand); color: var(--link); }
11
+ .help-toc a.is-current { background: var(--subtle-brand); color: var(--link); font-weight: 600; }
12
+ .help-toc a:focus-visible { outline: 2px solid var(--brand-primary); outline-offset: -2px; }
13
+ .help-section[hidden] { display: none; }
14
+ .help-section h2 { scroll-margin-top: 5rem; }
15
+ mark.help-hit { background: var(--subtle-brand); color: inherit; border-radius: 0.125rem; padding: 0 0.0625rem; }
16
+ @media (max-width: 59.9375em) {
17
+ .help-layout { grid-template-columns: 1fr; }
18
+ .help-toc { position: static; max-height: none; }
19
+ }
20
+ /* base.css underlines a link in a list item; contents are navigation, not prose. */
21
+ .help-toc li a:not(.uk-button):not(.uk-link-reset) { text-decoration: none; }
22
+ /* "?" beside a page's heading opens the part of the guide about that page. */
23
+ .page-help {
24
+ flex: none; display: inline-flex; align-items: center; justify-content: center; width: 1.75rem; height: 1.75rem;
25
+ margin-left: 0.75rem; border: 1px solid var(--line); border-radius: 50%; color: var(--text-subtle);
26
+ font-weight: 700; font-size: 0.875rem; text-decoration: none;
27
+ }
28
+ .page-help:hover { border-color: var(--brand-primary); color: var(--link); background: var(--subtle-brand); text-decoration: none; }
29
+ .page-help:focus-visible { outline: 2px solid var(--brand-primary); outline-offset: 2px; }
30
+ /* A code block's Copy button. */
31
+ .help-body pre.has-copy { position: relative; padding-right: 4.5rem; }
32
+ .help-copy {
33
+ position: absolute; top: 0.375rem; right: 0.375rem; padding: 0.125rem 0.5rem; border: 1px solid var(--line);
34
+ border-radius: 0.375rem; background: var(--surface-card); color: var(--text-default); font: inherit; font-size: 0.75rem; cursor: pointer;
35
+ }
36
+ .help-copy:hover { border-color: var(--brand-primary); color: var(--link); }
@@ -0,0 +1,16 @@
1
+ /* ---------- Hero ---------- */
2
+
3
+ .logo {
4
+ width:5.25rem;
5
+ height:5.25rem;
6
+ margin: 0 auto;
7
+ border-radius: 50%;
8
+ background: linear-gradient(150deg, var(--brand-primary), var(--brand-secondary));
9
+ display: flex;
10
+ align-items: center;
11
+ justify-content: center;
12
+ font-size:2.5rem;
13
+ box-shadow: 0 10px 24px rgba(30, 135, 240, .35);
14
+ }
15
+
16
+ .logo-sm { width:4.125rem; height:4.125rem; font-size:1.875rem; }
@@ -0,0 +1,70 @@
1
+ /* The images gallery uses the shared file list (.file-list, .fx-row) the docs and videos lists draw;
2
+ these are only what a picture needs on top of it. */
3
+ html[data-files-view^="grid"] .img-row .fx-thumb { cursor: zoom-in; }
4
+ html[data-files-view^="grid"] .img-row .fx-thumb.is-vector img { object-fit: contain; padding: 1.25rem; box-sizing: border-box; }
5
+ .fx-source { display: block; font-size: 0.72rem; font-weight: 400; color: var(--link); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
6
+
7
+ /* The viewer, in the editor modal. */
8
+ .img-viewer-head { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; margin-bottom: 0.5rem; }
9
+ .img-viewer-head h3 { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
10
+ .img-stage {
11
+ display: flex;
12
+ align-items: center;
13
+ justify-content: center;
14
+ max-height: 65vh;
15
+ overflow: auto;
16
+ border-radius: 0.6rem;
17
+ background: var(--surface-muted);
18
+ }
19
+ .img-stage.is-fit { overflow: hidden; }
20
+ .img-stage.is-fit img { max-width: 100%; max-height: 65vh; width: auto; height: auto; object-fit: contain; }
21
+ .img-stage:not(.is-fit) { justify-content: flex-start; align-items: flex-start; }
22
+ .img-stage:not(.is-fit) img { max-width: none; max-height: none; }
23
+ .img-nav { display: flex; justify-content: center; gap: 0.5rem; margin: 0.6rem 0; }
24
+ .img-info { display: grid; grid-template-columns: max-content 1fr; gap: 0.2rem 1rem; margin: 0.5rem 0; }
25
+ .img-info dt { color: var(--text-subtle); font-weight: 400; }
26
+ .img-info dd { margin: 0; overflow-wrap: anywhere; }
27
+ .img-made { border-top: 1px solid var(--line); padding-top: 0.5rem; }
28
+ .img-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0.75rem 0; }
29
+ .img-rename-row { gap: 0.5rem; }
30
+ .img-rename-row .uk-input { max-width: 24rem; }
31
+
32
+ /* Upload: a drop zone that is also the file picker. */
33
+ .img-drop {
34
+ display: flex;
35
+ flex-direction: column;
36
+ align-items: center;
37
+ gap: 0.35rem;
38
+ padding: 2rem 1rem;
39
+ border: 2px dashed var(--line-strong);
40
+ border-radius: 0.6rem;
41
+ text-align: center;
42
+ cursor: pointer;
43
+ color: var(--text-default);
44
+ }
45
+ .img-drop.is-over, .img-drop:hover { border-color: var(--brand-primary); background: var(--subtle-brand); }
46
+ .img-drop-text { font-weight: 600; }
47
+ .img-upload-log { margin-top: 0.75rem; max-height: 14rem; overflow: auto; }
48
+ .img-upload-log .msg { margin: 0; }
49
+ .img-edit { margin-top: 0.5rem; border-top: 1px solid var(--line); padding-top: 0.5rem; }
50
+ .img-edit > summary { cursor: pointer; font-weight: 600; }
51
+
52
+ /* What a generation made, before it is opened. */
53
+ .img-made-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr)); gap: 0.75rem; margin-top: 0.75rem; }
54
+ .img-made-thumb {
55
+ display: block; width: 100%; aspect-ratio: 4 / 3; padding: 0; overflow: hidden; cursor: zoom-in;
56
+ border: 1px solid var(--line); border-radius: 0.6rem; background: var(--surface-muted);
57
+ }
58
+ .img-made-thumb img { width: 100%; height: 100%; object-fit: contain; display: block; }
59
+
60
+ /* An AI prompt is a few lines: its editor leaves room for the provider's fields below it. */
61
+ #editor-modal .img-ai .ace-host:not(.ace-host-single),
62
+ #editor-modal .img-ai-edit .ace-host:not(.ace-host-single) { height: clamp(7rem, 20vh, 12rem) !important; }
63
+
64
+ /* Generate SVG: the palette as colour swatches, and its chips in the plan. */
65
+ .svg-palette { border: 0; padding: 0; margin: 0.5rem 0 0; display: flex; flex-wrap: wrap; gap: 0.75rem; }
66
+ .svg-palette legend { width: 100%; }
67
+ .svg-swatch { display: inline-flex; align-items: center; gap: 0.35rem; font-size: 0.85rem; }
68
+ .svg-swatch input[type="color"] { width: 2rem; height: 1.6rem; padding: 0; border: 1px solid var(--line); border-radius: 0.3rem; background: none; cursor: pointer; }
69
+ .svg-chip { display: inline-block; width: 1rem; height: 1rem; border-radius: 0.2rem; border: 1px solid var(--line); vertical-align: middle; margin-right: 0.15rem; }
70
+ .img-stage picture { display: contents; }
@@ -0,0 +1,139 @@
1
+ /* ---------- Layout rhythm & spacing polish ---------- */
2
+
3
+ .page-body {
4
+ padding-top:1.75rem;
5
+ padding-bottom:3rem;
6
+ }
7
+
8
+ /* Toolbar breathing room */
9
+ .toolbar .uk-navbar-item { padding:0 0.75rem 0 0; min-height:4rem; }
10
+
11
+ /* Workspace cards: even inner padding + consistent vertical spacing */
12
+ .workspace-card { padding:1.5rem 1rem 1.25rem; height: 100%; }
13
+ .workspace-card .icon { margin-bottom:0.75rem; }
14
+ .workspace-card .uk-card-title { margin-top:0.125rem; font-size:1.0625rem; }
15
+ .workspace-card .uk-text-meta { margin-top:0.125rem; min-height: 2.6em; display: block; }
16
+ .workspace-card .uk-label { margin-top:0.625rem; }
17
+
18
+ /* Equal-height card cells */
19
+ .workspace-grid > div, .uk-grid > .uk-position-relative { display: flex; }
20
+ .uk-grid > .uk-position-relative > .workspace-card { flex: 1; }
21
+
22
+ /* Workspaces panel: balanced padding */
23
+ .workspaces-card, .uk-card-body { border-radius:0.75rem; }
24
+
25
+ /* Section headings inside cards */
26
+ .webship-workspace-page .uk-card-body h3 { margin-top:1.5rem; }
27
+ .webship-workspace-page .uk-card-body h3:first-child { margin-top: 0; }
28
+
29
+ /* Project rows: consistent inner spacing */
30
+ .project-row { padding:0.875rem 1.125rem; margin-bottom:0.625rem; }
31
+
32
+ /* Footer: tighter */
33
+ footer.uk-section { padding-top:1.25rem; padding-bottom:1.625rem; }
34
+
35
+ /* Very large screens: cap content width, keep it centered comfortably */
36
+ @media (min-width: 112.5em) {
37
+ .uk-container-xlarge { max-width:97.5rem; }
38
+ }
39
+
40
+ /* Tablets: assistant stacks above with sane spacing */
41
+ @media (max-width: 59.9375em) {
42
+ .page-body { padding-top:1.125rem; }
43
+ .assistant-panel { margin-bottom:0.25rem; }
44
+ }
45
+
46
+ /* Phones: tighter cards, full-width floating assistant */
47
+ @media (max-width: 40em) {
48
+ .workspace-card { padding:1.125rem 0.75rem 1rem; }
49
+ .workspace-card .uk-text-meta { min-height: 0; }
50
+ .project-row { padding:0.75rem 0.875rem; }
51
+ .project-row .uk-flex { gap:0.5rem; }
52
+ .assistant-float {
53
+ right:0.625rem;
54
+ left:0.625rem;
55
+ width: auto;
56
+ bottom:5.375rem;
57
+ }
58
+ .assistant-launcher { left:0.875rem; bottom:0.875rem; }
59
+ .toolbar-logo span { font-size:1.0625rem; }
60
+ }
61
+
62
+ /* The user guide at /help. Rendered from markdown, so it is the one page whose content is
63
+ * long-form prose rather than controls: it needs a measure that can be read, and tables that
64
+ * do not force the page sideways. */
65
+ .help-page { max-width: 52rem; }
66
+ .help-page h1 { margin-top: 0; }
67
+ .help-page h2 { margin-top: 2.25rem; }
68
+ .help-page h3 { margin-top: 1.5rem; }
69
+ .help-page p, .help-page li { line-height: 1.65; }
70
+ .help-page table { width: 100%; display: block; overflow-x: auto; }
71
+ .help-page td, .help-page th { padding: .35rem .6rem; vertical-align: top; }
72
+ /* The guide is mostly command lines, and they are longer than a phone is wide:
73
+ * `bash ~/workspace/core/scripts/trust-https.sh` measured 383px in a 345px viewport and
74
+ * pushed the whole document sideways. Two different fixes, because they are two cases:
75
+ * - a BLOCK of code scrolls inside itself, and must be told it cannot exceed its column;
76
+ * - INLINE code in a sentence has to wrap, and `overflow-wrap: anywhere` is what breaks a
77
+ * path with no spaces in it. (`word-break: break-word` is non-standard and did not.) */
78
+ /* Inline code in the guide is mostly file paths and commands, and the site's own `code`
79
+ * styling sets white-space: nowrap — which BEATS overflow-wrap entirely, so a 425px path sat
80
+ * in a 345px viewport and pushed the document sideways. Both properties are needed, and the
81
+ * nowrap has to be undone first; overflow-wrap alone did nothing, which is what made this
82
+ * look like the rule was not applying.
83
+ * Blocks keep `pre` semantics and scroll inside themselves instead. */
84
+ .help-page :not(pre) > code {
85
+ white-space: normal;
86
+ overflow-wrap: anywhere;
87
+ }
88
+ /* Pandoc wraps a fenced block as div.sourceCode > pre > code, and it is the DIV that has to
89
+ * be constrained: constraining only the pre left the div sizing itself to an 784px line in a
90
+ * 345px viewport, which is what actually pushed the page. */
91
+ .help-page pre,
92
+ .help-page div.sourceCode { max-width: 100%; overflow-x: auto; }
93
+ .help-page pre code { overflow-wrap: normal; white-space: pre; }
94
+ .help-page hr { margin: 2rem 0 1rem; }
95
+
96
+ /* ---- keyboard access ------------------------------------------------------------------
97
+ * Measured by walking Tab through /dev: the page's own content — the build form, the project
98
+ * list — was tab stop EIGHTEEN, after the toolbar, the whole assistant panel and eleven rail
99
+ * controls. That is the cost of a rich chrome, and a skip link is the standard answer.
100
+ *
101
+ * Invisible until focused, then a real target at the top-left. It must never be
102
+ * `display: none` or `visibility: hidden`: both remove it from the tab order, which is the
103
+ * usual way a skip link ends up not working. */
104
+ .skip-link {
105
+ position: absolute;
106
+ left: .5rem;
107
+ top: -3rem;
108
+ z-index: 1100;
109
+ padding: .5rem .85rem;
110
+ background: var(--brand-primary);
111
+ color: var(--text-inverse);
112
+ border-radius: 0 0 8px 8px;
113
+ font-size: .8125rem;
114
+ text-decoration: none;
115
+ transition: top .12s ease-out;
116
+ }
117
+
118
+ .skip-link:focus,
119
+ .skip-link:focus-visible {
120
+ top: 0;
121
+ outline: 2px solid var(--text-default);
122
+ outline-offset: 2px;
123
+ }
124
+
125
+ @media (prefers-reduced-motion: reduce) {
126
+ .skip-link { transition: none; }
127
+ }
128
+
129
+ /* The target takes focus programmatically, so it must not draw a ring of its own when the
130
+ * skip link sends the caret there. */
131
+ #main-content:focus { outline: none; }
132
+
133
+ /* UIKit's checkbox draws no focus ring at all, so it was the one control on the page a
134
+ * keyboard user could land on without seeing where they were. */
135
+ .uk-checkbox:focus-visible,
136
+ .uk-radio:focus-visible {
137
+ outline: 2px solid var(--brand-primary);
138
+ outline-offset: 2px;
139
+ }