@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
- /** Italian (Italiano) — `it`. AI-drafted, not reviewed by a native speaker. Correctable one key at a time via `.messages` overrides. */
2
- export const IT = {
3
- 'action.undoHint': 'Annulla — ⌘Z',
4
- 'action.redoHint': 'Ripeti — ⌘⇧Z',
5
- 'action.chromeToDark': 'Scuro',
6
- 'action.chromeToLight': 'Chiaro',
7
- 'action.chromeHint': 'Tema dell’editor chiaro / scuro',
8
- 'action.aiCopy': 'Testo',
9
- 'action.aiCopyHint': 'Scrivi il testo con l’IA',
10
- 'action.code': 'Codice',
11
- 'action.codeHint': 'Modifica lHTML grezzo con anteprima dal vivo',
12
- 'action.preview': 'Anteprima',
13
- 'action.export': 'Esporta',
14
- 'device.desktop': 'Desktop',
15
- 'device.desktopHint': 'Larghezza desktop',
16
- 'device.mobile': 'Mobile',
17
- 'device.mobileHint': 'Larghezza mobile',
18
- 'device.dark': 'Scuro',
19
- 'device.darkHint': 'Posta in arrivo scura',
20
- 'status.autosaveOn': 'salvataggio automatico attivo',
21
- 'status.saved': 'salvato {time}',
22
- 'status.saveFailed': 'non salvato — spazio esaurito',
23
- 'canvas.meta': '{rows} righe · {blocks} blocchi · {width}px',
24
- 'tab.design': 'Stile',
25
- 'tab.designHint': 'Applica stile alla selezione',
26
- 'tab.blocks': 'Blocchi',
27
- 'tab.blocksHint': 'Blocchi di contenuto e variabili',
28
- 'tab.rows': 'Sez.',
29
- 'tab.rowsHint': 'Layout delle sezioni e modello del canvas',
30
- 'tab.files': 'File',
31
- 'tab.filesHint': 'Libreria risorse',
32
- 'tab.layers': 'Struttura',
33
- 'tab.layersHint': 'Struttura del documento',
34
- 'tab.theme': 'Tema',
35
- 'tab.themeHint': 'Stili globali',
36
- 'tab.data': 'Var.',
37
- 'tab.dataHint': 'Variabili fornite dal tuo codice',
38
- 'inspector.blockProperties': 'Proprietà del blocco',
39
- 'inspector.sectionProperties': 'Proprietà della sezione',
40
- 'inspector.title': 'Ispettore',
41
- 'inspector.sectionLabel': 'Sezione',
42
- 'inspector.nothingSelected': 'Nessuna selezione',
43
- 'action.duplicateHint': 'Duplica — ⌘D',
44
- 'action.deleteHint': 'Elimina — ⌫',
45
- 'inspector.emptyBody':
46
- 'Seleziona una riga o un blocco sul canvas per applicarne lo stile qui. Trascina i blocchi dalla scheda <strong style="color: var(--ed-text); font-weight: 600;">Blocchi</strong>; fai doppio clic su un testo per modificarlo direttamente.',
47
- 'inspector.shortcuts': 'Scorciatoie',
48
- 'shortcut.undoRedo': '⌘Z / ⌘⇧Z annulla, ripeti',
49
- 'shortcut.duplicate': '⌘D — duplica selezione',
50
- 'shortcut.delete': 'elimina selezione',
51
- 'shortcut.export': '⌘Eesporta HTML',
52
- 'shortcut.escape': 'ESCdeseleziona, chiudi',
53
- 'blocks.dragHint': 'Trascina sul canvas',
54
- 'blocks.count': '{count} blocchi',
55
- 'rows.sectionLayouts': 'Layout delle sezioni',
56
- 'rows.customMarkup': 'Markup personalizzato',
57
- 'rows.htmlRowHint': 'Trascina per inserire, o clicca per aggiungere — una riga a piena larghezza da riempire con HTML grezzo',
58
- 'rows.rawHtmlSection': 'Sezione HTML grezzo',
59
- 'rows.rawHtmlDesc': 'Sezione a piena larghezza, il tuo markup, ancora trascinabile',
60
- 'rows.canvasModel': 'Modello del canvas',
61
- 'rows.modeRowBased': 'Basato su righe',
62
- 'rows.modeFreeStack': 'Pila libera',
63
- 'rows.hintRows':
64
- 'Basato su sezioni: rilascia prima un layout, poi i blocchi nelle sue colonne — ogni sezione ha proprio sfondo, bordo, impostazioni flex o griglia.',
65
- 'rows.hintStack': 'Pila libera: senza layout — ogni blocco rilasciato diventa una propria sezione a piena larghezza, impilata in ordine.',
66
- 'files.libraryCount': 'Libreria{count} file',
67
- 'files.openManager': 'Apri gestione file',
68
- 'files.dragToCanvas': 'Trascina un qualsiasi file direttamente sul canvas per inserirlo come blocco immagine.',
69
- 'layers.structure': 'Struttura',
70
- 'layers.sectionSingle': 'Sezione',
71
- 'layers.sectionMulti': 'Sezione · {count} col.',
72
- 'layers.blockCount': '{count} bl.',
73
- 'theme.globalStyles': 'Stili globali',
74
- 'vars.title': 'Variabili',
75
- 'vars.fromCode': '{count} dal tuo codice',
76
- 'vars.declaredNote': 'Dichiarate dalla tua applicazione — il canvas mostra sempre il token, mai un valore.',
77
- 'vars.filterPlaceholder': 'Filtra variabili…',
78
- 'vars.insertHint': 'Clicca per inserire nel testo, titolo o pulsante selezionato',
79
- 'vars.insert': 'inserisci',
80
- 'vars.noMatch': 'Nessuna variabile corrisponde a questo filtro.',
81
- 'vars.noneDeclared': 'La tua applicazione non ha ancora dichiarato variabili.',
82
- 'vars.rteHint': 'Durante la modifica del testo puoi anche scegliere una variabile direttamente dal menu della barra degli strumenti in linea.',
83
- 'modal.fileManager': 'Gestione file',
84
- 'modal.assetsTitle': 'Risorse',
85
- 'modal.replaceImage': 'Sostituisci immagine',
86
- 'library.searchPlaceholder': 'Cerca file…',
87
- 'action.upload': 'Carica',
88
- 'library.clickToPlace': 'Clicca su un file per posizionarlo · o trascina un file sul canvas',
89
- 'library.clickToReplace': 'Clicca su un file per sostituire l’immagine selezionata',
90
- 'library.storageLabel': '{count} file · {size}',
91
- 'library.folders': 'Cartelle',
92
- 'library.dropHint': 'Rilascia qui i file immagine per caricarli — oppure usa il pulsante Carica.',
93
- 'library.deleteFileHint': 'Elimina file',
94
- 'library.del': 'ELIM',
95
- 'toast.assetDeleted': '{name} eliminato',
96
- 'modal.export': 'Esporta',
97
- 'modal.exportTitle': 'HTML email basato su tabelle',
98
- 'export.copy': 'Copia',
99
- 'export.copied': 'Copiato',
100
- 'action.download': 'Scarica',
101
- 'export.meta': '{kb} KB · tabelle + stili inline · larghezze sicure per Outlook',
102
- 'modal.rawHtmlTitle': 'HTML grezzo, anteprima dal vivo',
103
- 'code.statusEdited': 'Vista codice modificatoanteprima dal vivo, non ancora applicato',
104
- 'code.statusSynced': 'Vista codice sincronizzato con il canvas',
105
- 'action.reload': 'Ricarica',
106
- 'action.reloadHint': 'Ricarica il sorgente dal canvas',
107
- 'action.applyToCanvas': 'Applica al canvas',
108
- 'action.applyToCanvasHint': 'Analizza il sorgente riconvertendolo in righe modificabili',
109
- 'action.closeWithoutApplyingHint': 'Chiudi senza applicare',
110
- 'code.source': 'Sorgente',
111
- 'code.livePreview': 'Anteprima dal vivo',
112
- 'code.liveHtmlPreviewTitle': 'Anteprima HTML dal vivo',
113
- 'code.applyNote':
114
- 'Applica converte ogni riga di tabella di primo livello in una riga del canvas ancora selezionabile, riordinabile ed eliminabile il markup scritto a mano resta intatto.',
115
- 'code.meta': '{kb} KB · {lines} righe',
116
- 'toast.sourceReloaded': 'Sorgente ricaricato dal canvas',
117
- 'toast.sourceAppliedOne': 'Sorgente applicato — 1 riga sul canvas',
118
- 'toast.sourceAppliedMany': 'Sorgente applicato — {rows} righe sul canvas',
119
- 'toast.parseError': 'Impossibile analizzare questo HTML',
120
- 'modal.copyAssist': 'Assistente di scrittura',
121
- 'modal.draftCopyTitle': 'Scrivi il testo per questa campagna',
122
- 'ai.goal': 'Obiettivo',
123
- 'ai.tone': 'Tono',
124
- 'ai.briefLabel': 'Di cosa parla questa email?',
125
- 'ai.briefPlaceholder': 'es. Collezione autunno, 15% per gli iscritti, spedizione gratuita oltre 150€',
126
- 'ai.generate': 'Genera testo',
127
- 'ai.writing': 'Scrittura in corso…',
128
- 'ai.kindHeadline': 'Titolo',
129
- 'ai.kindBody': 'Corpo del testo',
130
- 'ai.kindButton': 'Testo del pulsante',
131
- 'ai.actionInsertHeading': 'Inserisci come titolo',
132
- 'ai.actionInsertText': 'Inserisci come blocco di testo',
133
- 'ai.actionInsertButton': 'Inserisci come pulsante',
134
- 'toast.headingAdded': 'Titolo aggiunto',
135
- 'toast.textBlockAdded': 'Blocco di testo aggiunto',
136
- 'toast.buttonAdded': 'Pulsante aggiunto',
137
- 'preview.kickerMobile': 'Anteprimamobile 375px',
138
- 'preview.kickerDark': 'Anteprima posta scura',
139
- 'preview.kickerDesktop': 'Anteprima desktop {width}px',
140
- 'action.close': 'Chiudi',
141
- 'toast.duplicated': 'Duplicato',
142
- 'toast.fileUploadedOne': '1 file caricato',
143
- 'toast.fileUploadedMany': '{count} file caricati',
144
- 'toast.imageReplaced': 'Immagine sostituita',
145
- 'toast.imageAdded': 'Immagine aggiunta al canvas',
146
- 'toast.htmlCopied': 'HTML copiato negli appunti',
147
- 'toast.templateLoaded': '{name} caricato',
148
- 'toast.snippetDefaultLabel': 'Snippet',
149
- 'toast.snippetInserted': '{name} inserito',
150
- 'toast.snippetCopied': '{name} copiato — seleziona un blocco di testo per inserirlo',
151
- };
152
-
1
+ /** Italian (Italiano) — `it`. AI-drafted, not reviewed by a native speaker. Correctable one key at a time via `.messages` overrides. */
2
+ export const IT = {
3
+ 'action.undoHint': 'Annulla — ⌘Z',
4
+ 'action.redoHint': 'Ripeti — ⌘⇧Z',
5
+ 'action.chromeToDark': 'Scuro',
6
+ 'action.chromeToLight': 'Chiaro',
7
+ 'action.chromeHint': 'Tema dell’editor chiaro / scuro',
8
+ 'action.chromeHintToDark': 'Modalità scura',
9
+ 'action.chromeHintToLight': 'Modalità chiara',
10
+ 'action.aiDraft': 'Bozza',
11
+ 'action.aiDraftHint': 'Scrivere il contenuto dellemail con l’IA',
12
+ 'action.code': 'Codice',
13
+ 'action.codeHint': 'Modifica l’HTML grezzo con anteprima dal vivo',
14
+ 'action.preview': 'Anteprima',
15
+ 'action.previewHint': 'Anteprima dell’email',
16
+ 'action.export': 'Esporta',
17
+ 'action.exportHint': 'Esporta la tua email',
18
+ 'device.desktop': 'Desktop',
19
+ 'device.desktopHint': 'Larghezza desktop',
20
+ 'device.mobile': 'Mobile',
21
+ 'device.mobileHint': 'Larghezza mobile',
22
+ 'status.autosaveOn': 'salvataggio automatico attivo',
23
+ 'status.saved': 'salvato {time}',
24
+ 'status.saveFailed': 'non salvato — spazio esaurito',
25
+ 'canvas.meta': '{rows} righe · {blocks} blocchi · {width}px',
26
+ 'tab.design': 'Stile',
27
+ 'tab.designHint': 'Applica stile alla selezione',
28
+ 'tab.blocks': 'Blocchi',
29
+ 'tab.blocksHint': 'Blocchi di contenuto e variabili',
30
+ 'tab.rows': 'Sez.',
31
+ 'tab.rowsHint': 'Layout delle sezioni e modello del canvas',
32
+ 'tab.files': 'File',
33
+ 'tab.filesHint': 'Libreria risorse',
34
+ 'tab.layers': 'Struttura',
35
+ 'tab.layersHint': 'Struttura del documento',
36
+ 'tab.settings': 'Impostazioni',
37
+ 'tab.settingsHint': 'Impostazioni dell’email',
38
+ 'tab.data': 'Var.',
39
+ 'tab.dataHint': 'Variabili fornite dal tuo codice',
40
+ 'inspector.blockProperties': 'Proprietà del blocco',
41
+ 'inspector.sectionProperties': 'Proprietà della sezione',
42
+ 'inspector.title': 'Ispettore',
43
+ 'inspector.sectionLabel': 'Sezione',
44
+ 'inspector.nothingSelected': 'Nessuna selezione',
45
+ 'action.duplicateHint': 'Duplica — ⌘D',
46
+ 'action.deleteHint': 'Elimina ',
47
+ 'inspector.emptyBody':
48
+ 'Seleziona una riga o un blocco sul canvas per applicarne lo stile qui. Trascina i blocchi dalla scheda <strong style="color: var(--ed-text); font-weight: 600;">Blocchi</strong>; fai doppio clic su un testo per modificarlo direttamente.',
49
+ 'inspector.shortcuts': 'Scorciatoie',
50
+ 'shortcut.undoRedo': '⌘Z / ⌘⇧Z annulla, ripeti',
51
+ 'shortcut.duplicate': '⌘Dduplica selezione',
52
+ 'shortcut.delete': 'elimina selezione',
53
+ 'shortcut.export': '⌘E esporta HTML',
54
+ 'shortcut.escape': 'ESC — deseleziona, chiudi',
55
+ 'blocks.dragHint': 'Trascina sul canvas',
56
+ 'blocks.count': '{count} blocchi',
57
+ 'rows.sectionLayouts': 'Layout delle sezioni',
58
+ 'rows.customMarkup': 'Markup personalizzato',
59
+ 'rows.htmlRowHint': 'Trascina per inserire, o clicca per aggiungere — una riga a piena larghezza da riempire con HTML grezzo',
60
+ 'rows.rawHtmlSection': 'Sezione HTML grezzo',
61
+ 'rows.rawHtmlDesc': 'Sezione a piena larghezza, il tuo markup, ancora trascinabile',
62
+ 'rows.canvasModel': 'Modello del canvas',
63
+ 'rows.modeRowBased': 'Basato su righe',
64
+ 'rows.modeFreeStack': 'Pila libera',
65
+ 'rows.hintRows':
66
+ 'Basato su sezioni: rilascia prima un layout, poi i blocchi nelle sue colonne ogni sezione ha proprio sfondo, bordo, impostazioni flex o griglia.',
67
+ 'rows.hintStack': 'Pila libera: senza layout — ogni blocco rilasciato diventa una propria sezione a piena larghezza, impilata in ordine.',
68
+ 'files.libraryCount': 'Libreria {count} file',
69
+ 'files.openManager': 'Apri gestione file',
70
+ 'files.dragToCanvas': 'Trascina un qualsiasi file direttamente sul canvas per inserirlo come blocco immagine.',
71
+ 'layers.structure': 'Struttura',
72
+ 'layers.sectionSingle': 'Sezione',
73
+ 'layers.sectionMulti': 'Sezione · {count} col.',
74
+ 'layers.column': 'Colonna {index}',
75
+ 'layers.blockCount': '{count} bl.',
76
+ 'vars.title': 'Variabili',
77
+ 'vars.fromCode': '{count} dal tuo codice',
78
+ 'vars.declaredNote': 'Dichiarate dalla tua applicazione — il canvas mostra sempre il token, mai un valore.',
79
+ 'vars.filterPlaceholder': 'Filtra variabili…',
80
+ 'vars.insertHint': 'Clicca per inserire nel testo, titolo o pulsante selezionato',
81
+ 'vars.insert': 'inserisci',
82
+ 'vars.noMatch': 'Nessuna variabile corrisponde a questo filtro.',
83
+ 'vars.noneDeclared': 'La tua applicazione non ha ancora dichiarato variabili.',
84
+ 'vars.rteHint': 'Durante la modifica del testo puoi anche scegliere una variabile direttamente dal menu della barra degli strumenti in linea.',
85
+ 'modal.fileManager': 'Gestione file',
86
+ 'modal.assetsTitle': 'Risorse',
87
+ 'modal.replaceImage': 'Sostituisci immagine',
88
+ 'library.searchPlaceholder': 'Cerca file',
89
+ 'action.upload': 'Carica',
90
+ 'library.clickToPlace': 'Clicca su un file per posizionarlo · o trascina un file sul canvas',
91
+ 'library.clickToReplace': 'Clicca su un file per sostituire l’immagine selezionata',
92
+ 'library.storageLabel': '{count} file · {size}',
93
+ 'library.folders': 'Cartelle',
94
+ 'library.dropHint': 'Rilascia qui i file immagine per caricarli — oppure usa il pulsante Carica.',
95
+ 'library.deleteFileHint': 'Elimina file',
96
+ 'library.del': 'ELIM',
97
+ 'toast.assetDeleted': '{name} eliminato',
98
+ 'library.allFiles': 'Tutti i file',
99
+ 'library.loadMore': 'Carica altri',
100
+ 'library.empty': 'Qui non ci sono ancora file.',
101
+ 'storage.loading': 'Caricamento dei file…',
102
+ 'storage.uploading': 'Caricamento di {count}…',
103
+ 'storage.errLoadFailed': 'Impossibile caricare la libreria file {reason}',
104
+ 'storage.errNoLimits': 'I caricamenti sono disattivati: questa applicazione non ha impostato limiti di caricamento.',
105
+ 'storage.errNoAccept': 'I caricamenti sono disattivati: nessun formato di file è stato consentito.',
106
+ 'storage.errNoMaxBytes': 'I caricamenti sono disattivati: non è stata impostata una dimensione massima del file.',
107
+ 'storage.errTooLarge': '{name} è {size} — il limite è {max}.',
108
+ 'storage.errFormat': '{name} è un file {type}, non consentito qui.',
109
+ 'storage.errSvg': '{name} è un SVG, che questa applicazione non accetta.',
110
+ 'storage.errDimensions': '{name} è {w}×{ht}px — il limite è {maxW}×{maxH}px.',
111
+ 'storage.errTooMany': 'Si possono caricare solo {max} file alla volta.',
112
+ 'storage.errUnreadable': '{name} non è un’immagine leggibile.',
113
+ 'storage.errUploadFailed': 'Impossibile caricare {name} — {reason}',
114
+ 'storage.errDeleteFailed': 'Impossibile eliminare {name}{reason}',
115
+ 'modal.export': 'Esporta',
116
+ 'modal.exportTitle': 'HTML email basato su tabelle',
117
+ 'export.copy': 'Copia',
118
+ 'export.copied': 'Copiato',
119
+ 'action.download': 'Scarica',
120
+ 'export.meta': '{kb} KB · tabelle + stili inline · larghezze sicure per Outlook',
121
+ 'modal.rawHtmlTitle': 'HTML grezzo, anteprima dal vivo',
122
+ 'code.statusEdited': 'Vista codice — modificato — anteprima dal vivo, non ancora applicato',
123
+ 'code.statusSynced': 'Vista codice — sincronizzato con il canvas',
124
+ 'action.reload': 'Ricarica',
125
+ 'action.reloadHint': 'Ricarica il sorgente dal canvas',
126
+ 'action.applyToCanvas': 'Applica al canvas',
127
+ 'action.applyToCanvasHint': 'Analizza il sorgente riconvertendolo in righe modificabili',
128
+ 'action.closeWithoutApplyingHint': 'Chiudi senza applicare',
129
+ 'code.source': 'Sorgente',
130
+ 'code.livePreview': 'Anteprima dal vivo',
131
+ 'code.liveHtmlPreviewTitle': 'Anteprima HTML dal vivo',
132
+ 'code.applyNote':
133
+ 'Applica converte ogni riga di tabella di primo livello in una riga del canvas ancora selezionabile, riordinabile ed eliminabile — il markup scritto a mano resta intatto.',
134
+ 'code.meta': '{kb} KB · {lines} righe',
135
+ 'toast.sourceReloaded': 'Sorgente ricaricato dal canvas',
136
+ 'toast.sourceAppliedOne': 'Sorgente applicato — 1 riga sul canvas',
137
+ 'toast.sourceAppliedMany': 'Sorgente applicato {rows} righe sul canvas',
138
+ 'toast.parseError': 'Impossibile analizzare questo HTML',
139
+ 'modal.aiDraft': 'Assistente di scrittura IA',
140
+ 'modal.aiDraftTitle': 'Scrivi la tua email con l’IA',
141
+ 'ai.disclosure': 'L’IA crea suggerimenti a partire dal tuo brief. Rivedi e modifica il risultato prima di inviarlo.',
142
+ 'ai.goal': 'Obiettivo',
143
+ 'ai.tone': 'Tono',
144
+ 'ai.briefLabel': 'Di cosa parla questa email?',
145
+ 'ai.briefPlaceholder': 'es. Collezione autunno, 15% per gli iscritti, spedizione gratuita oltre 150€',
146
+ 'ai.generate': 'Genera testo',
147
+ 'ai.writing': 'Scrittura in corso…',
148
+ 'ai.kindHeadline': 'Titolo',
149
+ 'ai.kindBody': 'Corpo del testo',
150
+ 'ai.kindButton': 'Testo del pulsante',
151
+ 'ai.actionInsertHeading': 'Inserisci come titolo',
152
+ 'ai.actionInsertText': 'Inserisci come blocco di testo',
153
+ 'ai.actionInsertButton': 'Inserisci come pulsante',
154
+ 'toast.headingAdded': 'Titolo aggiunto',
155
+ 'toast.textBlockAdded': 'Blocco di testo aggiunto',
156
+ 'toast.buttonAdded': 'Pulsante aggiunto',
157
+ 'preview.kickerMobile': 'Anteprima — mobile 375px',
158
+ 'preview.kickerDesktop': 'Anteprima — desktop {width}px',
159
+ 'action.close': 'Chiudi',
160
+ 'toast.duplicated': 'Duplicato',
161
+ 'toast.fileUploadedOne': '1 file caricato',
162
+ 'toast.fileUploadedMany': '{count} file caricati',
163
+ 'toast.imageReplaced': 'Immagine sostituita',
164
+ 'toast.imageAdded': 'Immagine aggiunta al canvas',
165
+ 'toast.htmlCopied': 'HTML copiato negli appunti',
166
+ 'toast.templateLoaded': '{name} caricato',
167
+ 'toast.snippetDefaultLabel': 'Snippet',
168
+ 'toast.snippetInserted': '{name} inserito',
169
+ 'toast.snippetCopied': '{name} copiato — seleziona un blocco di testo per inserirlo',
170
+ 'rte.textStyle': 'Stile del testo',
171
+ 'rte.mergeTags': 'Campi di unione',
172
+ 'rte.noMergeTags': 'Nessun campo di unione disponibile',
173
+ 'rte.textColor': 'Colore del testo',
174
+ 'rte.highlightColor': 'Colore evidenziazione',
175
+ 'rte.removeHighlight': 'Rimuovi evidenziazione',
176
+ 'rte.clearFormatting': 'Cancella formattazione',
177
+ 'action.downloadPng': 'Scarica PNG',
178
+ 'action.screenshot': 'Screenshot',
179
+ 'action.screenshotHint': 'Vedi l’intero modello come immagine e scaricalo',
180
+ 'toast.pngSaved': 'Screenshot scaricato',
181
+ 'toast.pngFailed': 'Screenshot non riuscito — un’immagine esterna non è stata caricata',
182
+ 'toast.pngCopied': 'Screenshot copiato negli appunti',
183
+ 'toast.pngCopyFailed': 'Questo browser non ha accettato un’immagine negli appunti',
184
+ 'story.kicker': 'Screenshot',
185
+ 'story.rendering': 'Creazione dello screenshot',
186
+ 'story.renderingHint': 'Ogni blocco viene disegnato a 2× — con un modello lungo richiede un momento.',
187
+ 'story.failed': 'Screenshot non riuscito',
188
+ 'story.failedHint': 'Un’immagine del modello non è stata caricata per l’acquisizione.',
189
+ 'story.retry': 'Riprova',
190
+ 'story.play': 'Riproduci',
191
+ 'story.pause': 'Pausa',
192
+ 'story.replay': 'Riproduci di nuovo',
193
+ 'story.copy': 'Copia',
194
+ 'story.meta': '{w}×{h} · schermata {i} di {n}',
195
+ 'footer.poweredBy': 'Con tecnologia SELISE Blocks © 2026',
196
+ };