@seliseblocks/mailcraft 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 (69) hide show
  1. package/DOCS.md +240 -12
  2. package/README.md +11 -3
  3. package/README.md.txt +134 -0
  4. package/dist/mailcraft-editor.bundle.js +51 -39
  5. package/dist/mailcraft-editor.bundle.js.map +3 -3
  6. package/examples/templates/order-confirmed.html +80 -80
  7. package/examples/vanilla.html +242 -23
  8. package/package.json +7 -2
  9. package/src/core/assets.js +10 -15
  10. package/src/core/binder.js +120 -118
  11. package/src/core/blocks.js +14 -1
  12. package/src/core/css-cascade.js +117 -117
  13. package/src/core/editor-core.js +1530 -1492
  14. package/src/core/export.js +142 -55
  15. package/src/core/i18n/ar.js +219 -177
  16. package/src/core/i18n/bg.js +196 -152
  17. package/src/core/i18n/bn.js +218 -176
  18. package/src/core/i18n/ca.js +196 -152
  19. package/src/core/i18n/cs.js +196 -152
  20. package/src/core/i18n/da.js +196 -152
  21. package/src/core/i18n/de-CH.js +196 -152
  22. package/src/core/i18n/de.js +196 -152
  23. package/src/core/i18n/dz.js +221 -179
  24. package/src/core/i18n/el.js +196 -152
  25. package/src/core/i18n/en.js +3 -10
  26. package/src/core/i18n/es.js +196 -152
  27. package/src/core/i18n/et.js +196 -152
  28. package/src/core/i18n/fi.js +196 -152
  29. package/src/core/i18n/fr.js +196 -152
  30. package/src/core/i18n/hr.js +196 -152
  31. package/src/core/i18n/hu.js +196 -152
  32. package/src/core/i18n/index.js +83 -83
  33. package/src/core/i18n/it.js +196 -152
  34. package/src/core/i18n/lt.js +196 -152
  35. package/src/core/i18n/lv.js +196 -152
  36. package/src/core/i18n/nb.js +196 -152
  37. package/src/core/i18n/nl.js +196 -152
  38. package/src/core/i18n/pl.js +196 -152
  39. package/src/core/i18n/pt.js +196 -152
  40. package/src/core/i18n/ro.js +196 -152
  41. package/src/core/i18n/ru.js +196 -152
  42. package/src/core/i18n/sk.js +196 -152
  43. package/src/core/i18n/sl.js +196 -152
  44. package/src/core/i18n/sv.js +196 -152
  45. package/src/core/i18n/tables.js +50 -50
  46. package/src/core/i18n/tr.js +196 -152
  47. package/src/core/i18n/uk.js +196 -152
  48. package/src/core/icons.js +237 -235
  49. package/src/core/ids.js +1 -1
  50. package/src/core/import-html.js +1025 -959
  51. package/src/core/layout-style.js +100 -100
  52. package/src/core/parse.js +10 -10
  53. package/src/core/placeholder.js +15 -15
  54. package/src/core/sanitize.js +141 -141
  55. package/src/core/storage-limits.js +184 -184
  56. package/src/core/storage.js +85 -85
  57. package/src/core/theme.js +1 -1
  58. package/src/core/variables.js +11 -11
  59. package/src/index.js +9 -9
  60. package/src/mailcraft-editor.js +26 -14
  61. package/src/render/block-body.js +49 -6
  62. package/src/render/canvas.js +31 -2
  63. package/src/render/fields.js +602 -588
  64. package/src/render/focus-preserve.js +158 -158
  65. package/src/render/rte.js +241 -212
  66. package/src/render/screenshot.js +132 -132
  67. package/src/render/story.js +415 -415
  68. package/src/render/style.js +8 -0
  69. package/types/index.d.ts +419 -0
@@ -1,152 +1,196 @@
1
- /** Dutch (Nederlands) — `nl`. AI-drafted, not reviewed by a native speaker. Correctable one key at a time via `.messages` overrides. */
2
- export const NL = {
3
- 'action.undoHint': 'Ongedaan maken — ⌘Z',
4
- 'action.redoHint': 'Opnieuw — ⌘⇧Z',
5
- 'action.chromeToDark': 'Donker',
6
- 'action.chromeToLight': 'Licht',
7
- 'action.chromeHint': 'Editorthema licht / donker',
8
- 'action.aiCopy': 'Tekst',
9
- 'action.aiCopyHint': 'Tekst opstellen met AI',
10
- 'action.code': 'Code',
11
- 'action.codeHint': 'Ruwe HTML bewerken met live voorbeeld',
12
- 'action.preview': 'Voorbeeld',
13
- 'action.export': 'Exporteren',
14
- 'device.desktop': 'Desktop',
15
- 'device.desktopHint': 'Desktopbreedte',
16
- 'device.mobile': 'Mobiel',
17
- 'device.mobileHint': 'Mobiele breedte',
18
- 'device.dark': 'Donker',
19
- 'device.darkHint': 'Donkere inbox',
20
- 'status.autosaveOn': 'automatisch opslaan aan',
21
- 'status.saved': 'opgeslagen {time}',
22
- 'status.saveFailed': 'niet opgeslagen — opslag vol',
23
- 'canvas.meta': '{rows} rijen · {blocks} blokken · {width}px',
24
- 'tab.design': 'Stijl',
25
- 'tab.designHint': 'Selectie stylen',
26
- 'tab.blocks': 'Blokken',
27
- 'tab.blocksHint': 'Inhoudsblokken en variabelen',
28
- 'tab.rows': 'Secties',
29
- 'tab.rowsHint': 'Sectielay-outs en canvasmodel',
30
- 'tab.files': 'Bestanden',
31
- 'tab.filesHint': 'Bibliotheek met bestanden',
32
- 'tab.layers': 'Structuur',
33
- 'tab.layersHint': 'Documentstructuur',
34
- 'tab.theme': 'Thema',
35
- 'tab.themeHint': 'Globale stijlen',
36
- 'tab.data': 'Var.',
37
- 'tab.dataHint': 'Variabelen aangeleverd door jouw code',
38
- 'inspector.blockProperties': 'Blokeigenschappen',
39
- 'inspector.sectionProperties': 'Sectie-eigenschappen',
40
- 'inspector.title': 'Inspecteur',
41
- 'inspector.sectionLabel': 'Sectie',
42
- 'inspector.nothingSelected': 'Niets geselecteerd',
43
- 'action.duplicateHint': 'Dupliceren — ⌘D',
44
- 'action.deleteHint': 'Verwijderen — ⌫',
45
- 'inspector.emptyBody':
46
- 'Kies een rij of blok op het canvas om het hier te stylen. Sleep blokken vanuit het tabblad <strong style="color: var(--ed-text); font-weight: 600;">Blokken</strong>; dubbelklik op tekst om deze direct te bewerken.',
47
- 'inspector.shortcuts': 'Sneltoetsen',
48
- 'shortcut.undoRedo': '⌘Z / ⌘⇧Z ongedaan maken, opnieuw',
49
- 'shortcut.duplicate': '⌘D — selectie dupliceren',
50
- 'shortcut.delete': 'selectie verwijderen',
51
- 'shortcut.export': '⌘EHTML exporteren',
52
- 'shortcut.escape': 'ESC — selectie opheffen, sluiten',
53
- 'blocks.dragHint': 'Sleep naar het canvas',
54
- 'blocks.count': '{count} blokken',
55
- 'rows.sectionLayouts': 'Sectielay-outs',
56
- 'rows.customMarkup': 'Aangepaste opmaak',
57
- 'rows.htmlRowHint': 'Sleep om in te voegen, of klik om toe te voegen — een volledige rij die je vult met ruwe HTML',
58
- 'rows.rawHtmlSection': 'Ruwe HTML-sectie',
59
- 'rows.rawHtmlDesc': 'Volledige sectie, jouw eigen opmaak, nog steeds versleepbaar',
60
- 'rows.canvasModel': 'Canvasmodel',
61
- 'rows.modeRowBased': 'Op rijen gebaseerd',
62
- 'rows.modeFreeStack': 'Vrije stapel',
63
- 'rows.hintRows':
64
- 'Op secties gebaseerd: plaats eerst een lay-out, sleep dan blokken in de kolommen — elke sectie heeft zijn eigen achtergrond, rand, flex- of gridinstellingen.',
65
- 'rows.hintStack': 'Vrije stapel: zonder lay-outs — elk blok dat je plaatst wordt een eigen sectie over de volle breedte, op volgorde gestapeld.',
66
- 'files.libraryCount': 'Bibliotheek{count} bestanden',
67
- 'files.openManager': 'Bestandsbeheer openen',
68
- 'files.dragToCanvas': 'Sleep elk bestand direct naar het canvas om het als afbeeldingsblok te plaatsen.',
69
- 'layers.structure': 'Structuur',
70
- 'layers.sectionSingle': 'Sectie',
71
- 'layers.sectionMulti': 'Sectie · {count} kol.',
72
- 'layers.blockCount': '{count} bl.',
73
- 'theme.globalStyles': 'Globale stijlen',
74
- 'vars.title': 'Variabelen',
75
- 'vars.fromCode': '{count} uit jouw code',
76
- 'vars.declaredNote': 'Gedeclareerd door jouw applicatie — het canvas toont altijd het token, nooit een waarde.',
77
- 'vars.filterPlaceholder': 'Variabelen filteren…',
78
- 'vars.insertHint': 'Klik om in te voegen in geselecteerde tekst, kop of knop',
79
- 'vars.insert': 'invoegen',
80
- 'vars.noMatch': 'Geen variabele komt overeen met dit filter.',
81
- 'vars.noneDeclared': 'Jouw applicatie heeft nog geen variabelen gedeclareerd.',
82
- 'vars.rteHint': 'Tijdens het bewerken van tekst kun je ook een variabele kiezen via het dropdownmenu van de inline werkbalk.',
83
- 'modal.fileManager': 'Bestandsbeheer',
84
- 'modal.assetsTitle': 'Bestanden',
85
- 'modal.replaceImage': 'Afbeelding vervangen',
86
- 'library.searchPlaceholder': 'Bestanden zoeken…',
87
- 'action.upload': 'Uploaden',
88
- 'library.clickToPlace': 'Klik op een bestand om te plaatsen · of sleep een bestand naar het canvas',
89
- 'library.clickToReplace': 'Klik op een bestand om de geselecteerde afbeelding te vervangen',
90
- 'library.storageLabel': '{count} bestanden · {size}',
91
- 'library.folders': 'Mappen',
92
- 'library.dropHint': 'Zet afbeeldingsbestanden hier neer om te uploaden — of gebruik de knop Uploaden.',
93
- 'library.deleteFileHint': 'Bestand verwijderen',
94
- 'library.del': 'VERW',
95
- 'toast.assetDeleted': '{name} verwijderd',
96
- 'modal.export': 'Exporteren',
97
- 'modal.exportTitle': 'Op tabellen gebaseerde e-mail-HTML',
98
- 'export.copy': 'Kopiëren',
99
- 'export.copied': 'Gekopieerd',
100
- 'action.download': 'Downloaden',
101
- 'export.meta': '{kb} KB · tabellen + inline stijlen · Outlook-veilige breedtes',
102
- 'modal.rawHtmlTitle': 'Ruwe HTML, live voorbeeld',
103
- 'code.statusEdited': 'Codeweergave bewerkt voorbeeld live, nog niet toegepast',
104
- 'code.statusSynced': 'Codeweergave gesynchroniseerd met het canvas',
105
- 'action.reload': 'Herladen',
106
- 'action.reloadHint': 'Bron herladen vanuit het canvas',
107
- 'action.applyToCanvas': 'Toepassen op canvas',
108
- 'action.applyToCanvasHint': 'Bron opnieuw ontleden tot bewerkbare rijen',
109
- 'action.closeWithoutApplyingHint': 'Sluiten zonder toe te passen',
110
- 'code.source': 'Bron',
111
- 'code.livePreview': 'Live voorbeeld',
112
- 'code.liveHtmlPreviewTitle': 'Live HTML-voorbeeld',
113
- 'code.applyNote':
114
- 'Toepassen ontleedt elke tabelrij op het hoogste niveau tot een canvasrij die je nog kunt selecteren, herschikken en verwijderen handgeschreven opmaak overleeft de omzetting.',
115
- 'code.meta': '{kb} KB · {lines} regels',
116
- 'toast.sourceReloaded': 'Bron herladen vanuit het canvas',
117
- 'toast.sourceAppliedOne': 'Bron toegepast — 1 rij op het canvas',
118
- 'toast.sourceAppliedMany': 'Bron toegepast — {rows} rijen op het canvas',
119
- 'toast.parseError': 'Kan die HTML niet ontleden',
120
- 'modal.copyAssist': 'Tekstassistent',
121
- 'modal.draftCopyTitle': 'Tekst opstellen voor deze campagne',
122
- 'ai.goal': 'Doel',
123
- 'ai.tone': 'Toon',
124
- 'ai.briefLabel': 'Waar gaat deze e-mail over?',
125
- 'ai.briefPlaceholder': 'bijv. Herfstcollectie, 15% voor abonnees, gratis verzending vanaf €150',
126
- 'ai.generate': 'Tekst genereren',
127
- 'ai.writing': 'Bezig met schrijven…',
128
- 'ai.kindHeadline': 'Kop',
129
- 'ai.kindBody': 'Hoofdtekst',
130
- 'ai.kindButton': 'Knoptekst',
131
- 'ai.actionInsertHeading': 'Invoegen als kop',
132
- 'ai.actionInsertText': 'Invoegen als tekstblok',
133
- 'ai.actionInsertButton': 'Invoegen als knop',
134
- 'toast.headingAdded': 'Kop toegevoegd',
135
- 'toast.textBlockAdded': 'Tekstblok toegevoegd',
136
- 'toast.buttonAdded': 'Knop toegevoegd',
137
- 'preview.kickerMobile': 'Voorbeeldmobiel 375px',
138
- 'preview.kickerDark': 'Voorbeeld donkere inbox',
139
- 'preview.kickerDesktop': 'Voorbeeld — desktop {width}px',
140
- 'action.close': 'Sluiten',
141
- 'toast.duplicated': 'Gedupliceerd',
142
- 'toast.fileUploadedOne': '1 bestand geüpload',
143
- 'toast.fileUploadedMany': '{count} bestanden geüpload',
144
- 'toast.imageReplaced': 'Afbeelding vervangen',
145
- 'toast.imageAdded': 'Afbeelding toegevoegd aan canvas',
146
- 'toast.htmlCopied': 'HTML gekopieerd naar klembord',
147
- 'toast.templateLoaded': '{name} geladen',
148
- 'toast.snippetDefaultLabel': 'Fragment',
149
- 'toast.snippetInserted': '{name} ingevoegd',
150
- 'toast.snippetCopied': '{name} gekopieerd — selecteer een tekstblok om in te voegen',
151
- };
152
-
1
+ /** Dutch (Nederlands) — `nl`. AI-drafted, not reviewed by a native speaker. Correctable one key at a time via `.messages` overrides. */
2
+ export const NL = {
3
+ 'action.undoHint': 'Ongedaan maken — ⌘Z',
4
+ 'action.redoHint': 'Opnieuw — ⌘⇧Z',
5
+ 'action.chromeToDark': 'Donker',
6
+ 'action.chromeToLight': 'Licht',
7
+ 'action.chromeHint': 'Editorthema licht / donker',
8
+ 'action.chromeHintToDark': 'Donkere modus',
9
+ 'action.chromeHintToLight': 'Lichte modus',
10
+ 'action.aiDraft': 'Concept',
11
+ 'action.aiDraftHint': 'E-mailinhoud schrijven met AI',
12
+ 'action.code': 'Code',
13
+ 'action.codeHint': 'Ruwe HTML bewerken met live voorbeeld',
14
+ 'action.preview': 'Voorbeeld',
15
+ 'action.previewHint': 'De e-mail bekijken',
16
+ 'action.export': 'Exporteren',
17
+ 'action.exportHint': 'Je e-mail exporteren',
18
+ 'device.desktop': 'Desktop',
19
+ 'device.desktopHint': 'Desktopbreedte',
20
+ 'device.mobile': 'Mobiel',
21
+ 'device.mobileHint': 'Mobiele breedte',
22
+ 'status.autosaveOn': 'automatisch opslaan aan',
23
+ 'status.saved': 'opgeslagen {time}',
24
+ 'status.saveFailed': 'niet opgeslagen — opslag vol',
25
+ 'canvas.meta': '{rows} rijen · {blocks} blokken · {width}px',
26
+ 'tab.design': 'Stijl',
27
+ 'tab.designHint': 'Selectie stylen',
28
+ 'tab.blocks': 'Blokken',
29
+ 'tab.blocksHint': 'Inhoudsblokken en variabelen',
30
+ 'tab.rows': 'Secties',
31
+ 'tab.rowsHint': 'Sectielay-outs en canvasmodel',
32
+ 'tab.files': 'Bestanden',
33
+ 'tab.filesHint': 'Bibliotheek met bestanden',
34
+ 'tab.layers': 'Structuur',
35
+ 'tab.layersHint': 'Documentstructuur',
36
+ 'tab.settings': 'Instellingen',
37
+ 'tab.settingsHint': 'E-mailinstellingen',
38
+ 'tab.data': 'Var.',
39
+ 'tab.dataHint': 'Variabelen aangeleverd door jouw code',
40
+ 'inspector.blockProperties': 'Blokeigenschappen',
41
+ 'inspector.sectionProperties': 'Sectie-eigenschappen',
42
+ 'inspector.title': 'Inspecteur',
43
+ 'inspector.sectionLabel': 'Sectie',
44
+ 'inspector.nothingSelected': 'Niets geselecteerd',
45
+ 'action.duplicateHint': 'Dupliceren — ⌘D',
46
+ 'action.deleteHint': 'Verwijderen ',
47
+ 'inspector.emptyBody':
48
+ 'Kies een rij of blok op het canvas om het hier te stylen. Sleep blokken vanuit het tabblad <strong style="color: var(--ed-text); font-weight: 600;">Blokken</strong>; dubbelklik op tekst om deze direct te bewerken.',
49
+ 'inspector.shortcuts': 'Sneltoetsen',
50
+ 'shortcut.undoRedo': '⌘Z / ⌘⇧Z ongedaan maken, opnieuw',
51
+ 'shortcut.duplicate': '⌘Dselectie dupliceren',
52
+ 'shortcut.delete': ' — selectie verwijderen',
53
+ 'shortcut.export': '⌘E HTML exporteren',
54
+ 'shortcut.escape': 'ESC — selectie opheffen, sluiten',
55
+ 'blocks.dragHint': 'Sleep naar het canvas',
56
+ 'blocks.count': '{count} blokken',
57
+ 'rows.sectionLayouts': 'Sectielay-outs',
58
+ 'rows.customMarkup': 'Aangepaste opmaak',
59
+ 'rows.htmlRowHint': 'Sleep om in te voegen, of klik om toe te voegen — een volledige rij die je vult met ruwe HTML',
60
+ 'rows.rawHtmlSection': 'Ruwe HTML-sectie',
61
+ 'rows.rawHtmlDesc': 'Volledige sectie, jouw eigen opmaak, nog steeds versleepbaar',
62
+ 'rows.canvasModel': 'Canvasmodel',
63
+ 'rows.modeRowBased': 'Op rijen gebaseerd',
64
+ 'rows.modeFreeStack': 'Vrije stapel',
65
+ 'rows.hintRows':
66
+ 'Op secties gebaseerd: plaats eerst een lay-out, sleep dan blokken in de kolommen elke sectie heeft zijn eigen achtergrond, rand, flex- of gridinstellingen.',
67
+ 'rows.hintStack': 'Vrije stapel: zonder lay-outs — elk blok dat je plaatst wordt een eigen sectie over de volle breedte, op volgorde gestapeld.',
68
+ 'files.libraryCount': 'Bibliotheek {count} bestanden',
69
+ 'files.openManager': 'Bestandsbeheer openen',
70
+ 'files.dragToCanvas': 'Sleep elk bestand direct naar het canvas om het als afbeeldingsblok te plaatsen.',
71
+ 'layers.structure': 'Structuur',
72
+ 'layers.sectionSingle': 'Sectie',
73
+ 'layers.sectionMulti': 'Sectie · {count} kol.',
74
+ 'layers.column': 'Kolom {index}',
75
+ 'layers.blockCount': '{count} bl.',
76
+ 'vars.title': 'Variabelen',
77
+ 'vars.fromCode': '{count} uit jouw code',
78
+ 'vars.declaredNote': 'Gedeclareerd door jouw applicatie het canvas toont altijd het token, nooit een waarde.',
79
+ 'vars.filterPlaceholder': 'Variabelen filteren…',
80
+ 'vars.insertHint': 'Klik om in te voegen in geselecteerde tekst, kop of knop',
81
+ 'vars.insert': 'invoegen',
82
+ 'vars.noMatch': 'Geen variabele komt overeen met dit filter.',
83
+ 'vars.noneDeclared': 'Jouw applicatie heeft nog geen variabelen gedeclareerd.',
84
+ 'vars.rteHint': 'Tijdens het bewerken van tekst kun je ook een variabele kiezen via het dropdownmenu van de inline werkbalk.',
85
+ 'modal.fileManager': 'Bestandsbeheer',
86
+ 'modal.assetsTitle': 'Bestanden',
87
+ 'modal.replaceImage': 'Afbeelding vervangen',
88
+ 'library.searchPlaceholder': 'Bestanden zoeken…',
89
+ 'action.upload': 'Uploaden',
90
+ 'library.clickToPlace': 'Klik op een bestand om te plaatsen · of sleep een bestand naar het canvas',
91
+ 'library.clickToReplace': 'Klik op een bestand om de geselecteerde afbeelding te vervangen',
92
+ 'library.storageLabel': '{count} bestanden · {size}',
93
+ 'library.folders': 'Mappen',
94
+ 'library.dropHint': 'Zet afbeeldingsbestanden hier neer om te uploaden — of gebruik de knop Uploaden.',
95
+ 'library.deleteFileHint': 'Bestand verwijderen',
96
+ 'library.del': 'VERW',
97
+ 'toast.assetDeleted': '{name} verwijderd',
98
+ 'library.allFiles': 'Alle bestanden',
99
+ 'library.loadMore': 'Meer laden',
100
+ 'library.empty': 'Hier staan nog geen bestanden.',
101
+ 'storage.loading': 'Bestanden laden…',
102
+ 'storage.uploading': '{count} uploaden…',
103
+ 'storage.errLoadFailed': 'De bestandsbibliotheek kon niet worden geladen {reason}',
104
+ 'storage.errNoLimits': 'Uploaden staat uit: deze app heeft geen uploadlimieten ingesteld.',
105
+ 'storage.errNoAccept': 'Uploaden staat uit: er zijn geen bestandsformaten toegestaan.',
106
+ 'storage.errNoMaxBytes': 'Uploaden staat uit: er is geen maximale bestandsgrootte ingesteld.',
107
+ 'storage.errTooLarge': '{name} is {size} — de limiet is {max}.',
108
+ 'storage.errFormat': '{name} is een {type}-bestand, dat hier niet is toegestaan.',
109
+ 'storage.errSvg': '{name} is een SVG, en die accepteert deze app niet.',
110
+ 'storage.errDimensions': '{name} is {w}×{ht}px — de limiet is {maxW}×{maxH}px.',
111
+ 'storage.errTooMany': 'Er kunnen maar {max} bestanden tegelijk worden geüpload.',
112
+ 'storage.errUnreadable': '{name} is geen leesbare afbeelding.',
113
+ 'storage.errUploadFailed': '{name} kon niet worden geüpload — {reason}',
114
+ 'storage.errDeleteFailed': '{name} kon niet worden verwijderd{reason}',
115
+ 'modal.export': 'Exporteren',
116
+ 'modal.exportTitle': 'Op tabellen gebaseerde e-mail-HTML',
117
+ 'export.copy': 'Kopiëren',
118
+ 'export.copied': 'Gekopieerd',
119
+ 'action.download': 'Downloaden',
120
+ 'export.meta': '{kb} KB · tabellen + inline stijlen · Outlook-veilige breedtes',
121
+ 'modal.rawHtmlTitle': 'Ruwe HTML, live voorbeeld',
122
+ 'code.statusEdited': 'Codeweergave — bewerkt — voorbeeld live, nog niet toegepast',
123
+ 'code.statusSynced': 'Codeweergave — gesynchroniseerd met het canvas',
124
+ 'action.reload': 'Herladen',
125
+ 'action.reloadHint': 'Bron herladen vanuit het canvas',
126
+ 'action.applyToCanvas': 'Toepassen op canvas',
127
+ 'action.applyToCanvasHint': 'Bron opnieuw ontleden tot bewerkbare rijen',
128
+ 'action.closeWithoutApplyingHint': 'Sluiten zonder toe te passen',
129
+ 'code.source': 'Bron',
130
+ 'code.livePreview': 'Live voorbeeld',
131
+ 'code.liveHtmlPreviewTitle': 'Live HTML-voorbeeld',
132
+ 'code.applyNote':
133
+ 'Toepassen ontleedt elke tabelrij op het hoogste niveau tot een canvasrij die je nog kunt selecteren, herschikken en verwijderen — handgeschreven opmaak overleeft de omzetting.',
134
+ 'code.meta': '{kb} KB · {lines} regels',
135
+ 'toast.sourceReloaded': 'Bron herladen vanuit het canvas',
136
+ 'toast.sourceAppliedOne': 'Bron toegepast — 1 rij op het canvas',
137
+ 'toast.sourceAppliedMany': 'Bron toegepast {rows} rijen op het canvas',
138
+ 'toast.parseError': 'Kan die HTML niet ontleden',
139
+ 'modal.aiDraft': 'AI-schrijfassistent',
140
+ 'modal.aiDraftTitle': 'Schrijf je e-mail met AI',
141
+ 'ai.disclosure': 'AI maakt suggesties op basis van je briefing. Controleer en bewerk het resultaat voordat je verzendt.',
142
+ 'ai.goal': 'Doel',
143
+ 'ai.tone': 'Toon',
144
+ 'ai.briefLabel': 'Waar gaat deze e-mail over?',
145
+ 'ai.briefPlaceholder': 'bijv. Herfstcollectie, 15% voor abonnees, gratis verzending vanaf €150',
146
+ 'ai.generate': 'Tekst genereren',
147
+ 'ai.writing': 'Bezig met schrijven…',
148
+ 'ai.kindHeadline': 'Kop',
149
+ 'ai.kindBody': 'Hoofdtekst',
150
+ 'ai.kindButton': 'Knoptekst',
151
+ 'ai.actionInsertHeading': 'Invoegen als kop',
152
+ 'ai.actionInsertText': 'Invoegen als tekstblok',
153
+ 'ai.actionInsertButton': 'Invoegen als knop',
154
+ 'toast.headingAdded': 'Kop toegevoegd',
155
+ 'toast.textBlockAdded': 'Tekstblok toegevoegd',
156
+ 'toast.buttonAdded': 'Knop toegevoegd',
157
+ 'preview.kickerMobile': 'Voorbeeld — mobiel 375px',
158
+ 'preview.kickerDesktop': 'Voorbeeld — desktop {width}px',
159
+ 'action.close': 'Sluiten',
160
+ 'toast.duplicated': 'Gedupliceerd',
161
+ 'toast.fileUploadedOne': '1 bestand geüpload',
162
+ 'toast.fileUploadedMany': '{count} bestanden geüpload',
163
+ 'toast.imageReplaced': 'Afbeelding vervangen',
164
+ 'toast.imageAdded': 'Afbeelding toegevoegd aan canvas',
165
+ 'toast.htmlCopied': 'HTML gekopieerd naar klembord',
166
+ 'toast.templateLoaded': '{name} geladen',
167
+ 'toast.snippetDefaultLabel': 'Fragment',
168
+ 'toast.snippetInserted': '{name} ingevoegd',
169
+ 'toast.snippetCopied': '{name} gekopieerd — selecteer een tekstblok om in te voegen',
170
+ 'rte.textStyle': 'Tekststijl',
171
+ 'rte.mergeTags': 'Samenvoegvelden',
172
+ 'rte.noMergeTags': 'Geen samenvoegvelden beschikbaar',
173
+ 'rte.textColor': 'Tekstkleur',
174
+ 'rte.highlightColor': 'Markeerkleur',
175
+ 'rte.removeHighlight': 'Markering verwijderen',
176
+ 'rte.clearFormatting': 'Opmaak wissen',
177
+ 'action.downloadPng': 'PNG downloaden',
178
+ 'action.screenshot': 'Schermafbeelding',
179
+ 'action.screenshotHint': 'Bekijk de hele template als afbeelding en download die',
180
+ 'toast.pngSaved': 'Schermafbeelding gedownload',
181
+ 'toast.pngFailed': 'Schermafbeelding mislukt — een externe afbeelding kon niet worden geladen',
182
+ 'toast.pngCopied': 'Schermafbeelding gekopieerd naar het klembord',
183
+ 'toast.pngCopyFailed': 'Deze browser accepteerde geen afbeelding op het klembord',
184
+ 'story.kicker': 'Schermafbeelding',
185
+ 'story.rendering': 'Schermafbeelding wordt gemaakt',
186
+ 'story.renderingHint': 'Elk blok wordt op 2× getekend — bij een lange template duurt dat even.',
187
+ 'story.failed': 'Schermafbeelding mislukt',
188
+ 'story.failedHint': 'Een afbeelding in de template kon niet worden geladen voor de opname.',
189
+ 'story.retry': 'Probeer het opnieuw',
190
+ 'story.play': 'Afspelen',
191
+ 'story.pause': 'Pauzeren',
192
+ 'story.replay': 'Opnieuw afspelen',
193
+ 'story.copy': 'Kopiëren',
194
+ 'story.meta': '{w}×{h} · scherm {i} van {n}',
195
+ 'footer.poweredBy': 'Mogelijk gemaakt door SELISE Blocks © 2026',
196
+ };