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,86 +0,0 @@
1
- {
2
- "name": "invoice",
3
- "displayName": "Invoices",
4
- "version": "1.4.0",
5
- "description": "Invoice generator. Issuer profiles, receivers importable from Contacts, line items, optional VAT, payments, archiving, CSV/Excel export, and a print-ready invoice you can email or download as a PDF.",
6
- "author": "Darryl Waterhouse",
7
- "date": "2026-09-21",
8
- "icon": "receipt",
9
- "admin": {
10
- "css": [
11
- "admin/css/index.css",
12
- "../_lib/admin/ui/help.css"
13
- ],
14
- "sidebar": [
15
- {
16
- "id": "invoice",
17
- "text": "Invoices",
18
- "icon": "file-text",
19
- "url": "#/plugins/invoice",
20
- "section": "#/plugins/invoice",
21
- "children": [
22
- {
23
- "id": "invoice-list",
24
- "text": "Invoices",
25
- "url": "#/plugins/invoice"
26
- },
27
- {
28
- "id": "invoice-issuers",
29
- "text": "Issuers",
30
- "url": "#/plugins/invoice/issuers"
31
- },
32
- {
33
- "id": "invoice-receivers",
34
- "text": "Receivers",
35
- "url": "#/plugins/invoice/receivers"
36
- }
37
- ]
38
- }
39
- ],
40
- "routes": [
41
- {
42
- "path": "/plugins/invoice",
43
- "view": "plugin-invoice-list",
44
- "title": "Invoices - Domma CMS"
45
- },
46
- {
47
- "path": "/plugins/invoice/new",
48
- "view": "plugin-invoice-editor",
49
- "title": "New Invoice - Domma CMS"
50
- },
51
- {
52
- "path": "/plugins/invoice/edit/:id",
53
- "view": "plugin-invoice-editor",
54
- "title": "Edit Invoice - Domma CMS"
55
- },
56
- {
57
- "path": "/plugins/invoice/issuers",
58
- "view": "plugin-invoice-issuers",
59
- "title": "Issuers - Domma CMS"
60
- },
61
- {
62
- "path": "/plugins/invoice/receivers",
63
- "view": "plugin-invoice-receivers",
64
- "title": "Receivers - Domma CMS"
65
- }
66
- ],
67
- "views": {
68
- "plugin-invoice-list": {
69
- "entry": "invoice/admin/views/index.js?v=350310c2",
70
- "exportName": "indexView"
71
- },
72
- "plugin-invoice-editor": {
73
- "entry": "invoice/admin/views/editor.js?v=78cd5797",
74
- "exportName": "editorView"
75
- },
76
- "plugin-invoice-issuers": {
77
- "entry": "invoice/admin/views/issuers.js?v=e2dd5ab2",
78
- "exportName": "issuersView"
79
- },
80
- "plugin-invoice-receivers": {
81
- "entry": "invoice/admin/views/receivers.js?v=ce0e3964",
82
- "exportName": "receiversView"
83
- }
84
- }
85
- }
86
- }
@@ -1 +0,0 @@
1
- :root{color-scheme:light}*{box-sizing:border-box}body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif;color:#222;background:#f3f3f3;margin:0;padding:24px;font-size:14px;line-height:1.5}.invoice{max-width:800px;margin:0 auto;background:#fff;padding:48px 56px;box-shadow:0 4px 20px #00000014}.top{display:flex;justify-content:space-between;align-items:flex-start;gap:24px;border-bottom:2px solid #e5e5e5;padding-bottom:24px;margin-bottom:32px}.logo{max-height:80px;max-width:240px;display:block;margin-bottom:12px}.meta{text-align:right}.meta h1{margin:0;font-size:28px;letter-spacing:1px;color:#000}.meta .number{font-size:18px;color:#555;margin-top:4px}.status{display:inline-block;padding:4px 10px;border-radius:4px;font-size:11px;font-weight:600;letter-spacing:.5px;background:#eee;color:#444;margin-top:8px}.parties{display:grid;grid-template-columns:1fr 1fr;gap:32px;margin-bottom:32px}.party h3{margin:0 0 8px;font-size:11px;text-transform:uppercase;letter-spacing:1px;color:#888}.party .name{font-weight:700;font-size:15px;margin-bottom:4px}.party .lines{color:#555;font-size:13px}table.items{width:100%;border-collapse:collapse;margin-bottom:24px}table.items th{text-align:left;font-size:11px;text-transform:uppercase;letter-spacing:1px;color:#888;padding:8px 10px;border-bottom:2px solid #e5e5e5}table.items td{padding:10px;border-bottom:1px solid #f0f0f0}table.items td.num,table.items th.num{text-align:right}.totals{width:320px;margin-left:auto;margin-bottom:32px}.totals table{width:100%;border-collapse:collapse}.totals th{text-align:left;padding:8px 10px;font-weight:500;color:#555}.totals td.num{text-align:right;padding:8px 10px;font-variant-numeric:tabular-nums}.bank .pay{border-collapse:collapse;margin-top:6px}.bank .pay th{text-align:left;font-weight:400;color:#666;padding:2px 14px 2px 0;white-space:nowrap;vertical-align:top}.bank .pay td{padding:2px 0;font-variant-numeric:tabular-nums;font-weight:600}.bank .pay-notes{margin-top:6px}.totals .balance th,.totals .balance td{font-weight:700;border-top:1px solid #ddd}.totals .settled th,.totals .settled td{color:#197a3d}.totals .grand th,.totals .grand td{font-size:17px;font-weight:700;color:#000;border-top:2px solid #222;padding-top:12px}.footer{margin-top:32px;padding-top:16px;border-top:1px solid #e5e5e5;font-size:12px;color:#888}.notes,.bank{margin-top:24px;padding:12px 16px;background:#fafafa;border-radius:4px;font-size:13px}.muted{color:#999;font-style:italic;text-align:center}.actions{max-width:800px;margin:0 auto 16px;display:flex;justify-content:flex-end;gap:8px}.actions button{background:#222;color:#fff;border:0;padding:8px 16px;font-size:13px;border-radius:4px;cursor:pointer}@media print{body{background:#fff;padding:0}.invoice{box-shadow:none;padding:24px}.actions{display:none}}
@@ -1,100 +0,0 @@
1
- <!--
2
- Classic, for an issuer with no logo.
3
-
4
- Not the logo template with an empty slot: an invoice whose masthead is a
5
- blank 80px gap looks like a page that failed to load. The trading name takes
6
- the space instead, set as a wordmark, which is what a letterhead does when
7
- there is no mark to print.
8
-
9
- Chosen automatically - buildPrintHtml() asks for `<style>-nologo` first when
10
- neither the issuer nor Settings > Branding has a logo.
11
- -->
12
- <!DOCTYPE html>
13
- <html lang="en">
14
- <head>
15
- <meta charset="utf-8">
16
- <title>Invoice {{number}}</title>
17
- <style>
18
- {{baseCss}}
19
-
20
- /* The name IS the masthead here, so it is set like one. */
21
- .wordmark {
22
- font-size: 26px;
23
- font-weight: 700;
24
- letter-spacing: -0.4px;
25
- color: #000;
26
- margin-bottom: 10px;
27
- line-height: 1.1;
28
- }
29
- .top .party .name { display: none; }
30
- </style>
31
- </head>
32
- <body>
33
-
34
- <div class="actions">
35
- <button onclick="window.print()">Print / Save as PDF</button>
36
- </div>
37
-
38
- <div class="invoice">
39
- <div class="top">
40
- <div>
41
- <div class="wordmark">{{issuerName}}</div>
42
- <div class="party">
43
- <div class="lines">{{issuerAddress}}</div>
44
- <div class="lines">{{issuerEmail}}</div>
45
- <div class="lines">{{issuerPhone}}</div>
46
- {{issuerVat}}
47
- </div>
48
- </div>
49
- <div class="meta">
50
- <h1>INVOICE</h1>
51
- <div class="number">{{number}}</div>
52
- <div>{{issueDate}}</div>
53
- {{dueDate}}
54
- <div class="status">{{status}}</div>
55
- </div>
56
- </div>
57
-
58
- <div class="parties">
59
- <div class="party">
60
- <h3>Billed To</h3>
61
- <div class="name">{{receiverName}}</div>
62
- <div class="lines">{{receiverAddress}}</div>
63
- <div class="lines">{{receiverEmail}}</div>
64
- {{receiverVat}}
65
- </div>
66
- </div>
67
-
68
- <table class="items">
69
- <thead>
70
- <tr>
71
- <th>Description</th>
72
- <th class="num">Qty</th>
73
- <th class="num">Unit</th>
74
- <th class="num">Total</th>
75
- </tr>
76
- </thead>
77
- <tbody>
78
- {{items}}
79
- </tbody>
80
- </table>
81
-
82
- <div class="totals">
83
- <table>
84
- <tr><th>Subtotal</th><td class="num">{{subtotal}}</td></tr>
85
- {{vatRow}}
86
- <tr class="grand"><th>Total</th><td class="num">{{total}}</td></tr>
87
- {{paidRows}}
88
- </table>
89
- </div>
90
-
91
- {{notes}}
92
- {{bankDetails}}
93
-
94
- <div class="footer">{{footerNote}}</div>
95
- </div>
96
-
97
- {{autoPrint}}
98
-
99
- </body>
100
- </html>
@@ -1,91 +0,0 @@
1
- <!--
2
- Classic - the default. Logo top left, invoice meta top right.
3
-
4
- Every template is a whole HTML document: a printout has no stylesheet of its
5
- own to fetch, so `{{baseCss}}` inlines the shared rules and anything below it
6
- is what makes this style itself.
7
-
8
- Slots: number issueDate dueDate status issuerLogo issuerName issuerAddress
9
- issuerEmail issuerPhone issuerVat receiverName receiverAddress receiverEmail
10
- receiverVat items subtotal vatRow paidRows total notes bankDetails footerNote
11
- autoPrint baseCss
12
- -->
13
- <!DOCTYPE html>
14
- <html lang="en">
15
- <head>
16
- <meta charset="utf-8">
17
- <title>Invoice {{number}}</title>
18
- <style>
19
- {{baseCss}}
20
- </style>
21
- </head>
22
- <body>
23
-
24
- <div class="actions">
25
- <button onclick="window.print()">Print / Save as PDF</button>
26
- </div>
27
-
28
- <div class="invoice">
29
- <div class="top">
30
- <div>
31
- {{issuerLogo}}
32
- <div class="party">
33
- <div class="name">{{issuerName}}</div>
34
- <div class="lines">{{issuerAddress}}</div>
35
- <div class="lines">{{issuerEmail}}</div>
36
- <div class="lines">{{issuerPhone}}</div>
37
- {{issuerVat}}
38
- </div>
39
- </div>
40
- <div class="meta">
41
- <h1>INVOICE</h1>
42
- <div class="number">{{number}}</div>
43
- <div>{{issueDate}}</div>
44
- {{dueDate}}
45
- <div class="status">{{status}}</div>
46
- </div>
47
- </div>
48
-
49
- <div class="parties">
50
- <div class="party">
51
- <h3>Billed To</h3>
52
- <div class="name">{{receiverName}}</div>
53
- <div class="lines">{{receiverAddress}}</div>
54
- <div class="lines">{{receiverEmail}}</div>
55
- {{receiverVat}}
56
- </div>
57
- </div>
58
-
59
- <table class="items">
60
- <thead>
61
- <tr>
62
- <th>Description</th>
63
- <th class="num">Qty</th>
64
- <th class="num">Unit</th>
65
- <th class="num">Total</th>
66
- </tr>
67
- </thead>
68
- <tbody>
69
- {{items}}
70
- </tbody>
71
- </table>
72
-
73
- <div class="totals">
74
- <table>
75
- <tr><th>Subtotal</th><td class="num">{{subtotal}}</td></tr>
76
- {{vatRow}}
77
- <tr class="grand"><th>Total</th><td class="num">{{total}}</td></tr>
78
- {{paidRows}}
79
- </table>
80
- </div>
81
-
82
- {{notes}}
83
- {{bankDetails}}
84
-
85
- <div class="footer">{{footerNote}}</div>
86
- </div>
87
-
88
- {{autoPrint}}
89
-
90
- </body>
91
- </html>
@@ -1,237 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8">
5
- <title>Invoice {{number}}</title>
6
- <style>
7
- :root { color-scheme: light; }
8
- * { box-sizing: border-box; }
9
- body {
10
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
11
- color: #222;
12
- background: #f3f3f3;
13
- margin: 0;
14
- padding: 24px;
15
- font-size: 14px;
16
- line-height: 1.5;
17
- }
18
- .invoice {
19
- max-width: 800px;
20
- margin: 0 auto;
21
- background: #fff;
22
- padding: 48px 56px;
23
- box-shadow: 0 4px 20px rgba(0,0,0,.08);
24
- }
25
- .top {
26
- display: flex;
27
- justify-content: space-between;
28
- align-items: flex-start;
29
- gap: 24px;
30
- border-bottom: 2px solid #e5e5e5;
31
- padding-bottom: 24px;
32
- margin-bottom: 32px;
33
- }
34
- .logo { max-height: 80px; max-width: 240px; display: block; margin-bottom: 12px; }
35
- .meta { text-align: right; }
36
- .meta h1 { margin: 0; font-size: 28px; letter-spacing: 1px; color: #000; }
37
- .meta .number { font-size: 18px; color: #555; margin-top: 4px; }
38
- .status {
39
- display: inline-block;
40
- padding: 4px 10px;
41
- border-radius: 4px;
42
- font-size: 11px;
43
- font-weight: 600;
44
- letter-spacing: .5px;
45
- background: #eee;
46
- color: #444;
47
- margin-top: 8px;
48
- }
49
- .parties {
50
- display: grid;
51
- grid-template-columns: 1fr 1fr;
52
- gap: 32px;
53
- margin-bottom: 32px;
54
- }
55
- .party h3 {
56
- margin: 0 0 8px;
57
- font-size: 11px;
58
- text-transform: uppercase;
59
- letter-spacing: 1px;
60
- color: #888;
61
- }
62
- .party .name { font-weight: 700; font-size: 15px; margin-bottom: 4px; }
63
- .party .lines { color: #555; font-size: 13px; }
64
- table.items {
65
- width: 100%;
66
- border-collapse: collapse;
67
- margin-bottom: 24px;
68
- }
69
- table.items th {
70
- text-align: left;
71
- font-size: 11px;
72
- text-transform: uppercase;
73
- letter-spacing: 1px;
74
- color: #888;
75
- padding: 8px 10px;
76
- border-bottom: 2px solid #e5e5e5;
77
- }
78
- table.items td {
79
- padding: 10px;
80
- border-bottom: 1px solid #f0f0f0;
81
- }
82
- table.items td.num, table.items th.num { text-align: right; }
83
- .totals {
84
- width: 320px;
85
- margin-left: auto;
86
- margin-bottom: 32px;
87
- }
88
- .totals table { width: 100%; border-collapse: collapse; }
89
- .totals th {
90
- text-align: left;
91
- padding: 8px 10px;
92
- font-weight: 500;
93
- color: #555;
94
- }
95
- .totals td.num {
96
- text-align: right;
97
- padding: 8px 10px;
98
- font-variant-numeric: tabular-nums;
99
- }
100
- .bank .pay {
101
- border-collapse: collapse;
102
- margin-top: 6px;
103
- }
104
- .bank .pay th {
105
- text-align: left;
106
- font-weight: 400;
107
- color: #666;
108
- padding: 2px 14px 2px 0;
109
- white-space: nowrap;
110
- vertical-align: top;
111
- }
112
- .bank .pay td {
113
- padding: 2px 0;
114
- font-variant-numeric: tabular-nums;
115
- font-weight: 600;
116
- }
117
- .bank .pay-notes { margin-top: 6px; }
118
- .totals .balance th, .totals .balance td {
119
- font-weight: 700;
120
- border-top: 1px solid #ddd;
121
- }
122
- .totals .settled th, .totals .settled td { color: #197a3d; }
123
- .totals .grand th, .totals .grand td {
124
- font-size: 17px;
125
- font-weight: 700;
126
- color: #000;
127
- border-top: 2px solid #222;
128
- padding-top: 12px;
129
- }
130
- .footer {
131
- margin-top: 32px;
132
- padding-top: 16px;
133
- border-top: 1px solid #e5e5e5;
134
- font-size: 12px;
135
- color: #888;
136
- }
137
- .notes, .bank {
138
- margin-top: 24px;
139
- padding: 12px 16px;
140
- background: #fafafa;
141
- border-radius: 4px;
142
- font-size: 13px;
143
- }
144
- .muted { color: #999; font-style: italic; text-align: center; }
145
- .actions {
146
- max-width: 800px;
147
- margin: 0 auto 16px;
148
- display: flex;
149
- justify-content: flex-end;
150
- gap: 8px;
151
- }
152
- .actions button {
153
- background: #222;
154
- color: #fff;
155
- border: 0;
156
- padding: 8px 16px;
157
- font-size: 13px;
158
- border-radius: 4px;
159
- cursor: pointer;
160
- }
161
- @media print {
162
- body { background: #fff; padding: 0; }
163
- .invoice { box-shadow: none; padding: 24px; }
164
- .actions { display: none; }
165
- }
166
- </style>
167
- </head>
168
- <body>
169
-
170
- <div class="actions">
171
- <button onclick="window.print()">Print / Save as PDF</button>
172
- </div>
173
-
174
- <div class="invoice">
175
- <div class="top">
176
- <div>
177
- {{issuerLogo}}
178
- <div class="party">
179
- <div class="name">{{issuerName}}</div>
180
- <div class="lines">{{issuerAddress}}</div>
181
- <div class="lines">{{issuerEmail}}</div>
182
- <div class="lines">{{issuerPhone}}</div>
183
- {{issuerVat}}
184
- </div>
185
- </div>
186
- <div class="meta">
187
- <h1>INVOICE</h1>
188
- <div class="number">{{number}}</div>
189
- <div>{{issueDate}}</div>
190
- {{dueDate}}
191
- <div class="status">{{status}}</div>
192
- </div>
193
- </div>
194
-
195
- <div class="parties">
196
- <div class="party">
197
- <h3>Billed To</h3>
198
- <div class="name">{{receiverName}}</div>
199
- <div class="lines">{{receiverAddress}}</div>
200
- <div class="lines">{{receiverEmail}}</div>
201
- {{receiverVat}}
202
- </div>
203
- </div>
204
-
205
- <table class="items">
206
- <thead>
207
- <tr>
208
- <th>Description</th>
209
- <th class="num">Qty</th>
210
- <th class="num">Unit</th>
211
- <th class="num">Total</th>
212
- </tr>
213
- </thead>
214
- <tbody>
215
- {{items}}
216
- </tbody>
217
- </table>
218
-
219
- <div class="totals">
220
- <table>
221
- <tr><th>Subtotal</th><td class="num">{{subtotal}}</td></tr>
222
- {{vatRow}}
223
- <tr class="grand"><th>Total</th><td class="num">{{total}}</td></tr>
224
- {{paidRows}}
225
- </table>
226
- </div>
227
-
228
- {{notes}}
229
- {{bankDetails}}
230
-
231
- <div class="footer">{{footerNote}}</div>
232
- </div>
233
-
234
- {{autoPrint}}
235
-
236
- </body>
237
- </html>
@@ -1,99 +0,0 @@
1
- <!--
2
- Minimal - typographic, no rules, no fills, no logo by design.
3
-
4
- It has no `-nologo` sibling on purpose: there is nowhere in this layout a
5
- logo would go, so it is the same document either way and the resolver falls
6
- back to this file.
7
- -->
8
- <!DOCTYPE html>
9
- <html lang="en">
10
- <head>
11
- <meta charset="utf-8">
12
- <title>Invoice {{number}}</title>
13
- <style>
14
- {{baseCss}}
15
-
16
- /* Minimal: no card, no shadow, no bands - just the page. */
17
- body { background: #fff; padding: 40px 24px; }
18
- .invoice { box-shadow: none; padding: 0; max-width: 680px; }
19
- .top { border-bottom: 1px solid #222; padding-bottom: 12px; margin-bottom: 28px; }
20
- .top .party .name { font-size: 15px; }
21
- .meta h1 { font-size: 15px; letter-spacing: 4px; font-weight: 600; }
22
- .meta .number { font-size: 14px; }
23
- .status { background: transparent; padding: 0; color: #666; letter-spacing: 1.5px; }
24
- table.items th { border-bottom-color: #222; }
25
- table.items td { border-bottom-color: #eee; }
26
- .totals .grand th, .totals .grand td { border-top-color: #222; font-size: 15px; }
27
- .notes, .bank { background: transparent; padding: 0; border-top: 1px solid #eee; padding-top: 12px; border-radius: 0; }
28
- .footer { border-top: 1px solid #eee; }
29
- </style>
30
- </head>
31
- <body>
32
-
33
- <div class="actions">
34
- <button onclick="window.print()">Print / Save as PDF</button>
35
- </div>
36
-
37
- <div class="invoice">
38
- <div class="top">
39
- <div>
40
- <div class="party">
41
- <div class="name">{{issuerName}}</div>
42
- <div class="lines">{{issuerAddress}}</div>
43
- <div class="lines">{{issuerEmail}}</div>
44
- <div class="lines">{{issuerPhone}}</div>
45
- {{issuerVat}}
46
- </div>
47
- </div>
48
- <div class="meta">
49
- <h1>INVOICE</h1>
50
- <div class="number">{{number}}</div>
51
- <div>{{issueDate}}</div>
52
- {{dueDate}}
53
- <div class="status">{{status}}</div>
54
- </div>
55
- </div>
56
-
57
- <div class="parties">
58
- <div class="party">
59
- <h3>Billed To</h3>
60
- <div class="name">{{receiverName}}</div>
61
- <div class="lines">{{receiverAddress}}</div>
62
- <div class="lines">{{receiverEmail}}</div>
63
- {{receiverVat}}
64
- </div>
65
- </div>
66
-
67
- <table class="items">
68
- <thead>
69
- <tr>
70
- <th>Description</th>
71
- <th class="num">Qty</th>
72
- <th class="num">Unit</th>
73
- <th class="num">Total</th>
74
- </tr>
75
- </thead>
76
- <tbody>
77
- {{items}}
78
- </tbody>
79
- </table>
80
-
81
- <div class="totals">
82
- <table>
83
- <tr><th>Subtotal</th><td class="num">{{subtotal}}</td></tr>
84
- {{vatRow}}
85
- <tr class="grand"><th>Total</th><td class="num">{{total}}</td></tr>
86
- {{paidRows}}
87
- </table>
88
- </div>
89
-
90
- {{notes}}
91
- {{bankDetails}}
92
-
93
- <div class="footer">{{footerNote}}</div>
94
- </div>
95
-
96
- {{autoPrint}}
97
-
98
- </body>
99
- </html>