domma-cms 0.1.0 → 0.2.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 (87) hide show
  1. package/admin/css/admin.css +78 -1
  2. package/admin/js/api.js +32 -0
  3. package/admin/js/app.js +24 -7
  4. package/admin/js/config/sidebar-config.js +8 -0
  5. package/admin/js/templates/collection-editor.html +80 -0
  6. package/admin/js/templates/collection-entries.html +36 -0
  7. package/admin/js/templates/collections.html +12 -0
  8. package/admin/js/templates/documentation.html +136 -0
  9. package/admin/js/templates/navigation.html +26 -4
  10. package/admin/js/templates/page-editor.html +91 -85
  11. package/admin/js/templates/settings.html +433 -172
  12. package/admin/js/views/collection-editor.js +487 -0
  13. package/admin/js/views/collection-entries.js +484 -0
  14. package/admin/js/views/collections.js +153 -0
  15. package/admin/js/views/dashboard.js +14 -6
  16. package/admin/js/views/index.js +9 -3
  17. package/admin/js/views/login.js +3 -2
  18. package/admin/js/views/navigation.js +77 -11
  19. package/admin/js/views/page-editor.js +207 -25
  20. package/admin/js/views/pages.js +14 -6
  21. package/admin/js/views/settings.js +137 -2
  22. package/admin/js/views/users.js +10 -7
  23. package/bin/cli.js +37 -10
  24. package/config/auth.json +2 -1
  25. package/config/content.json +1 -0
  26. package/config/navigation.json +14 -4
  27. package/config/plugins.json +0 -18
  28. package/config/presets.json +4 -8
  29. package/config/site.json +44 -3
  30. package/package.json +6 -2
  31. package/plugins/domma-effects/admin/templates/domma-effects.html +92 -3
  32. package/plugins/domma-effects/plugin.js +125 -0
  33. package/plugins/domma-effects/public/inject-body.html +19 -0
  34. package/plugins/example-analytics/admin/views/analytics.js +2 -2
  35. package/plugins/example-analytics/plugin.json +8 -0
  36. package/plugins/example-analytics/stats.json +15 -1
  37. package/plugins/form-builder/admin/templates/form-editor.html +19 -6
  38. package/plugins/form-builder/admin/views/form-editor.js +634 -9
  39. package/plugins/form-builder/admin/views/form-submissions.js +4 -4
  40. package/plugins/form-builder/admin/views/forms-list.js +5 -5
  41. package/plugins/form-builder/data/forms/consent.json +104 -0
  42. package/plugins/form-builder/data/forms/contacts.json +66 -0
  43. package/plugins/form-builder/data/submissions/consent.json +13 -0
  44. package/plugins/form-builder/data/submissions/contacts.json +26 -0
  45. package/plugins/form-builder/plugin.js +62 -11
  46. package/plugins/form-builder/plugin.json +12 -16
  47. package/plugins/form-builder/public/form-logic-engine.js +568 -0
  48. package/plugins/form-builder/public/inject-body.html +88 -6
  49. package/plugins/form-builder/public/inject-head.html +16 -0
  50. package/plugins/form-builder/public/package.json +1 -0
  51. package/public/css/site.css +113 -0
  52. package/public/js/btt.js +90 -0
  53. package/public/js/cookie-consent.js +61 -0
  54. package/public/js/site.js +129 -34
  55. package/scripts/build.js +129 -0
  56. package/scripts/seed.js +517 -7
  57. package/server/routes/api/collections.js +301 -0
  58. package/server/routes/api/settings.js +66 -2
  59. package/server/server.js +19 -15
  60. package/server/services/collections.js +430 -0
  61. package/server/services/content.js +11 -2
  62. package/server/services/hooks.js +109 -0
  63. package/server/services/markdown.js +500 -149
  64. package/server/services/plugins.js +6 -1
  65. package/server/services/renderer.js +73 -7
  66. package/server/templates/page.html +38 -3
  67. package/plugins/back-to-top/admin/templates/back-to-top-settings.html +0 -55
  68. package/plugins/back-to-top/admin/views/back-to-top-settings.js +0 -44
  69. package/plugins/back-to-top/config.js +0 -10
  70. package/plugins/back-to-top/plugin.js +0 -24
  71. package/plugins/back-to-top/plugin.json +0 -36
  72. package/plugins/back-to-top/public/inject-body.html +0 -105
  73. package/plugins/cookie-consent/admin/templates/cookie-consent-settings.html +0 -113
  74. package/plugins/cookie-consent/admin/views/cookie-consent-settings.js +0 -73
  75. package/plugins/cookie-consent/config.js +0 -30
  76. package/plugins/cookie-consent/plugin.js +0 -24
  77. package/plugins/cookie-consent/plugin.json +0 -36
  78. package/plugins/cookie-consent/public/inject-body.html +0 -69
  79. package/plugins/custom-css/admin/templates/custom-css.html +0 -17
  80. package/plugins/custom-css/admin/views/custom-css.js +0 -35
  81. package/plugins/custom-css/config.js +0 -1
  82. package/plugins/custom-css/data/custom.css +0 -0
  83. package/plugins/custom-css/plugin.js +0 -63
  84. package/plugins/custom-css/plugin.json +0 -32
  85. package/plugins/custom-css/public/inject-head.html +0 -1
  86. package/plugins/form-builder/data/forms/contact.json +0 -52
  87. package/plugins/form-builder/data/submissions/contact.json +0 -14
@@ -3,188 +3,449 @@
3
3
  <button id="save-settings-btn" class="btn btn-primary"><span data-icon="save"></span> Save</button>
4
4
  </div>
5
5
 
6
- <div class="card card-collapsible mb-4">
7
- <div class="card-header" role="button" tabindex="0">
8
- <div class="card-header-content"><h2>General</h2></div>
9
- <span class="card-collapse-icon" data-icon="chevron-down"></span>
6
+ <div class="tabs" id="settings-tabs">
7
+ <div class="tab-list">
8
+ <button class="tab-item active">General</button>
9
+ <button class="tab-item">SEO</button>
10
+ <button class="tab-item">Footer</button>
11
+ <button class="tab-item">Email / SMTP</button>
12
+ <button class="tab-item">Back to Top</button>
13
+ <button class="tab-item">Cookie Consent</button>
14
+ <button class="tab-item">Custom CSS</button>
10
15
  </div>
11
- <div class="card-body">
12
- <div class="row mb-3">
13
- <div class="col-6">
14
- <label class="form-label">Site Title</label>
15
- <input id="field-site-title" type="text" class="form-input" placeholder="My Site">
16
- </div>
17
- <div class="col-6">
18
- <label class="form-label">Tagline</label>
19
- <input id="field-tagline" type="text" class="form-input" placeholder="Built with Domma CMS">
20
- </div>
21
- </div>
22
- <div class="row">
23
- <div class="col-6">
24
- <label class="form-label">Public Site Theme</label>
25
- <select id="field-theme" class="form-select">
26
- <optgroup label="Charcoal">
27
- <option value="charcoal-dark">Charcoal Dark</option>
28
- <option value="charcoal-light">Charcoal Light</option>
29
- </optgroup>
30
- <optgroup label="Ocean">
31
- <option value="ocean-dark">Ocean Dark</option>
32
- <option value="ocean-light">Ocean Light</option>
33
- </optgroup>
34
- <optgroup label="Forest">
35
- <option value="forest-dark">Forest Dark</option>
36
- <option value="forest-light">Forest Light</option>
37
- </optgroup>
38
- <optgroup label="Sunset">
39
- <option value="sunset-dark">Sunset Dark</option>
40
- <option value="sunset-light">Sunset Light</option>
41
- </optgroup>
42
- <optgroup label="Royal">
43
- <option value="royal-dark">Royal Dark</option>
44
- <option value="royal-light">Royal Light</option>
45
- </optgroup>
46
- <optgroup label="Lemon">
47
- <option value="lemon-dark">Lemon Dark</option>
48
- <option value="lemon-light">Lemon Light</option>
49
- </optgroup>
50
- <optgroup label="Silver">
51
- <option value="silver-dark">Silver Dark</option>
52
- <option value="silver-light">Silver Light</option>
53
- </optgroup>
54
- <optgroup label="Other">
55
- <option value="grayve">Grayve</option>
56
- <option value="christmas-dark">Christmas Dark</option>
57
- <option value="christmas-light">Christmas Light</option>
58
- </optgroup>
59
- </select>
60
- <p class="form-hint text-muted" style="margin-top:0.4rem;font-size:0.8rem;">Applied to the public-facing website.</p>
61
- </div>
62
- <div class="col-6">
63
- <label class="form-label">Admin Theme</label>
64
- <select id="field-admin-theme" class="form-select">
65
- <optgroup label="Charcoal">
66
- <option value="charcoal-dark">Charcoal Dark</option>
67
- <option value="charcoal-light">Charcoal Light</option>
68
- </optgroup>
69
- <optgroup label="Ocean">
70
- <option value="ocean-dark">Ocean Dark</option>
71
- <option value="ocean-light">Ocean Light</option>
72
- </optgroup>
73
- <optgroup label="Forest">
74
- <option value="forest-dark">Forest Dark</option>
75
- <option value="forest-light">Forest Light</option>
76
- </optgroup>
77
- <optgroup label="Sunset">
78
- <option value="sunset-dark">Sunset Dark</option>
79
- <option value="sunset-light">Sunset Light</option>
80
- </optgroup>
81
- <optgroup label="Royal">
82
- <option value="royal-dark">Royal Dark</option>
83
- <option value="royal-light">Royal Light</option>
84
- </optgroup>
85
- <optgroup label="Lemon">
86
- <option value="lemon-dark">Lemon Dark</option>
87
- <option value="lemon-light">Lemon Light</option>
88
- </optgroup>
89
- <optgroup label="Silver">
90
- <option value="silver-dark">Silver Dark</option>
91
- <option value="silver-light">Silver Light</option>
92
- </optgroup>
93
- <optgroup label="Other">
94
- <option value="grayve">Grayve</option>
95
- <option value="christmas-dark">Christmas Dark</option>
96
- <option value="christmas-light">Christmas Light</option>
97
- </optgroup>
98
- </select>
99
- <p class="form-hint text-muted" style="margin-top:0.4rem;font-size:0.8rem;">Applied to the admin panel.</p>
100
- </div>
16
+ <div class="tab-content">
17
+
18
+ <!-- General -->
19
+ <div class="tab-panel active">
20
+ <div class="row mb-3">
21
+ <div class="col-6">
22
+ <label class="form-label">Site Title</label>
23
+ <input id="field-site-title" type="text" class="form-input" placeholder="My Site">
24
+ </div>
25
+ <div class="col-6">
26
+ <label class="form-label">Tagline</label>
27
+ <input id="field-tagline" type="text" class="form-input" placeholder="Built with Domma CMS">
28
+ </div>
29
+ </div>
30
+ <div class="row mb-3">
31
+ <div class="col-6">
32
+ <label class="form-label">Font Family</label>
33
+ <select id="field-font-family" class="form-select">
34
+ <option value="Roboto">Roboto (default)</option>
35
+ <option value="Inter">Inter</option>
36
+ <option value="Open Sans">Open Sans</option>
37
+ <option value="Lato">Lato</option>
38
+ <option value="Nunito">Nunito</option>
39
+ <option value="Poppins">Poppins</option>
40
+ <option value="Source Sans 3">Source Sans 3</option>
41
+ <option value="Merriweather">Merriweather (serif)</option>
42
+ <option value="Playfair Display">Playfair Display (serif)</option>
43
+ <option value="system-ui">System UI (no web font)</option>
44
+ </select>
45
+ <p class="form-hint text-muted" style="margin-top:0.4rem;font-size:0.8rem;">Applied to the public-facing
46
+ website body text.</p>
47
+ </div>
48
+ <div class="col-3">
49
+ <label class="form-label">Font Size</label>
50
+ <select id="field-font-size" class="form-select">
51
+ <option value="13">13px — Compact</option>
52
+ <option value="14">14px — Small</option>
53
+ <option value="15">15px — Slightly small</option>
54
+ <option value="16">16px — Default</option>
55
+ <option value="17">17px — Slightly large</option>
56
+ <option value="18">18px — Large</option>
57
+ <option value="20">20px — Extra large</option>
58
+ </select>
59
+ <p class="form-hint text-muted" style="margin-top:0.4rem;font-size:0.8rem;">Root font size. All rem/em values
60
+ scale with this.</p>
101
61
  </div>
62
+ </div>
63
+ <div class="row">
64
+ <div class="col-6">
65
+ <label class="form-label">Public Site Theme</label>
66
+ <select id="field-theme" class="form-select">
67
+ <optgroup label="Charcoal">
68
+ <option value="charcoal-dark">Charcoal Dark</option>
69
+ <option value="charcoal-light">Charcoal Light</option>
70
+ </optgroup>
71
+ <optgroup label="Ocean">
72
+ <option value="ocean-dark">Ocean Dark</option>
73
+ <option value="ocean-light">Ocean Light</option>
74
+ </optgroup>
75
+ <optgroup label="Forest">
76
+ <option value="forest-dark">Forest Dark</option>
77
+ <option value="forest-light">Forest Light</option>
78
+ </optgroup>
79
+ <optgroup label="Sunset">
80
+ <option value="sunset-dark">Sunset Dark</option>
81
+ <option value="sunset-light">Sunset Light</option>
82
+ </optgroup>
83
+ <optgroup label="Royal">
84
+ <option value="royal-dark">Royal Dark</option>
85
+ <option value="royal-light">Royal Light</option>
86
+ </optgroup>
87
+ <optgroup label="Lemon">
88
+ <option value="lemon-dark">Lemon Dark</option>
89
+ <option value="lemon-light">Lemon Light</option>
90
+ </optgroup>
91
+ <optgroup label="Silver">
92
+ <option value="silver-dark">Silver Dark</option>
93
+ <option value="silver-light">Silver Light</option>
94
+ </optgroup>
95
+ <optgroup label="Unicorn">
96
+ <option value="unicorn-dark">Unicorn Dark</option>
97
+ <option value="unicorn-light">Unicorn Light</option>
98
+ </optgroup>
99
+ <optgroup label="Dreamy">
100
+ <option value="dreamy-dark">Dreamy Dark</option>
101
+ <option value="dreamy-light">Dreamy Light</option>
102
+ </optgroup>
103
+ <optgroup label="Grayve">
104
+ <option value="grayve-dark">Grayve Dark</option>
105
+ <option value="grayve-light">Grayve Light</option>
106
+ </optgroup>
107
+ <optgroup label="Other">
108
+ <option value="christmas-dark">Christmas Dark</option>
109
+ <option value="christmas-light">Christmas Light</option>
110
+ </optgroup>
111
+ </select>
112
+ <p class="form-hint text-muted" style="margin-top:0.4rem;font-size:0.8rem;">Applied to the public-facing
113
+ website.</p>
114
+ </div>
115
+ <div class="col-6">
116
+ <label class="form-label">Admin Theme</label>
117
+ <select id="field-admin-theme" class="form-select">
118
+ <optgroup label="Charcoal">
119
+ <option value="charcoal-dark">Charcoal Dark</option>
120
+ <option value="charcoal-light">Charcoal Light</option>
121
+ </optgroup>
122
+ <optgroup label="Ocean">
123
+ <option value="ocean-dark">Ocean Dark</option>
124
+ <option value="ocean-light">Ocean Light</option>
125
+ </optgroup>
126
+ <optgroup label="Forest">
127
+ <option value="forest-dark">Forest Dark</option>
128
+ <option value="forest-light">Forest Light</option>
129
+ </optgroup>
130
+ <optgroup label="Sunset">
131
+ <option value="sunset-dark">Sunset Dark</option>
132
+ <option value="sunset-light">Sunset Light</option>
133
+ </optgroup>
134
+ <optgroup label="Royal">
135
+ <option value="royal-dark">Royal Dark</option>
136
+ <option value="royal-light">Royal Light</option>
137
+ </optgroup>
138
+ <optgroup label="Lemon">
139
+ <option value="lemon-dark">Lemon Dark</option>
140
+ <option value="lemon-light">Lemon Light</option>
141
+ </optgroup>
142
+ <optgroup label="Silver">
143
+ <option value="silver-dark">Silver Dark</option>
144
+ <option value="silver-light">Silver Light</option>
145
+ </optgroup>
146
+ <optgroup label="Unicorn">
147
+ <option value="unicorn-dark">Unicorn Dark</option>
148
+ <option value="unicorn-light">Unicorn Light</option>
149
+ </optgroup>
150
+ <optgroup label="Dreamy">
151
+ <option value="dreamy-dark">Dreamy Dark</option>
152
+ <option value="dreamy-light">Dreamy Light</option>
153
+ </optgroup>
154
+ <optgroup label="Grayve">
155
+ <option value="grayve-dark">Grayve Dark</option>
156
+ <option value="grayve-light">Grayve Light</option>
157
+ </optgroup>
158
+ <optgroup label="Other">
159
+ <option value="christmas-dark">Christmas Dark</option>
160
+ <option value="christmas-light">Christmas Light</option>
161
+ </optgroup>
162
+ </select>
163
+ <p class="form-hint text-muted" style="margin-top:0.4rem;font-size:0.8rem;">Applied to the admin panel.</p>
164
+ </div>
165
+ </div>
102
166
  </div>
103
- </div>
104
167
 
105
- <div class="card card-collapsible mb-4">
106
- <div class="card-header" role="button" tabindex="0">
107
- <div class="card-header-content"><h2>SEO Defaults</h2></div>
108
- <span class="card-collapse-icon" data-icon="chevron-down"></span>
109
- </div>
110
- <div class="card-body">
111
- <div class="row mb-3">
112
- <div class="col-8">
113
- <label class="form-label">Default Site Title</label>
114
- <input id="field-seo-title" type="text" class="form-input" placeholder="My Site">
115
- </div>
116
- <div class="col-4">
117
- <label class="form-label">Title Separator</label>
118
- <input id="field-seo-separator" type="text" class="form-input" placeholder=" | ">
119
- </div>
120
- </div>
121
- <div class="row">
122
- <div class="col">
123
- <label class="form-label">Default Meta Description</label>
124
- <input id="field-seo-desc" type="text" class="form-input" placeholder="Brief description of your site">
125
- </div>
168
+ <!-- SEO -->
169
+ <div class="tab-panel">
170
+ <div class="row mb-3">
171
+ <div class="col-8">
172
+ <label class="form-label">Default Site Title</label>
173
+ <input id="field-seo-title" type="text" class="form-input" placeholder="My Site">
126
174
  </div>
175
+ <div class="col-4">
176
+ <label class="form-label">Title Separator</label>
177
+ <input id="field-seo-separator" type="text" class="form-input" placeholder=" | ">
178
+ </div>
179
+ </div>
180
+ <div class="row">
181
+ <div class="col">
182
+ <label class="form-label">Default Meta Description</label>
183
+ <input id="field-seo-desc" type="text" class="form-input" placeholder="Brief description of your site">
184
+ </div>
185
+ </div>
127
186
  </div>
128
- </div>
129
187
 
130
- <div class="card card-collapsible mb-4">
131
- <div class="card-header" role="button" tabindex="0">
132
- <div class="card-header-content"><h2>Footer</h2></div>
133
- <span class="card-collapse-icon" data-icon="chevron-down"></span>
134
- </div>
135
- <div class="card-body">
136
- <div class="row">
137
- <div class="col">
138
- <label class="form-label">Copyright Text</label>
139
- <input id="field-footer-copy" type="text" class="form-input" placeholder="© 2026 My Site">
140
- </div>
188
+ <!-- Footer -->
189
+ <div class="tab-panel">
190
+ <div class="row mb-4">
191
+ <div class="col">
192
+ <label class="form-label">Copyright Text</label>
193
+ <input id="field-footer-copy" type="text" class="form-input" placeholder="© 2026 My Site">
194
+ </div>
195
+ </div>
196
+ <h3 class="mb-3" style="font-size:1rem;font-weight:600;">Social Media Icons</h3>
197
+ <p class="text-muted mb-3" style="font-size:.875rem;">Enter the full URL for each platform to show its icon in the
198
+ footer. Leave blank to hide.</p>
199
+ <div class="row mb-3">
200
+ <div class="col-6">
201
+ <label class="form-label">X / Twitter</label>
202
+ <input id="field-social-twitter" type="url" class="form-input" placeholder="https://x.com/yourhandle">
203
+ </div>
204
+ <div class="col-6">
205
+ <label class="form-label">Facebook</label>
206
+ <input id="field-social-facebook" type="url" class="form-input" placeholder="https://facebook.com/yourpage">
207
+ </div>
208
+ </div>
209
+ <div class="row mb-3">
210
+ <div class="col-6">
211
+ <label class="form-label">Instagram</label>
212
+ <input id="field-social-instagram" type="url" class="form-input"
213
+ placeholder="https://instagram.com/yourhandle">
141
214
  </div>
215
+ <div class="col-6">
216
+ <label class="form-label">LinkedIn</label>
217
+ <input id="field-social-linkedin" type="url" class="form-input"
218
+ placeholder="https://linkedin.com/company/yourcompany">
219
+ </div>
220
+ </div>
221
+ <div class="row">
222
+ <div class="col-6">
223
+ <label class="form-label">GitHub</label>
224
+ <input id="field-social-github" type="url" class="form-input" placeholder="https://github.com/yourorg">
225
+ </div>
226
+ <div class="col-6">
227
+ <label class="form-label">YouTube</label>
228
+ <input id="field-social-youtube" type="url" class="form-input" placeholder="https://youtube.com/@yourchannel">
229
+ </div>
230
+ </div>
142
231
  </div>
143
- </div>
144
232
 
145
- <div class="card card-collapsible mb-4">
146
- <div class="card-header" role="button" tabindex="0">
147
- <div class="card-header-content"><h2>Email / SMTP</h2></div>
148
- <span class="card-collapse-icon" data-icon="chevron-down"></span>
149
- </div>
150
- <div class="card-body">
151
- <div class="row mb-3">
152
- <div class="col-8">
153
- <label class="form-label">SMTP Host</label>
154
- <input id="field-smtp-host" type="text" class="form-input" placeholder="smtp.example.com">
155
- </div>
156
- <div class="col-4">
157
- <label class="form-label">Port</label>
158
- <input id="field-smtp-port" type="number" class="form-input" placeholder="587" value="587">
159
- </div>
160
- </div>
161
- <div class="row mb-3">
162
- <div class="col-6">
163
- <label class="form-label">Username</label>
164
- <input id="field-smtp-user" type="text" class="form-input" placeholder="user@example.com" autocomplete="off">
165
- </div>
166
- <div class="col-6">
167
- <label class="form-label">Password</label>
168
- <input id="field-smtp-pass" type="password" class="form-input" placeholder="••••••••" autocomplete="new-password">
169
- </div>
170
- </div>
171
- <div class="row mb-3">
172
- <div class="col">
173
- <label class="form-check-label" style="display:flex;align-items:center;gap:.5rem;cursor:pointer;">
174
- <input id="field-smtp-secure" type="checkbox" class="form-check"> Use TLS (port 465)
175
- </label>
176
- <p class="form-hint text-muted" style="margin-top:.35rem;font-size:.8rem;">Enable for SMTPS. Leave off for STARTTLS (port 587).</p>
177
- </div>
178
- </div>
179
- <div class="row">
180
- <div class="col-6">
181
- <label class="form-label">From Address</label>
182
- <input id="field-smtp-from-address" type="email" class="form-input" placeholder="noreply@example.com">
183
- </div>
184
- <div class="col-6">
185
- <label class="form-label">From Name</label>
186
- <input id="field-smtp-from-name" type="text" class="form-input" placeholder="My Website">
187
- </div>
233
+ <!-- Email / SMTP -->
234
+ <div class="tab-panel">
235
+ <div class="row mb-3">
236
+ <div class="col-8">
237
+ <label class="form-label">SMTP Host</label>
238
+ <input id="field-smtp-host" type="text" class="form-input" placeholder="smtp.example.com">
239
+ </div>
240
+ <div class="col-4">
241
+ <label class="form-label">Port</label>
242
+ <input id="field-smtp-port" type="number" class="form-input" placeholder="587" value="587">
243
+ </div>
244
+ </div>
245
+ <div class="row mb-3">
246
+ <div class="col-6">
247
+ <label class="form-label">Username</label>
248
+ <input id="field-smtp-user" type="text" class="form-input" placeholder="user@example.com" autocomplete="off">
249
+ </div>
250
+ <div class="col-6">
251
+ <label class="form-label">Password</label>
252
+ <input id="field-smtp-pass" type="password" class="form-input" placeholder="••••••••"
253
+ autocomplete="new-password">
188
254
  </div>
255
+ </div>
256
+ <div class="row mb-3">
257
+ <div class="col">
258
+ <label class="form-check-label" style="display:flex;align-items:center;gap:.5rem;cursor:pointer;">
259
+ <input id="field-smtp-secure" type="checkbox" class="form-check"> Use TLS (port 465)
260
+ </label>
261
+ <p class="form-hint text-muted" style="margin-top:.35rem;font-size:.8rem;">Enable for SMTPS. Leave off for
262
+ STARTTLS (port 587).</p>
263
+ </div>
264
+ </div>
265
+ <div class="row mb-4">
266
+ <div class="col-6">
267
+ <label class="form-label">From Address</label>
268
+ <input id="field-smtp-from-address" type="email" class="form-input" placeholder="noreply@example.com">
269
+ </div>
270
+ <div class="col-6">
271
+ <label class="form-label">From Name</label>
272
+ <input id="field-smtp-from-name" type="text" class="form-input" placeholder="My Website">
273
+ </div>
274
+ </div>
275
+ <div style="border-top:1px solid var(--border-color,#333);padding-top:1rem;">
276
+ <p class="form-label" style="margin-bottom:.5rem;">Send Test Email</p>
277
+ <p class="text-muted" style="font-size:.8rem;margin-bottom:.75rem;">Save your SMTP settings first, then send a test to verify the configuration.</p>
278
+ <div style="display:flex;gap:.5rem;align-items:center;flex-wrap:wrap;">
279
+ <input id="field-test-email-to" type="email" class="form-input" placeholder="recipient@example.com" style="max-width:280px;">
280
+ <button id="send-test-email-btn" class="btn btn-ghost btn-sm">
281
+ <span data-icon="mail"></span> Send Test
282
+ </button>
283
+ <span id="test-email-result" style="font-size:.85rem;"></span>
284
+ </div>
285
+ </div>
189
286
  </div>
287
+
288
+
289
+ <!-- Back to Top -->
290
+ <div class="tab-panel">
291
+ <div class="row mb-3">
292
+ <div class="col">
293
+ <label class="form-check-label" style="display:flex;align-items:center;gap:.5rem;cursor:pointer;">
294
+ <input id="field-btt-enabled" type="checkbox" class="form-check"> Enable Back to Top button
295
+ </label>
296
+ </div>
297
+ </div>
298
+ <div class="row mb-3">
299
+ <div class="col-4">
300
+ <label class="form-label">Scroll Threshold (px)</label>
301
+ <input id="field-btt-threshold" type="number" class="form-input" placeholder="300">
302
+ <p class="form-hint text-muted" style="margin-top:.35rem;font-size:.8rem;">Show button after scrolling this many pixels.</p>
303
+ </div>
304
+ <div class="col-4">
305
+ <label class="form-label">Position</label>
306
+ <select id="field-btt-position" class="form-select">
307
+ <option value="bottom-right">Bottom Right</option>
308
+ <option value="bottom-left">Bottom Left</option>
309
+ </select>
310
+ </div>
311
+ <div class="col-4">
312
+ <label class="form-label">Bottom Offset (px)</label>
313
+ <input id="field-btt-offset" type="number" class="form-input" placeholder="32">
314
+ </div>
315
+ </div>
316
+ <div class="row mb-3">
317
+ <div class="col-6">
318
+ <label class="form-label">Label <span class="text-muted" style="font-weight:400;">(optional)</span></label>
319
+ <input id="field-btt-label" type="text" class="form-input" placeholder="Back to top">
320
+ <p class="form-hint text-muted" style="margin-top:.35rem;font-size:.8rem;">Leave blank for icon-only button.</p>
321
+ </div>
322
+ <div class="col-6" style="padding-top:2rem;">
323
+ <label class="form-check-label" style="display:flex;align-items:center;gap:.5rem;cursor:pointer;">
324
+ <input id="field-btt-smooth" type="checkbox" class="form-check"> Smooth scroll
325
+ </label>
326
+ </div>
327
+ </div>
328
+ </div>
329
+
330
+ <!-- Cookie Consent -->
331
+ <div class="tab-panel">
332
+ <div class="row mb-3">
333
+ <div class="col">
334
+ <label class="form-check-label" style="display:flex;align-items:center;gap:.5rem;cursor:pointer;">
335
+ <input id="field-cc-enabled" type="checkbox" class="form-check"> Enable Cookie Consent banner
336
+ </label>
337
+ </div>
338
+ </div>
339
+ <div class="row mb-3">
340
+ <div class="col">
341
+ <label class="form-label">Message</label>
342
+ <textarea id="field-cc-message" class="form-input" rows="3" placeholder="We use cookies…"></textarea>
343
+ </div>
344
+ </div>
345
+ <div class="row mb-3">
346
+ <div class="col-3">
347
+ <label class="form-label">Accept All Text</label>
348
+ <input id="field-cc-accept-all" type="text" class="form-input" placeholder="Accept All">
349
+ </div>
350
+ <div class="col-3">
351
+ <label class="form-label">Reject All Text</label>
352
+ <input id="field-cc-reject-all" type="text" class="form-input" placeholder="Reject All">
353
+ </div>
354
+ <div class="col-3">
355
+ <label class="form-label">Customise Text</label>
356
+ <input id="field-cc-customize" type="text" class="form-input" placeholder="Customize">
357
+ </div>
358
+ <div class="col-3">
359
+ <label class="form-label">Save Preferences Text</label>
360
+ <input id="field-cc-save-prefs" type="text" class="form-input" placeholder="Save Preferences">
361
+ </div>
362
+ </div>
363
+ <div class="row mb-3">
364
+ <div class="col-6">
365
+ <label class="form-label">Privacy Policy Text</label>
366
+ <input id="field-cc-privacy-text" type="text" class="form-input" placeholder="Privacy Policy">
367
+ </div>
368
+ <div class="col-6">
369
+ <label class="form-label">Privacy Policy URL</label>
370
+ <input id="field-cc-privacy-url" type="text" class="form-input" placeholder="/privacy-policy">
371
+ </div>
372
+ </div>
373
+ <div class="row mb-3">
374
+ <div class="col-6">
375
+ <label class="form-label">Cookie Policy Text</label>
376
+ <input id="field-cc-cookie-text" type="text" class="form-input" placeholder="Cookie Policy">
377
+ </div>
378
+ <div class="col-6">
379
+ <label class="form-label">Cookie Policy URL <span class="text-muted" style="font-weight:400;">(leave blank to hide)</span></label>
380
+ <input id="field-cc-cookie-url" type="text" class="form-input" placeholder="/cookie-policy">
381
+ </div>
382
+ </div>
383
+ <div class="row mb-3">
384
+ <div class="col-4">
385
+ <label class="form-label">Position</label>
386
+ <select id="field-cc-position" class="form-select">
387
+ <option value="bottom">Bottom</option>
388
+ <option value="top">Top</option>
389
+ </select>
390
+ </div>
391
+ <div class="col-4">
392
+ <label class="form-label">Layout</label>
393
+ <select id="field-cc-layout" class="form-select">
394
+ <option value="bar">Bar</option>
395
+ <option value="modal">Modal</option>
396
+ </select>
397
+ </div>
398
+ <div class="col-4">
399
+ <label class="form-label">Theme</label>
400
+ <select id="field-cc-theme" class="form-select">
401
+ <option value="dark">Dark</option>
402
+ <option value="light">Light</option>
403
+ </select>
404
+ </div>
405
+ </div>
406
+ <div class="row mb-3">
407
+ <div class="col">
408
+ <label class="form-label" style="margin-bottom:.5rem;">Cookie Categories</label>
409
+ <p class="text-muted" style="font-size:.8rem;margin-bottom:.75rem;">Necessary cookies are always shown and required. Toggle additional categories below.</p>
410
+ <div style="display:flex;flex-direction:column;gap:.5rem;">
411
+ <label class="form-check-label" style="display:flex;align-items:center;gap:.5rem;cursor:pointer;">
412
+ <input id="field-cc-show-functional" type="checkbox" class="form-check"> Show Functional category
413
+ </label>
414
+ <label class="form-check-label" style="display:flex;align-items:center;gap:.5rem;cursor:pointer;">
415
+ <input id="field-cc-show-analytics" type="checkbox" class="form-check"> Show Analytics category
416
+ </label>
417
+ <label class="form-check-label" style="display:flex;align-items:center;gap:.5rem;cursor:pointer;">
418
+ <input id="field-cc-show-marketing" type="checkbox" class="form-check"> Show Marketing category
419
+ </label>
420
+ </div>
421
+ </div>
422
+ </div>
423
+ <div class="row">
424
+ <div class="col-4">
425
+ <label class="form-label">Consent Version</label>
426
+ <input id="field-cc-version" type="text" class="form-input" placeholder="1.0">
427
+ <p class="form-hint text-muted" style="margin-top:.35rem;font-size:.8rem;">Increment to re-prompt users who already accepted.</p>
428
+ </div>
429
+ </div>
430
+ </div>
431
+
432
+ <!-- Custom CSS -->
433
+ <div class="tab-panel">
434
+ <div class="row mb-3">
435
+ <div class="col">
436
+ <p class="text-muted" style="font-size:.875rem;margin-bottom:1rem;">
437
+ CSS entered here is injected as an inline <code>&lt;style&gt;</code> block into the
438
+ <code>&lt;head&gt;</code> of every public page. Changes take effect immediately on save.
439
+ </p>
440
+ <textarea id="field-custom-css" class="form-input" style="font-family:monospace;min-height:420px;resize:vertical;" spellcheck="false" placeholder="/* Add your custom CSS here */"></textarea>
441
+ </div>
442
+ </div>
443
+ <div class="row">
444
+ <div class="col">
445
+ <button id="save-css-btn" class="btn btn-primary"><span data-icon="save"></span> Save CSS</button>
446
+ </div>
447
+ </div>
448
+ </div>
449
+
450
+ </div>
190
451
  </div>