domma-cms 0.55.1 → 0.69.3

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 (305) hide show
  1. package/CLAUDE.md +194 -3
  2. package/README.md +18 -14
  3. package/admin/css/admin.css +1 -1
  4. package/admin/css/contacts.css +1 -0
  5. package/admin/dist/domma/domma-tools.css +3 -3
  6. package/admin/dist/domma/domma-tools.min.js +3 -3
  7. package/admin/index.html +1 -0
  8. package/admin/js/api.js +1 -1
  9. package/admin/js/app.js +4 -4
  10. package/admin/js/lib/analytics-shape.js +1 -0
  11. package/admin/js/lib/contacts-arrange.js +1 -0
  12. package/admin/js/lib/help-popover.js +1 -0
  13. package/admin/js/lib/notes-arrange.js +1 -0
  14. package/admin/js/lib/page-picker.js +1 -0
  15. package/admin/js/lib/plugin-accent.js +1 -0
  16. package/admin/js/lib/plugin-chrome.js +1 -0
  17. package/admin/js/lib/shortcode-context-menu.js +2 -2
  18. package/admin/js/lib/sidebar-grouping.js +1 -1
  19. package/admin/js/lib/sidebar-grouping.test.js +1 -1
  20. package/admin/js/lib/sidebar-renderer.js +4 -4
  21. package/admin/js/lib/slideover-resizable.js +1 -0
  22. package/admin/js/lib/todo-arrange.js +1 -0
  23. package/admin/js/lib/tool-kit.js +1 -0
  24. package/admin/js/templates/analytics.html +138 -0
  25. package/admin/js/templates/contacts.html +156 -0
  26. package/admin/js/templates/context-menu-editor.html +212 -0
  27. package/admin/js/templates/context-menus.html +16 -0
  28. package/admin/js/templates/notes.html +137 -0
  29. package/admin/js/templates/plugin-code.html +1 -1
  30. package/admin/js/templates/plugin-marketplace.html +17 -4
  31. package/admin/js/templates/plugins.html +13 -7
  32. package/{plugins/site-search/admin/templates/site-search.html → admin/js/templates/search.html} +50 -4
  33. package/admin/js/templates/settings.html +16 -97
  34. package/admin/js/templates/theme.html +211 -0
  35. package/admin/js/templates/todo.html +113 -0
  36. package/admin/js/views/analytics.js +62 -0
  37. package/admin/js/views/contacts.js +174 -0
  38. package/admin/js/views/context-menu-editor.js +55 -0
  39. package/admin/js/views/context-menus.js +5 -0
  40. package/admin/js/views/form-editor.js +7 -7
  41. package/admin/js/views/index.js +1 -1
  42. package/admin/js/views/notes.js +104 -0
  43. package/admin/js/views/plugin-marketplace.js +1 -1
  44. package/admin/js/views/plugins.js +28 -24
  45. package/admin/js/views/search.js +1 -0
  46. package/admin/js/views/settings.js +3 -3
  47. package/admin/js/views/theme.js +1 -0
  48. package/admin/js/views/todo.js +96 -0
  49. package/bin/cli.js +6 -10
  50. package/bin/lib/plugin-version.js +28 -0
  51. package/bin/update.js +27 -2
  52. package/config/menus/admin-sidebar.json +129 -23
  53. package/config/plugins.json +5 -5
  54. package/config/search.json +13 -0
  55. package/config/server.json +3 -1
  56. package/package.json +14 -10
  57. package/plugins/_lib/admin/mail/compose-window.js +914 -0
  58. package/plugins/_lib/admin/mail/contacts.js +301 -0
  59. package/plugins/_lib/admin/mail/diagnostics-section.js +133 -0
  60. package/plugins/_lib/admin/mail/folder-tree.js +254 -0
  61. package/plugins/_lib/admin/mail/identity.js +480 -0
  62. package/plugins/_lib/admin/mail/image-senders-section.js +131 -0
  63. package/plugins/_lib/admin/mail/keyboard.js +136 -0
  64. package/plugins/_lib/admin/mail/mail.css +1 -0
  65. package/plugins/_lib/admin/mail/mail.html +71 -0
  66. package/plugins/_lib/admin/mail/panes.js +253 -0
  67. package/plugins/_lib/admin/mail/reader-view.js +4473 -0
  68. package/plugins/_lib/admin/mail/resizable.js +26 -0
  69. package/plugins/_lib/admin/mail/rules.js +343 -0
  70. package/plugins/_lib/admin/mail/scheduling.js +203 -0
  71. package/plugins/_lib/admin/mail/section-kit.js +277 -0
  72. package/plugins/_lib/admin/mail/templates.js +238 -0
  73. package/plugins/_lib/admin/mail/threads.js +200 -0
  74. package/plugins/_lib/admin/mail/vacation.js +269 -0
  75. package/plugins/_lib/admin/ui/help.css +1 -0
  76. package/plugins/_lib/admin/ui/help.js +174 -0
  77. package/plugins/_lib/admin/ui/resizable.js +151 -0
  78. package/plugins/_lib/dataStore.js +117 -0
  79. package/plugins/_lib/mail/accounts.js +919 -0
  80. package/plugins/_lib/mail/bodyTokens.js +101 -0
  81. package/plugins/_lib/mail/compose.js +256 -0
  82. package/plugins/_lib/mail/defaults.js +57 -0
  83. package/plugins/_lib/mail/diagnostics.js +154 -0
  84. package/plugins/_lib/mail/envelope.js +161 -0
  85. package/plugins/_lib/mail/folders.js +192 -0
  86. package/plugins/_lib/mail/handoff.js +274 -0
  87. package/plugins/_lib/mail/imapPool.js +293 -0
  88. package/plugins/_lib/mail/mbox.js +74 -0
  89. package/plugins/_lib/mail/pollSchedule.js +79 -0
  90. package/plugins/_lib/mail/poller.js +135 -0
  91. package/plugins/_lib/mail/priority.js +138 -0
  92. package/plugins/_lib/mail/readRoutes.js +680 -0
  93. package/plugins/_lib/mail/render.js +291 -0
  94. package/plugins/_lib/mail/ruleRunner.js +152 -0
  95. package/plugins/_lib/mail/scheduler.js +254 -0
  96. package/plugins/_lib/mail/secretbox.js +229 -0
  97. package/plugins/_lib/mail/send.js +396 -0
  98. package/plugins/_lib/mail/store.js +1022 -0
  99. package/plugins/_lib/mail/sync.js +292 -0
  100. package/plugins/_lib/mail/syncPlan.js +126 -0
  101. package/plugins/_lib/mail/syncSelection.js +82 -0
  102. package/plugins/_lib/mail/unsubscribe.js +183 -0
  103. package/plugins/_lib/mail/vacationRunner.js +114 -0
  104. package/plugins/_lib/mail/write.js +473 -0
  105. package/plugins/_lib/schemaSync.js +83 -0
  106. package/plugins/_template/admin/css/index.css +0 -0
  107. package/plugins/_template/admin/templates/index.html +4 -4
  108. package/plugins/_template/admin/views/index.js +7 -0
  109. package/plugins/blog/CLAUDE.md +237 -0
  110. package/plugins/blog/admin/css/index.css +178 -0
  111. package/plugins/blog/admin/templates/blog.html +35 -41
  112. package/plugins/blog/admin/templates/categories.html +19 -6
  113. package/plugins/blog/admin/templates/comments.html +26 -9
  114. package/plugins/blog/admin/templates/post-editor.html +63 -40
  115. package/plugins/blog/admin/templates/settings.html +3 -9
  116. package/plugins/blog/admin/views/blog.js +288 -159
  117. package/plugins/blog/admin/views/categories.js +212 -206
  118. package/plugins/blog/admin/views/comments.js +207 -158
  119. package/plugins/blog/admin/views/kit.js +372 -0
  120. package/plugins/blog/admin/views/post-editor.js +306 -39
  121. package/plugins/blog/admin/views/settings-cog.js +56 -0
  122. package/plugins/blog/admin/views/settings.js +16 -84
  123. package/plugins/blog/blocks/blog-card-compact.css +17 -0
  124. package/plugins/blog/blocks/blog-card-compact.html +8 -0
  125. package/plugins/blog/blocks/blog-card-row.css +22 -0
  126. package/plugins/blog/blocks/blog-card-row.html +11 -0
  127. package/plugins/blog/blocks/blog-card.css +35 -0
  128. package/plugins/blog/blocks/blog-card.html +16 -0
  129. package/plugins/blog/blocks/blog-post-classic.css +15 -0
  130. package/plugins/blog/blocks/blog-post-classic.html +28 -0
  131. package/plugins/blog/blocks/blog-post-feature.css +20 -0
  132. package/plugins/blog/blocks/blog-post-feature.html +30 -0
  133. package/plugins/blog/blocks/blog-post-minimal.css +10 -0
  134. package/plugins/blog/blocks/blog-post-minimal.html +23 -0
  135. package/plugins/blog/blocks/blog-post-sidebar.css +22 -0
  136. package/plugins/blog/blocks/blog-post-sidebar.html +36 -0
  137. package/plugins/blog/collections/categories/schema.json +7 -6
  138. package/plugins/blog/collections/comments/schema.json +11 -10
  139. package/plugins/blog/collections/posts/schema.json +16 -13
  140. package/plugins/blog/config.js +6 -0
  141. package/plugins/blog/lib/layouts.js +304 -0
  142. package/plugins/blog/lib/page.js +158 -0
  143. package/plugins/blog/lib/render.js +119 -0
  144. package/plugins/blog/lib/samples.js +234 -0
  145. package/plugins/blog/plugin.js +259 -26
  146. package/plugins/blog/plugin.json +21 -73
  147. package/plugins/blog/plugin.public.js +217 -0
  148. package/plugins/blog/public/blog.css +177 -0
  149. package/plugins/blog/public/blog.js +586 -0
  150. package/plugins/blog/public/samples/aurora.svg +7 -0
  151. package/plugins/blog/public/samples/dusk.svg +7 -0
  152. package/plugins/blog/public/samples/ember.svg +7 -0
  153. package/plugins/blog/public/samples/harbour.svg +7 -0
  154. package/plugins/blog/public/samples/meadow.svg +7 -0
  155. package/plugins/blog/public/samples/rosewood.svg +7 -0
  156. package/plugins/blog/templates/index.html +9 -8
  157. package/plugins/blog/templates/post.html +4 -17
  158. package/plugins/blog/tests/layouts.test.js +97 -0
  159. package/plugins/blog/tests/public.test.js +71 -0
  160. package/plugins/free-tier.lock.json +74 -0
  161. package/plugins/mail-reader/CLAUDE.md +78 -0
  162. package/plugins/mail-reader/admin/views/mail.js +19 -0
  163. package/plugins/mail-reader/config.js +7 -0
  164. package/plugins/mail-reader/plugin.js +48 -0
  165. package/plugins/mail-reader/plugin.json +34 -0
  166. package/public/css/forms.css +1 -1
  167. package/public/css/search.css +1 -0
  168. package/public/css/site.css +1 -1
  169. package/public/css/theme-switcher.css +1 -0
  170. package/public/js/analytics.js +1 -0
  171. package/public/js/collection-context.js +2 -2
  172. package/public/js/context-menus.js +1 -0
  173. package/public/js/form-logic-engine.js +1 -1
  174. package/public/js/forms.js +2 -2
  175. package/public/js/search.js +1 -0
  176. package/public/js/site.js +1 -1
  177. package/public/js/theme-switcher.js +1 -0
  178. package/scripts/build.js +77 -4
  179. package/scripts/copy-domma.js +48 -0
  180. package/scripts/run-tests.mjs +92 -0
  181. package/scripts/seed.js +1996 -0
  182. package/{plugins/analytics/plugin.js → server/routes/api/analytics.js} +89 -41
  183. package/server/routes/api/collections.js +34 -0
  184. package/server/routes/api/contacts.js +506 -0
  185. package/server/routes/api/context-menus.js +104 -0
  186. package/server/routes/api/dashboard.js +8 -2
  187. package/server/routes/api/forms.js +42 -3
  188. package/{plugins/notes/plugin.js → server/routes/api/notes.js} +61 -17
  189. package/server/routes/api/notifications.js +69 -19
  190. package/server/routes/api/plugin-marketplace.js +78 -23
  191. package/server/routes/api/plugins.js +198 -9
  192. package/server/routes/api/search.js +43 -0
  193. package/server/routes/api/theme.js +69 -0
  194. package/server/routes/api/todo.js +178 -0
  195. package/server/routes/public.js +42 -7
  196. package/server/server.js +135 -1
  197. package/server/services/adapters/FileAdapter.js +6 -1
  198. package/server/services/collections.js +13 -3
  199. package/server/services/content.js +26 -0
  200. package/server/services/contextMenus.js +477 -0
  201. package/server/services/managerClient.js +72 -136
  202. package/server/services/markdown.js +124 -10
  203. package/server/services/permissionRegistry.js +74 -0
  204. package/server/services/pluginEntitlement.js +171 -0
  205. package/server/services/pluginEnvelope.js +242 -0
  206. package/server/services/pluginFiles.js +52 -11
  207. package/server/services/pluginInstaller.js +246 -26
  208. package/server/services/pluginScaffold.js +5 -0
  209. package/server/services/plugins.js +340 -7
  210. package/server/services/presetCollections.js +344 -0
  211. package/server/services/promoted-plugins-migration.js +254 -0
  212. package/server/services/publicCors.js +46 -0
  213. package/server/services/renderer.js +224 -22
  214. package/server/services/roles.js +1 -1
  215. package/server/services/search-migration.js +82 -0
  216. package/server/services/search.js +413 -0
  217. package/server/services/sidebar-migration.js +1 -0
  218. package/server/services/sidebarBadges.js +37 -0
  219. package/server/services/siteGitignore.js +307 -0
  220. package/server/services/themeSettings.js +580 -0
  221. package/server/services/users.js +8 -0
  222. package/server/templates/page.html +4 -2
  223. package/plugins/analytics/admin/templates/analytics.html +0 -61
  224. package/plugins/analytics/admin/views/analytics.js +0 -176
  225. package/plugins/analytics/config.js +0 -14
  226. package/plugins/analytics/plugin.json +0 -57
  227. package/plugins/analytics/public/inject-body.html +0 -60
  228. package/plugins/analytics/public/inject-head.html +0 -1
  229. package/plugins/blog/templates/author.html +0 -9
  230. package/plugins/blog/templates/category.html +0 -9
  231. package/plugins/blog/templates/tag.html +0 -9
  232. package/plugins/contacts/admin/templates/contacts.html +0 -126
  233. package/plugins/contacts/admin/views/contacts.js +0 -710
  234. package/plugins/contacts/collections/user-contact-groups/schema.json +0 -35
  235. package/plugins/contacts/collections/user-contacts/schema.json +0 -71
  236. package/plugins/contacts/config.js +0 -6
  237. package/plugins/contacts/data/contacts.json +0 -20
  238. package/plugins/contacts/plugin.js +0 -291
  239. package/plugins/contacts/plugin.json +0 -33
  240. package/plugins/demo-viewer/config.js +0 -4
  241. package/plugins/demo-viewer/plugin.js +0 -36
  242. package/plugins/demo-viewer/plugin.json +0 -9
  243. package/plugins/invoice/admin/templates/editor.html +0 -129
  244. package/plugins/invoice/admin/templates/index.html +0 -43
  245. package/plugins/invoice/admin/templates/issuers.html +0 -5
  246. package/plugins/invoice/admin/templates/receivers.html +0 -5
  247. package/plugins/invoice/admin/views/editor.js +0 -267
  248. package/plugins/invoice/admin/views/index.js +0 -155
  249. package/plugins/invoice/admin/views/issuers.js +0 -23
  250. package/plugins/invoice/admin/views/party-view.js +0 -148
  251. package/plugins/invoice/admin/views/receivers.js +0 -22
  252. package/plugins/invoice/collections/invoice-issuers/schema.json +0 -16
  253. package/plugins/invoice/collections/invoice-receivers/schema.json +0 -15
  254. package/plugins/invoice/collections/invoices/schema.json +0 -27
  255. package/plugins/invoice/config.js +0 -16
  256. package/plugins/invoice/plugin.js +0 -283
  257. package/plugins/invoice/plugin.json +0 -85
  258. package/plugins/invoice/templates/invoice-print.html +0 -213
  259. package/plugins/notes/admin/templates/notes.html +0 -83
  260. package/plugins/notes/admin/views/notes.js +0 -281
  261. package/plugins/notes/collections/user-notes/schema.json +0 -54
  262. package/plugins/notes/config.js +0 -6
  263. package/plugins/notes/data/notes.json +0 -1
  264. package/plugins/notes/plugin.json +0 -33
  265. package/plugins/site-search/admin/views/site-search.js +0 -116
  266. package/plugins/site-search/config.js +0 -15
  267. package/plugins/site-search/plugin.js +0 -188
  268. package/plugins/site-search/plugin.json +0 -40
  269. package/plugins/site-search/public/inject-body.html +0 -17
  270. package/plugins/site-search/public/inject-head.html +0 -1
  271. package/plugins/site-search/public/search.css +0 -1
  272. package/plugins/site-search/public/search.js +0 -1
  273. package/plugins/surveys/admin/templates/audience.html +0 -47
  274. package/plugins/surveys/admin/templates/results.html +0 -58
  275. package/plugins/surveys/admin/templates/survey-editor.html +0 -141
  276. package/plugins/surveys/admin/templates/surveys.html +0 -25
  277. package/plugins/surveys/admin/views/audience.js +0 -301
  278. package/plugins/surveys/admin/views/results.js +0 -172
  279. package/plugins/surveys/admin/views/survey-editor.js +0 -211
  280. package/plugins/surveys/admin/views/surveys.js +0 -161
  281. package/plugins/surveys/collections/survey-contacts/schema.json +0 -13
  282. package/plugins/surveys/collections/survey-groups/schema.json +0 -11
  283. package/plugins/surveys/collections/survey-invites/schema.json +0 -16
  284. package/plugins/surveys/collections/surveys/schema.json +0 -23
  285. package/plugins/surveys/config.js +0 -8
  286. package/plugins/surveys/plugin.js +0 -174
  287. package/plugins/surveys/plugin.json +0 -65
  288. package/plugins/surveys/public/dist-shared.mjs +0 -1
  289. package/plugins/surveys/public/survey.css +0 -1
  290. package/plugins/surveys/public/survey.mjs +0 -1
  291. package/plugins/surveys/templates/survey-page.html +0 -63
  292. package/plugins/theme-switcher/admin/templates/theme-switcher.html +0 -86
  293. package/plugins/theme-switcher/admin/views/theme-switcher.js +0 -65
  294. package/plugins/theme-switcher/config.js +0 -10
  295. package/plugins/theme-switcher/plugin.js +0 -26
  296. package/plugins/theme-switcher/plugin.json +0 -74
  297. package/plugins/theme-switcher/public/inject-body.html +0 -153
  298. package/plugins/theme-switcher/public/inject-head.html +0 -260
  299. package/plugins/todo/admin/templates/todo.html +0 -158
  300. package/plugins/todo/admin/views/todo.js +0 -343
  301. package/plugins/todo/collections/todos/schema.json +0 -60
  302. package/plugins/todo/config.js +0 -7
  303. package/plugins/todo/data/todos.json +0 -1
  304. package/plugins/todo/plugin.js +0 -102
  305. package/plugins/todo/plugin.json +0 -33
@@ -0,0 +1,137 @@
1
+ <!-- No heading: the banner above (admin/js/lib/plugin-chrome.js) is the title.
2
+ Everything that changes is bound (M.applyBindings) - see admin/js/views/notes.js. -->
3
+ <div class="notes-tool">
4
+
5
+ <!-- One compact bar: find, filter, count, layout, new. -->
6
+ <div class="notes-bar">
7
+ <label class="notes-search">
8
+ <span data-icon="search" data-icon-size="14"></span>
9
+ <input type="search" class="form-input" placeholder="Search notes…" aria-label="Search notes"
10
+ data-model="query.value" data-focus="searchFocus.value">
11
+ </label>
12
+ <select class="form-input notes-cat-select" aria-label="Filter by category"
13
+ data-options="categories.value" data-options-caption="'All categories'"
14
+ data-model="category.value"></select>
15
+ <span data-help-title="Finding notes"
16
+ data-help="Search matches titles, content and categories as you type. Pick a category to narrow the list, or click a category chip on any note. Press / to jump to search."></span>
17
+
18
+ <span class="notes-count" data-bind-text="countText.value"></span>
19
+
20
+ <div class="notes-bar-end">
21
+ <div class="notes-layout" role="group" aria-label="Layout">
22
+ <button type="button" class="btn btn-sm btn-ghost" title="Cards" aria-label="Card layout"
23
+ data-bind-class="isCards.value && 'is-active'" data-on-click="useCards">
24
+ <span data-icon="grid" data-icon-size="15"></span>
25
+ </button>
26
+ <button type="button" class="btn btn-sm btn-ghost" title="List" aria-label="List layout"
27
+ data-bind-class="!isCards.value && 'is-active'" data-on-click="useList">
28
+ <span data-icon="list" data-icon-size="15"></span>
29
+ </button>
30
+ </div>
31
+ <button type="button" class="btn btn-sm btn-primary" data-on-click="create" title="New note (N)">
32
+ <span data-icon="plus" data-icon-size="14"></span> New
33
+ </button>
34
+ </div>
35
+ </div>
36
+
37
+ <p class="notes-state" data-if="loading.value">Loading notes…</p>
38
+ <p class="notes-state" data-if="isEmpty.value" data-bind-text="emptyText.value"></p>
39
+
40
+ <!-- Right-click a note (or its ⋮) for everything you can do to it. -->
41
+ <div class="notes-list" data-bind-class="listClass.value">
42
+ <!-- The item template is inserted by notes.js (CARD_TEMPLATE): the router
43
+ renders this file through _.render first, which would eat its {{…}}. -->
44
+ <div class="notes-items" data-each="visible.value key=id"></div>
45
+ </div>
46
+ </div>
47
+
48
+ <style>
49
+ .notes-tool { display: flex; flex-direction: column; gap: .75rem; }
50
+
51
+ .notes-bar { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
52
+ .notes-search { position: relative; flex: 1 1 200px; max-width: 320px; margin: 0; }
53
+ .notes-search > svg, .notes-search > [data-icon] {
54
+ position: absolute; left: .6rem; top: 50%; transform: translateY(-50%);
55
+ color: var(--dm-text-muted); pointer-events: none;
56
+ }
57
+ .notes-search .form-input { padding-left: 1.9rem; height: 2rem; }
58
+ .notes-cat-select { width: auto; min-width: 9rem; max-width: 14rem; height: 2rem; padding-top: 0; padding-bottom: 0; }
59
+ .notes-count { font-size: var(--dm-text-xs); color: var(--dm-text-muted); white-space: nowrap; }
60
+ .notes-bar-end { display: flex; align-items: center; gap: .5rem; margin-left: auto; }
61
+ .notes-layout { display: inline-flex; border: 1px solid var(--dm-border); border-radius: var(--dm-radius-md); overflow: hidden; }
62
+ .notes-layout .btn { border-radius: 0; padding: .25rem .45rem; line-height: 1; color: var(--dm-text-muted); }
63
+ .notes-layout .btn.is-active { background: var(--dm-surface-hover, rgba(127,127,127,.15)); color: var(--dm-primary); }
64
+
65
+ .notes-state { margin: 1.5rem 0; text-align: center; color: var(--dm-text-muted); }
66
+
67
+ /* Cards: a responsive grid. */
68
+ .notes-list.is-cards .notes-items {
69
+ display: grid; gap: .75rem;
70
+ grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
71
+ }
72
+ .note-card {
73
+ position: relative; display: flex; flex-direction: column; gap: .4rem; min-width: 0;
74
+ padding: .75rem .85rem; cursor: pointer;
75
+ background: var(--dm-surface); border: 1px solid var(--dm-border); border-radius: var(--dm-radius-md);
76
+ transition: border-color var(--dm-transition-fast);
77
+ }
78
+ .note-card:hover, .note-card:focus-visible { border-color: var(--dm-primary); outline: none; }
79
+ .note-title { margin: 0; padding-right: 1.5rem; font-size: var(--dm-text-sm); font-weight: 600; overflow-wrap: anywhere; }
80
+ .note-kebab {
81
+ position: absolute; top: .45rem; right: .4rem;
82
+ border: 0; background: none; cursor: pointer; padding: 0 .3rem;
83
+ font-size: var(--dm-text-lg); line-height: 1.2; color: var(--dm-text-muted); border-radius: var(--dm-radius-sm);
84
+ }
85
+ .note-kebab:hover { color: var(--dm-primary); background: var(--dm-surface-hover, rgba(127,127,127,.15)); }
86
+ .note-preview { margin: 0; font-size: var(--dm-text-sm); color: var(--dm-text-muted); white-space: pre-line; overflow-wrap: anywhere; }
87
+ .note-preview:empty { display: none; }
88
+ .note-foot { display: flex; align-items: center; gap: .5rem; margin-top: auto; }
89
+ .note-cats { display: flex; flex-wrap: wrap; gap: .25rem; flex: 1; min-width: 0; }
90
+ .note-cat {
91
+ font-size: var(--dm-text-xs); padding: .05rem .45rem; border-radius: 999px; cursor: pointer;
92
+ background: var(--dm-surface-hover, rgba(127,127,127,.15)); color: var(--dm-text);
93
+ }
94
+ .note-cat:hover { background: var(--dm-primary); color: var(--dm-text-inverse, #fff); }
95
+ .note-time { font-size: var(--dm-text-xs); color: var(--dm-text-muted); white-space: nowrap; }
96
+ .notes-list.hide-cats .note-cats { visibility: hidden; }
97
+
98
+ /* List: one dense row per note. */
99
+ .notes-list.is-list .notes-items {
100
+ display: flex; flex-direction: column;
101
+ border: 1px solid var(--dm-border); border-radius: var(--dm-radius-md); overflow: hidden;
102
+ }
103
+ .notes-list.is-list .note-card {
104
+ flex-direction: row; align-items: center; gap: .75rem;
105
+ padding: .45rem .5rem .45rem .75rem; border: 0; border-radius: 0; border-bottom: 1px solid var(--dm-border);
106
+ }
107
+ .notes-list.is-list .note-card:last-child { border-bottom: 0; }
108
+ .notes-list.is-list .note-card:hover { background: var(--dm-surface-hover, rgba(127,127,127,.08)); }
109
+ .notes-list.is-list .note-title {
110
+ flex: 0 0 28%; padding: 0; font-size: var(--dm-text-sm); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
111
+ }
112
+ .notes-list.is-list .note-preview { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
113
+ .notes-list.is-list .note-preview:empty { display: block; }
114
+ .notes-list.is-list .note-foot { flex: 0 0 auto; margin: 0; }
115
+ .notes-list.is-list .note-cats { flex: 0 1 auto; flex-wrap: nowrap; }
116
+ .notes-list.is-list .note-kebab { position: static; }
117
+ @media (max-width: 640px) {
118
+ .notes-list.is-list .note-preview { display: none; }
119
+ .notes-list.is-list .note-title { flex: 1; }
120
+ }
121
+
122
+ /* The editor and settings slideovers. */
123
+ .notes-panel { display: flex; flex-direction: column; gap: 1rem; padding: .25rem 0 .5rem; height: 100%; }
124
+ .notes-panel .form-label { display: flex; align-items: center; font-weight: 500; margin-bottom: .3rem; }
125
+ .notes-panel textarea { min-height: 260px; resize: vertical; font-family: inherit; line-height: 1.5; }
126
+ .notes-panel .notes-field-grow { flex: 1; display: flex; flex-direction: column; }
127
+ .notes-panel .notes-field-grow textarea { flex: 1; }
128
+ .notes-panel-meta { font-size: var(--dm-text-xs); color: var(--dm-text-muted); display: flex; justify-content: space-between; gap: .5rem; }
129
+ .notes-panel-actions { display: flex; align-items: center; gap: .5rem; padding-top: .75rem; border-top: 1px solid var(--dm-border); }
130
+ .notes-panel-actions .spacer { flex: 1; }
131
+ .notes-setting { display: flex; flex-direction: column; gap: .3rem; }
132
+ .notes-setting-row { display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
133
+ .notes-setting small { color: var(--dm-text-muted); }
134
+ .notes-range { display: flex; align-items: center; gap: .6rem; }
135
+ .notes-range input { flex: 1; }
136
+ .notes-range output { min-width: 3.5rem; text-align: right; font-variant-numeric: tabular-nums; font-size: var(--dm-text-sm); }
137
+ </style>
@@ -68,7 +68,7 @@
68
68
  <span class="pcode-current" id="pcode-current">Select a file</span>
69
69
  <span style="flex:1"></span>
70
70
  <button id="pcode-rename" class="btn btn-sm btn-ghost" title="Rename file" disabled><span data-icon="edit-3"></span></button>
71
- <button id="pcode-delete" class="btn btn-sm btn-ghost" title="Delete file" disabled><span data-icon="trash-2"></span></button>
71
+ <button id="pcode-delete" class="btn btn-sm btn-ghost" title="Delete file" disabled><span data-icon="trash"></span></button>
72
72
  <button id="pcode-saveall" class="btn btn-sm btn-ghost" disabled>Save All</button>
73
73
  <button id="pcode-save" class="btn btn-sm btn-primary" disabled><span data-icon="save"></span> Save</button>
74
74
  </div>
@@ -1,16 +1,29 @@
1
1
  <div class="view-header">
2
- <h2><span data-icon="store"></span> Plugin Marketplace</h2>
3
- <p class="text-muted">Install premium plugins from the Domma manager.</p>
2
+ <h2><span data-icon="store"></span> Browse</h2>
3
+ <p class="text-muted">Plugins available to this site.</p>
4
4
  </div>
5
5
 
6
+ <!--
7
+ Shown when this site is not managed. Telling an unmanaged customer to set
8
+ MANAGER_URL is telling them to configure something they will never have: a
9
+ standalone purchase arrives as a file, and Install from File is the whole
10
+ procedure. The managed path is mentioned second because it is not theirs to
11
+ set up.
12
+ -->
6
13
  <div id="marketplace-unavailable" style="display:none">
7
14
  <div class="card">
8
- <div class="card-body text-center">
9
- <p>The Domma Manager is not configured. Set <code>MANAGER_URL</code> and <code>LICENCE_TOKEN</code> in your <code>.env</code> to enable the marketplace.</p>
15
+ <div class="card-body">
16
+ <p><strong>This site installs plugins from a file.</strong></p>
17
+ <p class="text-muted">Buy a plugin and you are sent a single <code>.dcmsplugin</code> file. Use
18
+ <strong>Install from File</strong> above to install it - no connection to anything is needed, and the
19
+ same button takes an update later.</p>
20
+ <p class="text-muted" style="margin-bottom:0">Sites managed for you browse and install here instead, over their
21
+ manager connection.</p>
10
22
  </div>
11
23
  </div>
12
24
  </div>
13
25
 
14
26
  <div id="marketplace-available" style="display:none">
27
+ <p id="marketplace-site" class="text-muted" style="display:none;font-size:.85rem;margin:0 0 .75rem"></p>
15
28
  <div id="marketplace-grid" class="card-grid"></div>
16
29
  </div>
@@ -1,17 +1,23 @@
1
1
  <div class="view-header d-flex justify-content-between align-items-center">
2
2
  <div>
3
- <h1><span data-icon="package"></span> Plugins</h1>
4
- <p class="text-muted" style="margin:0;font-size:.875rem">Plugins extend the CMS with new features. Changes take effect after a server restart.</p>
3
+ <h1><span data-icon="store"></span> Marketplace</h1>
4
+ <p class="text-muted" style="margin:0;font-size:.875rem">Install plugins to add features. Once enabled, a plugin appears under Tools. Changes take effect after a server restart.</p>
5
5
  </div>
6
- <button id="new-plugin-btn" class="btn btn-primary">
7
- <span data-icon="plus"></span> New Plugin
8
- </button>
6
+ <div style="display:flex;gap:.5rem;align-items:center;">
7
+ <button id="install-file-btn" class="btn btn-secondary" title="Install a .dcmsplugin file">
8
+ <span data-icon="upload"></span> Install from File
9
+ </button>
10
+ <button id="new-plugin-btn" class="btn btn-primary">
11
+ <span data-icon="plus"></span> New Plugin
12
+ </button>
13
+ </div>
14
+ <input type="file" id="install-file-input" accept=".dcmsplugin" hidden>
9
15
  </div>
10
16
 
11
17
  <div id="plugin-tabs" class="tabs">
12
18
  <div class="tab-list">
13
- <button class="tab-item active" data-tab="installed">Installed Plugins</button>
14
- <button class="tab-item" data-tab="marketplace">Marketplace</button>
19
+ <button class="tab-item active" data-tab="installed">Installed</button>
20
+ <button class="tab-item" data-tab="marketplace">Browse</button>
15
21
  </div>
16
22
 
17
23
  <div class="tab-panel active" data-panel="installed">
@@ -1,5 +1,5 @@
1
1
  <div class="view-header">
2
- <h1><span data-icon="search"></span> Site Search</h1>
2
+ <h1><span data-icon="search"></span> Search</h1>
3
3
  <div>
4
4
  <button id="save-settings-btn" class="btn btn-primary">
5
5
  <span data-icon="save"></span> Save
@@ -20,6 +20,16 @@
20
20
  <div class="card mb-4" style="margin-top:1rem;">
21
21
  <div class="card-body">
22
22
 
23
+ <div class="row mb-3">
24
+ <div class="col">
25
+ <label class="form-check-label">
26
+ <input id="field-enabled" type="checkbox">
27
+ Enable search on the public site
28
+ </label>
29
+ <span class="form-hint">When off, no search trigger, stylesheet or script is added to public pages.</span>
30
+ </div>
31
+ </div>
32
+
23
33
  <div class="row mb-3">
24
34
  <div class="col">
25
35
  <label class="form-label">Search placeholder text</label>
@@ -100,6 +110,41 @@
100
110
  </div>
101
111
  </div>
102
112
 
113
+ <div class="row mb-3" id="ss-size-row">
114
+ <div class="col">
115
+ <label class="form-label" for="field-icon-size">Icon size</label>
116
+ <div style="display:flex;align-items:center;gap:1rem;flex-wrap:wrap;">
117
+ <input id="field-icon-size" type="range" min="32" max="96" step="2" value="52"
118
+ style="flex:1 1 200px;max-width:260px;">
119
+ <span id="ss-size-value" class="text-sm font-mono" style="min-width:3.5rem;">52px</span>
120
+ </div>
121
+ <span class="form-hint">How big the floating button is, in pixels (32-96). The search glyph inside
122
+ scales with it. 44px and up is the comfortable range for tapping on a phone.</span>
123
+ </div>
124
+ </div>
125
+
126
+ <div class="row mb-3" id="ss-radius-row">
127
+ <div class="col">
128
+ <label class="form-label" for="field-icon-radius">Icon corner radius</label>
129
+ <div style="display:flex;align-items:center;gap:1rem;flex-wrap:wrap;">
130
+ <input id="field-icon-radius" type="range" min="0" max="26" step="1" value="26"
131
+ style="flex:1 1 200px;max-width:260px;">
132
+ <span id="ss-radius-value" class="text-sm font-mono" style="min-width:3.5rem;">26px</span>
133
+ <span id="ss-radius-preview" aria-hidden="true"
134
+ style="width:52px;height:52px;display:inline-flex;align-items:center;justify-content:center;
135
+ background:var(--dm-surface);color:var(--dm-text);
136
+ border:1px solid var(--dm-border);border-radius:26px;
137
+ box-shadow:0 4px 16px rgba(0,0,0,.14);flex:0 0 auto;transition:border-radius .12s;">
138
+ <span data-icon="search" style="width:20px;height:20px;"></span>
139
+ </span>
140
+ </div>
141
+ <span class="form-hint">0 is a square, <span id="ss-radius-max-hint">26</span> a circle - the top of the
142
+ range is always half the icon size, so it moves when you change the size above. The preview is the real
143
+ button at its real size. Applies to the floating button in icon mode only - the navbar icon has no
144
+ surface to round, and the labelled variant is a pill by definition.</span>
145
+ </div>
146
+ </div>
147
+
103
148
  <div class="row" style="align-items:flex-start;gap:0;">
104
149
 
105
150
  <div class="col-auto" style="margin-right:1.5rem;margin-bottom:1rem;">
@@ -175,14 +220,15 @@
175
220
  <div class="tab-panel" id="tab-how-it-works">
176
221
  <div class="card mb-4" style="margin-top:1rem;">
177
222
  <div class="card-body">
178
- <p class="text-muted mb-2">Site Search adds a search icon to the public navbar. Visitors can click
179
- it or use
180
- the keyboard shortcut to open a full-screen overlay with live results.</p>
223
+ <p class="text-muted mb-2">Search adds a search icon to the public navbar, or a floating button
224
+ if you prefer. Visitors can click it or use the keyboard shortcut to open a full-screen overlay
225
+ with live results.</p>
181
226
  <ul class="text-muted" style="padding-left:1.25rem;line-height:1.8;">
182
227
  <li>Results are weighted: title matches score highest, followed by tags, description, and page
183
228
  content.
184
229
  </li>
185
230
  <li>Draft pages and private pages are excluded from results.</li>
231
+ <li>An authored context menu can offer "Site search" as an action, which opens the same overlay.</li>
186
232
  <li>Use <kbd>↑</kbd> <kbd>↓</kbd> to navigate results, <kbd>↵</kbd> to open, <kbd>Esc</kbd> to
187
233
  close.
188
234
  </li>
@@ -30,101 +30,20 @@
30
30
  </div>
31
31
  </div>
32
32
  <div class="row mb-3">
33
- <div class="col-6">
34
- <label class="form-label">Font Family</label>
35
- <select id="field-font-family" class="form-select">
36
- <optgroup label="Sans-serif">
37
- <option value="Roboto">Roboto (default)</option>
38
- <option value="Inter">Inter</option>
39
- <option value="Open Sans">Open Sans</option>
40
- <option value="Lato">Lato</option>
41
- <option value="Nunito">Nunito</option>
42
- <option value="Poppins">Poppins</option>
43
- <option value="Source Sans 3">Source Sans 3</option>
44
- <option value="Montserrat">Montserrat</option>
45
- <option value="Raleway">Raleway</option>
46
- <option value="DM Sans">DM Sans</option>
47
- <option value="Work Sans">Work Sans</option>
48
- </optgroup>
49
- <optgroup label="Serif">
50
- <option value="Merriweather">Merriweather</option>
51
- <option value="Playfair Display">Playfair Display</option>
52
- <option value="Lora">Lora</option>
53
- <option value="Roboto Slab">Roboto Slab</option>
54
- </optgroup>
55
- <optgroup label="Dyslexia-friendly">
56
- <option value="Lexend">Lexend</option>
57
- <option value="Atkinson Hyperlegible">Atkinson Hyperlegible</option>
58
- <option value="Andika">Andika</option>
59
- </optgroup>
60
- <optgroup label="System">
61
- <option value="system-ui">System UI (no web font)</option>
62
- </optgroup>
63
- </select>
64
- <p class="form-hint text-muted" style="margin-top:0.4rem;font-size:0.8rem;">Applied to the public-facing
65
- website body text. The dyslexia-friendly group uses wider letterforms and spacing to reduce character
66
- confusion.</p>
67
- </div>
68
- <div class="col-3">
69
- <label class="form-label">Font Size</label>
70
- <select id="field-font-size" class="form-select">
71
- <option value="13">13px - Compact</option>
72
- <option value="14">14px - Small</option>
73
- <option value="15">15px - Slightly small</option>
74
- <option value="16">16px - Default</option>
75
- <option value="17">17px - Slightly large</option>
76
- <option value="18">18px - Large</option>
77
- <option value="20">20px - Extra large</option>
78
- </select>
79
- <p class="form-hint text-muted" style="margin-top:0.4rem;font-size:0.8rem;">Root font size. All rem/em values
80
- scale with this.</p>
81
- </div>
82
- </div>
83
- <div class="row">
84
- <div class="col-6">
85
- <label class="form-label">Public Site Theme</label>
86
- <select id="field-theme" class="form-select"></select>
87
- <p class="form-hint text-muted" style="margin-top:0.4rem;font-size:0.8rem;">Applied to the public-facing
88
- website.</p>
89
- </div>
90
- <div class="col-6">
91
- <label class="form-label">Admin Theme</label>
92
- <select id="field-admin-theme" class="form-select"></select>
93
- <p class="form-hint text-muted" style="margin-top:0.4rem;font-size:0.8rem;">Applied to the admin panel.</p>
94
- </div>
95
- </div>
96
- <!-- Auto day/night theme -->
97
- <div class="row mt-3">
98
- <div class="col">
99
- <label class="form-check-label" style="display:flex;align-items:center;gap:.5rem;cursor:pointer;">
100
- <input id="field-auto-theme-enabled" type="checkbox" class="form-check"> Enable automatic day/night
101
- theme switching
102
- </label>
103
- <p id="auto-theme-roller-hint" class="form-hint text-muted"
104
- style="display:none;margin-top:.35rem;font-size:.8rem;">Custom themes (Theme Roller) do not support
105
- auto-switching.</p>
106
- </div>
107
- </div>
108
- <div id="auto-theme-fields" class="row mt-3" style="display:none;">
109
- <div class="col-6">
110
- <label class="form-label">Day Theme</label>
111
- <select id="field-day-theme" class="form-select"></select>
112
- </div>
113
- <div class="col-6">
114
- <label class="form-label">Night Theme</label>
115
- <select id="field-night-theme" class="form-select"></select>
116
- </div>
117
- <div class="col-3 mt-3">
118
- <label class="form-label">Day Starts At</label>
119
- <input id="field-day-start" type="time" class="form-input" value="07:00">
120
- </div>
121
- <div class="col-3 mt-3">
122
- <label class="form-label">Night Starts At</label>
123
- <input id="field-night-start" type="time" class="form-input" value="19:00">
33
+ <div class="col">
34
+ <div class="card" style="background:var(--dm-surface-raised);">
35
+ <div class="card-body" style="display:flex;align-items:center;gap:1rem;flex-wrap:wrap;">
36
+ <span data-icon="droplet"></span>
37
+ <div style="flex:1 1 240px;">
38
+ <strong>Themes, fonts and element overrides moved.</strong>
39
+ <p class="text-muted" style="margin:.25rem 0 0;font-size:.85rem;">
40
+ The site theme, admin theme, automatic day/night pair and typography now live in
41
+ Content &rsaquo; Theme, alongside per-element theme overrides.
42
+ </p>
43
+ </div>
44
+ <a href="#/theme" class="btn btn-ghost btn-sm">Open Theme</a>
124
45
  </div>
125
- <div class="col-12 mt-2">
126
- <p class="form-hint text-muted" style="font-size:.8rem;">Themes switch based on each visitor's local
127
- time. Any theme can be used - they need not be light/dark pairs.</p>
46
+ </div>
128
47
  </div>
129
48
  </div>
130
49
  <div class="row mt-3">
@@ -448,7 +367,7 @@
448
367
  </div>
449
368
 
450
369
  <div class="row mb-4" style="align-items:flex-end;gap:0;">
451
- <div class="col-sm-4">
370
+ <div class="col-4">
452
371
  <label class="form-label">Home label</label>
453
372
  <input id="field-breadcrumbs-home-label" type="text" class="form-input" placeholder="Home">
454
373
  </div>
@@ -490,7 +409,7 @@
490
409
  </div>
491
410
 
492
411
  <!-- Offsets -->
493
- <div class="col-sm-3" style="margin-right:1rem;">
412
+ <div class="col-3" style="margin-right:1rem;">
494
413
  <label class="form-label" for="field-bc-offset-x">Horizontal offset</label>
495
414
  <div style="display:flex;align-items:center;gap:.4rem;">
496
415
  <input id="field-bc-offset-x" type="number" class="form-input" min="0" max="500" placeholder="8"
@@ -501,7 +420,7 @@
501
420
  right edge.</p>
502
421
  </div>
503
422
 
504
- <div class="col-sm-3">
423
+ <div class="col-3">
505
424
  <label class="form-label" for="field-bc-offset-y">Vertical offset</label>
506
425
  <div style="display:flex;align-items:center;gap:.4rem;">
507
426
  <input id="field-bc-offset-y" type="number" class="form-input" min="0" max="500" placeholder="60"