domma-cms 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +469 -0
  3. package/admin/css/admin.css +1123 -0
  4. package/admin/index.html +72 -0
  5. package/admin/js/api.js +210 -0
  6. package/admin/js/app.js +270 -0
  7. package/admin/js/config/sidebar-config.js +107 -0
  8. package/admin/js/lib/card.js +63 -0
  9. package/admin/js/lib/image-editor.js +869 -0
  10. package/admin/js/lib/markdown-toolbar.js +421 -0
  11. package/admin/js/templates/dashboard.html +50 -0
  12. package/admin/js/templates/documentation.html +237 -0
  13. package/admin/js/templates/layouts.html +11 -0
  14. package/admin/js/templates/login.html +58 -0
  15. package/admin/js/templates/media.html +16 -0
  16. package/admin/js/templates/navigation.html +50 -0
  17. package/admin/js/templates/page-editor.html +126 -0
  18. package/admin/js/templates/pages.html +18 -0
  19. package/admin/js/templates/plugins.html +12 -0
  20. package/admin/js/templates/settings.html +190 -0
  21. package/admin/js/templates/tutorials.html +233 -0
  22. package/admin/js/templates/user-editor.html +12 -0
  23. package/admin/js/templates/users.html +10 -0
  24. package/admin/js/views/dashboard.js +48 -0
  25. package/admin/js/views/documentation.js +12 -0
  26. package/admin/js/views/index.js +33 -0
  27. package/admin/js/views/layouts.js +49 -0
  28. package/admin/js/views/login.js +254 -0
  29. package/admin/js/views/media.js +240 -0
  30. package/admin/js/views/navigation.js +152 -0
  31. package/admin/js/views/page-editor.js +479 -0
  32. package/admin/js/views/pages.js +64 -0
  33. package/admin/js/views/plugins.js +100 -0
  34. package/admin/js/views/settings.js +64 -0
  35. package/admin/js/views/tutorials.js +12 -0
  36. package/admin/js/views/user-editor.js +88 -0
  37. package/admin/js/views/users.js +73 -0
  38. package/bin/cli.js +334 -0
  39. package/config/auth.json +20 -0
  40. package/config/content.json +10 -0
  41. package/config/navigation.json +63 -0
  42. package/config/plugins.json +47 -0
  43. package/config/presets.json +34 -0
  44. package/config/server.json +6 -0
  45. package/config/site.json +33 -0
  46. package/package.json +67 -0
  47. package/plugins/back-to-top/admin/templates/back-to-top-settings.html +55 -0
  48. package/plugins/back-to-top/admin/views/back-to-top-settings.js +44 -0
  49. package/plugins/back-to-top/config.js +10 -0
  50. package/plugins/back-to-top/plugin.js +24 -0
  51. package/plugins/back-to-top/plugin.json +36 -0
  52. package/plugins/back-to-top/public/inject-body.html +105 -0
  53. package/plugins/cookie-consent/admin/templates/cookie-consent-settings.html +113 -0
  54. package/plugins/cookie-consent/admin/views/cookie-consent-settings.js +73 -0
  55. package/plugins/cookie-consent/config.js +30 -0
  56. package/plugins/cookie-consent/plugin.js +24 -0
  57. package/plugins/cookie-consent/plugin.json +36 -0
  58. package/plugins/cookie-consent/public/inject-body.html +69 -0
  59. package/plugins/custom-css/admin/templates/custom-css.html +17 -0
  60. package/plugins/custom-css/admin/views/custom-css.js +35 -0
  61. package/plugins/custom-css/config.js +1 -0
  62. package/plugins/custom-css/data/custom.css +0 -0
  63. package/plugins/custom-css/plugin.js +63 -0
  64. package/plugins/custom-css/plugin.json +32 -0
  65. package/plugins/custom-css/public/inject-head.html +1 -0
  66. package/plugins/domma-effects/admin/templates/domma-effects.html +488 -0
  67. package/plugins/domma-effects/admin/views/domma-effects.js +56 -0
  68. package/plugins/domma-effects/config.js +9 -0
  69. package/plugins/domma-effects/plugin.js +22 -0
  70. package/plugins/domma-effects/plugin.json +36 -0
  71. package/plugins/domma-effects/public/celebrations/core/canvas.js +111 -0
  72. package/plugins/domma-effects/public/celebrations/core/particles.js +144 -0
  73. package/plugins/domma-effects/public/celebrations/core/physics.js +166 -0
  74. package/plugins/domma-effects/public/celebrations/index.js +535 -0
  75. package/plugins/domma-effects/public/celebrations/themes/christmas.js +1805 -0
  76. package/plugins/domma-effects/public/celebrations/themes/guy-fawkes.js +1477 -0
  77. package/plugins/domma-effects/public/celebrations/themes/halloween.js +1837 -0
  78. package/plugins/domma-effects/public/celebrations/themes/st-andrews.js +1175 -0
  79. package/plugins/domma-effects/public/celebrations/themes/st-davids.js +1258 -0
  80. package/plugins/domma-effects/public/celebrations/themes/st-georges.js +1754 -0
  81. package/plugins/domma-effects/public/celebrations/themes/st-patricks.js +1290 -0
  82. package/plugins/domma-effects/public/celebrations/themes/valentines.js +1361 -0
  83. package/plugins/domma-effects/public/inject-body.html +268 -0
  84. package/plugins/example-analytics/admin/templates/analytics.html +10 -0
  85. package/plugins/example-analytics/admin/views/analytics.js +51 -0
  86. package/plugins/example-analytics/config.js +6 -0
  87. package/plugins/example-analytics/plugin.js +58 -0
  88. package/plugins/example-analytics/plugin.json +27 -0
  89. package/plugins/example-analytics/public/inject-body.html +13 -0
  90. package/plugins/example-analytics/public/inject-head.html +1 -0
  91. package/plugins/example-analytics/stats.json +1 -0
  92. package/plugins/form-builder/admin/templates/form-editor.html +158 -0
  93. package/plugins/form-builder/admin/templates/form-settings.html +29 -0
  94. package/plugins/form-builder/admin/templates/form-submissions.html +30 -0
  95. package/plugins/form-builder/admin/templates/forms-list.html +17 -0
  96. package/plugins/form-builder/admin/views/form-editor.js +817 -0
  97. package/plugins/form-builder/admin/views/form-settings.js +38 -0
  98. package/plugins/form-builder/admin/views/form-submissions.js +295 -0
  99. package/plugins/form-builder/admin/views/forms-list.js +164 -0
  100. package/plugins/form-builder/config.js +9 -0
  101. package/plugins/form-builder/data/forms/contact-details.json +63 -0
  102. package/plugins/form-builder/data/forms/contact.json +52 -0
  103. package/plugins/form-builder/data/submissions/contact-details.json +1 -0
  104. package/plugins/form-builder/data/submissions/contact.json +14 -0
  105. package/plugins/form-builder/email.js +103 -0
  106. package/plugins/form-builder/plugin.js +454 -0
  107. package/plugins/form-builder/plugin.json +56 -0
  108. package/plugins/form-builder/public/inject-body.html +270 -0
  109. package/plugins/form-builder/public/inject-head.html +42 -0
  110. package/public/css/site.css +189 -0
  111. package/public/js/site.js +109 -0
  112. package/scripts/copy-domma.js +48 -0
  113. package/scripts/fresh.js +41 -0
  114. package/scripts/reset.js +124 -0
  115. package/scripts/seed.js +666 -0
  116. package/scripts/setup.js +263 -0
  117. package/server/config.js +56 -0
  118. package/server/middleware/auth.js +97 -0
  119. package/server/routes/api/auth.js +116 -0
  120. package/server/routes/api/layouts.js +25 -0
  121. package/server/routes/api/media.js +93 -0
  122. package/server/routes/api/navigation.js +37 -0
  123. package/server/routes/api/pages.js +118 -0
  124. package/server/routes/api/plugins.js +46 -0
  125. package/server/routes/api/settings.js +25 -0
  126. package/server/routes/api/users.js +110 -0
  127. package/server/routes/public.js +108 -0
  128. package/server/server.js +169 -0
  129. package/server/services/content.js +298 -0
  130. package/server/services/images.js +334 -0
  131. package/server/services/markdown.js +297 -0
  132. package/server/services/plugins.js +246 -0
  133. package/server/services/renderer.js +80 -0
  134. package/server/services/users.js +212 -0
  135. package/server/templates/page.html +78 -0
@@ -0,0 +1,1123 @@
1
+ /* =========================================================
2
+ Domma CMS - Admin Panel Styles
3
+ ========================================================= */
4
+
5
+ /* Dashboard layout */
6
+ .dashboard-layout {
7
+ display: flex;
8
+ flex-direction: column;
9
+ min-height: 100vh;
10
+ }
11
+
12
+ .dashboard-wrapper {
13
+ display: flex;
14
+ flex: 1;
15
+ min-height: 0;
16
+ }
17
+
18
+ .dashboard-main {
19
+ flex: 1;
20
+ min-width: 0;
21
+ overflow-y: auto;
22
+ }
23
+
24
+ /* View container */
25
+ .view-container {
26
+ padding: 1.5rem 2rem;
27
+ max-width: 1200px;
28
+ }
29
+
30
+ /* View header */
31
+ .view-header {
32
+ display: flex;
33
+ align-items: center;
34
+ justify-content: space-between;
35
+ margin-bottom: 1.5rem;
36
+ gap: 1rem;
37
+ }
38
+
39
+ .view-header h1 {
40
+ font-size: 1.5rem;
41
+ font-weight: 700;
42
+ margin: 0;
43
+ display: flex;
44
+ align-items: center;
45
+ gap: .5rem;
46
+ }
47
+
48
+ .view-header-actions {
49
+ display: flex;
50
+ gap: .5rem;
51
+ }
52
+
53
+ /* Stat cards */
54
+ .stat-card .card-body {
55
+ display: flex;
56
+ align-items: center;
57
+ gap: 1rem;
58
+ }
59
+
60
+ .stat-icon {
61
+ width: 44px;
62
+ height: 44px;
63
+ border-radius: 8px;
64
+ background: var(--primary-alpha, rgba(91,140,255,.15));
65
+ color: var(--primary, #5b8cff);
66
+ display: flex;
67
+ align-items: center;
68
+ justify-content: center;
69
+ font-size: 1.25rem;
70
+ flex-shrink: 0;
71
+ }
72
+
73
+ .stat-icon--success { background: rgba(52,211,153,.15); color: #34d399; }
74
+ .stat-icon--warning { background: rgba(251,191,36,.15); color: #fbbf24; }
75
+
76
+ .stat-value {
77
+ font-size: 1.75rem;
78
+ font-weight: 700;
79
+ line-height: 1;
80
+ }
81
+
82
+ .stat-label {
83
+ font-size: .8rem;
84
+ color: var(--text-muted, #888);
85
+ margin-top: .25rem;
86
+ }
87
+
88
+ /* Toolbar */
89
+ .toolbar {
90
+ display: flex;
91
+ align-items: center;
92
+ gap: .75rem;
93
+ }
94
+
95
+
96
+ .form-check-label {
97
+ display: flex;
98
+ align-items: center;
99
+ gap: .5rem;
100
+ cursor: pointer;
101
+ font-size: .9rem;
102
+ }
103
+
104
+ .form-hint {
105
+ display: block;
106
+ font-size: .8rem;
107
+ color: var(--text-muted, #888);
108
+ margin-top: .25rem;
109
+ }
110
+
111
+ /* Markdown editor */
112
+ .editor-card .card-body {
113
+ display: flex;
114
+ flex-direction: column;
115
+ min-height: 500px;
116
+ padding: 0 !important;
117
+ }
118
+
119
+ .editor-toolbar {
120
+ display: flex;
121
+ align-items: center;
122
+ gap: 2px;
123
+ padding: 6px 10px;
124
+ border-bottom: 1px solid var(--border-color, rgba(255, 255, 255, .08));
125
+ flex-wrap: wrap;
126
+ flex-shrink: 0;
127
+ }
128
+
129
+ .editor-toolbar-btn {
130
+ background: none;
131
+ border: none;
132
+ color: var(--text-muted, #888);
133
+ padding: 6px 8px;
134
+ border-radius: 4px;
135
+ cursor: pointer;
136
+ display: flex;
137
+ align-items: center;
138
+ transition: color .15s, background .15s;
139
+ }
140
+
141
+ .editor-toolbar-btn:hover {
142
+ color: var(--text, #eee);
143
+ background: rgba(255, 255, 255, .08);
144
+ }
145
+
146
+ .editor-toolbar-sep {
147
+ width: 1px;
148
+ height: 20px;
149
+ background: var(--border-color, rgba(255, 255, 255, .08));
150
+ margin: 0 4px;
151
+ flex-shrink: 0;
152
+ }
153
+
154
+ .editor-toolbar-right {
155
+ margin-left: auto;
156
+ display: flex;
157
+ align-items: center;
158
+ gap: 2px;
159
+ }
160
+
161
+ .editor-view-btn {
162
+ background: none;
163
+ border: none;
164
+ color: var(--text-muted, #888);
165
+ padding: 6px 8px;
166
+ border-radius: 4px;
167
+ cursor: pointer;
168
+ display: flex;
169
+ align-items: center;
170
+ transition: color .15s, background .15s;
171
+ }
172
+
173
+ .editor-view-btn:hover {
174
+ color: var(--text, #eee);
175
+ background: rgba(255, 255, 255, .08);
176
+ }
177
+
178
+ .editor-view-btn.active {
179
+ color: var(--primary, #5b8cff);
180
+ background: var(--primary-alpha, rgba(91, 140, 255, .12));
181
+ }
182
+
183
+ .editor-body {
184
+ display: flex;
185
+ flex: 1;
186
+ min-height: 0;
187
+ }
188
+
189
+ .editor-pane {
190
+ flex: 1;
191
+ display: flex;
192
+ flex-direction: column;
193
+ min-width: 0;
194
+ }
195
+
196
+ .editor-pane--write,
197
+ .editor-pane--preview {
198
+ overflow: hidden;
199
+ }
200
+
201
+ /* View mode classes */
202
+ .editor-mode-write .editor-pane--preview,
203
+ .editor-mode-write .editor-divider {
204
+ display: none;
205
+ }
206
+
207
+ .editor-mode-preview .editor-pane--write,
208
+ .editor-mode-preview .editor-divider {
209
+ display: none;
210
+ }
211
+
212
+ .editor-divider {
213
+ width: 1px;
214
+ background: var(--border-color, rgba(255,255,255,.08));
215
+ flex-shrink: 0;
216
+ }
217
+
218
+ .editor-textarea {
219
+ flex: 1;
220
+ resize: none;
221
+ border: none;
222
+ border-radius: 0;
223
+ background: transparent;
224
+ font-family: 'Fira Code', 'Courier New', monospace;
225
+ font-size: .9rem;
226
+ padding: 1rem;
227
+ outline: none;
228
+ color: inherit;
229
+ line-height: 1.6;
230
+ }
231
+
232
+ .editor-preview {
233
+ flex: 1;
234
+ padding: 1rem;
235
+ overflow-y: auto;
236
+ line-height: 1.7;
237
+ }
238
+
239
+ .editor-preview h1,
240
+ .editor-preview h2,
241
+ .editor-preview h3 { margin-top: 1.5rem; }
242
+ .editor-preview p { margin-bottom: .75rem; }
243
+ .editor-preview code { background: rgba(255,255,255,.06); padding: .1em .3em; border-radius: 3px; font-size: .9em; }
244
+
245
+ /* Fullscreen editor */
246
+ .editor-fullscreen {
247
+ position: fixed;
248
+ inset: 0;
249
+ z-index: 1000;
250
+ border-radius: 0;
251
+ margin: 0;
252
+ }
253
+
254
+ .editor-fullscreen .card-body {
255
+ height: 100vh;
256
+ }
257
+
258
+ /* Media picker */
259
+ .media-picker-grid {
260
+ display: grid;
261
+ grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
262
+ gap: .75rem;
263
+ max-height: 400px;
264
+ overflow-y: auto;
265
+ padding: .25rem;
266
+ }
267
+
268
+ .media-picker-item {
269
+ cursor: pointer;
270
+ border: 2px solid transparent;
271
+ border-radius: 6px;
272
+ overflow: hidden;
273
+ transition: border-color .15s;
274
+ }
275
+
276
+ .media-picker-item:hover {
277
+ border-color: var(--primary, #5b8cff);
278
+ }
279
+
280
+ .media-picker-item img {
281
+ width: 100%;
282
+ height: 80px;
283
+ object-fit: cover;
284
+ display: block;
285
+ }
286
+
287
+ .media-picker-item span {
288
+ display: block;
289
+ font-size: .75rem;
290
+ padding: 4px 6px;
291
+ overflow: hidden;
292
+ text-overflow: ellipsis;
293
+ white-space: nowrap;
294
+ }
295
+
296
+ /* Documentation / tutorial page body styles */
297
+ .docs-body h3 {
298
+ margin-top: 1.25rem;
299
+ margin-bottom: .5rem;
300
+ }
301
+
302
+ .docs-body p {
303
+ margin-bottom: .5rem;
304
+ line-height: 1.6;
305
+ }
306
+
307
+ .docs-body ol, .docs-body ul {
308
+ margin-bottom: .75rem;
309
+ padding-left: 1.25rem;
310
+ }
311
+
312
+ .docs-body li {
313
+ margin-bottom: .25rem;
314
+ }
315
+
316
+ .docs-body hr {
317
+ margin: 1.25rem 0;
318
+ border-color: var(--border-color, rgba(255, 255, 255, .08));
319
+ }
320
+
321
+ .docs-body .table {
322
+ margin-bottom: .75rem;
323
+ }
324
+
325
+ /* Navigation builder */
326
+ .nav-items-header,
327
+ .nav-item-row {
328
+ display: flex;
329
+ gap: .5rem;
330
+ align-items: center;
331
+ padding: .35rem .75rem;
332
+ }
333
+
334
+ .nav-items-header {
335
+ border-bottom: 1px solid var(--border-color, rgba(255,255,255,.08));
336
+ padding-bottom: .4rem;
337
+ margin-bottom: .25rem;
338
+ }
339
+
340
+ .nav-item-row {
341
+ border-bottom: 1px solid var(--border-color, rgba(255,255,255,.04));
342
+ }
343
+
344
+ .nav-item-row:last-child { border-bottom: none; }
345
+
346
+ .nav-col-indent { width: 18px; flex-shrink: 0; color: var(--text-muted, #888); text-align: center; font-size: .85rem; }
347
+ .nav-col-main { flex: 2; min-width: 0; }
348
+ .nav-col-icon { flex: 0 0 90px; }
349
+ .nav-col-parent { flex: 2; min-width: 0; }
350
+ .nav-col-action { flex-shrink: 0; }
351
+
352
+ .nav-item-row--child { background: rgba(255,255,255,.02); }
353
+
354
+ .toggle-label {
355
+ display: flex;
356
+ align-items: center;
357
+ gap: .4rem;
358
+ font-size: .9rem;
359
+ cursor: pointer;
360
+ margin-right: 1rem;
361
+ }
362
+
363
+ .preset-toggles {
364
+ display: flex;
365
+ flex-wrap: wrap;
366
+ margin-top: .75rem;
367
+ }
368
+
369
+ /* Presets grid */
370
+ .presets-grid {
371
+ display: grid;
372
+ grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
373
+ gap: 1rem;
374
+ }
375
+
376
+ /* Compact card headers throughout admin */
377
+ .card-header {
378
+ padding: 0.5rem 1rem;
379
+ }
380
+
381
+ .card-header h2 {
382
+ margin: 0;
383
+ font-size: 0.9rem;
384
+ font-weight: 600;
385
+ letter-spacing: 0.02em;
386
+ }
387
+
388
+ .preset-card .card-header {
389
+ display: flex;
390
+ align-items: center;
391
+ justify-content: space-between;
392
+ }
393
+
394
+ .preset-card .card-header h3 {
395
+ margin: 0;
396
+ font-size: 1rem;
397
+ }
398
+
399
+ /* Media grid */
400
+ .media-grid {
401
+ display: grid;
402
+ grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
403
+ gap: 1rem;
404
+ }
405
+
406
+ .media-card {
407
+ background: var(--card-bg, rgba(255,255,255,.04));
408
+ border: 1px solid var(--border-color, rgba(255,255,255,.08));
409
+ border-radius: 8px;
410
+ overflow: hidden;
411
+ }
412
+
413
+ .media-preview {
414
+ height: 130px;
415
+ display: flex;
416
+ align-items: center;
417
+ justify-content: center;
418
+ background: rgba(0,0,0,.2);
419
+ overflow: hidden;
420
+ }
421
+
422
+ .media-thumb {
423
+ width: 100%;
424
+ height: 100%;
425
+ object-fit: cover;
426
+ }
427
+
428
+ .media-thumb--file {
429
+ font-size: 2rem;
430
+ color: var(--text-muted, #888);
431
+ }
432
+
433
+ .media-info {
434
+ padding: .5rem .75rem;
435
+ display: flex;
436
+ flex-direction: column;
437
+ gap: .15rem;
438
+ }
439
+
440
+ .media-name {
441
+ font-size: .8rem;
442
+ font-weight: 500;
443
+ overflow: hidden;
444
+ text-overflow: ellipsis;
445
+ white-space: nowrap;
446
+ cursor: default;
447
+ }
448
+
449
+ .media-rename-input {
450
+ width: 100%;
451
+ font-size: .8rem;
452
+ font-weight: 500;
453
+ padding: 0.1rem 0.25rem;
454
+ border: 1px solid var(--primary, #7c6af7);
455
+ border-radius: 3px;
456
+ background: var(--input-bg, transparent);
457
+ color: inherit;
458
+ outline: none;
459
+ }
460
+
461
+ .media-size {
462
+ font-size: .75rem;
463
+ color: var(--text-muted, #888);
464
+ }
465
+
466
+ .media-actions {
467
+ padding: .5rem .75rem;
468
+ display: flex;
469
+ gap: .4rem;
470
+ border-top: 1px solid var(--border-color, rgba(255,255,255,.08));
471
+ }
472
+
473
+ /* ── Admin Top Bar ──────────────────────────────── */
474
+ #admin-topbar {
475
+ height: 60px;
476
+ display: flex;
477
+ align-items: center;
478
+ gap: 1rem;
479
+ padding: 0 1.25rem;
480
+ background: var(--navbar-bg, rgba(0,0,0,.3));
481
+ border-bottom: 1px solid var(--border-color, rgba(255,255,255,.08));
482
+ position: sticky;
483
+ top: 0;
484
+ z-index: 200;
485
+ flex-shrink: 0;
486
+ }
487
+
488
+ .topbar-brand {
489
+ display: flex;
490
+ align-items: center;
491
+ gap: .5rem;
492
+ font-weight: 700;
493
+ font-size: .95rem;
494
+ color: inherit;
495
+ flex-shrink: 0;
496
+ margin-right: .5rem;
497
+ }
498
+
499
+ .topbar-brand span[data-icon],
500
+ .topbar-brand svg { color: var(--primary, #5b8cff); width: 22px; height: 22px; }
501
+
502
+ .topbar-brand-text { opacity: .85; }
503
+
504
+ .topbar-user {
505
+ display: flex;
506
+ align-items: center;
507
+ gap: .6rem;
508
+ flex: 1;
509
+ }
510
+
511
+ .topbar-user-name { font-size: .875rem; font-weight: 500; }
512
+
513
+ .topbar-role-badge {
514
+ font-size: .7rem;
515
+ font-weight: 600;
516
+ letter-spacing: .04em;
517
+ text-transform: uppercase;
518
+ padding: .15rem .45rem;
519
+ border-radius: 4px;
520
+ }
521
+
522
+ .topbar-role-badge--admin { background: rgba(91,140,255,.15); color: #5b8cff; }
523
+ .topbar-role-badge--manager { background: rgba(52,211,153,.15); color: #34d399; }
524
+ .topbar-role-badge--editor { background: rgba(251,191,36,.15); color: #fbbf24; }
525
+ .topbar-role-badge--subscriber { background: rgba(148,163,184,.15); color: #94a3b8; }
526
+
527
+ .topbar-actions {
528
+ display: flex;
529
+ align-items: center;
530
+ gap: .5rem;
531
+ flex-shrink: 0;
532
+ }
533
+
534
+ .topbar-action-link {
535
+ display: flex;
536
+ align-items: center;
537
+ gap: .35rem;
538
+ font-size: .875rem;
539
+ color: var(--text-muted, #888);
540
+ text-decoration: none;
541
+ padding: .4rem .65rem;
542
+ border-radius: 6px;
543
+ transition: color .15s, background .15s;
544
+ }
545
+
546
+ .topbar-action-link:hover {
547
+ color: var(--text, #eee);
548
+ background: rgba(255,255,255,.06);
549
+ }
550
+
551
+ .topbar-action-link span[data-icon],
552
+ .topbar-action-link svg { width: 16px; height: 16px; }
553
+
554
+ .topbar-signout {
555
+ display: flex;
556
+ align-items: center;
557
+ gap: .35rem;
558
+ font-size: .875rem;
559
+ }
560
+
561
+ .topbar-signout span[data-icon],
562
+ .topbar-signout svg { width: 16px; height: 16px; }
563
+
564
+ /* Login / setup page */
565
+ .login-wrap {
566
+ position: fixed;
567
+ inset: 0;
568
+ display: flex;
569
+ align-items: center;
570
+ justify-content: center;
571
+ padding: 1rem;
572
+ background: var(--body-bg, #0f1117);
573
+ z-index: 100;
574
+ overflow-y: auto;
575
+ }
576
+
577
+ .login-card {
578
+ width: 100%;
579
+ max-width: 460px;
580
+ }
581
+
582
+ /* Onboarding done icon */
583
+ .ob-done-icon {
584
+ font-size: 3rem;
585
+ color: #34d399;
586
+ margin-bottom: 1rem;
587
+ text-align: center;
588
+ }
589
+
590
+ /* Skip link */
591
+ .btn-skip {
592
+ display: block;
593
+ text-align: center;
594
+ margin-top: .75rem;
595
+ font-size: .85rem;
596
+ color: var(--text-muted, #888);
597
+ text-decoration: none;
598
+ }
599
+ .btn-skip:hover { text-decoration: underline; }
600
+
601
+ /* Theme swatch grid */
602
+ .theme-grid {
603
+ display: grid;
604
+ grid-template-columns: repeat(3, 1fr);
605
+ gap: .6rem;
606
+ }
607
+
608
+ .theme-swatch {
609
+ border: 2px solid var(--border-color, rgba(255,255,255,.1));
610
+ border-radius: 8px;
611
+ overflow: hidden;
612
+ cursor: pointer;
613
+ transition: border-color .15s, transform .1s;
614
+ }
615
+
616
+ .theme-swatch:hover {
617
+ border-color: var(--primary, #5b8cff);
618
+ transform: translateY(-1px);
619
+ }
620
+
621
+ .theme-swatch.selected {
622
+ border-color: var(--primary, #5b8cff);
623
+ box-shadow: 0 0 0 2px var(--primary, #5b8cff);
624
+ }
625
+
626
+ .theme-swatch-preview {
627
+ height: 52px;
628
+ position: relative;
629
+ display: flex;
630
+ align-items: flex-end;
631
+ padding: .35rem;
632
+ }
633
+
634
+ .theme-swatch-accent {
635
+ width: 28px;
636
+ height: 6px;
637
+ border-radius: 3px;
638
+ }
639
+
640
+ .theme-swatch-label {
641
+ display: flex;
642
+ justify-content: space-between;
643
+ align-items: center;
644
+ padding: .3rem .45rem;
645
+ font-size: .7rem;
646
+ background: var(--card-bg, rgba(255,255,255,.04));
647
+ }
648
+
649
+ .theme-swatch-mode {
650
+ color: var(--text-muted, #888);
651
+ font-size: .65rem;
652
+ }
653
+
654
+ .login-logo {
655
+ display: flex;
656
+ align-items: center;
657
+ gap: .75rem;
658
+ margin-bottom: 1.75rem;
659
+ font-size: 1.5rem;
660
+ }
661
+
662
+ .login-logo span[data-icon] { font-size: 2rem; color: var(--primary, #5b8cff); }
663
+ .login-logo h1 { margin: 0; font-size: 1.5rem; font-weight: 700; }
664
+
665
+ .login-heading {
666
+ font-size: 1.1rem;
667
+ font-weight: 600;
668
+ margin-bottom: 1.25rem;
669
+ }
670
+
671
+ .btn-block { width: 100%; }
672
+
673
+ /* Plugin cards grid */
674
+ .plugins-grid {
675
+ display: grid;
676
+ grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
677
+ gap: 1rem;
678
+ }
679
+
680
+ .plugin-card {
681
+ display: flex;
682
+ flex-direction: column;
683
+ }
684
+
685
+ .plugin-card .card-body { flex: 1; }
686
+
687
+ .plugin-header {
688
+ display: flex;
689
+ align-items: flex-start;
690
+ gap: .75rem;
691
+ margin-bottom: .75rem;
692
+ }
693
+
694
+ .plugin-icon {
695
+ width: 40px;
696
+ height: 40px;
697
+ border-radius: 8px;
698
+ background: var(--primary-alpha, rgba(91,140,255,.15));
699
+ color: var(--primary, #5b8cff);
700
+ display: flex;
701
+ align-items: center;
702
+ justify-content: center;
703
+ flex-shrink: 0;
704
+ }
705
+
706
+ .plugin-meta { flex: 1; min-width: 0; }
707
+ .plugin-name { font-weight: 600; margin-bottom: .15rem; }
708
+ .plugin-version { font-size: .75rem; color: var(--text-muted, #888); }
709
+ .plugin-desc { font-size: .875rem; color: var(--text-muted, #888); margin-bottom: 1rem; }
710
+
711
+ .plugin-footer {
712
+ display: flex;
713
+ align-items: center;
714
+ justify-content: space-between;
715
+ padding: .75rem 1rem;
716
+ border-top: 1px solid var(--border-color, rgba(255,255,255,.08));
717
+ }
718
+
719
+ /* Sidebar badge right-alignment */
720
+ #admin-sidebar .sidebar-badge {
721
+ margin-left: auto;
722
+ }
723
+
724
+ /* ===== Theme-aware sidebar overrides =====
725
+ Domma's sidebar defaults to .sidebar-dark which uses fixed --dm-gray-* values.
726
+ These overrides replace those with --dm-surface/text vars so the sidebar
727
+ responds properly to theme changes. */
728
+ #admin-sidebar.sidebar-dark {
729
+ background: var(--dm-surface);
730
+ border-color: var(--dm-border);
731
+ }
732
+ #admin-sidebar.sidebar-dark .sidebar-header {
733
+ background: var(--dm-surface-raised);
734
+ border-color: var(--dm-border);
735
+ }
736
+ #admin-sidebar.sidebar-dark .sidebar-header-title {
737
+ color: var(--dm-text);
738
+ }
739
+ #admin-sidebar.sidebar-dark .sidebar-link {
740
+ color: var(--dm-text-muted);
741
+ }
742
+ #admin-sidebar.sidebar-dark .sidebar-link:hover {
743
+ color: var(--dm-text);
744
+ background: var(--dm-surface-overlay);
745
+ }
746
+ #admin-sidebar.sidebar-dark .sidebar-link.active {
747
+ color: var(--dm-primary);
748
+ background: var(--dm-primary-alpha, rgba(91,140,255,.12));
749
+ border-left-color: var(--dm-primary);
750
+ }
751
+ #admin-sidebar.sidebar-dark .sidebar-heading {
752
+ color: var(--dm-text-muted);
753
+ }
754
+ #admin-sidebar.sidebar-dark .sidebar-divider {
755
+ background: var(--dm-border);
756
+ }
757
+ #admin-sidebar.sidebar-dark .sidebar-footer {
758
+ background: var(--dm-surface-raised);
759
+ border-color: var(--dm-border);
760
+ }
761
+
762
+ /* Collapsible sidebar section headings */
763
+ .sidebar-heading--collapsible {
764
+ display: flex !important;
765
+ align-items: center;
766
+ justify-content: space-between;
767
+ cursor: pointer;
768
+ user-select: none;
769
+ }
770
+
771
+ .sidebar-heading-toggle {
772
+ display: flex;
773
+ align-items: center;
774
+ opacity: 0.5;
775
+ flex-shrink: 0;
776
+ transition: transform 0.2s ease;
777
+ }
778
+
779
+ .sidebar-heading--collapsible.is-collapsed .sidebar-heading-toggle {
780
+ transform: rotate(-90deg);
781
+ }
782
+
783
+ /* Utilities */
784
+ .mt-3 { margin-top: .75rem; }
785
+ .mt-4 { margin-top: 1rem; }
786
+ .mb-2 { margin-bottom: .5rem; }
787
+ .mb-3 { margin-bottom: .75rem; }
788
+ .mb-4 { margin-bottom: 1rem; }
789
+ .p-0 { padding: 0 !important; }
790
+ .text-muted { color: var(--text-muted, #888); }
791
+
792
+ @media (max-width: 768px) {
793
+ .view-container { padding: 1rem; }
794
+
795
+ .editor-body {
796
+ flex-direction: column;
797
+ }
798
+ .editor-divider { width: auto; height: 1px; }
799
+ }
800
+
801
+ /* =========================================================
802
+ Image Editor
803
+ ========================================================= */
804
+
805
+ .image-editor {
806
+ display: flex;
807
+ flex-direction: column;
808
+ gap: 0;
809
+ }
810
+
811
+ .image-editor-toolbar {
812
+ display: flex;
813
+ flex-direction: row;
814
+ align-items: center;
815
+ gap: 0.25rem;
816
+ padding: 0.5rem 0.75rem;
817
+ border-bottom: 1px solid var(--border, rgba(255, 255, 255, .1));
818
+ }
819
+
820
+ .image-editor-sep {
821
+ display: inline-block;
822
+ width: 1px;
823
+ height: 1.5rem;
824
+ background: var(--border, rgba(255, 255, 255, .15));
825
+ margin: 0 0.25rem;
826
+ flex-shrink: 0;
827
+ }
828
+
829
+ .editor-toolbar-btn.active {
830
+ color: var(--primary, #7c6af7);
831
+ background: color-mix(in srgb, var(--primary, #7c6af7) 15%, transparent);
832
+ }
833
+
834
+ /* Effects dropdown */
835
+ .editor-toolbar {
836
+ position: relative;
837
+ }
838
+
839
+ .editor-effects-dropdown-menu {
840
+ position: absolute;
841
+ top: 100%;
842
+ z-index: 1000;
843
+ background: var(--dm-surface, #1e1e2e);
844
+ border: 1px solid var(--border-color, rgba(255, 255, 255, .1));
845
+ border-radius: 8px;
846
+ box-shadow: 0 8px 24px rgba(0, 0, 0, .4);
847
+ padding: 6px;
848
+ min-width: 180px;
849
+ max-height: 340px;
850
+ overflow-y: auto;
851
+ }
852
+
853
+ .editor-effects-category {
854
+ padding: 6px 8px 3px;
855
+ font-size: .7rem;
856
+ font-weight: 700;
857
+ letter-spacing: .07em;
858
+ text-transform: uppercase;
859
+ color: var(--dm-text-muted, #888);
860
+ }
861
+
862
+ .editor-effects-item {
863
+ display: block;
864
+ width: 100%;
865
+ text-align: left;
866
+ background: none;
867
+ border: none;
868
+ color: var(--dm-text, #ddd);
869
+ padding: 6px 10px;
870
+ border-radius: 5px;
871
+ cursor: pointer;
872
+ font-size: .85rem;
873
+ transition: background .12s, color .12s;
874
+ }
875
+
876
+ .editor-effects-item:hover {
877
+ background: rgba(255, 255, 255, .08);
878
+ color: var(--dm-text-bright, #fff);
879
+ }
880
+
881
+ .image-editor-canvas {
882
+ min-height: 320px;
883
+ max-height: 520px;
884
+ background: #111;
885
+ overflow: hidden;
886
+ display: flex;
887
+ align-items: center;
888
+ justify-content: center;
889
+ }
890
+
891
+ .image-editor-canvas img {
892
+ display: block;
893
+ max-width: 100%;
894
+ max-height: 520px;
895
+ }
896
+
897
+ .image-editor-resize {
898
+ display: flex;
899
+ flex-direction: row;
900
+ align-items: center;
901
+ gap: 0.5rem;
902
+ padding: 0.6rem 0.75rem;
903
+ border-top: 1px solid var(--border, rgba(255, 255, 255, .1));
904
+ font-size: 0.85rem;
905
+ }
906
+
907
+ .image-editor-resize label {
908
+ font-weight: 600;
909
+ color: var(--text-muted, #888);
910
+ font-size: 0.8rem;
911
+ }
912
+
913
+ .image-editor-resize .form-input {
914
+ width: 5rem;
915
+ padding: 0.25rem 0.5rem;
916
+ font-size: 0.85rem;
917
+ }
918
+
919
+ .image-editor-footer {
920
+ display: flex;
921
+ flex-direction: row;
922
+ align-items: center;
923
+ justify-content: space-between;
924
+ padding: 0.75rem;
925
+ border-top: 1px solid var(--border, rgba(255, 255, 255, .1));
926
+ gap: 0.5rem;
927
+ }
928
+
929
+ /* =========================================================
930
+ Image Editor — Effects panel (tabs, sliders, watermark, border, format)
931
+ ========================================================= */
932
+
933
+ .image-editor-effects {
934
+ border-top: 1px solid var(--border, rgba(255, 255, 255, .1));
935
+ }
936
+
937
+ .image-editor-tab-bar {
938
+ display: flex;
939
+ flex-direction: row;
940
+ overflow-x: auto;
941
+ border-bottom: 1px solid var(--border, rgba(255, 255, 255, .1));
942
+ scrollbar-width: none;
943
+ }
944
+
945
+ .image-editor-tab-bar::-webkit-scrollbar {
946
+ display: none;
947
+ }
948
+
949
+ .image-editor-tab-btn {
950
+ display: inline-flex;
951
+ align-items: center;
952
+ gap: 0.35rem;
953
+ padding: 0.5rem 0.85rem;
954
+ font-size: 0.8rem;
955
+ font-weight: 500;
956
+ border: none;
957
+ border-bottom: 2px solid transparent;
958
+ background: transparent;
959
+ cursor: pointer;
960
+ color: var(--text-muted, #888);
961
+ white-space: nowrap;
962
+ transition: color 0.15s, border-color 0.15s;
963
+ flex-shrink: 0;
964
+ }
965
+
966
+ .image-editor-tab-btn:hover {
967
+ color: var(--text, #eee);
968
+ }
969
+
970
+ .image-editor-tab-btn.active {
971
+ color: var(--primary, #7c6af7);
972
+ border-bottom-color: var(--primary, #7c6af7);
973
+ }
974
+
975
+ .image-editor-tab-panel {
976
+ padding: 0.75rem;
977
+ max-height: 200px;
978
+ overflow-y: auto;
979
+ }
980
+
981
+ /* Preset filter buttons */
982
+ .ie-presets-grid {
983
+ display: flex;
984
+ flex-wrap: wrap;
985
+ gap: 0.35rem;
986
+ margin-bottom: 0.5rem;
987
+ }
988
+
989
+ .ie-preset-btn.active {
990
+ color: var(--primary, #7c6af7);
991
+ background: color-mix(in srgb, var(--primary, #7c6af7) 15%, transparent);
992
+ border-color: var(--primary, #7c6af7);
993
+ }
994
+
995
+ .ie-server-note {
996
+ font-size: 0.73rem;
997
+ color: var(--text-muted, #888);
998
+ font-style: italic;
999
+ margin: 0.25rem 0 0;
1000
+ line-height: 1.4;
1001
+ }
1002
+
1003
+ /* Slider rows */
1004
+ .ie-slider-row {
1005
+ display: flex;
1006
+ align-items: center;
1007
+ gap: 0.5rem;
1008
+ margin-bottom: 0.4rem;
1009
+ }
1010
+
1011
+ .ie-slider-label {
1012
+ width: 6rem;
1013
+ font-size: 0.8rem;
1014
+ color: var(--text-muted, #888);
1015
+ font-weight: 600;
1016
+ flex-shrink: 0;
1017
+ }
1018
+
1019
+ .ie-slider {
1020
+ flex: 1;
1021
+ accent-color: var(--primary, #7c6af7);
1022
+ cursor: pointer;
1023
+ }
1024
+
1025
+ .ie-slider-val {
1026
+ width: 3rem;
1027
+ font-size: 0.8rem;
1028
+ text-align: right;
1029
+ color: var(--text, #eee);
1030
+ flex-shrink: 0;
1031
+ }
1032
+
1033
+ /* Selects inside panels */
1034
+ .ie-select {
1035
+ flex: 1;
1036
+ font-size: 0.85rem;
1037
+ padding: 0.25rem 0.5rem;
1038
+ }
1039
+
1040
+ /* Colour picker */
1041
+ .ie-colour-input {
1042
+ width: 40px;
1043
+ height: 28px;
1044
+ padding: 0;
1045
+ border: 1px solid var(--border, rgba(255, 255, 255, .15));
1046
+ border-radius: 4px;
1047
+ cursor: pointer;
1048
+ background: transparent;
1049
+ flex-shrink: 0;
1050
+ }
1051
+
1052
+ /* Watermark preview row */
1053
+ .ie-wm-preview-row {
1054
+ display: flex;
1055
+ align-items: center;
1056
+ gap: 0.5rem;
1057
+ margin: 0.4rem 0;
1058
+ }
1059
+
1060
+ .ie-wm-preview-img {
1061
+ width: 48px;
1062
+ height: 48px;
1063
+ object-fit: contain;
1064
+ border-radius: 4px;
1065
+ background: var(--surface-2, rgba(255, 255, 255, .06));
1066
+ flex-shrink: 0;
1067
+ }
1068
+
1069
+ .ie-wm-preview-name {
1070
+ font-size: 0.8rem;
1071
+ flex: 1;
1072
+ overflow: hidden;
1073
+ text-overflow: ellipsis;
1074
+ white-space: nowrap;
1075
+ color: var(--text, #eee);
1076
+ }
1077
+
1078
+ /* Media picker modal */
1079
+ .ie-media-picker {
1080
+ padding: 0.25rem 0;
1081
+ }
1082
+
1083
+ .ie-media-picker-grid {
1084
+ display: grid;
1085
+ grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));
1086
+ gap: 0.5rem;
1087
+ max-height: 300px;
1088
+ overflow-y: auto;
1089
+ }
1090
+
1091
+ .ie-media-thumb {
1092
+ display: flex;
1093
+ flex-direction: column;
1094
+ align-items: center;
1095
+ gap: 0.25rem;
1096
+ padding: 0.4rem;
1097
+ border-radius: 6px;
1098
+ cursor: pointer;
1099
+ border: 2px solid transparent;
1100
+ transition: border-color 0.15s, background 0.15s;
1101
+ }
1102
+
1103
+ .ie-media-thumb:hover {
1104
+ background: var(--surface-2, rgba(255, 255, 255, .08));
1105
+ border-color: var(--primary, #7c6af7);
1106
+ }
1107
+
1108
+ .ie-media-thumb img {
1109
+ width: 72px;
1110
+ height: 72px;
1111
+ object-fit: cover;
1112
+ border-radius: 4px;
1113
+ }
1114
+
1115
+ .ie-media-thumb-name {
1116
+ font-size: 0.7rem;
1117
+ color: var(--text-muted, #888);
1118
+ text-align: center;
1119
+ overflow: hidden;
1120
+ text-overflow: ellipsis;
1121
+ white-space: nowrap;
1122
+ max-width: 72px;
1123
+ }