@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
- /** Greek (Ελληνικά) — `el`. AI-drafted, not reviewed by a native speaker. Correctable one key at a time via `.messages` overrides. */
2
- export const EL = {
3
- 'action.undoHint': 'Αναίρεση — ⌘Z',
4
- 'action.redoHint': 'Επανάληψη — ⌘⇧Z',
5
- 'action.chromeToDark': 'Σκούρο',
6
- 'action.chromeToLight': 'Ανοιχτόχρωμο',
7
- 'action.chromeHint': 'Θέμα επεξεργαστή ανοιχτό / σκούρο',
8
- 'action.aiCopy': 'Κείμενο',
9
- 'action.aiCopyHint': 'Σύνταξη κειμένου με AI',
10
- 'action.code': 'Κώδικας',
11
- 'action.codeHint': 'Επεξεργασία ακατέργαστου HTML με ζωντανή προεπισκόπηση',
12
- 'action.preview': 'Προεπισκόπηση',
13
- 'action.export': 'Εξαγωγή',
14
- 'device.desktop': 'Υπολογιστής',
15
- 'device.desktopHint': 'Πλάτος υπολογιστή',
16
- 'device.mobile': 'Κινητό',
17
- 'device.mobileHint': 'Πλάτος κινητού',
18
- 'device.dark': 'Σκούρο',
19
- 'device.darkHint': 'Σκούρα λειτουργία εισερχομένων',
20
- 'status.autosaveOn': 'η αυτόματη αποθήκευση είναι ενεργή',
21
- 'status.saved': 'αποθηκεύτηκε {time}',
22
- 'status.saveFailed': 'δεν αποθηκεύτηκε ο χώρος αποθήκευσης γέμισε',
23
- 'canvas.meta': '{rows} γραμμές · {blocks} μπλοκ · {width}px',
24
- 'tab.design': 'Στυλ',
25
- 'tab.designHint': 'Μορφοποίηση επιλογής',
26
- 'tab.blocks': 'Μπλοκ',
27
- 'tab.blocksHint': 'Μπλοκ περιεχομένου και μεταβλητές',
28
- 'tab.rows': 'Ενότητες',
29
- 'tab.rowsHint': 'Διατάξεις ενοτήτων και μοντέλο καμβά',
30
- 'tab.files': 'Αρχεία',
31
- 'tab.filesHint': 'Βιβλιοθήκη πόρων',
32
- 'tab.layers': 'Δομή',
33
- 'tab.layersHint': 'Δομή εγγράφου',
34
- 'tab.theme': 'Θέμα',
35
- 'tab.themeHint': 'Καθολικά στυλ',
36
- 'tab.data': 'Μετ.',
37
- 'tab.dataHint': 'Μεταβλητές που παρέχονται από τον κώδικά σας',
38
- 'inspector.blockProperties': 'Ιδιότητες μπλοκ',
39
- 'inspector.sectionProperties': 'Ιδιότητες ενότητας',
40
- 'inspector.title': 'Επόπτης',
41
- 'inspector.sectionLabel': 'Ενότητα',
42
- 'inspector.nothingSelected': 'Καμία επιλογή',
43
- 'action.duplicateHint': 'Διπλασιασμός — ⌘D',
44
- 'action.deleteHint': 'Διαγραφή — ⌫',
45
- 'inspector.emptyBody':
46
- 'Επιλέξτε μια γραμμή ή ένα μπλοκ στον καμβά για να το μορφοποιήσετε εδώ. Σύρετε μπλοκ από την καρτέλα <strong style="color: var(--ed-text); font-weight: 600;">Μπλοκ</strong>· κάντε διπλό κλικ σε οποιοδήποτε κείμενο για να το επεξεργαστείτε απευθείας.',
47
- 'inspector.shortcuts': 'Συντομεύσεις',
48
- 'shortcut.undoRedo': '⌘Z / ⌘⇧Z αναίρεση, επανάληψη',
49
- 'shortcut.duplicate': '⌘D — διπλασιασμός επιλογής',
50
- 'shortcut.delete': 'διαγραφή επιλογής',
51
- 'shortcut.export': '⌘Eεξαγωγή HTML',
52
- 'shortcut.escape': 'ESCκατάργηση επιλογής, κλείσιμο',
53
- 'blocks.dragHint': 'Σύρετε στον καμβά',
54
- 'blocks.count': '{count} μπλοκ',
55
- 'rows.sectionLayouts': 'Διατάξεις ενοτήτων',
56
- 'rows.customMarkup': 'Προσαρμοσμένη σήμανση',
57
- 'rows.htmlRowHint': 'Σύρετε για εισαγωγή ή κάντε κλικ για προσθήκη — μια γραμμή πλήρους πλάτους που γεμίζετε με ακατέργαστο HTML',
58
- 'rows.rawHtmlSection': 'Ενότητα ακατέργαστου HTML',
59
- 'rows.rawHtmlDesc': 'Ενότητα πλήρους πλάτους, δική σας σήμανση, εξακολουθεί να είναι μεταφέρσιμη',
60
- 'rows.canvasModel': 'Μοντέλο καμβά',
61
- 'rows.modeRowBased': 'Βάσει γραμμών',
62
- 'rows.modeFreeStack': 'Ελεύθερη στοίβα',
63
- 'rows.hintRows':
64
- 'Βάσει ενοτήτων: αποθέστε πρώτα μια διάταξη, μετά μπλοκ στις στήλες της — κάθε ενότητα έχει το δικό της φόντο, περίγραμμα, ρυθμίσεις flex ή πλέγματος.',
65
- 'rows.hintStack': 'Ελεύθερη στοίβα: χωρίς διατάξεις — κάθε μπλοκ που αποθέτετε γίνεται δική του ενότητα πλήρους πλάτους, στοιβαγμένη με τη σειρά.',
66
- 'files.libraryCount': 'Βιβλιοθήκη{count} αρχεία',
67
- 'files.openManager': 'Άνοιγμα διαχείρισης αρχείων',
68
- 'files.dragToCanvas': 'Σύρετε οποιοδήποτε αρχείο απευθείας στον καμβά για να το τοποθετήσετε ως μπλοκ εικόνας.',
69
- 'layers.structure': 'Δομή',
70
- 'layers.sectionSingle': 'Ενότητα',
71
- 'layers.sectionMulti': 'Ενότητα · {count} στήλες',
72
- 'layers.blockCount': '{count} μπλ.',
73
- 'theme.globalStyles': 'Καθολικά στυλ',
74
- 'vars.title': 'Μεταβλητές',
75
- 'vars.fromCode': '{count} από τον κώδικά σας',
76
- 'vars.declaredNote': 'Δηλωμένες από την εφαρμογή σας — ο καμβάς εμφανίζει πάντα το token, ποτέ μια τιμή.',
77
- 'vars.filterPlaceholder': 'Φιλτράρισμα μεταβλητών…',
78
- 'vars.insertHint': 'Κάντε κλικ για εισαγωγή στο επιλεγμένο κείμενο, τίτλο ή κουμπί',
79
- 'vars.insert': 'εισαγωγή',
80
- 'vars.noMatch': 'Καμία μεταβλητή δεν ταιριάζει με αυτό το φίλτρο.',
81
- 'vars.noneDeclared': 'Η εφαρμογή σας δεν έχει δηλώσει ακόμη μεταβλητές.',
82
- 'vars.rteHint': 'Κατά την επεξεργασία κειμένου, μπορείτε επίσης να επιλέξετε μια μεταβλητή απευθείας από το αναπτυσσόμενο μενού της ενσωματωμένης γραμμής εργαλείων.',
83
- 'modal.fileManager': 'Διαχείριση αρχείων',
84
- 'modal.assetsTitle': 'Πόροι',
85
- 'modal.replaceImage': 'Αντικατάσταση εικόνας',
86
- 'library.searchPlaceholder': 'Αναζήτηση αρχείων…',
87
- 'action.upload': 'Μεταφόρτωση',
88
- 'library.clickToPlace': 'Κάντε κλικ σε ένα αρχείο για να το τοποθετήσετε · ή σύρετε ένα αρχείο στον καμβά',
89
- 'library.clickToReplace': 'Κάντε κλικ σε ένα αρχείο για να αντικαταστήσετε την επιλεγμένη εικόνα',
90
- 'library.storageLabel': '{count} αρχεία · {size}',
91
- 'library.folders': 'Φάκελοι',
92
- 'library.dropHint': 'Αποθέστε εδώ αρχεία εικόνας για μεταφόρτωση — ή χρησιμοποιήστε το κουμπί Μεταφόρτωση.',
93
- 'library.deleteFileHint': 'Διαγραφή αρχείου',
94
- 'library.del': 'ΔΙΑΓΡ',
95
- 'toast.assetDeleted': 'Το {name} διαγράφηκε',
96
- 'modal.export': 'Εξαγωγή',
97
- 'modal.exportTitle': 'HTML email βασισμένο σε πίνακες',
98
- 'export.copy': 'Αντιγραφή',
99
- 'export.copied': 'Αντιγράφηκε',
100
- 'action.download': 'Λήψη',
101
- 'export.meta': '{kb} KB · πίνακες + ενσωματωμένα στυλ · πλάτη ασφαλή για Outlook',
102
- 'modal.rawHtmlTitle': 'Ακατέργαστο HTML, ζωντανή προεπισκόπηση',
103
- 'code.statusEdited': 'Προβολή κώδικα επεξεργάστηκε ζωντανή προεπισκόπηση, δεν έχει εφαρμοστεί ακόμη',
104
- 'code.statusSynced': 'Προβολή κώδικα συγχρονισμένη με τον καμβά',
105
- 'action.reload': 'Επαναφόρτωση',
106
- 'action.reloadHint': 'Επαναφόρτωση πηγής από τον καμβά',
107
- 'action.applyToCanvas': 'Εφαρμογή στον καμβά',
108
- 'action.applyToCanvasHint': 'Ανάλυση της πηγής ξανά σε επεξεργάσιμες γραμμές',
109
- 'action.closeWithoutApplyingHint': 'Κλείσιμο χωρίς εφαρμογή',
110
- 'code.source': 'Πηγή',
111
- 'code.livePreview': 'Ζωντανή προεπισκόπηση',
112
- 'code.liveHtmlPreviewTitle': 'Ζωντανή προεπισκόπηση HTML',
113
- 'code.applyNote':
114
- 'Η εφαρμογή αναλύει κάθε γραμμή πίνακα ανώτατου επιπέδου σε γραμμή καμβά που μπορείτε ακόμη να επιλέξετε, να αναδιατάξετε και να διαγράψετε ο χειρόγραφος κώδικας επιβιώνει αναλλοίωτος.',
115
- 'code.meta': '{kb} KB · {lines} γραμμές',
116
- 'toast.sourceReloaded': 'Η πηγή επαναφορτώθηκε από τον καμβά',
117
- 'toast.sourceAppliedOne': 'Η πηγή εφαρμόστηκε — 1 γραμμή στον καμβά',
118
- 'toast.sourceAppliedMany': 'Η πηγή εφαρμόστηκε — {rows} γραμμές στον καμβά',
119
- 'toast.parseError': 'Δεν ήταν δυνατή η ανάλυση αυτού του HTML',
120
- 'modal.copyAssist': 'Βοηθός κειμένου',
121
- 'modal.draftCopyTitle': 'Σύνταξη κειμένου για αυτήν την καμπάνια',
122
- 'ai.goal': 'Στόχος',
123
- 'ai.tone': 'Τόνος',
124
- 'ai.briefLabel': 'Για τι αφορά αυτό το email;',
125
- 'ai.briefPlaceholder': 'π.χ. Φθινοπωρινή συλλογή, 15% για συνδρομητές, δωρεάν αποστολή άνω των 150€',
126
- 'ai.generate': 'Δημιουργία κειμένου',
127
- 'ai.writing': 'Γίνεται συγγραφή…',
128
- 'ai.kindHeadline': 'Τίτλος',
129
- 'ai.kindBody': 'Κύριο κείμενο',
130
- 'ai.kindButton': 'Κείμενο κουμπιού',
131
- 'ai.actionInsertHeading': 'Εισαγωγή ως τίτλος',
132
- 'ai.actionInsertText': 'Εισαγωγή ως μπλοκ κειμένου',
133
- 'ai.actionInsertButton': 'Εισαγωγή ως κουμπί',
134
- 'toast.headingAdded': 'Ο τίτλος προστέθηκε',
135
- 'toast.textBlockAdded': 'Το μπλοκ κειμένου προστέθηκε',
136
- 'toast.buttonAdded': 'Το κουμπί προστέθηκε',
137
- 'preview.kickerMobile': 'Προεπισκόπησηκινητό 375px',
138
- 'preview.kickerDark': 'Προεπισκόπηση σκούρα εισερχόμενα',
139
- 'preview.kickerDesktop': 'Προεπισκόπηση υπολογιστής {width}px',
140
- 'action.close': 'Κλείσιμο',
141
- 'toast.duplicated': 'Διπλασιάστηκε',
142
- 'toast.fileUploadedOne': '1 αρχείο μεταφορτώθηκε',
143
- 'toast.fileUploadedMany': '{count} αρχεία μεταφορτώθηκαν',
144
- 'toast.imageReplaced': 'Η εικόνα αντικαταστάθηκε',
145
- 'toast.imageAdded': 'Η εικόνα προστέθηκε στον καμβά',
146
- 'toast.htmlCopied': 'Το HTML αντιγράφηκε στο πρόχειρο',
147
- 'toast.templateLoaded': 'Το {name} φορτώθηκε',
148
- 'toast.snippetDefaultLabel': 'Απόσπασμα',
149
- 'toast.snippetInserted': 'Το {name} εισήχθη',
150
- 'toast.snippetCopied': 'Το {name} αντιγράφηκε — επιλέξτε ένα μπλοκ κειμένου για να το εισαγάγετε',
151
- };
152
-
1
+ /** Greek (Ελληνικά) — `el`. AI-drafted, not reviewed by a native speaker. Correctable one key at a time via `.messages` overrides. */
2
+ export const EL = {
3
+ 'action.undoHint': 'Αναίρεση — ⌘Z',
4
+ 'action.redoHint': 'Επανάληψη — ⌘⇧Z',
5
+ 'action.chromeToDark': 'Σκούρο',
6
+ 'action.chromeToLight': 'Ανοιχτόχρωμο',
7
+ 'action.chromeHint': 'Θέμα επεξεργαστή ανοιχτό / σκούρο',
8
+ 'action.chromeHintToDark': 'Σκούρα λειτουργία',
9
+ 'action.chromeHintToLight': 'Φωτεινή λειτουργία',
10
+ 'action.aiDraft': 'Προσχέδιο',
11
+ 'action.aiDraftHint': 'Σύνταξη περιεχομένου email με AI',
12
+ 'action.code': 'Κώδικας',
13
+ 'action.codeHint': 'Επεξεργασία ακατέργαστου HTML με ζωντανή προεπισκόπηση',
14
+ 'action.preview': 'Προεπισκόπηση',
15
+ 'action.previewHint': 'Προεπισκόπηση του email',
16
+ 'action.export': 'Εξαγωγή',
17
+ 'action.exportHint': 'Εξαγωγή του email σας',
18
+ 'device.desktop': 'Υπολογιστής',
19
+ 'device.desktopHint': 'Πλάτος υπολογιστή',
20
+ 'device.mobile': 'Κινητό',
21
+ 'device.mobileHint': 'Πλάτος κινητού',
22
+ 'status.autosaveOn': 'η αυτόματη αποθήκευση είναι ενεργή',
23
+ 'status.saved': 'αποθηκεύτηκε {time}',
24
+ 'status.saveFailed': 'δεν αποθηκεύτηκε — ο χώρος αποθήκευσης γέμισε',
25
+ 'canvas.meta': '{rows} γραμμές · {blocks} μπλοκ · {width}px',
26
+ 'tab.design': 'Στυλ',
27
+ 'tab.designHint': 'Μορφοποίηση επιλογής',
28
+ 'tab.blocks': 'Μπλοκ',
29
+ 'tab.blocksHint': 'Μπλοκ περιεχομένου και μεταβλητές',
30
+ 'tab.rows': 'Ενότητες',
31
+ 'tab.rowsHint': 'Διατάξεις ενοτήτων και μοντέλο καμβά',
32
+ 'tab.files': 'Αρχεία',
33
+ 'tab.filesHint': 'Βιβλιοθήκη πόρων',
34
+ 'tab.layers': 'Δομή',
35
+ 'tab.layersHint': 'Δομή εγγράφου',
36
+ 'tab.settings': 'Ρυθμίσεις',
37
+ 'tab.settingsHint': 'Ρυθμίσεις email',
38
+ 'tab.data': 'Μετ.',
39
+ 'tab.dataHint': 'Μεταβλητές που παρέχονται από τον κώδικά σας',
40
+ 'inspector.blockProperties': 'Ιδιότητες μπλοκ',
41
+ 'inspector.sectionProperties': 'Ιδιότητες ενότητας',
42
+ 'inspector.title': 'Επόπτης',
43
+ 'inspector.sectionLabel': 'Ενότητα',
44
+ 'inspector.nothingSelected': 'Καμία επιλογή',
45
+ 'action.duplicateHint': 'Διπλασιασμός — ⌘D',
46
+ 'action.deleteHint': 'Διαγραφή ',
47
+ 'inspector.emptyBody':
48
+ 'Επιλέξτε μια γραμμή ή ένα μπλοκ στον καμβά για να το μορφοποιήσετε εδώ. Σύρετε μπλοκ από την καρτέλα <strong style="color: var(--ed-text); font-weight: 600;">Μπλοκ</strong>· κάντε διπλό κλικ σε οποιοδήποτε κείμενο για να το επεξεργαστείτε απευθείας.',
49
+ 'inspector.shortcuts': 'Συντομεύσεις',
50
+ 'shortcut.undoRedo': '⌘Z / ⌘⇧Z αναίρεση, επανάληψη',
51
+ 'shortcut.duplicate': '⌘Dδιπλασιασμός επιλογής',
52
+ 'shortcut.delete': 'διαγραφή επιλογής',
53
+ 'shortcut.export': '⌘E εξαγωγή HTML',
54
+ 'shortcut.escape': 'ESC — κατάργηση επιλογής, κλείσιμο',
55
+ 'blocks.dragHint': 'Σύρετε στον καμβά',
56
+ 'blocks.count': '{count} μπλοκ',
57
+ 'rows.sectionLayouts': 'Διατάξεις ενοτήτων',
58
+ 'rows.customMarkup': 'Προσαρμοσμένη σήμανση',
59
+ 'rows.htmlRowHint': 'Σύρετε για εισαγωγή ή κάντε κλικ για προσθήκη μια γραμμή πλήρους πλάτους που γεμίζετε με ακατέργαστο HTML',
60
+ 'rows.rawHtmlSection': 'Ενότητα ακατέργαστου HTML',
61
+ 'rows.rawHtmlDesc': 'Ενότητα πλήρους πλάτους, δική σας σήμανση, εξακολουθεί να είναι μεταφέρσιμη',
62
+ 'rows.canvasModel': 'Μοντέλο καμβά',
63
+ 'rows.modeRowBased': 'Βάσει γραμμών',
64
+ 'rows.modeFreeStack': 'Ελεύθερη στοίβα',
65
+ 'rows.hintRows':
66
+ 'Βάσει ενοτήτων: αποθέστε πρώτα μια διάταξη, μετά μπλοκ στις στήλες της κάθε ενότητα έχει το δικό της φόντο, περίγραμμα, ρυθμίσεις flex ή πλέγματος.',
67
+ 'rows.hintStack': 'Ελεύθερη στοίβα: χωρίς διατάξεις — κάθε μπλοκ που αποθέτετε γίνεται δική του ενότητα πλήρους πλάτους, στοιβαγμένη με τη σειρά.',
68
+ 'files.libraryCount': 'Βιβλιοθήκη {count} αρχεία',
69
+ 'files.openManager': 'Άνοιγμα διαχείρισης αρχείων',
70
+ 'files.dragToCanvas': 'Σύρετε οποιοδήποτε αρχείο απευθείας στον καμβά για να το τοποθετήσετε ως μπλοκ εικόνας.',
71
+ 'layers.structure': 'Δομή',
72
+ 'layers.sectionSingle': 'Ενότητα',
73
+ 'layers.sectionMulti': 'Ενότητα · {count} στήλες',
74
+ 'layers.column': 'Στήλη {index}',
75
+ 'layers.blockCount': '{count} μπλ.',
76
+ 'vars.title': 'Μεταβλητές',
77
+ 'vars.fromCode': '{count} από τον κώδικά σας',
78
+ 'vars.declaredNote': 'Δηλωμένες από την εφαρμογή σας ο καμβάς εμφανίζει πάντα το token, ποτέ μια τιμή.',
79
+ 'vars.filterPlaceholder': 'Φιλτράρισμα μεταβλητών…',
80
+ 'vars.insertHint': 'Κάντε κλικ για εισαγωγή στο επιλεγμένο κείμενο, τίτλο ή κουμπί',
81
+ 'vars.insert': 'εισαγωγή',
82
+ 'vars.noMatch': 'Καμία μεταβλητή δεν ταιριάζει με αυτό το φίλτρο.',
83
+ 'vars.noneDeclared': 'Η εφαρμογή σας δεν έχει δηλώσει ακόμη μεταβλητές.',
84
+ 'vars.rteHint': 'Κατά την επεξεργασία κειμένου, μπορείτε επίσης να επιλέξετε μια μεταβλητή απευθείας από το αναπτυσσόμενο μενού της ενσωματωμένης γραμμής εργαλείων.',
85
+ 'modal.fileManager': 'Διαχείριση αρχείων',
86
+ 'modal.assetsTitle': 'Πόροι',
87
+ 'modal.replaceImage': 'Αντικατάσταση εικόνας',
88
+ 'library.searchPlaceholder': 'Αναζήτηση αρχείων…',
89
+ 'action.upload': 'Μεταφόρτωση',
90
+ 'library.clickToPlace': 'Κάντε κλικ σε ένα αρχείο για να το τοποθετήσετε · ή σύρετε ένα αρχείο στον καμβά',
91
+ 'library.clickToReplace': 'Κάντε κλικ σε ένα αρχείο για να αντικαταστήσετε την επιλεγμένη εικόνα',
92
+ 'library.storageLabel': '{count} αρχεία · {size}',
93
+ 'library.folders': 'Φάκελοι',
94
+ 'library.dropHint': 'Αποθέστε εδώ αρχεία εικόνας για μεταφόρτωση — ή χρησιμοποιήστε το κουμπί Μεταφόρτωση.',
95
+ 'library.deleteFileHint': 'Διαγραφή αρχείου',
96
+ 'library.del': 'ΔΙΑΓΡ',
97
+ 'toast.assetDeleted': 'Το {name} διαγράφηκε',
98
+ 'library.allFiles': 'Όλα τα αρχεία',
99
+ 'library.loadMore': 'Φόρτωση περισσότερων',
100
+ 'library.empty': 'Δεν υπάρχουν ακόμη αρχεία εδώ.',
101
+ 'storage.loading': 'Φόρτωση αρχείων…',
102
+ 'storage.uploading': 'Μεταφόρτωση {count}…',
103
+ 'storage.errLoadFailed': 'Δεν ήταν δυνατή η φόρτωση της βιβλιοθήκης αρχείων {reason}',
104
+ 'storage.errNoLimits': 'Οι μεταφορτώσεις είναι απενεργοποιημένες: αυτή η εφαρμογή δεν έχει ορίσει όρια μεταφόρτωσης.',
105
+ 'storage.errNoAccept': 'Οι μεταφορτώσεις είναι απενεργοποιημένες: δεν έχει επιτραπεί κανένας τύπος αρχείου.',
106
+ 'storage.errNoMaxBytes': 'Οι μεταφορτώσεις είναι απενεργοποιημένες: δεν έχει οριστεί μέγιστο μέγεθος αρχείου.',
107
+ 'storage.errTooLarge': 'Το {name} είναι {size} — το όριο είναι {max}.',
108
+ 'storage.errFormat': 'Το {name} είναι αρχείο {type}, που δεν επιτρέπεται εδώ.',
109
+ 'storage.errSvg': 'Το {name} είναι SVG, το οποίο αυτή η εφαρμογή δεν δέχεται.',
110
+ 'storage.errDimensions': 'Το {name} είναι {w}×{ht}px — το όριο είναι {maxW}×{maxH}px.',
111
+ 'storage.errTooMany': 'Μπορούν να μεταφορτωθούν μόνο {max} αρχεία τη φορά.',
112
+ 'storage.errUnreadable': 'Το {name} δεν είναι αναγνώσιμη εικόνα.',
113
+ 'storage.errUploadFailed': 'Δεν ήταν δυνατή η μεταφόρτωση του {name} — {reason}',
114
+ 'storage.errDeleteFailed': 'Δεν ήταν δυνατή η διαγραφή του {name}{reason}',
115
+ 'modal.export': 'Εξαγωγή',
116
+ 'modal.exportTitle': 'HTML email βασισμένο σε πίνακες',
117
+ 'export.copy': 'Αντιγραφή',
118
+ 'export.copied': 'Αντιγράφηκε',
119
+ 'action.download': 'Λήψη',
120
+ 'export.meta': '{kb} KB · πίνακες + ενσωματωμένα στυλ · πλάτη ασφαλή για Outlook',
121
+ 'modal.rawHtmlTitle': 'Ακατέργαστο HTML, ζωντανή προεπισκόπηση',
122
+ 'code.statusEdited': 'Προβολή κώδικα — επεξεργάστηκε — ζωντανή προεπισκόπηση, δεν έχει εφαρμοστεί ακόμη',
123
+ 'code.statusSynced': 'Προβολή κώδικα — συγχρονισμένη με τον καμβά',
124
+ 'action.reload': 'Επαναφόρτωση',
125
+ 'action.reloadHint': 'Επαναφόρτωση πηγής από τον καμβά',
126
+ 'action.applyToCanvas': 'Εφαρμογή στον καμβά',
127
+ 'action.applyToCanvasHint': 'Ανάλυση της πηγής ξανά σε επεξεργάσιμες γραμμές',
128
+ 'action.closeWithoutApplyingHint': 'Κλείσιμο χωρίς εφαρμογή',
129
+ 'code.source': 'Πηγή',
130
+ 'code.livePreview': 'Ζωντανή προεπισκόπηση',
131
+ 'code.liveHtmlPreviewTitle': 'Ζωντανή προεπισκόπηση HTML',
132
+ 'code.applyNote':
133
+ 'Η εφαρμογή αναλύει κάθε γραμμή πίνακα ανώτατου επιπέδου σε γραμμή καμβά που μπορείτε ακόμη να επιλέξετε, να αναδιατάξετε και να διαγράψετε — ο χειρόγραφος κώδικας επιβιώνει αναλλοίωτος.',
134
+ 'code.meta': '{kb} KB · {lines} γραμμές',
135
+ 'toast.sourceReloaded': 'Η πηγή επαναφορτώθηκε από τον καμβά',
136
+ 'toast.sourceAppliedOne': 'Η πηγή εφαρμόστηκε — 1 γραμμή στον καμβά',
137
+ 'toast.sourceAppliedMany': 'Η πηγή εφαρμόστηκε {rows} γραμμές στον καμβά',
138
+ 'toast.parseError': 'Δεν ήταν δυνατή η ανάλυση αυτού του HTML',
139
+ 'modal.aiDraft': 'Βοηθός σύνταξης AI',
140
+ 'modal.aiDraftTitle': 'Συντάξτε το email σας με AI',
141
+ 'ai.disclosure': 'Το AI δημιουργεί προτάσεις από τη σύνοψή σας. Ελέγξτε και επεξεργαστείτε το αποτέλεσμα πριν το στείλετε.',
142
+ 'ai.goal': 'Στόχος',
143
+ 'ai.tone': 'Τόνος',
144
+ 'ai.briefLabel': 'Για τι αφορά αυτό το email;',
145
+ 'ai.briefPlaceholder': 'π.χ. Φθινοπωρινή συλλογή, 15% για συνδρομητές, δωρεάν αποστολή άνω των 150€',
146
+ 'ai.generate': 'Δημιουργία κειμένου',
147
+ 'ai.writing': 'Γίνεται συγγραφή…',
148
+ 'ai.kindHeadline': 'Τίτλος',
149
+ 'ai.kindBody': 'Κύριο κείμενο',
150
+ 'ai.kindButton': 'Κείμενο κουμπιού',
151
+ 'ai.actionInsertHeading': 'Εισαγωγή ως τίτλος',
152
+ 'ai.actionInsertText': 'Εισαγωγή ως μπλοκ κειμένου',
153
+ 'ai.actionInsertButton': 'Εισαγωγή ως κουμπί',
154
+ 'toast.headingAdded': 'Ο τίτλος προστέθηκε',
155
+ 'toast.textBlockAdded': 'Το μπλοκ κειμένου προστέθηκε',
156
+ 'toast.buttonAdded': 'Το κουμπί προστέθηκε',
157
+ 'preview.kickerMobile': 'Προεπισκόπηση — κινητό 375px',
158
+ 'preview.kickerDesktop': 'Προεπισκόπηση — υπολογιστής {width}px',
159
+ 'action.close': 'Κλείσιμο',
160
+ 'toast.duplicated': 'Διπλασιάστηκε',
161
+ 'toast.fileUploadedOne': '1 αρχείο μεταφορτώθηκε',
162
+ 'toast.fileUploadedMany': '{count} αρχεία μεταφορτώθηκαν',
163
+ 'toast.imageReplaced': 'Η εικόνα αντικαταστάθηκε',
164
+ 'toast.imageAdded': 'Η εικόνα προστέθηκε στον καμβά',
165
+ 'toast.htmlCopied': 'Το HTML αντιγράφηκε στο πρόχειρο',
166
+ 'toast.templateLoaded': 'Το {name} φορτώθηκε',
167
+ 'toast.snippetDefaultLabel': 'Απόσπασμα',
168
+ 'toast.snippetInserted': 'Το {name} εισήχθη',
169
+ 'toast.snippetCopied': 'Το {name} αντιγράφηκε — επιλέξτε ένα μπλοκ κειμένου για να το εισαγάγετε',
170
+ 'rte.textStyle': 'Στυλ κειμένου',
171
+ 'rte.mergeTags': 'Πεδία συγχώνευσης',
172
+ 'rte.noMergeTags': 'Δεν υπάρχουν διαθέσιμα πεδία συγχώνευσης',
173
+ 'rte.textColor': 'Χρώμα κειμένου',
174
+ 'rte.highlightColor': 'Χρώμα επισήμανσης',
175
+ 'rte.removeHighlight': 'Αφαίρεση επισήμανσης',
176
+ 'rte.clearFormatting': 'Καθαρισμός μορφοποίησης',
177
+ 'action.downloadPng': 'Λήψη PNG',
178
+ 'action.screenshot': 'Στιγμιότυπο',
179
+ 'action.screenshotHint': 'Δείτε όλο το πρότυπο ως εικόνα και κατεβάστε το',
180
+ 'toast.pngSaved': 'Το στιγμιότυπο κατέβηκε',
181
+ 'toast.pngFailed': 'Το στιγμιότυπο απέτυχε — μια εξωτερική εικόνα δεν φορτώθηκε',
182
+ 'toast.pngCopied': 'Το στιγμιότυπο αντιγράφηκε στο πρόχειρο',
183
+ 'toast.pngCopyFailed': 'Αυτό το πρόγραμμα περιήγησης δεν δέχτηκε εικόνα στο πρόχειρο',
184
+ 'story.kicker': 'Στιγμιότυπο',
185
+ 'story.rendering': 'Δημιουργία στιγμιότυπου',
186
+ 'story.renderingHint': 'Κάθε μπλοκ σχεδιάζεται σε 2× — σε μεγάλο πρότυπο θέλει λίγη ώρα.',
187
+ 'story.failed': 'Το στιγμιότυπο απέτυχε',
188
+ 'story.failedHint': 'Μια εικόνα του προτύπου δεν φορτώθηκε για τη λήψη.',
189
+ 'story.retry': 'Δοκιμάστε ξανά',
190
+ 'story.play': 'Αναπαραγωγή',
191
+ 'story.pause': 'Παύση',
192
+ 'story.replay': 'Επανάληψη',
193
+ 'story.copy': 'Αντιγραφή',
194
+ 'story.meta': '{w}×{h} · οθόνη {i} από {n}',
195
+ 'footer.poweredBy': 'Με την υποστήριξη του SELISE Blocks © 2026',
196
+ };
@@ -21,8 +21,6 @@ export const EN = {
21
21
  'action.chromeHint': 'Light / dark editor chrome',
22
22
  'action.chromeHintToDark': 'Dark mode',
23
23
  'action.chromeHintToLight': 'Light mode',
24
- 'action.aiCopy': 'Draft',
25
- 'action.aiCopyHint': 'Draft email content with AI',
26
24
  'action.aiDraft': 'Draft',
27
25
  'action.aiDraftHint': 'Draft email content with AI',
28
26
  'action.code': 'Code',
@@ -57,9 +55,9 @@ export const EN = {
57
55
  'tab.filesHint': 'Asset library',
58
56
  'tab.layers': 'Layers',
59
57
  'tab.layersHint': 'Document structure',
60
- // Renamed keys (were tab.theme/tab.themeHint "Theme / Global styles"): new
61
- // key names on purpose, so locales that still carry the old translation
62
- // fall back to this English name instead of showing the stale "Theme".
58
+ // Renamed from tab.theme/tab.themeHint ("Theme / Global styles") when the
59
+ // panel stopped being about theming alone. Every shipped locale translates
60
+ // the new names; test/system.test.mjs fails if one falls back to English.
63
61
  'tab.settings': 'Settings',
64
62
  'tab.settingsHint': 'Email settings',
65
63
  'tab.data': 'Variables',
@@ -112,9 +110,6 @@ export const EN = {
112
110
  'layers.column': 'Column {index}',
113
111
  'layers.blockCount': '{count} blocks',
114
112
 
115
- // Theme tab
116
- 'theme.globalStyles': 'Global styles',
117
-
118
113
  // Data (Vars) tab
119
114
  'vars.title': 'Variables',
120
115
  'vars.fromCode': '{count} from your code',
@@ -190,8 +185,6 @@ export const EN = {
190
185
  'toast.parseError': 'Could not parse that HTML',
191
186
 
192
187
  // AI copy modal
193
- 'modal.copyAssist': 'AI writing assistant',
194
- 'modal.draftCopyTitle': 'Draft your email with AI',
195
188
  'modal.aiDraft': 'AI writing assistant',
196
189
  'modal.aiDraftTitle': 'Draft your email with AI',
197
190
  'ai.disclosure': 'AI creates suggestions from your brief. Review and edit the result before sending.',