domma-cms 0.66.0 → 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 (221) hide show
  1. package/CLAUDE.md +64 -1
  2. package/README.md +14 -10
  3. package/admin/css/admin.css +1 -1
  4. package/admin/index.html +1 -0
  5. package/admin/js/api.js +1 -1
  6. package/admin/js/app.js +4 -4
  7. package/admin/js/lib/analytics-shape.js +1 -0
  8. package/admin/js/lib/contacts-arrange.js +1 -0
  9. package/admin/js/lib/help-popover.js +1 -0
  10. package/admin/js/lib/notes-arrange.js +1 -0
  11. package/admin/js/lib/plugin-accent.js +1 -1
  12. package/admin/js/lib/plugin-chrome.js +1 -1
  13. package/admin/js/lib/sidebar-grouping.js +1 -1
  14. package/admin/js/lib/sidebar-grouping.test.js +1 -1
  15. package/admin/js/lib/sidebar-renderer.js +3 -3
  16. package/admin/js/lib/todo-arrange.js +1 -0
  17. package/admin/js/lib/tool-kit.js +1 -0
  18. package/admin/js/templates/analytics.html +138 -0
  19. package/admin/js/templates/contacts.html +156 -0
  20. package/admin/js/templates/notes.html +137 -0
  21. package/admin/js/templates/plugin-marketplace.html +17 -4
  22. package/admin/js/templates/plugins.html +13 -7
  23. package/admin/js/templates/theme.html +38 -0
  24. package/admin/js/templates/todo.html +113 -0
  25. package/admin/js/views/analytics.js +62 -0
  26. package/admin/js/views/contacts.js +174 -0
  27. package/admin/js/views/index.js +1 -1
  28. package/admin/js/views/notes.js +104 -0
  29. package/admin/js/views/plugin-marketplace.js +1 -1
  30. package/admin/js/views/plugins.js +24 -22
  31. package/admin/js/views/theme.js +1 -1
  32. package/admin/js/views/todo.js +96 -0
  33. package/bin/cli.js +4 -10
  34. package/bin/lib/plugin-version.js +28 -0
  35. package/bin/update.js +14 -0
  36. package/config/menus/admin-sidebar.json +1 -1
  37. package/config/server.json +3 -1
  38. package/package.json +3 -7
  39. package/plugins/_lib/admin/mail/reader-view.js +20 -0
  40. package/plugins/_lib/mail/store.js +21 -1
  41. package/plugins/blog/CLAUDE.md +237 -0
  42. package/plugins/blog/admin/css/index.css +178 -1
  43. package/plugins/blog/admin/templates/blog.html +35 -53
  44. package/plugins/blog/admin/templates/categories.html +19 -6
  45. package/plugins/blog/admin/templates/comments.html +26 -9
  46. package/plugins/blog/admin/templates/post-editor.html +36 -13
  47. package/plugins/blog/admin/templates/settings.html +2 -11
  48. package/plugins/blog/admin/views/blog.js +288 -162
  49. package/plugins/blog/admin/views/categories.js +212 -201
  50. package/plugins/blog/admin/views/comments.js +207 -158
  51. package/plugins/blog/admin/views/kit.js +372 -0
  52. package/plugins/blog/admin/views/post-editor.js +269 -21
  53. package/plugins/blog/admin/views/settings-cog.js +56 -0
  54. package/plugins/blog/admin/views/settings.js +16 -86
  55. package/plugins/blog/blocks/blog-card-compact.css +17 -0
  56. package/plugins/blog/blocks/blog-card-compact.html +8 -0
  57. package/plugins/blog/blocks/blog-card-row.css +22 -0
  58. package/plugins/blog/blocks/blog-card-row.html +11 -0
  59. package/plugins/blog/blocks/blog-card.css +35 -0
  60. package/plugins/blog/blocks/blog-card.html +16 -0
  61. package/plugins/blog/blocks/blog-post-classic.css +15 -0
  62. package/plugins/blog/blocks/blog-post-classic.html +28 -0
  63. package/plugins/blog/blocks/blog-post-feature.css +20 -0
  64. package/plugins/blog/blocks/blog-post-feature.html +30 -0
  65. package/plugins/blog/blocks/blog-post-minimal.css +10 -0
  66. package/plugins/blog/blocks/blog-post-minimal.html +23 -0
  67. package/plugins/blog/blocks/blog-post-sidebar.css +22 -0
  68. package/plugins/blog/blocks/blog-post-sidebar.html +36 -0
  69. package/plugins/blog/collections/posts/schema.json +3 -1
  70. package/plugins/blog/config.js +6 -0
  71. package/plugins/blog/lib/layouts.js +304 -0
  72. package/plugins/blog/lib/page.js +158 -0
  73. package/plugins/blog/lib/render.js +119 -0
  74. package/plugins/blog/lib/samples.js +234 -0
  75. package/plugins/blog/plugin.js +225 -15
  76. package/plugins/blog/plugin.json +21 -81
  77. package/plugins/blog/plugin.public.js +115 -210
  78. package/plugins/blog/public/blog.css +177 -0
  79. package/plugins/blog/public/blog.js +586 -0
  80. package/plugins/blog/public/samples/aurora.svg +7 -0
  81. package/plugins/blog/public/samples/dusk.svg +7 -0
  82. package/plugins/blog/public/samples/ember.svg +7 -0
  83. package/plugins/blog/public/samples/harbour.svg +7 -0
  84. package/plugins/blog/public/samples/meadow.svg +7 -0
  85. package/plugins/blog/public/samples/rosewood.svg +7 -0
  86. package/plugins/blog/templates/index.html +9 -8
  87. package/plugins/blog/templates/post.html +4 -17
  88. package/plugins/blog/tests/layouts.test.js +97 -0
  89. package/plugins/blog/tests/public.test.js +71 -0
  90. package/plugins/free-tier.lock.json +74 -0
  91. package/plugins/mail-reader/CLAUDE.md +78 -0
  92. package/plugins/mail-reader/plugin.json +2 -1
  93. package/public/css/theme-switcher.css +1 -0
  94. package/public/js/analytics.js +1 -0
  95. package/public/js/theme-switcher.js +1 -0
  96. package/scripts/build.js +41 -2
  97. package/scripts/run-tests.mjs +92 -0
  98. package/{plugins/analytics/plugin.js → server/routes/api/analytics.js} +89 -41
  99. package/{plugins/contacts/plugin.js → server/routes/api/contacts.js} +71 -43
  100. package/server/routes/api/dashboard.js +8 -2
  101. package/{plugins/notes/plugin.js → server/routes/api/notes.js} +61 -17
  102. package/server/routes/api/plugin-marketplace.js +78 -23
  103. package/server/routes/api/plugins.js +148 -3
  104. package/server/routes/api/todo.js +178 -0
  105. package/server/server.js +61 -1
  106. package/server/services/collections.js +13 -3
  107. package/server/services/managerClient.js +72 -136
  108. package/server/services/markdown.js +54 -1
  109. package/server/services/permissionRegistry.js +50 -0
  110. package/server/services/pluginEntitlement.js +171 -0
  111. package/server/services/pluginEnvelope.js +242 -0
  112. package/server/services/pluginInstaller.js +246 -26
  113. package/server/services/pluginScaffold.js +5 -0
  114. package/server/services/plugins.js +117 -7
  115. package/server/services/presetCollections.js +344 -0
  116. package/server/services/promoted-plugins-migration.js +254 -0
  117. package/server/services/publicCors.js +46 -0
  118. package/server/services/renderer.js +83 -3
  119. package/server/services/sidebarBadges.js +37 -0
  120. package/server/services/siteGitignore.js +307 -0
  121. package/server/services/themeSettings.js +39 -0
  122. package/config/theme.json +0 -18
  123. package/plugins/analytics/admin/css/index.css +0 -1
  124. package/plugins/analytics/admin/templates/analytics.html +0 -70
  125. package/plugins/analytics/admin/views/analytics.js +0 -176
  126. package/plugins/analytics/config.js +0 -14
  127. package/plugins/analytics/plugin.json +0 -60
  128. package/plugins/analytics/public/inject-body.html +0 -60
  129. package/plugins/analytics/public/inject-head.html +0 -1
  130. package/plugins/blog/templates/author.html +0 -9
  131. package/plugins/blog/templates/category.html +0 -9
  132. package/plugins/blog/templates/tag.html +0 -9
  133. package/plugins/contacts/admin/templates/contacts.html +0 -254
  134. package/plugins/contacts/admin/views/contacts.js +0 -943
  135. package/plugins/contacts/collections/user-contact-groups/schema.json +0 -35
  136. package/plugins/contacts/collections/user-contacts/schema.json +0 -179
  137. package/plugins/contacts/config.js +0 -6
  138. package/plugins/contacts/plugin.json +0 -36
  139. package/plugins/demo-viewer/config.js +0 -4
  140. package/plugins/demo-viewer/plugin.js +0 -36
  141. package/plugins/demo-viewer/plugin.json +0 -9
  142. package/plugins/invoice/admin/css/index.css +0 -1
  143. package/plugins/invoice/admin/templates/editor.html +0 -220
  144. package/plugins/invoice/admin/templates/index.html +0 -173
  145. package/plugins/invoice/admin/templates/issuers.html +0 -2
  146. package/plugins/invoice/admin/templates/receivers.html +0 -2
  147. package/plugins/invoice/admin/views/contacts-source.js +0 -266
  148. package/plugins/invoice/admin/views/editor.js +0 -434
  149. package/plugins/invoice/admin/views/export.js +0 -199
  150. package/plugins/invoice/admin/views/help-content.js +0 -61
  151. package/plugins/invoice/admin/views/index.js +0 -643
  152. package/plugins/invoice/admin/views/issuers.js +0 -30
  153. package/plugins/invoice/admin/views/media.js +0 -172
  154. package/plugins/invoice/admin/views/party-view.js +0 -386
  155. package/plugins/invoice/admin/views/payments.js +0 -127
  156. package/plugins/invoice/admin/views/print.js +0 -130
  157. package/plugins/invoice/admin/views/receivers.js +0 -55
  158. package/plugins/invoice/admin/views/send.js +0 -212
  159. package/plugins/invoice/admin/views/settings.js +0 -594
  160. package/plugins/invoice/admin/views/view-lifecycle.js +0 -33
  161. package/plugins/invoice/collections/invoice-issuers/schema.json +0 -82
  162. package/plugins/invoice/collections/invoice-receivers/schema.json +0 -16
  163. package/plugins/invoice/collections/invoices/schema.json +0 -33
  164. package/plugins/invoice/config.js +0 -37
  165. package/plugins/invoice/pdf.js +0 -164
  166. package/plugins/invoice/plugin.js +0 -1456
  167. package/plugins/invoice/plugin.json +0 -86
  168. package/plugins/invoice/templates/_base.css +0 -1
  169. package/plugins/invoice/templates/classic-nologo.html +0 -100
  170. package/plugins/invoice/templates/classic.html +0 -91
  171. package/plugins/invoice/templates/invoice-print.html +0 -237
  172. package/plugins/invoice/templates/minimal.html +0 -99
  173. package/plugins/invoice/templates/modern-nologo.html +0 -114
  174. package/plugins/invoice/templates/modern.html +0 -113
  175. package/plugins/invoice/templates/templates.json +0 -11
  176. package/plugins/notes/admin/templates/notes.html +0 -83
  177. package/plugins/notes/admin/views/notes.js +0 -281
  178. package/plugins/notes/collections/user-notes/schema.json +0 -54
  179. package/plugins/notes/config.js +0 -6
  180. package/plugins/notes/plugin.json +0 -33
  181. package/plugins/surveys/admin/templates/audience.html +0 -47
  182. package/plugins/surveys/admin/templates/results.html +0 -58
  183. package/plugins/surveys/admin/templates/survey-editor.html +0 -141
  184. package/plugins/surveys/admin/templates/surveys.html +0 -25
  185. package/plugins/surveys/admin/views/audience.js +0 -301
  186. package/plugins/surveys/admin/views/results.js +0 -172
  187. package/plugins/surveys/admin/views/survey-editor.js +0 -211
  188. package/plugins/surveys/admin/views/surveys.js +0 -161
  189. package/plugins/surveys/collections/survey-contacts/schema.json +0 -13
  190. package/plugins/surveys/collections/survey-groups/schema.json +0 -11
  191. package/plugins/surveys/collections/survey-invites/schema.json +0 -16
  192. package/plugins/surveys/collections/surveys/schema.json +0 -23
  193. package/plugins/surveys/config.js +0 -8
  194. package/plugins/surveys/lib/audience.js +0 -37
  195. package/plugins/surveys/lib/campaigns.js +0 -43
  196. package/plugins/surveys/lib/ledger.js +0 -110
  197. package/plugins/surveys/lib/sending.js +0 -106
  198. package/plugins/surveys/lib/stats.js +0 -62
  199. package/plugins/surveys/lib/submit.js +0 -95
  200. package/plugins/surveys/lib/tokens.js +0 -28
  201. package/plugins/surveys/plugin.js +0 -174
  202. package/plugins/surveys/plugin.json +0 -65
  203. package/plugins/surveys/plugin.public.js +0 -149
  204. package/plugins/surveys/public/dist-shared.mjs +0 -1
  205. package/plugins/surveys/public/survey.css +0 -1
  206. package/plugins/surveys/public/survey.mjs +0 -1
  207. package/plugins/surveys/templates/survey-page.html +0 -63
  208. package/plugins/theme-switcher/admin/templates/theme-switcher.html +0 -86
  209. package/plugins/theme-switcher/admin/views/theme-switcher.js +0 -65
  210. package/plugins/theme-switcher/config.js +0 -10
  211. package/plugins/theme-switcher/plugin.js +0 -26
  212. package/plugins/theme-switcher/plugin.json +0 -74
  213. package/plugins/theme-switcher/public/inject-body.html +0 -153
  214. package/plugins/theme-switcher/public/inject-head.html +0 -260
  215. package/plugins/todo/admin/templates/todo.html +0 -158
  216. package/plugins/todo/admin/views/todo.js +0 -343
  217. package/plugins/todo/collections/todos/schema.json +0 -60
  218. package/plugins/todo/config.js +0 -7
  219. package/plugins/todo/plugin.js +0 -102
  220. package/plugins/todo/plugin.json +0 -33
  221. /package/{plugins/contacts/admin/css/index.css → admin/css/contacts.css} +0 -0
@@ -1,153 +0,0 @@
1
- <div class="dm-theme-switcher" id="dm-theme-switcher" role="navigation" aria-label="Theme switcher">
2
- <button class="dm-ts-trigger" data-tooltip="Switch theme" aria-haspopup="true" aria-expanded="false"></button>
3
- <div class="dm-ts-options" role="menu">
4
- <button class="dm-ts-dot dm-ts-dot-charcoal-dark" data-theme="charcoal-dark" data-tooltip="Charcoal Dark"
5
- aria-label="Charcoal Dark"></button>
6
- <button class="dm-ts-dot dm-ts-dot-charcoal-light" data-theme="charcoal-light" data-tooltip="Charcoal Light"
7
- aria-label="Charcoal Light"></button>
8
- <button class="dm-ts-dot dm-ts-dot-christmas-dark" data-theme="christmas-dark" data-tooltip="Christmas Dark"
9
- aria-label="Christmas Dark"></button>
10
- <button class="dm-ts-dot dm-ts-dot-christmas-light" data-theme="christmas-light" data-tooltip="Christmas Light"
11
- aria-label="Christmas Light"></button>
12
- <button class="dm-ts-dot dm-ts-dot-dreamy-dark" data-theme="dreamy-dark" data-tooltip="Dreamy Dark"
13
- aria-label="Dreamy Dark"></button>
14
- <button class="dm-ts-dot dm-ts-dot-dreamy-light" data-theme="dreamy-light" data-tooltip="Dreamy Light"
15
- aria-label="Dreamy Light"></button>
16
- <button class="dm-ts-dot dm-ts-dot-forest-dark" data-theme="forest-dark" data-tooltip="Forest Dark"
17
- aria-label="Forest Dark"></button>
18
- <button class="dm-ts-dot dm-ts-dot-forest-light" data-theme="forest-light" data-tooltip="Forest Light"
19
- aria-label="Forest Light"></button>
20
- <button class="dm-ts-dot dm-ts-dot-grayve-dark" data-theme="grayve-dark" data-tooltip="Grayve Dark"
21
- aria-label="Grayve Dark"></button>
22
- <button class="dm-ts-dot dm-ts-dot-grayve-light" data-theme="grayve-light" data-tooltip="Grayve Light"
23
- aria-label="Grayve Light"></button>
24
- <button class="dm-ts-dot dm-ts-dot-lemon-dark" data-theme="lemon-dark" data-tooltip="Lemon Dark"
25
- aria-label="Lemon Dark"></button>
26
- <button class="dm-ts-dot dm-ts-dot-lemon-light" data-theme="lemon-light" data-tooltip="Lemon Light"
27
- aria-label="Lemon Light"></button>
28
- <button class="dm-ts-dot dm-ts-dot-mint-dark" data-theme="mint-dark" data-tooltip="Mint Dark"
29
- aria-label="Mint Dark"></button>
30
- <button class="dm-ts-dot dm-ts-dot-mint-light" data-theme="mint-light" data-tooltip="Mint Light"
31
- aria-label="Mint Light"></button>
32
- <button class="dm-ts-dot dm-ts-dot-ocean-dark" data-theme="ocean-dark" data-tooltip="Ocean Dark"
33
- aria-label="Ocean Dark"></button>
34
- <button class="dm-ts-dot dm-ts-dot-ocean-light" data-theme="ocean-light" data-tooltip="Ocean Light"
35
- aria-label="Ocean Light"></button>
36
- <button class="dm-ts-dot dm-ts-dot-royal-dark" data-theme="royal-dark" data-tooltip="Royal Dark"
37
- aria-label="Royal Dark"></button>
38
- <button class="dm-ts-dot dm-ts-dot-royal-light" data-theme="royal-light" data-tooltip="Royal Light"
39
- aria-label="Royal Light"></button>
40
- <button class="dm-ts-dot dm-ts-dot-silver-dark" data-theme="silver-dark" data-tooltip="Silver Dark"
41
- aria-label="Silver Dark"></button>
42
- <button class="dm-ts-dot dm-ts-dot-silver-light" data-theme="silver-light" data-tooltip="Silver Light"
43
- aria-label="Silver Light"></button>
44
- <button class="dm-ts-dot dm-ts-dot-sunset-dark" data-theme="sunset-dark" data-tooltip="Sunset Dark"
45
- aria-label="Sunset Dark"></button>
46
- <button class="dm-ts-dot dm-ts-dot-sunset-light" data-theme="sunset-light" data-tooltip="Sunset Light"
47
- aria-label="Sunset Light"></button>
48
- <button class="dm-ts-dot dm-ts-dot-unicorn-dark" data-theme="unicorn-dark" data-tooltip="Unicorn Dark"
49
- aria-label="Unicorn Dark"></button>
50
- <button class="dm-ts-dot dm-ts-dot-unicorn-light" data-theme="unicorn-light" data-tooltip="Unicorn Light"
51
- aria-label="Unicorn Light"></button>
52
- <button class="dm-ts-dot dm-ts-dot-wedding-dark" data-theme="wedding-dark" data-tooltip="Wedding Dark"
53
- aria-label="Wedding Dark"></button>
54
- <button class="dm-ts-dot dm-ts-dot-wedding-light" data-theme="wedding-light" data-tooltip="Wedding Light"
55
- aria-label="Wedding Light"></button>
56
- </div>
57
- </div>
58
-
59
- <script>
60
- (function () {
61
- var el = document.getElementById('dm-theme-switcher');
62
- if (!el) return;
63
-
64
- // ── Placement ──────────────────────────────────────────────────────────────
65
- function applyPlacement(position, offsetX, offsetY) {
66
- var isLeft = position === 'left-center' || position === 'bottom-left' || position === 'top-left';
67
- var isBottom = position === 'bottom-left' || position === 'bottom-right';
68
- var isTop = position === 'top-left' || position === 'top-right';
69
-
70
- if (isLeft) el.classList.add('dm-ts-left');
71
- else el.classList.remove('dm-ts-left');
72
-
73
- if (isTop) el.classList.add('dm-ts-top');
74
- else el.classList.remove('dm-ts-top');
75
-
76
- Object.assign(el.style, {
77
- right: isLeft ? 'auto' : offsetX + 'px',
78
- left: isLeft ? offsetX + 'px' : 'auto',
79
- top: isTop ? offsetY + 'px' : (isBottom ? 'auto' : '50vh'),
80
- bottom: isBottom ? offsetY + 'px' : 'auto',
81
- transform: (isTop || isBottom) ? 'none' : 'translateY(-50%)',
82
- });
83
-
84
- var opts = el.querySelector('.dm-ts-options');
85
- if (opts) {
86
- if (isLeft) {
87
- opts.style.left = '0';
88
- opts.style.right = 'auto';
89
- } else {
90
- opts.style.left = '';
91
- opts.style.right = '';
92
- }
93
- }
94
- }
95
-
96
- fetch('/api/plugins/theme-switcher/settings')
97
- .then(function (r) {
98
- return r.ok ? r.json() : {};
99
- })
100
- .catch(function () {
101
- return {};
102
- })
103
- .then(function (cfg) {
104
- applyPlacement(
105
- cfg.position || 'right-center',
106
- cfg.offsetX != null ? cfg.offsetX : 32,
107
- cfg.offsetY != null ? cfg.offsetY : 32
108
- );
109
- });
110
-
111
- // ── Theme engine ───────────────────────────────────────────────────────────
112
- function waitForDomma(cb, retries) {
113
- if (typeof Domma !== 'undefined' && Domma.theme) {
114
- cb(Domma.theme);
115
- } else if (retries > 0) {
116
- setTimeout(function () {
117
- waitForDomma(cb, retries - 1);
118
- }, 100);
119
- }
120
- }
121
-
122
- waitForDomma(function (themeEngine) {
123
- var trigger = el.querySelector('.dm-ts-trigger');
124
- var dots = el.querySelectorAll('.dm-ts-dot');
125
-
126
- function updateActive() {
127
- var current = themeEngine.get();
128
- dots.forEach(function (dot) {
129
- dot.classList.toggle('active', dot.dataset.theme === current);
130
- });
131
- }
132
-
133
- dots.forEach(function (dot) {
134
- dot.addEventListener('click', function () {
135
- themeEngine.set(dot.dataset.theme);
136
- updateActive();
137
- });
138
- });
139
-
140
- themeEngine.onChange(function () {
141
- updateActive();
142
- });
143
- updateActive();
144
-
145
- if (trigger) {
146
- trigger.addEventListener('click', function () {
147
- var expanded = trigger.getAttribute('aria-expanded') === 'true';
148
- trigger.setAttribute('aria-expanded', String(!expanded));
149
- });
150
- }
151
- }, 30);
152
- }());
153
- </script>
@@ -1,260 +0,0 @@
1
- <style>
2
- /* ============================================================
3
- Theme Switcher - Floating Disc
4
- Position is applied inline by inject-body.html script.
5
- ============================================================ */
6
- .dm-theme-switcher {
7
- position: fixed;
8
- z-index: 9998;
9
- }
10
-
11
- .dm-ts-trigger {
12
- width: 48px;
13
- height: 48px;
14
- border-radius: 50%;
15
- border: 2px solid rgba(255, 255, 255, 0.25);
16
- cursor: pointer;
17
- background: conic-gradient(
18
- #0077b6 0deg 28deg,
19
- #48cae4 28deg 56deg,
20
- #2d6a4f 56deg 84deg,
21
- #74c69d 84deg 112deg,
22
- #c67b5c 112deg 140deg,
23
- #4169e1 140deg 168deg,
24
- #c9b458 168deg 196deg,
25
- #708090 196deg 224deg,
26
- #5cb875 224deg 252deg,
27
- #9b59b6 252deg 280deg,
28
- #00838f 280deg 308deg,
29
- #2e9e6e 308deg 336deg,
30
- #c5a55a 336deg 360deg
31
- );
32
- padding: 0;
33
- transition: transform 0.18s ease, box-shadow 0.18s ease;
34
- box-shadow: 0 3px 12px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(255, 255, 255, 0.08);
35
- }
36
-
37
- .dm-ts-trigger:hover {
38
- transform: scale(1.14);
39
- box-shadow: 0 6px 20px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(255, 255, 255, 0.15);
40
- }
41
-
42
- .dm-ts-options {
43
- position: absolute;
44
- display: grid;
45
- grid-template-columns: repeat(2, 28px);
46
- gap: 8px;
47
- padding: 10px;
48
- background: var(--dm-surface, #1e2030);
49
- border: 1px solid var(--dm-border, rgba(255, 255, 255, 0.12));
50
- border-radius: 14px;
51
- box-shadow: 0 10px 28px rgba(0, 0, 0, 0.45);
52
- opacity: 0;
53
- visibility: hidden;
54
- transform: scale(0.92) translateY(6px);
55
- transform-origin: bottom right;
56
- transition: opacity 0.18s ease, transform 0.18s ease, visibility 0.18s;
57
- pointer-events: none;
58
- bottom: 56px;
59
- right: 0;
60
- }
61
-
62
- /* Left-anchored: panel opens to the right */
63
- .dm-theme-switcher.dm-ts-left .dm-ts-options {
64
- right: auto;
65
- left: 0;
66
- transform-origin: bottom left;
67
- }
68
-
69
- /* Top-anchored: panel opens downward */
70
- .dm-theme-switcher.dm-ts-top .dm-ts-options {
71
- bottom: auto;
72
- top: 56px;
73
- transform: scale(0.92) translateY(-6px);
74
- transform-origin: top right;
75
- }
76
-
77
- .dm-theme-switcher.dm-ts-top.dm-ts-left .dm-ts-options {
78
- transform-origin: top left;
79
- }
80
-
81
- .dm-theme-switcher:hover .dm-ts-options,
82
- .dm-theme-switcher:focus-within .dm-ts-options {
83
- opacity: 1;
84
- visibility: visible;
85
- transform: scale(1) translateY(0);
86
- pointer-events: all;
87
- }
88
-
89
- /* Top-anchored open state uses same final transform */
90
- .dm-theme-switcher.dm-ts-top:hover .dm-ts-options,
91
- .dm-theme-switcher.dm-ts-top:focus-within .dm-ts-options {
92
- transform: scale(1) translateY(0);
93
- }
94
-
95
- .dm-ts-dot {
96
- width: 28px;
97
- height: 28px;
98
- border-radius: 50%;
99
- border: 2px solid transparent;
100
- cursor: pointer;
101
- padding: 0;
102
- position: relative;
103
- transition: transform 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
104
- box-shadow: 0 1px 4px rgba(0, 0, 0, 0.35);
105
- outline: none;
106
- }
107
-
108
- .dm-ts-dot:hover {
109
- transform: scale(1.22);
110
- box-shadow: 0 3px 10px rgba(0, 0, 0, 0.4);
111
- }
112
-
113
- .dm-ts-dot.active {
114
- border-color: #fff;
115
- box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.5), 0 2px 8px rgba(0, 0, 0, 0.4);
116
- }
117
-
118
- /* Tooltip */
119
- .dm-ts-dot::after,
120
- .dm-ts-trigger::after {
121
- content: attr(data-tooltip);
122
- position: absolute;
123
- top: 50%;
124
- transform: translateY(-50%);
125
- background: rgba(10, 12, 20, 0.92);
126
- color: #fff;
127
- padding: 4px 9px;
128
- border-radius: 5px;
129
- font-size: 0.7rem;
130
- font-family: system-ui, sans-serif;
131
- white-space: nowrap;
132
- opacity: 0;
133
- pointer-events: none;
134
- transition: opacity 0.15s ease;
135
- z-index: 1;
136
- }
137
-
138
- /* Tooltip direction flips with anchor side */
139
- .dm-theme-switcher:not(.dm-ts-left) .dm-ts-dot::after,
140
- .dm-theme-switcher:not(.dm-ts-left) .dm-ts-trigger::after {
141
- right: calc(100% + 7px);
142
- left: auto;
143
- }
144
-
145
- .dm-theme-switcher.dm-ts-left .dm-ts-dot::after,
146
- .dm-theme-switcher.dm-ts-left .dm-ts-trigger::after {
147
- left: calc(100% + 7px);
148
- right: auto;
149
- }
150
-
151
- .dm-ts-dot:hover::after,
152
- .dm-ts-trigger:hover::after {
153
- opacity: 1;
154
- }
155
-
156
- /* Dot colours */
157
- .dm-ts-dot-ocean-dark {
158
- background: linear-gradient(135deg, #023e8a, #0077b6);
159
- }
160
-
161
- .dm-ts-dot-ocean-light {
162
- background: linear-gradient(135deg, #48cae4, #90e0ef);
163
- }
164
-
165
- .dm-ts-dot-forest-dark {
166
- background: linear-gradient(135deg, #1b4332, #2d6a4f);
167
- }
168
-
169
- .dm-ts-dot-forest-light {
170
- background: linear-gradient(135deg, #52b788, #95d5b2);
171
- }
172
-
173
- .dm-ts-dot-sunset-dark {
174
- background: linear-gradient(135deg, #8b4513, #c67b5c);
175
- }
176
-
177
- .dm-ts-dot-sunset-light {
178
- background: linear-gradient(135deg, #f4a261, #ffc09f);
179
- }
180
-
181
- .dm-ts-dot-royal-dark {
182
- background: linear-gradient(135deg, #1e3a8a, #2b4c9e);
183
- }
184
-
185
- .dm-ts-dot-royal-light {
186
- background: linear-gradient(135deg, #6495ed, #a3b8f2);
187
- }
188
-
189
- .dm-ts-dot-lemon-dark {
190
- background: linear-gradient(135deg, #854d0e, #a89c3a);
191
- }
192
-
193
- .dm-ts-dot-lemon-light {
194
- background: linear-gradient(135deg, #f9e44a, #fffbeb);
195
- }
196
-
197
- .dm-ts-dot-silver-dark {
198
- background: linear-gradient(135deg, #2d3748, #4a5568);
199
- }
200
-
201
- .dm-ts-dot-silver-light {
202
- background: linear-gradient(135deg, #e2e8f0, #a0aec0);
203
- }
204
-
205
- .dm-ts-dot-charcoal-dark {
206
- background: linear-gradient(135deg, #1a202c, #2d3748);
207
- }
208
-
209
- .dm-ts-dot-charcoal-light {
210
- background: linear-gradient(135deg, #718096, #cbd5e0);
211
- }
212
-
213
- .dm-ts-dot-christmas-dark {
214
- background: linear-gradient(135deg, #0a1a10, #1a3020);
215
- }
216
-
217
- .dm-ts-dot-christmas-light {
218
- background: linear-gradient(135deg, #228b22, #c41e3a);
219
- }
220
-
221
- .dm-ts-dot-unicorn-dark {
222
- background: linear-gradient(135deg, #1a0e24, #4a2660);
223
- }
224
-
225
- .dm-ts-dot-unicorn-light {
226
- background: linear-gradient(135deg, #e91e90, #9b59b6);
227
- }
228
-
229
- .dm-ts-dot-dreamy-dark {
230
- background: linear-gradient(135deg, #1c1410, #4e342e);
231
- }
232
-
233
- .dm-ts-dot-dreamy-light {
234
- background: linear-gradient(135deg, #d7ccc8, #8d6e63);
235
- }
236
-
237
- .dm-ts-dot-grayve-dark {
238
- background: linear-gradient(135deg, #1a1e21, #343a40);
239
- }
240
-
241
- .dm-ts-dot-grayve-light {
242
- background: linear-gradient(135deg, #b2ebf2, #00838f);
243
- }
244
-
245
- .dm-ts-dot-mint-dark {
246
- background: linear-gradient(135deg, #1e3a2f, #2e6e52);
247
- }
248
-
249
- .dm-ts-dot-mint-light {
250
- background: linear-gradient(135deg, #a8edcc, #2e9e6e);
251
- }
252
-
253
- .dm-ts-dot-wedding-dark {
254
- background: linear-gradient(135deg, #12121f, #c5a55a);
255
- }
256
-
257
- .dm-ts-dot-wedding-light {
258
- background: linear-gradient(135deg, #fffdf7, #c5a55a);
259
- }
260
- </style>
@@ -1,158 +0,0 @@
1
- <div class="p-4">
2
- <div class="card">
3
- <div class="card-body">
4
-
5
- <!-- Header -->
6
- <div class="flex items-center justify-between mb-4">
7
- <h2 class="text-lg font-semibold" style="margin:0;">
8
- <span data-icon="check-square" data-icon-size="20" style="vertical-align:middle;margin-right:8px;"></span>
9
- Todo
10
- </h2>
11
- <button id="clear-completed-btn" class="btn btn-sm btn-danger">
12
- <span data-icon="trash" data-icon-size="14"></span>
13
- Clear Completed
14
- </button>
15
- </div>
16
-
17
- <!-- Add new todo row -->
18
- <div class="flex gap-2 mb-4" style="display:flex;gap:8px;align-items:center;flex-wrap:wrap;">
19
- <input
20
- type="text"
21
- id="todo-input"
22
- class="form-input"
23
- placeholder="What needs to be done?"
24
- autocomplete="off"
25
- style="flex:1;min-width:200px;"
26
- />
27
- <select id="priority-input" class="form-input" style="width:130px;">
28
- <option value="highest">Highest</option>
29
- <option value="high">High</option>
30
- <option value="medium" selected>Medium</option>
31
- <option value="low">Low</option>
32
- <option value="lowest">Lowest</option>
33
- </select>
34
- <input type="date" id="due-date-input" class="form-input" title="Due date (optional)"
35
- style="width:145px;"/>
36
- <button id="add-todo-btn" class="btn btn-primary">
37
- <span data-icon="plus" data-icon-size="14"></span>
38
- Add
39
- </button>
40
- </div>
41
-
42
- <!-- Filter bar -->
43
- <div id="filter-bar" class="flex gap-2 mb-4" style="display:flex;gap:8px;flex-wrap:wrap;">
44
- <button class="btn btn-sm filter-btn active" data-filter="all">All</button>
45
- <button class="btn btn-sm filter-btn" data-filter="not-started">Not Started</button>
46
- <button class="btn btn-sm filter-btn" data-filter="in-progress">In Progress</button>
47
- <button class="btn btn-sm filter-btn" data-filter="completed">Completed</button>
48
- </div>
49
-
50
- <!-- Todo table -->
51
- <div id="todo-table"></div>
52
-
53
- </div>
54
- </div>
55
- </div>
56
-
57
- <style>
58
- .todo-item {
59
- display: flex;
60
- align-items: center;
61
- gap: 10px;
62
- padding: 9px 0;
63
- border-bottom: 1px solid var(--dm-border);
64
- }
65
-
66
- .todo-item:last-child {
67
- border-bottom: none;
68
- }
69
- .todo-item.completed .todo-text {
70
- text-decoration: line-through;
71
- opacity: 0.45;
72
- }
73
-
74
- .todo-checkbox {
75
- flex-shrink: 0;
76
- }
77
-
78
- .todo-text {
79
- flex: 1;
80
- min-width: 0;
81
- word-break: break-word;
82
- font-size: 0.9rem;
83
- }
84
-
85
- .todo-selects {
86
- display: flex;
87
- gap: 5px;
88
- flex-shrink: 0;
89
- }
90
-
91
- .todo-select-pill {
92
- appearance: none;
93
- -webkit-appearance: none;
94
- border: none;
95
- border-radius: 999px;
96
- padding: 2px 10px 2px 8px;
97
- font-size: 0.72rem;
98
- font-weight: 500;
99
- cursor: pointer;
100
- outline: none;
101
- }
102
-
103
- .todo-select-pill:focus {
104
- box-shadow: 0 0 0 2px var(--dm-primary-soft, rgba(99, 102, 241, .3));
105
- }
106
- .todo-actions {
107
- display: flex;
108
- gap: 3px;
109
- flex-shrink: 0;
110
- }
111
- .filter-btn.active {
112
- background: var(--dm-primary);
113
- color: #fff;
114
- border-color: var(--dm-primary);
115
- }
116
-
117
- /* Status pill colours */
118
- .status-pill-not-started {
119
- background: var(--dm-gray-200, #e5e7eb);
120
- color: var(--dm-gray-700, #374151);
121
- }
122
-
123
- .status-pill-in-progress {
124
- background: #dbeafe;
125
- color: #2563eb;
126
- }
127
-
128
- .status-pill-completed {
129
- background: #dcfce7;
130
- color: #16a34a;
131
- }
132
-
133
- /* Priority pill colours */
134
- .priority-pill-highest {
135
- background: #fee2e2;
136
- color: #b91c1c;
137
- }
138
-
139
- .priority-pill-high {
140
- background: #ffedd5;
141
- color: #c2410c;
142
- }
143
-
144
- .priority-pill-medium {
145
- background: #fef9c3;
146
- color: #a16207;
147
- }
148
-
149
- .priority-pill-low {
150
- background: #dbeafe;
151
- color: #1d4ed8;
152
- }
153
-
154
- .priority-pill-lowest {
155
- background: #f3f4f6;
156
- color: #6b7280;
157
- }
158
- </style>