@seliseblocks/mailcraft 0.1.1 → 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 +238 -10
  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 +234 -22
  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
- /** Portuguese (Português) — `pt`. AI-drafted, not reviewed by a native speaker. Correctable one key at a time via `.messages` overrides. */
2
- export const PT = {
3
- 'action.undoHint': 'Desfazer — ⌘Z',
4
- 'action.redoHint': 'Refazer — ⌘⇧Z',
5
- 'action.chromeToDark': 'Escuro',
6
- 'action.chromeToLight': 'Claro',
7
- 'action.chromeHint': 'Tema do editor claro / escuro',
8
- 'action.aiCopy': 'Texto',
9
- 'action.aiCopyHint': 'Redigir texto com IA',
10
- 'action.code': 'Código',
11
- 'action.codeHint': 'Editar o HTML bruto com pré-visualização ao vivo',
12
- 'action.preview': 'Pré-visualizar',
13
- 'action.export': 'Exportar',
14
- 'device.desktop': 'Desktop',
15
- 'device.desktopHint': 'Largura desktop',
16
- 'device.mobile': 'Móvel',
17
- 'device.mobileHint': 'Largura móvel',
18
- 'device.dark': 'Escuro',
19
- 'device.darkHint': 'Caixa de entrada escura',
20
- 'status.autosaveOn': 'salvamento automático ativado',
21
- 'status.saved': 'salvo {time}',
22
- 'status.saveFailed': 'não salvo — armazenamento cheio',
23
- 'canvas.meta': '{rows} linhas · {blocks} blocos · {width}px',
24
- 'tab.design': 'Estilo',
25
- 'tab.designHint': 'Estilizar a seleção',
26
- 'tab.blocks': 'Blocos',
27
- 'tab.blocksHint': 'Blocos de conteúdo e variáveis',
28
- 'tab.rows': 'Seções',
29
- 'tab.rowsHint': 'Layouts de seção e modelo de tela',
30
- 'tab.files': 'Arquivos',
31
- 'tab.filesHint': 'Biblioteca de recursos',
32
- 'tab.layers': 'Estrutura',
33
- 'tab.layersHint': 'Estrutura do documento',
34
- 'tab.theme': 'Tema',
35
- 'tab.themeHint': 'Estilos globais',
36
- 'tab.data': 'Var.',
37
- 'tab.dataHint': 'Variáveis fornecidas pelo seu código',
38
- 'inspector.blockProperties': 'Propriedades do bloco',
39
- 'inspector.sectionProperties': 'Propriedades da seção',
40
- 'inspector.title': 'Inspetor',
41
- 'inspector.sectionLabel': 'Seção',
42
- 'inspector.nothingSelected': 'Nada selecionado',
43
- 'action.duplicateHint': 'Duplicar — ⌘D',
44
- 'action.deleteHint': 'Excluir — ⌫',
45
- 'inspector.emptyBody':
46
- 'Selecione uma linha ou um bloco na tela para estilizá-lo aqui. Arraste blocos da aba <strong style="color: var(--ed-text); font-weight: 600;">Blocos</strong>; clique duas vezes em qualquer texto para editá-lo diretamente.',
47
- 'inspector.shortcuts': 'Atalhos',
48
- 'shortcut.undoRedo': '⌘Z / ⌘⇧Z desfazer, refazer',
49
- 'shortcut.duplicate': '⌘D — duplicar seleção',
50
- 'shortcut.delete': 'excluir seleção',
51
- 'shortcut.export': '⌘Eexportar HTML',
52
- 'shortcut.escape': 'ESCdesmarcar, fechar',
53
- 'blocks.dragHint': 'Arraste para a tela',
54
- 'blocks.count': '{count} blocos',
55
- 'rows.sectionLayouts': 'Layouts de seção',
56
- 'rows.customMarkup': 'Marcação personalizada',
57
- 'rows.htmlRowHint': 'Arraste para inserir, ou clique para adicionar — uma linha de sangria total que você preenche com HTML bruto',
58
- 'rows.rawHtmlSection': 'Seção de HTML bruto',
59
- 'rows.rawHtmlDesc': 'Seção de sangria total, sua própria marcação, ainda arrastável',
60
- 'rows.canvasModel': 'Modelo de tela',
61
- 'rows.modeRowBased': 'Baseado em linhas',
62
- 'rows.modeFreeStack': 'Pilha livre',
63
- 'rows.hintRows':
64
- 'Baseado em seções: solte um layout primeiro, depois blocos em suas colunas — cada seção tem seu próprio fundo, borda, configurações flex ou grade.',
65
- 'rows.hintStack': 'Pilha livre: sem layouts — cada bloco que você solta se torna sua própria seção de largura total, empilhada em ordem.',
66
- 'files.libraryCount': 'Biblioteca{count} arquivos',
67
- 'files.openManager': 'Abrir gerenciador de arquivos',
68
- 'files.dragToCanvas': 'Arraste qualquer arquivo diretamente para a tela para colocá-lo como bloco de imagem.',
69
- 'layers.structure': 'Estrutura',
70
- 'layers.sectionSingle': 'Seção',
71
- 'layers.sectionMulti': 'Seção · {count} col.',
72
- 'layers.blockCount': '{count} bl.',
73
- 'theme.globalStyles': 'Estilos globais',
74
- 'vars.title': 'Variáveis',
75
- 'vars.fromCode': '{count} do seu código',
76
- 'vars.declaredNote': 'Declaradas pela sua aplicação — a tela sempre mostra o token, nunca um valor.',
77
- 'vars.filterPlaceholder': 'Filtrar variáveis…',
78
- 'vars.insertHint': 'Clique para inserir no texto, título ou botão selecionado',
79
- 'vars.insert': 'inserir',
80
- 'vars.noMatch': 'Nenhuma variável corresponde a esse filtro.',
81
- 'vars.noneDeclared': 'Sua aplicação ainda não declarou nenhuma variável.',
82
- 'vars.rteHint': 'Ao editar texto, você também pode escolher uma variável diretamente no menu da barra de ferramentas em linha.',
83
- 'modal.fileManager': 'Gerenciador de arquivos',
84
- 'modal.assetsTitle': 'Recursos',
85
- 'modal.replaceImage': 'Substituir imagem',
86
- 'library.searchPlaceholder': 'Pesquisar arquivos…',
87
- 'action.upload': 'Enviar',
88
- 'library.clickToPlace': 'Clique em um arquivo para posicioná-lo · ou arraste um arquivo para a tela',
89
- 'library.clickToReplace': 'Clique em um arquivo para substituir a imagem selecionada',
90
- 'library.storageLabel': '{count} arquivos · {size}',
91
- 'library.folders': 'Pastas',
92
- 'library.dropHint': 'Solte arquivos de imagem aqui para enviá-los — ou use o botão Enviar.',
93
- 'library.deleteFileHint': 'Excluir arquivo',
94
- 'library.del': 'EXCL',
95
- 'toast.assetDeleted': '{name} excluído',
96
- 'modal.export': 'Exportar',
97
- 'modal.exportTitle': 'HTML de e-mail baseado em tabelas',
98
- 'export.copy': 'Copiar',
99
- 'export.copied': 'Copiado',
100
- 'action.download': 'Baixar',
101
- 'export.meta': '{kb} KB · tabelas + estilos inline · larguras seguras para o Outlook',
102
- 'modal.rawHtmlTitle': 'HTML bruto, pré-visualização ao vivo',
103
- 'code.statusEdited': 'Visualização de código editado pré-visualização ao vivo, ainda não aplicado',
104
- 'code.statusSynced': 'Visualização de código sincronizado com a tela',
105
- 'action.reload': 'Recarregar',
106
- 'action.reloadHint': 'Recarregar a origem a partir da tela',
107
- 'action.applyToCanvas': 'Aplicar à tela',
108
- 'action.applyToCanvasHint': 'Analisar a origem novamente em linhas editáveis',
109
- 'action.closeWithoutApplyingHint': 'Fechar sem aplicar',
110
- 'code.source': 'Origem',
111
- 'code.livePreview': 'Pré-visualização ao vivo',
112
- 'code.liveHtmlPreviewTitle': 'Pré-visualização de HTML ao vivo',
113
- 'code.applyNote':
114
- 'Aplicar analisa cada linha de tabela de nível superior em uma linha de tela que você ainda pode selecionar, reordenar e excluir a marcação escrita à mão sobrevive ao processo.',
115
- 'code.meta': '{kb} KB · {lines} linhas',
116
- 'toast.sourceReloaded': 'Origem recarregada a partir da tela',
117
- 'toast.sourceAppliedOne': 'Origem aplicada — 1 linha na tela',
118
- 'toast.sourceAppliedMany': 'Origem aplicada — {rows} linhas na tela',
119
- 'toast.parseError': 'Não foi possível analisar esse HTML',
120
- 'modal.copyAssist': 'Assistente de redação',
121
- 'modal.draftCopyTitle': 'Redigir texto para esta campanha',
122
- 'ai.goal': 'Objetivo',
123
- 'ai.tone': 'Tom',
124
- 'ai.briefLabel': 'Sobre o que é este e-mail?',
125
- 'ai.briefPlaceholder': 'ex. Coleção de outono, 15% para assinantes, frete grátis acima de R$150',
126
- 'ai.generate': 'Gerar texto',
127
- 'ai.writing': 'Escrevendo…',
128
- 'ai.kindHeadline': 'Título',
129
- 'ai.kindBody': 'Corpo do texto',
130
- 'ai.kindButton': 'Texto do botão',
131
- 'ai.actionInsertHeading': 'Inserir como título',
132
- 'ai.actionInsertText': 'Inserir como bloco de texto',
133
- 'ai.actionInsertButton': 'Inserir como botão',
134
- 'toast.headingAdded': 'Título adicionado',
135
- 'toast.textBlockAdded': 'Bloco de texto adicionado',
136
- 'toast.buttonAdded': 'Botão adicionado',
137
- 'preview.kickerMobile': 'Pré-visualizaçãomóvel 375px',
138
- 'preview.kickerDark': 'Pré-visualização caixa escura',
139
- 'preview.kickerDesktop': 'Pré-visualização desktop {width}px',
140
- 'action.close': 'Fechar',
141
- 'toast.duplicated': 'Duplicado',
142
- 'toast.fileUploadedOne': '1 arquivo enviado',
143
- 'toast.fileUploadedMany': '{count} arquivos enviados',
144
- 'toast.imageReplaced': 'Imagem substituída',
145
- 'toast.imageAdded': 'Imagem adicionada à tela',
146
- 'toast.htmlCopied': 'HTML copiado para a área de transferência',
147
- 'toast.templateLoaded': '{name} carregado',
148
- 'toast.snippetDefaultLabel': 'Trecho',
149
- 'toast.snippetInserted': '{name} inserido',
150
- 'toast.snippetCopied': '{name} copiado — selecione um bloco de texto para inseri-lo',
151
- };
152
-
1
+ /** Portuguese (Português) — `pt`. AI-drafted, not reviewed by a native speaker. Correctable one key at a time via `.messages` overrides. */
2
+ export const PT = {
3
+ 'action.undoHint': 'Desfazer — ⌘Z',
4
+ 'action.redoHint': 'Refazer — ⌘⇧Z',
5
+ 'action.chromeToDark': 'Escuro',
6
+ 'action.chromeToLight': 'Claro',
7
+ 'action.chromeHint': 'Tema do editor claro / escuro',
8
+ 'action.chromeHintToDark': 'Modo escuro',
9
+ 'action.chromeHintToLight': 'Modo claro',
10
+ 'action.aiDraft': 'Rascunho',
11
+ 'action.aiDraftHint': 'Escrever o conteúdo do e-mail com IA',
12
+ 'action.code': 'Código',
13
+ 'action.codeHint': 'Editar o HTML bruto com pré-visualização ao vivo',
14
+ 'action.preview': 'Pré-visualizar',
15
+ 'action.previewHint': 'Pré-visualizar o e-mail',
16
+ 'action.export': 'Exportar',
17
+ 'action.exportHint': 'Exportar o seu e-mail',
18
+ 'device.desktop': 'Desktop',
19
+ 'device.desktopHint': 'Largura desktop',
20
+ 'device.mobile': 'Móvel',
21
+ 'device.mobileHint': 'Largura móvel',
22
+ 'status.autosaveOn': 'salvamento automático ativado',
23
+ 'status.saved': 'salvo {time}',
24
+ 'status.saveFailed': 'não salvo — armazenamento cheio',
25
+ 'canvas.meta': '{rows} linhas · {blocks} blocos · {width}px',
26
+ 'tab.design': 'Estilo',
27
+ 'tab.designHint': 'Estilizar a seleção',
28
+ 'tab.blocks': 'Blocos',
29
+ 'tab.blocksHint': 'Blocos de conteúdo e variáveis',
30
+ 'tab.rows': 'Seções',
31
+ 'tab.rowsHint': 'Layouts de seção e modelo de tela',
32
+ 'tab.files': 'Arquivos',
33
+ 'tab.filesHint': 'Biblioteca de recursos',
34
+ 'tab.layers': 'Estrutura',
35
+ 'tab.layersHint': 'Estrutura do documento',
36
+ 'tab.settings': 'Definições',
37
+ 'tab.settingsHint': 'Definições do e-mail',
38
+ 'tab.data': 'Var.',
39
+ 'tab.dataHint': 'Variáveis fornecidas pelo seu código',
40
+ 'inspector.blockProperties': 'Propriedades do bloco',
41
+ 'inspector.sectionProperties': 'Propriedades da seção',
42
+ 'inspector.title': 'Inspetor',
43
+ 'inspector.sectionLabel': 'Seção',
44
+ 'inspector.nothingSelected': 'Nada selecionado',
45
+ 'action.duplicateHint': 'Duplicar — ⌘D',
46
+ 'action.deleteHint': 'Excluir ',
47
+ 'inspector.emptyBody':
48
+ 'Selecione uma linha ou um bloco na tela para estilizá-lo aqui. Arraste blocos da aba <strong style="color: var(--ed-text); font-weight: 600;">Blocos</strong>; clique duas vezes em qualquer texto para editá-lo diretamente.',
49
+ 'inspector.shortcuts': 'Atalhos',
50
+ 'shortcut.undoRedo': '⌘Z / ⌘⇧Z desfazer, refazer',
51
+ 'shortcut.duplicate': '⌘Dduplicar seleção',
52
+ 'shortcut.delete': 'excluir seleção',
53
+ 'shortcut.export': '⌘E exportar HTML',
54
+ 'shortcut.escape': 'ESC — desmarcar, fechar',
55
+ 'blocks.dragHint': 'Arraste para a tela',
56
+ 'blocks.count': '{count} blocos',
57
+ 'rows.sectionLayouts': 'Layouts de seção',
58
+ 'rows.customMarkup': 'Marcação personalizada',
59
+ 'rows.htmlRowHint': 'Arraste para inserir, ou clique para adicionar — uma linha de sangria total que você preenche com HTML bruto',
60
+ 'rows.rawHtmlSection': 'Seção de HTML bruto',
61
+ 'rows.rawHtmlDesc': 'Seção de sangria total, sua própria marcação, ainda arrastável',
62
+ 'rows.canvasModel': 'Modelo de tela',
63
+ 'rows.modeRowBased': 'Baseado em linhas',
64
+ 'rows.modeFreeStack': 'Pilha livre',
65
+ 'rows.hintRows':
66
+ 'Baseado em seções: solte um layout primeiro, depois blocos em suas colunas cada seção tem seu próprio fundo, borda, configurações flex ou grade.',
67
+ 'rows.hintStack': 'Pilha livre: sem layouts — cada bloco que você solta se torna sua própria seção de largura total, empilhada em ordem.',
68
+ 'files.libraryCount': 'Biblioteca {count} arquivos',
69
+ 'files.openManager': 'Abrir gerenciador de arquivos',
70
+ 'files.dragToCanvas': 'Arraste qualquer arquivo diretamente para a tela para colocá-lo como bloco de imagem.',
71
+ 'layers.structure': 'Estrutura',
72
+ 'layers.sectionSingle': 'Seção',
73
+ 'layers.sectionMulti': 'Seção · {count} col.',
74
+ 'layers.column': 'Coluna {index}',
75
+ 'layers.blockCount': '{count} bl.',
76
+ 'vars.title': 'Variáveis',
77
+ 'vars.fromCode': '{count} do seu código',
78
+ 'vars.declaredNote': 'Declaradas pela sua aplicação — a tela sempre mostra o token, nunca um valor.',
79
+ 'vars.filterPlaceholder': 'Filtrar variáveis…',
80
+ 'vars.insertHint': 'Clique para inserir no texto, título ou botão selecionado',
81
+ 'vars.insert': 'inserir',
82
+ 'vars.noMatch': 'Nenhuma variável corresponde a esse filtro.',
83
+ 'vars.noneDeclared': 'Sua aplicação ainda não declarou nenhuma variável.',
84
+ 'vars.rteHint': 'Ao editar texto, você também pode escolher uma variável diretamente no menu da barra de ferramentas em linha.',
85
+ 'modal.fileManager': 'Gerenciador de arquivos',
86
+ 'modal.assetsTitle': 'Recursos',
87
+ 'modal.replaceImage': 'Substituir imagem',
88
+ 'library.searchPlaceholder': 'Pesquisar arquivos…',
89
+ 'action.upload': 'Enviar',
90
+ 'library.clickToPlace': 'Clique em um arquivo para posicioná-lo · ou arraste um arquivo para a tela',
91
+ 'library.clickToReplace': 'Clique em um arquivo para substituir a imagem selecionada',
92
+ 'library.storageLabel': '{count} arquivos · {size}',
93
+ 'library.folders': 'Pastas',
94
+ 'library.dropHint': 'Solte arquivos de imagem aqui para enviá-los — ou use o botão Enviar.',
95
+ 'library.deleteFileHint': 'Excluir arquivo',
96
+ 'library.del': 'EXCL',
97
+ 'toast.assetDeleted': '{name} excluído',
98
+ 'library.allFiles': 'Todos os ficheiros',
99
+ 'library.loadMore': 'Carregar mais',
100
+ 'library.empty': 'Ainda não há ficheiros aqui.',
101
+ 'storage.loading': 'A carregar ficheiros…',
102
+ 'storage.uploading': 'A carregar {count}…',
103
+ 'storage.errLoadFailed': 'Não foi possível carregar a biblioteca de ficheiros {reason}',
104
+ 'storage.errNoLimits': 'Os carregamentos estão desativados: esta aplicação não definiu limites de carregamento.',
105
+ 'storage.errNoAccept': 'Os carregamentos estão desativados: não foi permitido nenhum formato de ficheiro.',
106
+ 'storage.errNoMaxBytes': 'Os carregamentos estão desativados: não foi definido um tamanho máximo de ficheiro.',
107
+ 'storage.errTooLarge': '{name} tem {size} — o limite é {max}.',
108
+ 'storage.errFormat': '{name} é um ficheiro {type}, que não é permitido aqui.',
109
+ 'storage.errSvg': '{name} é um SVG, que esta aplicação não aceita.',
110
+ 'storage.errDimensions': '{name} tem {w}×{ht}px — o limite é {maxW}×{maxH}px.',
111
+ 'storage.errTooMany': ' é possível carregar {max} ficheiros de cada vez.',
112
+ 'storage.errUnreadable': '{name} não é uma imagem legível.',
113
+ 'storage.errUploadFailed': 'Não foi possível carregar {name} — {reason}',
114
+ 'storage.errDeleteFailed': 'Não foi possível eliminar {name}{reason}',
115
+ 'modal.export': 'Exportar',
116
+ 'modal.exportTitle': 'HTML de e-mail baseado em tabelas',
117
+ 'export.copy': 'Copiar',
118
+ 'export.copied': 'Copiado',
119
+ 'action.download': 'Baixar',
120
+ 'export.meta': '{kb} KB · tabelas + estilos inline · larguras seguras para o Outlook',
121
+ 'modal.rawHtmlTitle': 'HTML bruto, pré-visualização ao vivo',
122
+ 'code.statusEdited': 'Visualização de código — editado — pré-visualização ao vivo, ainda não aplicado',
123
+ 'code.statusSynced': 'Visualização de código — sincronizado com a tela',
124
+ 'action.reload': 'Recarregar',
125
+ 'action.reloadHint': 'Recarregar a origem a partir da tela',
126
+ 'action.applyToCanvas': 'Aplicar à tela',
127
+ 'action.applyToCanvasHint': 'Analisar a origem novamente em linhas editáveis',
128
+ 'action.closeWithoutApplyingHint': 'Fechar sem aplicar',
129
+ 'code.source': 'Origem',
130
+ 'code.livePreview': 'Pré-visualização ao vivo',
131
+ 'code.liveHtmlPreviewTitle': 'Pré-visualização de HTML ao vivo',
132
+ 'code.applyNote':
133
+ 'Aplicar analisa cada linha de tabela de nível superior em uma linha de tela que você ainda pode selecionar, reordenar e excluir — a marcação escrita à mão sobrevive ao processo.',
134
+ 'code.meta': '{kb} KB · {lines} linhas',
135
+ 'toast.sourceReloaded': 'Origem recarregada a partir da tela',
136
+ 'toast.sourceAppliedOne': 'Origem aplicada — 1 linha na tela',
137
+ 'toast.sourceAppliedMany': 'Origem aplicada {rows} linhas na tela',
138
+ 'toast.parseError': 'Não foi possível analisar esse HTML',
139
+ 'modal.aiDraft': 'Assistente de escrita com IA',
140
+ 'modal.aiDraftTitle': 'Escreva o seu e-mail com IA',
141
+ 'ai.disclosure': 'A IA cria sugestões a partir do seu resumo. Reveja e edite o resultado antes de enviar.',
142
+ 'ai.goal': 'Objetivo',
143
+ 'ai.tone': 'Tom',
144
+ 'ai.briefLabel': 'Sobre o que é este e-mail?',
145
+ 'ai.briefPlaceholder': 'ex. Coleção de outono, 15% para assinantes, frete grátis acima de R$150',
146
+ 'ai.generate': 'Gerar texto',
147
+ 'ai.writing': 'Escrevendo…',
148
+ 'ai.kindHeadline': 'Título',
149
+ 'ai.kindBody': 'Corpo do texto',
150
+ 'ai.kindButton': 'Texto do botão',
151
+ 'ai.actionInsertHeading': 'Inserir como título',
152
+ 'ai.actionInsertText': 'Inserir como bloco de texto',
153
+ 'ai.actionInsertButton': 'Inserir como botão',
154
+ 'toast.headingAdded': 'Título adicionado',
155
+ 'toast.textBlockAdded': 'Bloco de texto adicionado',
156
+ 'toast.buttonAdded': 'Botão adicionado',
157
+ 'preview.kickerMobile': 'Pré-visualização — móvel 375px',
158
+ 'preview.kickerDesktop': 'Pré-visualização — desktop {width}px',
159
+ 'action.close': 'Fechar',
160
+ 'toast.duplicated': 'Duplicado',
161
+ 'toast.fileUploadedOne': '1 arquivo enviado',
162
+ 'toast.fileUploadedMany': '{count} arquivos enviados',
163
+ 'toast.imageReplaced': 'Imagem substituída',
164
+ 'toast.imageAdded': 'Imagem adicionada à tela',
165
+ 'toast.htmlCopied': 'HTML copiado para a área de transferência',
166
+ 'toast.templateLoaded': '{name} carregado',
167
+ 'toast.snippetDefaultLabel': 'Trecho',
168
+ 'toast.snippetInserted': '{name} inserido',
169
+ 'toast.snippetCopied': '{name} copiado — selecione um bloco de texto para inseri-lo',
170
+ 'rte.textStyle': 'Estilo do texto',
171
+ 'rte.mergeTags': 'Campos de intercalação',
172
+ 'rte.noMergeTags': 'Não há campos de intercalação disponíveis',
173
+ 'rte.textColor': 'Cor do texto',
174
+ 'rte.highlightColor': 'Cor de destaque',
175
+ 'rte.removeHighlight': 'Remover destaque',
176
+ 'rte.clearFormatting': 'Limpar formatação',
177
+ 'action.downloadPng': 'Transferir PNG',
178
+ 'action.screenshot': 'Captura de ecrã',
179
+ 'action.screenshotHint': 'Ver todo o modelo como imagem e transferi-lo',
180
+ 'toast.pngSaved': 'Captura transferida',
181
+ 'toast.pngFailed': 'A captura falhou — não foi possível carregar uma imagem externa',
182
+ 'toast.pngCopied': 'Captura copiada para a área de transferência',
183
+ 'toast.pngCopyFailed': 'Este navegador não aceitou uma imagem na área de transferência',
184
+ 'story.kicker': 'Captura de ecrã',
185
+ 'story.rendering': 'A gerar a captura',
186
+ 'story.renderingHint': 'Cada bloco é desenhado a 2× — num modelo longo demora um momento.',
187
+ 'story.failed': 'A captura falhou',
188
+ 'story.failedHint': 'Não foi possível carregar uma imagem do modelo para a captura.',
189
+ 'story.retry': 'Tentar novamente',
190
+ 'story.play': 'Reproduzir',
191
+ 'story.pause': 'Pausa',
192
+ 'story.replay': 'Reproduzir de novo',
193
+ 'story.copy': 'Copiar',
194
+ 'story.meta': '{w}×{h} · ecrã {i} de {n}',
195
+ 'footer.poweredBy': 'Com tecnologia SELISE Blocks © 2026',
196
+ };