diff --git a/frontend/js/i18n/de.js b/frontend/js/i18n/de.js index 5e98fe6..d401a30 100644 --- a/frontend/js/i18n/de.js +++ b/frontend/js/i18n/de.js @@ -549,4 +549,80 @@ export default { 'widget.dir.remove_logo': 'Entfernen', 'widget.dir.no_bg_images': 'Keine Hintergrundbilder ausgewählt', 'widget.dir.remove_bg': 'Entfernen', + + // Designer + 'designer.title': 'Inhaltsdesigner', + 'designer.subtitle': 'Erstellen Sie dynamischen Anzeigeinhalt', + 'designer.help_tip': 'Erstellen Sie individuelle Anzeigen mit Live-Elementen: Uhren, Wetter, RSS-Ticker, Countdowns, QR-Codes. Als Widget veröffentlichen oder als PNG exportieren.', + 'designer.load_design': 'Design laden', + 'designer.export_png': 'PNG exportieren', + 'designer.publish': 'In Bibliothek veröffentlichen', + 'designer.preview_hint': 'Klicken Sie auf Elemente zur Auswahl. Ziehen zum Verschieben. Live-Vorschau aktualisiert in Echtzeit.', + 'designer.add_element': 'Element hinzufügen', + 'designer.background': 'Hintergrund', + 'designer.bg_image': 'Bild', + 'designer.properties': 'Eigenschaften', + 'designer.layers': 'Ebenen', + 'designer.no_elements': 'Noch keine Elemente', + 'designer.save_design_file': 'Design-Datei speichern', + 'designer.qr_label': 'QR-CODE', + 'designer.loading_news': 'Nachrichten werden geladen...', + 'designer.no_items': 'Keine Einträge', + 'designer.feed_unavailable': 'Feed nicht verfügbar', + 'designer.countdown_now': 'JETZT!', + 'designer.widget_name': 'Design {date}', + 'designer.el.text': 'Text', + 'designer.el.heading': 'Überschrift', + 'designer.el.image': 'Bild', + 'designer.el.video': 'Video', + 'designer.el.clock': 'Uhr', + 'designer.el.date': 'Datum', + 'designer.el.weather': 'Wetter', + 'designer.el.ticker': 'Ticker', + 'designer.el.shape': 'Form', + 'designer.el.qr': 'QR-Code', + 'designer.el.countdown': 'Countdown', + 'designer.el.webpage': 'Webseite', + 'designer.bg.black': 'Schwarz', + 'designer.bg.dark_blue': 'Dunkelblau', + 'designer.bg.dark_gradient': 'Dunkler Verlauf', + 'designer.bg.blue_gradient': 'Blauer Verlauf', + 'designer.bg.sunset': 'Sonnenuntergang', + 'designer.bg.ocean': 'Ozean', + 'designer.bg.forest': 'Wald', + 'designer.bg.dark_red': 'Dunkelrot', + 'designer.bg.white': 'Weiß', + 'designer.default.text': 'Ihr Text hier', + 'designer.default.heading': 'ÜBERSCHRIFT', + 'designer.default.coming_soon': 'Demnächst', + 'designer.prompt.video_url': 'Video-URL (MP4):', + 'designer.prompt.weather_location': 'Stadt, Land:', + 'designer.prompt.rss_url': 'RSS-Feed-URL:', + 'designer.prompt.qr_url': 'QR-Code-URL:', + 'designer.prompt.countdown_date': 'Zieldatum (JJJJ-MM-TT):', + 'designer.prompt.webpage_url': 'Webseiten-URL:', + 'designer.prop.text': 'Text', + 'designer.prop.size': 'Größe', + 'designer.prop.font': 'Schriftart', + 'designer.prop.color': 'Farbe', + 'designer.prop.bold': 'Fett', + 'designer.prop.shadow': 'Schatten', + 'designer.prop.format': 'Format', + 'designer.prop.show_seconds': 'Sekunden anzeigen', + 'designer.prop.muted': 'Stumm', + 'designer.prop.loop': 'Schleife', + 'designer.prop.opacity': 'Deckkraft', + 'designer.prop.shape': 'Form', + 'designer.prop.location': 'Standort', + 'designer.prop.feed_url': 'Feed-URL', + 'designer.prop.speed': 'Geschwindigkeit (Sekunden)', + 'designer.prop.text_color': 'Textfarbe', + 'designer.prop.bg_color': 'Hintergrundfarbe', + 'designer.prop.target_date': 'Zieldatum', + 'designer.prop.label': 'Beschriftung', + 'designer.toast.published': 'Als Widget veröffentlicht! Weisen Sie es einer Layout-Zone zu.', + 'designer.toast.publish_failed': 'Veröffentlichung fehlgeschlagen', + 'designer.toast.export_failed': 'Export fehlgeschlagen: {error}', + 'designer.toast.loaded': 'Design geladen', + 'designer.toast.invalid_file': 'Ungültige Design-Datei', }; diff --git a/frontend/js/i18n/en.js b/frontend/js/i18n/en.js index 8a1ff86..1839253 100644 --- a/frontend/js/i18n/en.js +++ b/frontend/js/i18n/en.js @@ -580,4 +580,85 @@ export default { 'widget.dir.remove_logo': 'Remove', 'widget.dir.no_bg_images': 'No background images selected', 'widget.dir.remove_bg': 'Remove', + + // Designer + 'designer.title': 'Content Designer', + 'designer.subtitle': 'Create dynamic signage content', + 'designer.help_tip': 'Create custom signage with live elements: clocks, weather, RSS tickers, countdowns, QR codes. Publish as a widget or export as PNG.', + 'designer.load_design': 'Load Design', + 'designer.export_png': 'Export PNG', + 'designer.publish': 'Publish to Library', + 'designer.preview_hint': 'Click elements to select. Drag to reposition. Live preview updates in real-time.', + 'designer.add_element': 'Add Element', + 'designer.background': 'Background', + 'designer.bg_image': 'Image', + 'designer.properties': 'Properties', + 'designer.layers': 'Layers', + 'designer.no_elements': 'No elements yet', + 'designer.save_design_file': 'Save Design File', + 'designer.qr_label': 'QR CODE', + 'designer.loading_news': 'Loading news...', + 'designer.no_items': 'No items', + 'designer.feed_unavailable': 'Feed unavailable', + 'designer.countdown_now': 'NOW!', + 'designer.widget_name': 'Design {date}', + // Element buttons + 'designer.el.text': 'Text', + 'designer.el.heading': 'Heading', + 'designer.el.image': 'Image', + 'designer.el.video': 'Video', + 'designer.el.clock': 'Clock', + 'designer.el.date': 'Date', + 'designer.el.weather': 'Weather', + 'designer.el.ticker': 'Ticker', + 'designer.el.shape': 'Shape', + 'designer.el.qr': 'QR Code', + 'designer.el.countdown': 'Countdown', + 'designer.el.webpage': 'Webpage', + // Backgrounds + 'designer.bg.black': 'Black', + 'designer.bg.dark_blue': 'Dark Blue', + 'designer.bg.dark_gradient': 'Dark Gradient', + 'designer.bg.blue_gradient': 'Blue Gradient', + 'designer.bg.sunset': 'Sunset', + 'designer.bg.ocean': 'Ocean', + 'designer.bg.forest': 'Forest', + 'designer.bg.dark_red': 'Dark Red', + 'designer.bg.white': 'White', + // Defaults / prompts + 'designer.default.text': 'Your text here', + 'designer.default.heading': 'HEADING', + 'designer.default.coming_soon': 'Coming Soon', + 'designer.prompt.video_url': 'Video URL (MP4):', + 'designer.prompt.weather_location': 'City, State:', + 'designer.prompt.rss_url': 'RSS Feed URL:', + 'designer.prompt.qr_url': 'QR Code URL:', + 'designer.prompt.countdown_date': 'Target date (YYYY-MM-DD):', + 'designer.prompt.webpage_url': 'Webpage URL:', + // Properties + 'designer.prop.text': 'Text', + 'designer.prop.size': 'Size', + 'designer.prop.font': 'Font', + 'designer.prop.color': 'Color', + 'designer.prop.bold': 'Bold', + 'designer.prop.shadow': 'Shadow', + 'designer.prop.format': 'Format', + 'designer.prop.show_seconds': 'Show seconds', + 'designer.prop.muted': 'Muted', + 'designer.prop.loop': 'Loop', + 'designer.prop.opacity': 'Opacity', + 'designer.prop.shape': 'Shape', + 'designer.prop.location': 'Location', + 'designer.prop.feed_url': 'Feed URL', + 'designer.prop.speed': 'Speed (seconds)', + 'designer.prop.text_color': 'Text Color', + 'designer.prop.bg_color': 'BG Color', + 'designer.prop.target_date': 'Target Date', + 'designer.prop.label': 'Label', + // Toasts + 'designer.toast.published': 'Published as widget! Assign it to a layout zone.', + 'designer.toast.publish_failed': 'Publish failed', + 'designer.toast.export_failed': 'Export failed: {error}', + 'designer.toast.loaded': 'Design loaded', + 'designer.toast.invalid_file': 'Invalid design file', }; diff --git a/frontend/js/i18n/es.js b/frontend/js/i18n/es.js index 6d4f295..f085d54 100644 --- a/frontend/js/i18n/es.js +++ b/frontend/js/i18n/es.js @@ -548,4 +548,80 @@ export default { 'widget.dir.remove_logo': 'Quitar', 'widget.dir.no_bg_images': 'No se han seleccionado imágenes de fondo', 'widget.dir.remove_bg': 'Quitar', + + // Designer + 'designer.title': 'Diseñador de contenido', + 'designer.subtitle': 'Crea contenido dinámico para señalización', + 'designer.help_tip': 'Crea señalización personalizada con elementos en vivo: relojes, clima, tickers RSS, cuentas regresivas, códigos QR. Publica como widget o exporta como PNG.', + 'designer.load_design': 'Cargar diseño', + 'designer.export_png': 'Exportar PNG', + 'designer.publish': 'Publicar en biblioteca', + 'designer.preview_hint': 'Haz clic en los elementos para seleccionar. Arrastra para reposicionar. La vista previa se actualiza en tiempo real.', + 'designer.add_element': 'Agregar elemento', + 'designer.background': 'Fondo', + 'designer.bg_image': 'Imagen', + 'designer.properties': 'Propiedades', + 'designer.layers': 'Capas', + 'designer.no_elements': 'Aún no hay elementos', + 'designer.save_design_file': 'Guardar archivo de diseño', + 'designer.qr_label': 'CÓDIGO QR', + 'designer.loading_news': 'Cargando noticias...', + 'designer.no_items': 'Sin elementos', + 'designer.feed_unavailable': 'Feed no disponible', + 'designer.countdown_now': '¡AHORA!', + 'designer.widget_name': 'Diseño {date}', + 'designer.el.text': 'Texto', + 'designer.el.heading': 'Título', + 'designer.el.image': 'Imagen', + 'designer.el.video': 'Video', + 'designer.el.clock': 'Reloj', + 'designer.el.date': 'Fecha', + 'designer.el.weather': 'Clima', + 'designer.el.ticker': 'Ticker', + 'designer.el.shape': 'Forma', + 'designer.el.qr': 'Código QR', + 'designer.el.countdown': 'Cuenta regresiva', + 'designer.el.webpage': 'Página web', + 'designer.bg.black': 'Negro', + 'designer.bg.dark_blue': 'Azul oscuro', + 'designer.bg.dark_gradient': 'Gradiente oscuro', + 'designer.bg.blue_gradient': 'Gradiente azul', + 'designer.bg.sunset': 'Atardecer', + 'designer.bg.ocean': 'Océano', + 'designer.bg.forest': 'Bosque', + 'designer.bg.dark_red': 'Rojo oscuro', + 'designer.bg.white': 'Blanco', + 'designer.default.text': 'Tu texto aquí', + 'designer.default.heading': 'TÍTULO', + 'designer.default.coming_soon': 'Próximamente', + 'designer.prompt.video_url': 'URL del video (MP4):', + 'designer.prompt.weather_location': 'Ciudad, Estado:', + 'designer.prompt.rss_url': 'URL del feed RSS:', + 'designer.prompt.qr_url': 'URL del código QR:', + 'designer.prompt.countdown_date': 'Fecha objetivo (AAAA-MM-DD):', + 'designer.prompt.webpage_url': 'URL de la página web:', + 'designer.prop.text': 'Texto', + 'designer.prop.size': 'Tamaño', + 'designer.prop.font': 'Fuente', + 'designer.prop.color': 'Color', + 'designer.prop.bold': 'Negrita', + 'designer.prop.shadow': 'Sombra', + 'designer.prop.format': 'Formato', + 'designer.prop.show_seconds': 'Mostrar segundos', + 'designer.prop.muted': 'Silenciado', + 'designer.prop.loop': 'Bucle', + 'designer.prop.opacity': 'Opacidad', + 'designer.prop.shape': 'Forma', + 'designer.prop.location': 'Ubicación', + 'designer.prop.feed_url': 'URL del feed', + 'designer.prop.speed': 'Velocidad (segundos)', + 'designer.prop.text_color': 'Color del texto', + 'designer.prop.bg_color': 'Color de fondo', + 'designer.prop.target_date': 'Fecha objetivo', + 'designer.prop.label': 'Etiqueta', + 'designer.toast.published': '¡Publicado como widget! Asígnalo a una zona de diseño.', + 'designer.toast.publish_failed': 'Falló la publicación', + 'designer.toast.export_failed': 'Falló la exportación: {error}', + 'designer.toast.loaded': 'Diseño cargado', + 'designer.toast.invalid_file': 'Archivo de diseño no válido', }; diff --git a/frontend/js/i18n/fr.js b/frontend/js/i18n/fr.js index 06bbfc9..38d039b 100644 --- a/frontend/js/i18n/fr.js +++ b/frontend/js/i18n/fr.js @@ -549,4 +549,80 @@ export default { 'widget.dir.remove_logo': 'Retirer', 'widget.dir.no_bg_images': 'Aucune image de fond sélectionnée', 'widget.dir.remove_bg': 'Retirer', + + // Designer + 'designer.title': 'Concepteur de contenu', + 'designer.subtitle': 'Créez du contenu d\'affichage dynamique', + 'designer.help_tip': 'Créez de l\'affichage personnalisé avec des éléments en direct : horloges, météo, tickers RSS, comptes à rebours, codes QR. Publiez comme widget ou exportez en PNG.', + 'designer.load_design': 'Charger un design', + 'designer.export_png': 'Exporter PNG', + 'designer.publish': 'Publier dans la bibliothèque', + 'designer.preview_hint': 'Cliquez sur les éléments pour les sélectionner. Glissez pour les repositionner. L\'aperçu se met à jour en temps réel.', + 'designer.add_element': 'Ajouter un élément', + 'designer.background': 'Fond', + 'designer.bg_image': 'Image', + 'designer.properties': 'Propriétés', + 'designer.layers': 'Calques', + 'designer.no_elements': 'Pas encore d\'éléments', + 'designer.save_design_file': 'Enregistrer le fichier de design', + 'designer.qr_label': 'CODE QR', + 'designer.loading_news': 'Chargement des actualités...', + 'designer.no_items': 'Aucun élément', + 'designer.feed_unavailable': 'Flux indisponible', + 'designer.countdown_now': 'MAINTENANT !', + 'designer.widget_name': 'Design {date}', + 'designer.el.text': 'Texte', + 'designer.el.heading': 'Titre', + 'designer.el.image': 'Image', + 'designer.el.video': 'Vidéo', + 'designer.el.clock': 'Horloge', + 'designer.el.date': 'Date', + 'designer.el.weather': 'Météo', + 'designer.el.ticker': 'Bandeau', + 'designer.el.shape': 'Forme', + 'designer.el.qr': 'Code QR', + 'designer.el.countdown': 'Compte à rebours', + 'designer.el.webpage': 'Page web', + 'designer.bg.black': 'Noir', + 'designer.bg.dark_blue': 'Bleu sombre', + 'designer.bg.dark_gradient': 'Dégradé sombre', + 'designer.bg.blue_gradient': 'Dégradé bleu', + 'designer.bg.sunset': 'Coucher de soleil', + 'designer.bg.ocean': 'Océan', + 'designer.bg.forest': 'Forêt', + 'designer.bg.dark_red': 'Rouge sombre', + 'designer.bg.white': 'Blanc', + 'designer.default.text': 'Votre texte ici', + 'designer.default.heading': 'TITRE', + 'designer.default.coming_soon': 'Bientôt', + 'designer.prompt.video_url': 'URL de la vidéo (MP4) :', + 'designer.prompt.weather_location': 'Ville, Région :', + 'designer.prompt.rss_url': 'URL du flux RSS :', + 'designer.prompt.qr_url': 'URL du code QR :', + 'designer.prompt.countdown_date': 'Date cible (AAAA-MM-JJ) :', + 'designer.prompt.webpage_url': 'URL de la page web :', + 'designer.prop.text': 'Texte', + 'designer.prop.size': 'Taille', + 'designer.prop.font': 'Police', + 'designer.prop.color': 'Couleur', + 'designer.prop.bold': 'Gras', + 'designer.prop.shadow': 'Ombre', + 'designer.prop.format': 'Format', + 'designer.prop.show_seconds': 'Afficher les secondes', + 'designer.prop.muted': 'Muet', + 'designer.prop.loop': 'Boucle', + 'designer.prop.opacity': 'Opacité', + 'designer.prop.shape': 'Forme', + 'designer.prop.location': 'Emplacement', + 'designer.prop.feed_url': 'URL du flux', + 'designer.prop.speed': 'Vitesse (secondes)', + 'designer.prop.text_color': 'Couleur du texte', + 'designer.prop.bg_color': 'Couleur de fond', + 'designer.prop.target_date': 'Date cible', + 'designer.prop.label': 'Étiquette', + 'designer.toast.published': 'Publié comme widget ! Attribuez-le à une zone de mise en page.', + 'designer.toast.publish_failed': 'Échec de la publication', + 'designer.toast.export_failed': 'Échec de l\'export : {error}', + 'designer.toast.loaded': 'Design chargé', + 'designer.toast.invalid_file': 'Fichier de design invalide', }; diff --git a/frontend/js/i18n/pt.js b/frontend/js/i18n/pt.js index 5b5d078..8171d55 100644 --- a/frontend/js/i18n/pt.js +++ b/frontend/js/i18n/pt.js @@ -549,4 +549,80 @@ export default { 'widget.dir.remove_logo': 'Remover', 'widget.dir.no_bg_images': 'Nenhuma imagem de fundo selecionada', 'widget.dir.remove_bg': 'Remover', + + // Designer + 'designer.title': 'Designer de conteúdo', + 'designer.subtitle': 'Crie conteúdo dinâmico de sinalização', + 'designer.help_tip': 'Crie sinalização personalizada com elementos ao vivo: relógios, clima, tickers RSS, contagens regressivas, códigos QR. Publique como widget ou exporte como PNG.', + 'designer.load_design': 'Carregar design', + 'designer.export_png': 'Exportar PNG', + 'designer.publish': 'Publicar na biblioteca', + 'designer.preview_hint': 'Clique em elementos para selecionar. Arraste para reposicionar. Pré-visualização atualiza em tempo real.', + 'designer.add_element': 'Adicionar elemento', + 'designer.background': 'Fundo', + 'designer.bg_image': 'Imagem', + 'designer.properties': 'Propriedades', + 'designer.layers': 'Camadas', + 'designer.no_elements': 'Sem elementos ainda', + 'designer.save_design_file': 'Salvar arquivo de design', + 'designer.qr_label': 'CÓDIGO QR', + 'designer.loading_news': 'Carregando notícias...', + 'designer.no_items': 'Sem itens', + 'designer.feed_unavailable': 'Feed indisponível', + 'designer.countdown_now': 'AGORA!', + 'designer.widget_name': 'Design {date}', + 'designer.el.text': 'Texto', + 'designer.el.heading': 'Título', + 'designer.el.image': 'Imagem', + 'designer.el.video': 'Vídeo', + 'designer.el.clock': 'Relógio', + 'designer.el.date': 'Data', + 'designer.el.weather': 'Clima', + 'designer.el.ticker': 'Ticker', + 'designer.el.shape': 'Forma', + 'designer.el.qr': 'Código QR', + 'designer.el.countdown': 'Contagem regressiva', + 'designer.el.webpage': 'Página web', + 'designer.bg.black': 'Preto', + 'designer.bg.dark_blue': 'Azul escuro', + 'designer.bg.dark_gradient': 'Gradiente escuro', + 'designer.bg.blue_gradient': 'Gradiente azul', + 'designer.bg.sunset': 'Pôr do sol', + 'designer.bg.ocean': 'Oceano', + 'designer.bg.forest': 'Floresta', + 'designer.bg.dark_red': 'Vermelho escuro', + 'designer.bg.white': 'Branco', + 'designer.default.text': 'Seu texto aqui', + 'designer.default.heading': 'TÍTULO', + 'designer.default.coming_soon': 'Em breve', + 'designer.prompt.video_url': 'URL do vídeo (MP4):', + 'designer.prompt.weather_location': 'Cidade, Estado:', + 'designer.prompt.rss_url': 'URL do feed RSS:', + 'designer.prompt.qr_url': 'URL do código QR:', + 'designer.prompt.countdown_date': 'Data alvo (AAAA-MM-DD):', + 'designer.prompt.webpage_url': 'URL da página web:', + 'designer.prop.text': 'Texto', + 'designer.prop.size': 'Tamanho', + 'designer.prop.font': 'Fonte', + 'designer.prop.color': 'Cor', + 'designer.prop.bold': 'Negrito', + 'designer.prop.shadow': 'Sombra', + 'designer.prop.format': 'Formato', + 'designer.prop.show_seconds': 'Mostrar segundos', + 'designer.prop.muted': 'Mudo', + 'designer.prop.loop': 'Loop', + 'designer.prop.opacity': 'Opacidade', + 'designer.prop.shape': 'Forma', + 'designer.prop.location': 'Local', + 'designer.prop.feed_url': 'URL do feed', + 'designer.prop.speed': 'Velocidade (segundos)', + 'designer.prop.text_color': 'Cor do texto', + 'designer.prop.bg_color': 'Cor de fundo', + 'designer.prop.target_date': 'Data alvo', + 'designer.prop.label': 'Rótulo', + 'designer.toast.published': 'Publicado como widget! Atribua a uma zona de layout.', + 'designer.toast.publish_failed': 'Falha ao publicar', + 'designer.toast.export_failed': 'Falha ao exportar: {error}', + 'designer.toast.loaded': 'Design carregado', + 'designer.toast.invalid_file': 'Arquivo de design inválido', }; diff --git a/frontend/js/views/designer.js b/frontend/js/views/designer.js index 72b2ade..50988d5 100644 --- a/frontend/js/views/designer.js +++ b/frontend/js/views/designer.js @@ -1,16 +1,19 @@ import { api } from '../api.js'; import { showToast } from '../components/toast.js'; +import { t } from '../i18n.js'; +// Background swatches: ids resolve to translated names; values are the actual +// CSS to apply. const BACKGROUNDS = [ - { name: 'Black', value: '#000000' }, - { name: 'Dark Blue', value: '#0f172a' }, - { name: 'Dark Gradient', value: 'linear-gradient(135deg, #0c0c0c 0%, #1a1a2e 50%, #16213e 100%)' }, - { name: 'Blue Gradient', value: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)' }, - { name: 'Sunset', value: 'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)' }, - { name: 'Ocean', value: 'linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)' }, - { name: 'Forest', value: 'linear-gradient(135deg, #134e5e 0%, #71b280 100%)' }, - { name: 'Dark Red', value: 'linear-gradient(135deg, #200122 0%, #6f0000 100%)' }, - { name: 'White', value: '#FFFFFF' }, + { id: 'black', value: '#000000' }, + { id: 'dark_blue', value: '#0f172a' }, + { id: 'dark_gradient', value: 'linear-gradient(135deg, #0c0c0c 0%, #1a1a2e 50%, #16213e 100%)' }, + { id: 'blue_gradient', value: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)' }, + { id: 'sunset', value: 'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)' }, + { id: 'ocean', value: 'linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)' }, + { id: 'forest', value: 'linear-gradient(135deg, #134e5e 0%, #71b280 100%)' }, + { id: 'dark_red', value: 'linear-gradient(135deg, #200122 0%, #6f0000 100%)' }, + { id: 'white', value: '#FFFFFF' }, ]; const FONTS = ['Arial', 'Helvetica', 'Georgia', 'Impact', 'Verdana', 'Trebuchet MS', 'Courier New', 'Times New Roman']; @@ -30,11 +33,11 @@ export function render(container) { container.innerHTML = `
Click elements to select. Drag to reposition. Live preview updates in real-time.
+${t('designer.preview_hint')}
No elements yet
'; + `).join('') || `${t('designer.no_elements')}
`; list.querySelectorAll('[data-layer]').forEach(el => { el.onclick = () => { selectedIdx = parseInt(el.dataset.layer); redraw(); };