diff --git a/docs/SPEC.md b/docs/SPEC.md
index 052de3a..faa3732 100644
--- a/docs/SPEC.md
+++ b/docs/SPEC.md
@@ -135,17 +135,18 @@ ist grau (`#6B7A8C`) — kein Petrol mehr im Diagramm. Der Modus ändert nur die
des Teilbaums.
### Grafikexport des Diagramms
-Das Diagramm ist per Icon-Schaltfläche als **Bild** in die Zwischenablage
-kopierbar (grafisches Format, in Dokumente/Chats einfügbar):
+Das Diagramm wird aus der Live-Geometrie in ein eigenständiges SVG (nur Formen
++ Text, keine externen Ressourcen) nachgezeichnet. Zwei Icon-Schaltflächen:
-- Das gerenderte Diagramm wird aus der Live-Geometrie in ein eigenständiges
- SVG (nur Formen + Text, keine externen Ressourcen) nachgezeichnet und als
- **PNG** in die Zwischenablage gelegt. Es werden zwei Flavors geschrieben:
- `image/png` (das eigentliche Bild) und `text/html` mit eingebettetem PNG
- (``) — Office-Programme wie LibreOffice Writer
- bevorzugen den HTML-Flavor und betten das Bild dann korrekt ein. Fällt der
- Bild-Clipboard ganz aus (fehlende `ClipboardItem`-Unterstützung), wird der
- **SVG-Quelltext** kopiert (ebenfalls ein Grafikformat).
+- **Kopieren** — als **PNG** in die Zwischenablage. Es werden zwei Flavors
+ geschrieben: `image/png` (das eigentliche Bild) und `text/html` mit
+ eingebettetem PNG. Fällt der Bild-Clipboard ganz aus (fehlende
+ `ClipboardItem`-Unterstützung), wird der **SVG-Quelltext** kopiert.
+- **Herunterladen** — als **SVG-Datei** (`werkbaum-diagramm.svg`, Vektor).
+ Verlässlicher Weg für Programme, die das Browser-Bild-Clipboard nicht
+ erkennen (z. B. LibreOffice Writer: Einfügen → Bild → Datei). Das
+ Browser-Clipboard erlaubt nur `image/png`/Text als Bildtypen, kein SVG —
+ daher der Datei-Weg für Vektor.
- Übernommen werden Knotenfarben (Status §4), Größen-Badge, Tags und der
Geister-Knoten; die Verbindungslinien werden je Gate neu gezogen
(und = durchgezogen Tinte, oder = gestrichelt Grau) und treffen die Knoten
diff --git a/frontend/index.html b/frontend/index.html
index ab64737..faf0f72 100644
--- a/frontend/index.html
+++ b/frontend/index.html
@@ -572,6 +572,9 @@
+
@@ -863,6 +866,18 @@ async function copyDiagramImage(){
}
await writeClipboard(svg); /* Fallback: SVG-Quelltext (ebenfalls Grafik) */
}
+/* Als Datei speichern (SVG, Vektor). Verlässlicher Weg z. B. für LibreOffice
+ Writer: Einfügen → Bild → die Datei; das Bild-Clipboard aus dem Browser
+ erkennt LibreOffice nicht zuverlässig. */
+function downloadDiagramSvg(){
+ const {svg} = diagramToSvg();
+ const blob = new Blob([`\n` + svg], {type:'image/svg+xml'});
+ const url = URL.createObjectURL(blob);
+ const a = document.createElement('a');
+ a.href = url; a.download = 'werkbaum-diagramm.svg';
+ document.body.appendChild(a); a.click(); a.remove();
+ setTimeout(() => URL.revokeObjectURL(url), 1000);
+}
/* Tab-Taste rückt ein statt den Fokus zu wechseln */
src.addEventListener('keydown', e => {
@@ -1029,6 +1044,12 @@ document.getElementById('copyDiagram').addEventListener('click', async () => {
await copyDiagramImage();
flashCopied(document.getElementById('copyDiagram'), 'copyDiagramTooltip');
});
+document.getElementById('dlDiagram').addEventListener('click', () => {
+ downloadDiagramSvg();
+ const b = document.getElementById('dlDiagram'); /* kurzer Petrol-Blitz, Tooltip bleibt */
+ b.classList.add('done');
+ setTimeout(() => b.classList.remove('done'), 1500);
+});
/* ---------- Internationalisierung (DE/EN/ES/FR) ---------- */
const I18N = {
@@ -1041,6 +1062,7 @@ const I18N = {
editorTitle:"Struktur (Text)", diagramTitle:"Diagramm",
copy:"kopieren", copyDone:"kopiert ✓", copyTooltip:"Text in die Zwischenablage kopieren",
copyDiagramTooltip:"Diagramm als PNG-Bild in die Zwischenablage kopieren",
+ downloadDiagramTooltip:"Diagramm als SVG-Datei herunterladen (z. B. für LibreOffice: Einfügen → Bild)",
minimize:"minimieren", normal:"normal", maximize:"maximieren",
agenda:"Agenda", discarded:"verworfene",
modeHorizontal:"Horizontal – Organigramm, Diagramm über dem Editor",
@@ -1070,6 +1092,7 @@ const I18N = {
editorTitle:"Structure (text)", diagramTitle:"Diagram",
copy:"copy", copyDone:"copied ✓", copyTooltip:"Copy text to clipboard",
copyDiagramTooltip:"Copy diagram as a PNG image to the clipboard",
+ downloadDiagramTooltip:"Download diagram as an SVG file (e.g. for LibreOffice: Insert → Image)",
minimize:"minimize", normal:"normal", maximize:"maximize",
agenda:"Legend", discarded:"discarded",
modeHorizontal:"Horizontal – org chart, diagram above the editor",
@@ -1099,6 +1122,7 @@ const I18N = {
editorTitle:"Estructura (texto)", diagramTitle:"Diagrama",
copy:"copiar", copyDone:"copiado ✓", copyTooltip:"Copiar el texto al portapapeles",
copyDiagramTooltip:"Copiar el diagrama como imagen PNG al portapapeles",
+ downloadDiagramTooltip:"Descargar el diagrama como archivo SVG (p. ej. para LibreOffice: Insertar → Imagen)",
minimize:"minimizar", normal:"normal", maximize:"maximizar",
agenda:"Leyenda", discarded:"descartados",
modeHorizontal:"Horizontal – organigrama, diagrama sobre el editor",
@@ -1128,6 +1152,7 @@ const I18N = {
editorTitle:"Structure (texte)", diagramTitle:"Diagramme",
copy:"copier", copyDone:"copié ✓", copyTooltip:"Copier le texte dans le presse-papiers",
copyDiagramTooltip:"Copier le diagramme comme image PNG dans le presse-papiers",
+ downloadDiagramTooltip:"Télécharger le diagramme en fichier SVG (p. ex. pour LibreOffice : Insertion → Image)",
minimize:"réduire", normal:"normal", maximize:"agrandir",
agenda:"Légende", discarded:"abandonnés",
modeHorizontal:"Horizontal – organigramme, diagramme au-dessus de l'éditeur",
@@ -1157,6 +1182,7 @@ const I18N = {
editorTitle:"Struktura (tekst)", diagramTitle:"Diagram",
copy:"kopiuj", copyDone:"skopiowano ✓", copyTooltip:"Kopiuj tekst do schowka",
copyDiagramTooltip:"Kopiuj diagram jako obraz PNG do schowka",
+ downloadDiagramTooltip:"Pobierz diagram jako plik SVG (np. dla LibreOffice: Wstaw → Obraz)",
minimize:"minimalizuj", normal:"normalny", maximize:"maksymalizuj",
agenda:"Legenda", discarded:"odrzucone",
modeHorizontal:"Poziomo – schemat organizacyjny, diagram nad edytorem",
@@ -1186,6 +1212,7 @@ const I18N = {
editorTitle:"Структура (текст)", diagramTitle:"Диаграмма",
copy:"копировать", copyDone:"скопировано ✓", copyTooltip:"Скопировать текст в буфер обмена",
copyDiagramTooltip:"Скопировать диаграмму как изображение PNG в буфер обмена",
+ downloadDiagramTooltip:"Скачать диаграмму как файл SVG (напр. для LibreOffice: Вставка → Изображение)",
minimize:"свернуть", normal:"обычный", maximize:"развернуть",
agenda:"Легенда", discarded:"отклонённые",
modeHorizontal:"Горизонтально – оргсхема, диаграмма над редактором",
@@ -1215,6 +1242,7 @@ const I18N = {
editorTitle:"संरचना (टेक्स्ट)", diagramTitle:"आरेख",
copy:"कॉपी करें", copyDone:"कॉपी हो गया ✓", copyTooltip:"टेक्स्ट को क्लिपबोर्ड पर कॉपी करें",
copyDiagramTooltip:"आरेख को PNG छवि के रूप में क्लिपबोर्ड पर कॉपी करें",
+ downloadDiagramTooltip:"आरेख को SVG फ़ाइल के रूप में डाउनलोड करें (जैसे LibreOffice: सम्मिलित करें → छवि)",
minimize:"छोटा करें", normal:"सामान्य", maximize:"बड़ा करें",
agenda:"लेजेंड", discarded:"अस्वीकृत",
modeHorizontal:"क्षैतिज – संगठन-चार्ट, संपादक के ऊपर आरेख",
@@ -1244,6 +1272,7 @@ const I18N = {
editorTitle:"结构(文本)", diagramTitle:"图表",
copy:"复制", copyDone:"已复制 ✓", copyTooltip:"将文本复制到剪贴板",
copyDiagramTooltip:"将图表作为 PNG 图片复制到剪贴板",
+ downloadDiagramTooltip:"将图表下载为 SVG 文件(例如用于 LibreOffice:插入 → 图像)",
minimize:"最小化", normal:"正常", maximize:"最大化",
agenda:"图例", discarded:"已放弃",
modeHorizontal:"横向——组织结构图,图表在编辑器上方",
@@ -1273,6 +1302,7 @@ const I18N = {
editorTitle:"構造(テキスト)", diagramTitle:"ダイアグラム",
copy:"コピー", copyDone:"コピーしました ✓", copyTooltip:"テキストをクリップボードにコピー",
copyDiagramTooltip:"ダイアグラムを PNG 画像としてクリップボードにコピー",
+ downloadDiagramTooltip:"ダイアグラムを SVG ファイルとしてダウンロード(例:LibreOffice の 挿入 → 画像)",
minimize:"最小化", normal:"標準", maximize:"最大化",
agenda:"凡例", discarded:"破棄",
modeHorizontal:"横 — 組織図、ダイアグラムはエディターの上",