Files
vendoo/public/index.html
T
Masterluke77andGitHub 40071f718e Vendoo 1.43.0 – Production Update
Manifestbasierter Production-Updater 3.3, Modulnavigation, optionales Produktbild Studio, Listing-Studio-Aktionsleiste sowie plattformübergreifende Windows-/Linux-Release-Gates.
2026-07-10 13:16:21 +02:00

2405 lines
177 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="vendoo-build" content="1.43.0">
<title>Vendoo</title>
<link rel="icon" href="/brand/favicons/favicon.ico" sizes="any">
<link rel="icon" type="image/png" sizes="16x16" href="/brand/favicons/favicon-16x16.png">
<link rel="icon" type="image/png" sizes="32x32" href="/brand/favicons/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="48x48" href="/brand/favicons/favicon-48x48.png">
<link rel="apple-touch-icon" sizes="180x180" href="/brand/favicons/apple-touch-icon.png">
<link rel="manifest" href="/brand/favicons/site.webmanifest">
<meta name="msapplication-config" content="/brand/favicons/browserconfig.xml">
<meta name="theme-color" content="#FAF6F2">
<link rel="stylesheet" href="style.css?v=1.43.0">
<link rel="stylesheet" href="modules/theme-manager/theme-manager.css?v=1.43.0">
<link rel="stylesheet" href="modules/module-manager/module-manager.css?v=1.43.0">
<link href="https://cdn.jsdelivr.net/npm/quill@2.0.3/dist/quill.snow.css" rel="stylesheet">
</head>
<body>
<aside class="sidebar" id="sidebar" aria-label="Hauptnavigation">
<div class="sidebar-header">
<div class="sidebar-logo" aria-label="Vendoo">
<img class="brand-logo-full" src="/brand/logo/vendoo-logo-transparent.png" alt="Vendoo">
<img class="brand-logo-icon" src="/brand/icons/vendoo-icon-64x64.png" alt="" aria-hidden="true">
</div>
<button class="sidebar-close" id="sidebar-close" type="button" aria-label="Navigation schließen">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round"><path d="m6 6 12 12M18 6 6 18"/></svg>
</button>
</div>
<nav class="sidebar-nav">
<div class="nav-group nav-group-primary">
<button class="nav-item active" data-tab="dashboard">
<svg width="19" height="19" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/></svg>
<span>Dashboard</span>
</button>
<button class="nav-item" data-tab="generator" data-module="vendoo.ai">
<svg width="19" height="19" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 5v14M5 12h14"/><rect x="3" y="3" width="18" height="18" rx="3"/></svg>
<span>Neuer Artikel</span>
</button>
<button class="nav-item" data-tab="today" data-module="vendoo.listings">
<svg width="19" height="19" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M3 11.5 12 4l9 7.5"/><path d="M5.5 10.5V20h13v-9.5"/><path d="M9.5 20v-6h5v6"/></svg>
<span>Heute</span>
</button>
<button class="nav-item" data-tab="history" data-module="vendoo.listings">
<svg width="19" height="19" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="4" y="3" width="16" height="18" rx="2"/><path d="M8 7h8M8 11h8M8 15h5"/></svg>
<span>Artikel</span>
</button>
<button class="nav-item" data-tab="quality-center" data-module="vendoo.quality">
<svg width="19" height="19" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3 20 7v5c0 5-3.4 8.3-8 10-4.6-1.7-8-5-8-10V7Z"/><path d="m8.5 12 2.2 2.2 4.8-5"/></svg>
<span>Qualitätscenter</span>
</button>
<button class="nav-item" data-tab="publish" data-module="vendoo.publishing">
<svg width="19" height="19" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="m22 2-7 20-4-9-9-4Z"/><path d="M22 2 11 13"/></svg>
<span>Publish</span>
</button>
<button class="nav-item" data-tab="inventory" data-module="vendoo.inventory">
<svg width="19" height="19" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="m4 7 8-4 8 4-8 4Z"/><path d="m4 7 8 4 8-4v10l-8 4-8-4Z"/><path d="M12 11v10"/></svg>
<span>Lager</span>
</button>
<button class="nav-item" data-tab="templates" data-module="vendoo.listings">
<svg width="19" height="19" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="4" y="3" width="16" height="18" rx="2"/><path d="M8 8h8M8 12h8M8 16h5"/></svg>
<span>Vorlagen</span>
</button>
<button class="nav-item" data-tab="flux-studio" data-module="vendoo.flux-studio">
<svg width="19" height="19" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3 9.8 8.2 4 10l5 3.2L8 19l4-3 4 3-1-5.8 5-3.2-5.8-1.8Z"/><path d="M18 3v4M16 5h4"/></svg>
<span>FLUX Studio</span>
</button>
<button class="nav-item" data-tab="media-library" data-module="vendoo.media">
<svg width="19" height="19" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="16" rx="2"/><circle cx="8.5" cy="9" r="1.5"/><path d="m4 17 5-5 4 4 2-2 5 5"/></svg>
<span>Bilder</span>
</button>
<button class="nav-item" data-tab="image-factory" data-module="vendoo.ai">
<svg width="19" height="19" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4 4h6v6H4zM14 4h6v6h-6zM4 14h6v6H4z"/><path d="M14 17h6M17 14v6"/></svg>
<span>Bildproduktion</span>
</button>
<button class="nav-item" data-tab="extensions" data-module="vendoo.module-manager">
<svg width="19" height="19" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M8.5 3v4M15.5 3v4M6 7h12v4a6 6 0 0 1-12 0Z"/><path d="M12 17v4M9 21h6"/></svg>
<span>Extensions</span>
</button>
<button class="nav-item" data-tab="settings" data-module="vendoo.settings">
<svg width="19" height="19" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.7 1.7 0 0 0 .34 1.87l.05.05-2.83 2.83-.05-.05a1.7 1.7 0 0 0-1.87-.34 1.7 1.7 0 0 0-1.04 1.57V21h-4v-.07a1.7 1.7 0 0 0-1.04-1.57 1.7 1.7 0 0 0-1.87.34l-.05.05-2.83-2.83.05-.05A1.7 1.7 0 0 0 4.6 15a1.7 1.7 0 0 0-1.57-1.04H3v-4h.07A1.7 1.7 0 0 0 4.64 8.9a1.7 1.7 0 0 0-.34-1.87l-.05-.05 2.83-2.83.05.05A1.7 1.7 0 0 0 9 4.54 1.7 1.7 0 0 0 10.04 3H10V3h4v.07A1.7 1.7 0 0 0 15.04 4.6a1.7 1.7 0 0 0 1.87-.34l.05-.05 2.83 2.83-.05.05A1.7 1.7 0 0 0 19.4 9c.24.63.85 1.04 1.53 1.04H21v4h-.07c-.68 0-1.29.41-1.53 1.04Z"/></svg>
<span>Einstellungen</span>
</button>
<button class="nav-item" data-tab="admin" data-module="vendoo.users" data-admin-tab="users" id="nav-admin-main">
<svg width="19" height="19" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10Z"/><path d="M9 12h6M12 9v6"/></svg>
<span>Admin</span>
</button>
</div>
<div class="nav-group nav-group-tools" id="nav-system-group">
<div class="nav-divider"></div>
<button class="nav-item nav-item-quiet" data-tab="fees" data-module="vendoo.publishing">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="4" y="3" width="16" height="18" rx="2"/><path d="M8 7h8M8 11h3M8 15h3M15 11v5M13 13.5h4"/></svg>
<span>Gebühren</span>
</button>
<button class="nav-item nav-item-quiet" data-tab="trash" data-module="vendoo.listings">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4 7h16M9 7V4h6v3M7 7l1 14h8l1-14"/></svg>
<span>Papierkorb</span>
<span id="trash-badge" class="nav-badge hidden">0</span>
</button>
</div>
</nav>
<div class="sidebar-footer">
<div class="sidebar-user" id="sidebar-user">
<div class="sidebar-user-avatar" id="sidebar-avatar"></div>
<div class="sidebar-user-info">
<div class="sidebar-user-name" id="sidebar-name"></div>
<div class="sidebar-user-role" id="sidebar-role"></div>
</div>
<button class="sidebar-logout" id="sidebar-logout-btn" title="Abmelden" aria-label="Abmelden">
<svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M10 17l5-5-5-5M15 12H3M15 4h4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2h-4"/></svg>
</button>
</div>
<button id="theme-toggle" class="theme-toggle" title="Darstellung wechseln" aria-label="Darstellung wechseln">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.93 4.93l1.42 1.42M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.42-1.42M17.66 6.34l1.41-1.41"/></svg>
<span>Darstellung</span>
</button>
</div>
</aside>
<div class="sidebar-overlay" id="sidebar-overlay"></div>
<div class="main-wrapper">
<header class="topbar" id="topbar">
<div class="topbar-context">
<button class="sidebar-toggle" id="sidebar-toggle" type="button" aria-label="Menü" aria-controls="sidebar" aria-expanded="false">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"><path d="M4 7h16M4 12h16M4 17h16"/></svg>
</button>
<div class="topbar-context-icon" aria-hidden="true">
<svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3 4 7v10l8 4 8-4V7Z"/><path d="m4 7 8 4 8-4M12 11v10"/></svg>
</div>
<div class="topbar-heading">
<h1 class="topbar-title" id="topbar-title">Dashboard</h1>
<span class="topbar-kicker" id="topbar-kicker">Analytics</span>
</div>
</div>
<button class="command-search" id="topbar-search-btn" type="button" aria-label="Globale Suche öffnen">
<svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"><circle cx="11" cy="11" r="7"/><path d="m20 20-4-4"/></svg>
<span>Suche oder Befehl eingeben…</span>
<kbd>⌘ K</kbd>
</button>
<div class="topbar-actions">
<button class="topbar-btn primary" id="topbar-new-btn" data-module="vendoo.ai">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round"><path d="M12 5v14M5 12h14"/></svg>
<span>Neuer Artikel</span>
</button>
<button class="topbar-icon-btn" type="button" aria-label="Benachrichtigungen">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M18 8a6 6 0 0 0-12 0c0 7-3 7-3 9h18c0-2-3-2-3-9"/><path d="M10 21h4"/></svg>
<span class="topbar-dot" aria-hidden="true"></span>
</button>
<div class="topbar-avatar" id="topbar-avatar" aria-hidden="true">V</div>
</div>
</header>
<div class="connection-banner hidden" id="connection-banner" role="status" aria-live="polite">
<span class="connection-banner-dot" aria-hidden="true"></span>
<strong id="connection-banner-title">Vendoo ist nicht erreichbar</strong>
<span id="connection-banner-detail">Verbindung wird automatisch erneut geprüft.</span>
<button type="button" id="connection-retry-btn">Erneut prüfen</button>
</div>
<main>
<!-- ANALYTICS DASHBOARD -->
<section id="dashboard" class="tab-content active dashboard-page">
<header class="page-heading dashboard-heading">
<div>
<p class="eyebrow">Business Intelligence</p>
<h2>Dashboard</h2>
<p>Dein Überblick über Umsatz, Artikel, Lagerbestand und Performance.</p>
</div>
<div class="dashboard-controls">
<select id="dashboard-period" aria-label="Zeitraum">
<option value="7">Letzte 7 Tage</option>
<option value="30" selected>Letzte 30 Tage</option>
<option value="90">Letzte 90 Tage</option>
</select>
<button id="dashboard-refresh" class="vd-button" type="button">Aktualisieren</button>
</div>
</header>
<div class="dashboard-layout">
<div class="dashboard-main">
<section class="dashboard-kpis" aria-label="Kennzahlen">
<article class="dashboard-kpi"><span class="dashboard-kpi-icon"></span><div><small>Umsatz heute</small><strong id="dash-revenue-today"></strong><em>Aktueller Tageswert</em></div><svg id="spark-revenue" viewBox="0 0 100 28" aria-hidden="true"></svg></article>
<article class="dashboard-kpi"><span class="dashboard-kpi-icon"></span><div><small>Verkäufe 7 Tage</small><strong id="dash-sales-week"></strong><em>Abgeschlossene Verkäufe</em></div><svg id="spark-sales" viewBox="0 0 100 28" aria-hidden="true"></svg></article>
<article class="dashboard-kpi"><span class="dashboard-kpi-icon"></span><div><small>Aktive Artikel</small><strong id="dash-active-listings"></strong><em>Aktuell im Bestand</em></div><svg id="spark-active" viewBox="0 0 100 28" aria-hidden="true"></svg></article>
<article class="dashboard-kpi"><span class="dashboard-kpi-icon"></span><div><small>Entwürfe</small><strong id="dash-drafts"></strong><em>Noch nicht veröffentlicht</em></div><svg id="spark-drafts" viewBox="0 0 100 28" aria-hidden="true"></svg></article>
<article class="dashboard-kpi"><span class="dashboard-kpi-icon"></span><div><small>Lagerwert</small><strong id="dash-inventory-value"></strong><em>Geschätzter Gesamtwert</em></div><svg id="spark-inventory" viewBox="0 0 100 28" aria-hidden="true"></svg></article>
<article class="dashboard-kpi"><span class="dashboard-kpi-icon"></span><div><small>Publish-Erfolgsquote</small><strong id="dash-publish-rate"></strong><em>Erfolgreiche Versuche</em></div><svg id="spark-publish" viewBox="0 0 100 28" aria-hidden="true"></svg></article>
</section>
<section class="dashboard-chart-grid">
<article class="dashboard-card dashboard-line-card">
<header><div><span>Umsatzentwicklung</span><strong id="dash-period-revenue"></strong></div><small id="dash-period-label">Letzte 30 Tage</small></header>
<div id="dashboard-line-chart" class="dashboard-chart" aria-label="Umsatzentwicklung"></div>
</article>
<article class="dashboard-card">
<header><div><span>Umsatz nach Plattform</span><strong id="dash-platform-total"></strong></div></header>
<div id="dashboard-platform-chart" class="dashboard-bar-chart" aria-label="Umsatz nach Plattform"></div>
</article>
<article class="dashboard-card">
<header><div><span>Umsatz nach Kategorie</span><strong>Verteilung</strong></div></header>
<div id="dashboard-category-chart" class="dashboard-category-chart" aria-label="Umsatz nach Kategorie"></div>
</article>
</section>
<section class="dashboard-card dashboard-focus-card">
<header><div><span>Heute im Fokus</span><strong>Direkt handlungsrelevant</strong></div></header>
<div id="dashboard-focus" class="dashboard-focus-grid"></div>
</section>
<section class="dashboard-lower-grid">
<article class="dashboard-card dashboard-sellers-card">
<header><div><span>Top Seller / Bestseller</span><strong>Nach Umsatz</strong></div><button class="text-action" type="button" data-tab-target="history">Alle anzeigen</button></header>
<div class="dashboard-table-wrap"><table class="dashboard-table"><thead><tr><th>Artikel</th><th>SKU</th><th>Plattform</th><th>Umsatz</th><th>Verkäufe</th><th>Status</th></tr></thead><tbody id="dashboard-top-sellers"></tbody></table></div>
</article>
<article class="dashboard-card dashboard-actions-card">
<header><div><span>Schnellaktionen</span><strong>Häufige Aufgaben</strong></div></header>
<div class="dashboard-actions">
<button type="button" class="primary" data-dashboard-action="new">+ Neuer Artikel</button>
<button type="button" data-dashboard-action="qr">QR-Upload starten</button>
<button type="button" data-dashboard-action="photos">Fotos als ZIP laden</button>
<button type="button" data-dashboard-action="publish">Bulk Publish</button>
<button type="button" data-dashboard-action="template">Vorlage anwenden</button>
</div>
</article>
</section>
</div>
<aside class="dashboard-rail">
<section class="dashboard-card dashboard-quality-card">
<header><div><span>AI &amp; Qualität</span><strong>Listing-Qualität</strong></div></header>
<div class="dashboard-quality"><div id="dashboard-quality-ring" class="confidence-ring"><span id="dashboard-quality-value"></span></div><div><strong id="dashboard-quality-label">Wird berechnet</strong><p>Durchschnittliche Vollständigkeit deiner Artikel.</p></div></div>
<button class="vd-button full" type="button" data-tab-target="history">Analyse öffnen</button>
</section>
<section class="dashboard-card"><header><div><span>Aktivität</span><strong>Letzte Ereignisse</strong></div></header><div id="dashboard-activity" class="dashboard-feed"></div></section>
<section class="dashboard-card"><header><div><span>Benachrichtigungen</span><strong>Benötigt Aufmerksamkeit</strong></div></header><div id="dashboard-notifications" class="dashboard-feed"></div></section>
<section class="dashboard-card dashboard-system"><header><div><span>Systemstatus</span><strong id="dashboard-system-state">Wird geprüft</strong></div></header><p id="dashboard-system-copy">Verbindungen und Warteschlangen werden geladen.</p><button class="vd-button full" type="button" data-tab-target="settings">Verbindungen prüfen</button></section>
</aside>
</div>
</section>
<!-- STUDIO FLOW / HEUTE -->
<section id="today" class="tab-content studio-flow-page studio-flow-v2">
<header class="page-heading studio-heading">
<div>
<p class="eyebrow">Commerce Workbench</p>
<h2>Studio Flow</h2>
<p>Deine nächsten Schritte klar priorisiert und ohne Kartenüberladung.</p>
</div>
</header>
<section class="today-summary-grid" aria-label="Studio-Flow-Status">
<button type="button" data-today-filter="ready"><span></span><strong id="today-count-ready">0</strong><small>Bereit</small><em>Prüfbereit</em></button>
<button type="button" data-today-filter="scheduled"><span></span><strong id="today-count-scheduled">0</strong><small>Geplant</small><em>In Warteschlange</em></button>
<button type="button" data-today-filter="published"><span></span><strong id="today-count-published">0</strong><small>Veröffentlicht</small><em>Aktuell live</em></button>
<button type="button" data-today-filter="sold"><span></span><strong id="today-count-sold">0</strong><small>Verkauft</small><em>Abgeschlossen</em></button>
<button type="button" data-today-filter="attention"><span>!</span><strong id="today-count-attention">0</strong><small>Benötigt</small><em>Aufmerksamkeit</em></button>
</section>
<div class="today-filterbar">
<div class="today-filter-tabs" role="tablist">
<button class="active" type="button" data-today-filter="all">Alle</button>
<button type="button" data-today-filter="ready">Bereit</button>
<button type="button" data-today-filter="scheduled">Geplant</button>
<button type="button" data-today-filter="attention">Probleme</button>
<button type="button" data-today-filter="sold">Verkauft</button>
</div>
<select id="today-sort" aria-label="Sortierung"><option value="priority">Sortieren: Priorität</option><option value="newest">Neueste zuerst</option><option value="price">Preis absteigend</option></select>
</div>
<div class="studio-layout studio-layout-v2">
<div class="studio-workspace">
<section class="work-panel today-ready-panel">
<div class="work-panel-header"><div><h3>Bereit für den nächsten Schritt</h3><span class="panel-count" id="today-ready-total">0</span></div><button class="text-action" type="button" data-tab-target="history">Alle Bereit anzeigen</button></div>
<div id="today-ready-grid" class="today-ready-grid"></div>
</section>
<div class="today-middle-grid">
<section class="work-panel today-scheduled-panel">
<div class="work-panel-header"><div><h3>Geplant &amp; in Warteschlange</h3><span class="panel-count" id="today-scheduled-total">0</span></div><button class="text-action" type="button" data-tab-target="publish">Alle Planungen</button></div>
<div class="today-table-wrap"><table class="today-table"><thead><tr><th>Artikel</th><th>Plattform</th><th>Geplant am</th><th>Status</th><th>Aktion</th></tr></thead><tbody id="today-scheduled-list"></tbody></table></div>
</section>
<section class="work-panel attention-panel">
<div class="work-panel-header"><div><span class="panel-icon panel-icon-warning">!</span><h3>Benötigt Aufmerksamkeit</h3></div><span class="panel-count" id="attention-count">0</span></div>
<div id="studio-attention" class="attention-list compact"></div>
<button class="text-action today-panel-footer" type="button" data-today-filter="attention">Alle Probleme anzeigen</button>
</section>
</div>
<section class="work-panel activity-panel today-activity-panel">
<div class="work-panel-header"><div><h3>Aktivität</h3></div><button class="text-action" type="button" data-tab-target="history">Alle Aktivitäten</button></div>
<div class="today-activity-grid"><div><h4>Letzte Aktivitäten</h4><div id="studio-activity" class="activity-list"></div></div><div><h4>Abgeschlossene Aktionen</h4><div id="studio-completed" class="activity-list"></div></div></div>
</section>
</div>
<aside class="studio-inspector" id="studio-inspector" aria-label="Artikelkontext">
<div class="inspector-empty" id="studio-inspector-empty"><div class="inspector-empty-mark"></div><h3>Artikel auswählen</h3><p>Wähle ein Listing, um Details und nächste Aktionen zu sehen.</p></div>
<div class="inspector-content hidden" id="studio-inspector-content"></div>
</aside>
</div>
</section>
<!-- GENERATOR -->
<section id="generator" class="tab-content generator-studio-page">
<header class="page-heading generator-heading">
<div>
<p class="eyebrow">Listing Studio</p>
<h2>Neuer Artikel</h2>
<p>Fotos erfassen, AI gezielt steuern und das Ergebnis ohne Kontextwechsel fertigstellen.</p>
</div>
<div class="generator-heading-actions">
<button id="reset-generator-btn" class="vd-button secondary" type="button">
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"><path d="M3 12a9 9 0 1 0 3-6.7L3 8"/><path d="M3 3v5h5"/></svg>
Formular leeren
</button>
</div>
</header>
<div class="generator-commandbar" id="generator-commandbar">
<div class="generator-command-progress">
<div class="generator-stepper" aria-label="Arbeitsfortschritt">
<span class="generator-step is-active" id="generator-step-photos"><b>1</b> Fotos</span>
<span class="generator-step" id="generator-step-ai"><b>2</b> Generieren</span>
<span class="generator-step" id="generator-step-result"><b>3</b> Prüfen</span>
</div>
<div class="generator-readiness">
<span id="generator-readiness-dot"></span>
<div>
<strong id="generator-readiness-title">Fotos fehlen</strong>
<small id="generator-readiness-copy">Lade mindestens ein Produktfoto hoch.</small>
</div>
</div>
</div>
<div class="generator-command-actions">
<button id="generate-btn" class="vd-button primary generator-primary-action" disabled>
<span aria-hidden="true"></span>
Artikel generieren
</button>
<button id="save-btn" class="vd-button generator-save-action" disabled>
Speichern
</button>
</div>
</div>
<div class="generator-studio-layout">
<section class="generator-panel media-workbench" aria-labelledby="generator-media-title">
<div class="generator-panel-header">
<div>
<span class="generator-panel-index">01</span>
<div>
<h3 id="generator-media-title">Fotos &amp; Medien</h3>
<p>Das erste Bild wird als Cover verwendet.</p>
</div>
</div>
<span id="generator-photo-count" class="generator-count">0 / 10</span>
</div>
<div id="generator-photo-stage" class="generator-photo-stage">
<div id="generator-photo-empty" class="generator-photo-empty">
<div class="generator-photo-empty-mark">
<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="16" rx="2"/><circle cx="9" cy="10" r="2"/><path d="m21 15-5-5L5 20"/></svg>
</div>
<strong>Noch keine Produktfotos</strong>
<span>Gute Bilder erhöhen Erkennungsqualität und Verkaufschance.</span>
</div>
<img id="generator-cover" class="generator-cover hidden" alt="Coverfoto des Artikels">
<span id="generator-cover-badge" class="generator-cover-badge hidden">Cover</span>
</div>
<div id="dropzone" class="dropzone generator-dropzone">
<input type="file" id="file-input" multiple accept="image/*" hidden>
<div class="generator-dropzone-icon">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><path d="M12 16V4"/><path d="m7 9 5-5 5 5"/><path d="M20 15v4a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-4"/></svg>
</div>
<p><strong>Fotos hierher ziehen</strong><br>oder klicken zum Auswählen</p>
<small>JPG, PNG, WEBP oder GIF · maximal 10 Bilder</small>
</div>
<button id="generator-mobile-upload" class="mobile-upload-trigger" type="button">
<span class="mobile-upload-trigger-icon"></span>
<span><strong>Mit dem Handy fotografieren</strong><small>QR-Code scannen und Bilder direkt übertragen</small></span>
<b>QR</b>
</button>
<div id="photo-preview" class="photo-preview generator-photo-strip" aria-label="Hochgeladene Fotos"></div>
<div id="image-tools" class="image-tools generator-image-tools hidden">
<button id="advanced-image-editor-btn" class="small-btn advanced-editor-entry" type="button">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20h9"/><path d="M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z"/><path d="m15 5 3 3"/></svg>
Advanced Editor öffnen
</button>
<button id="generator-download-photos" class="small-btn" type="button">Fotos herunterladen</button>
</div>
<section id="generator-ai-model-card" class="ai-model-card generator-ai-model-card hidden" data-module-panel="vendoo.product-image-tools">
<div class="ai-model-card-head">
<div>
<span class="generator-panel-index">AI</span>
<div>
<h4>Produktbild Studio</h4>
<p>Optionales Modul für kontrollierte Ghost-Mannequin- und Flatlay-Varianten. Aktivierung und Deaktivierung erfolgen im Modulmanager.</p>
</div>
</div>
<span id="generator-ai-model-badge" class="generator-beta">Safe</span>
</div>
<div class="ai-model-controls">
<label>Look
<select id="generator-ai-model-preset" class="model-select">
<option value="mixed">Mix</option>
<option value="studio">Studio</option>
<option value="indoor">Indoor</option>
<option value="outdoor">Outdoor</option>
</select>
</label>
<label>Modus
<select id="generator-ai-model-mode" class="model-select">
<option value="ghost_mannequin">Ghost Mannequin</option>
<option value="flatlay" selected>Flatlay</option>
</select>
</label>
<label>Varianten
<select id="generator-ai-model-variants" class="model-select">
<option value="1" selected>1 Bild</option>
<option value="2">2 Bilder</option>
<option value="3">3 Bilder</option>
</select>
</label>
<button id="generator-ai-model-prompt-btn" class="small-btn ghost" type="button">Prompt…</button>
<button id="generator-ai-model-btn" class="small-btn" type="button">Bild erzeugen</button>
</div>
<div id="generator-ai-model-status" class="ai-model-status">Wartet auf Produktfotos.</div>
<div id="generator-ai-model-grid" class="ai-model-grid hidden"></div>
</section>
<div class="generator-photo-quality">
<div class="generator-photo-quality-head">
<div>
<span class="quality-spark"></span>
<strong>Foto-Check</strong>
</div>
<span id="generator-photo-quality-score">0 / 5</span>
</div>
<ul id="generator-photo-tips">
<li data-photo-tip="count"><span></span>Mindestens drei Perspektiven</li>
<li data-photo-tip="cover"><span></span>Klares Coverfoto</li>
<li data-photo-tip="details"><span></span>Detail- und Etikettfoto</li>
<li data-photo-tip="background"><span></span>Ruhiger Hintergrund empfohlen</li>
<li data-photo-tip="order"><span></span>Reihenfolge per Drag &amp; Drop</li>
</ul>
</div>
</section>
<section class="generator-panel generator-config-panel" aria-labelledby="generator-ai-title">
<div class="generator-panel-header">
<div>
<span class="generator-panel-index">02</span>
<div>
<h3 id="generator-ai-title">AI-Generator</h3>
<p>Lege Ziel, Sprache und Tonalität fest.</p>
</div>
</div>
<span class="generator-beta">Assistiert</span>
</div>
<div class="generator-config-stack">
<div class="generator-config-card">
<div class="generator-config-copy">
<label>Plattform</label>
<span>Optimiert Aufbau, Ton und Pflichtfelder.</span>
</div>
<div id="platform-buttons" class="button-group generator-choice-group"></div>
</div>
<div class="generator-config-card">
<div class="generator-config-copy">
<label>AI Provider</label>
<span>Wähle den bevorzugten Analyse-Dienst.</span>
</div>
<div id="provider-buttons" class="button-group generator-choice-group"></div>
</div>
<div id="model-select-wrap" class="generator-config-card hidden">
<div class="generator-config-copy">
<label for="model-select">Modell</label>
<span>Steuert Qualität, Geschwindigkeit und Kosten.</span>
</div>
<select id="model-select" class="model-select"></select>
</div>
<div class="generator-config-pair">
<div class="generator-config-card compact">
<div class="generator-config-copy">
<label for="language-select">Sprache</label>
</div>
<select id="language-select" class="model-select">
<option value="de">Deutsch</option>
<option value="en">English</option>
<option value="fr">Français</option>
<option value="nl">Nederlands</option>
<option value="pl">Polski</option>
<option value="es">Español</option>
<option value="it">Italiano</option>
<option value="pt">Português</option>
</select>
</div>
<div class="generator-config-card compact">
<div class="generator-config-copy">
<label for="variants-select">Varianten</label>
</div>
<select id="variants-select" class="model-select">
<option value="1">1 Variante</option>
<option value="2">2 Varianten</option>
<option value="3">3 Varianten</option>
</select>
</div>
</div>
<div class="generator-config-card">
<div class="generator-config-copy">
<label for="template-select">Vorlage</label>
<span>Übernimmt Plattform, Sprache, Hinweise und Standard-Tags.</span>
</div>
<select id="template-select" class="model-select">
<option value="">Keine Vorlage</option>
</select>
<div id="generator-template-tags" class="generator-template-tags hidden"></div>
</div>
<div class="generator-notes-card">
<div class="generator-notes-head">
<div>
<label for="generator-seller-notes">Verkäufer-Notizen</label>
<span>Nur relevante Besonderheiten für diesen Artikel.</span>
</div>
<span id="generator-notes-count">0 / 500</span>
</div>
<textarea id="generator-seller-notes" maxlength="500" rows="5" placeholder="Zum Beispiel: leichte Gebrauchsspur am Ärmel, Originalverpackung vorhanden, Nichtraucherhaushalt …"></textarea>
<div class="generator-tone-row">
<span>Ton: freundlich &amp; präzise</span>
<span>Detailgrad: hoch</span>
<span>Keine Übertreibungen</span>
</div>
</div>
</div>
<div id="loading" class="loading generator-loading hidden" aria-live="polite">
<div class="spinner"></div>
<p><strong>AI analysiert deine Fotos</strong><br><span id="generator-loading-copy">Produkt, Zustand und Marktplatzdaten werden vorbereitet.</span></p>
</div>
</section>
<aside class="generator-panel generator-preview-panel" aria-labelledby="generator-preview-title">
<div class="generator-panel-header generator-preview-header">
<div>
<span class="generator-panel-index">03</span>
<div>
<h3 id="generator-preview-title">Vorschau &amp; Bearbeiten</h3>
<p>Prüfe jeden Vorschlag vor dem Speichern.</p>
</div>
</div>
<span id="generator-preview-status" class="generator-preview-status">Wartet</span>
</div>
<div id="generator-preview-empty" class="generator-preview-empty">
<div class="generator-preview-empty-mark">VD</div>
<h3>Dein Listing entsteht hier</h3>
<p>Sobald Fotos hochgeladen und analysiert wurden, kannst du Titel, Text, Attribute und Preis direkt bearbeiten.</p>
<div class="generator-preview-skeleton" aria-hidden="true">
<span></span><span></span><span></span><span></span>
</div>
</div>
<div id="variants-section" class="hidden generator-variant-wrap">
<div class="generator-section-label">Textvarianten</div>
<div id="variant-tabs" class="variant-tabs"></div>
</div>
<div id="result-section" class="result-section generator-result hidden">
<div class="generator-result-score">
<div>
<span>Listing-Qualität</span>
<strong id="generator-quality-label">Sehr gut</strong>
</div>
<div class="generator-quality-ring" id="generator-quality-ring" style="--quality: 0%"><span id="generator-quality-score">0%</span></div>
</div>
<div class="result-field">
<div class="field-header">
<label for="result-title">Titel</label>
<div><span id="result-title-count" class="field-count">0 / 80</span><button class="copy-btn" data-target="result-title">Kopieren</button></div>
</div>
<input type="text" id="result-title" class="result-input" maxlength="120">
</div>
<div class="result-field">
<div class="field-header">
<label>Beschreibung</label>
<div><span id="result-description-count" class="field-count">0 Zeichen</span><button class="copy-btn" id="copy-desc-text">Text kopieren</button></div>
</div>
<div id="result-description-editor"></div>
</div>
<div class="result-field">
<div class="field-header">
<label id="tags-label" for="result-tags">Tags</label>
<div><span id="result-tags-count" class="field-count">0</span><button class="copy-btn" data-target="result-tags">Kopieren</button></div>
</div>
<input type="text" id="result-tags" class="result-input" placeholder="Tags durch Komma trennen">
</div>
<div id="meta-section" class="meta-section generator-meta-section hidden">
<div class="generator-section-label">Erkannte Eigenschaften</div>
<div class="meta-grid-edit">
<div class="meta-edit-item"><label class="meta-label" for="meta-sku">Artikelnr. (SKU)</label><input type="text" id="meta-sku" class="meta-input" readonly></div>
<div class="meta-edit-item"><label class="meta-label" for="meta-brand">Marke</label><input type="text" id="meta-brand" class="meta-input"></div>
<div class="meta-edit-item meta-category-item"><label class="meta-label">Kategorie</label><div id="meta-category-picker" class="cat-picker"></div></div>
<div class="meta-edit-item"><label class="meta-label" for="meta-size">Größe</label><input type="text" id="meta-size" class="meta-input"></div>
<div class="meta-edit-item"><label class="meta-label" for="meta-color">Farbe</label><input type="text" id="meta-color" class="meta-input"></div>
<div class="meta-edit-item"><label class="meta-label" for="meta-condition">Zustand</label><input type="text" id="meta-condition" class="meta-input"></div>
<div class="meta-edit-item"><label class="meta-label" for="meta-price">Preisvorschlag (€)</label><input type="number" id="meta-price" class="meta-input" step="0.5" min="0"></div>
<div class="meta-edit-item"><label class="meta-label" for="meta-storage-location">Lagerort</label><input type="text" id="meta-storage-location" class="meta-input" placeholder="z. B. Regal A2"></div>
</div>
<div id="fee-info" class="fee-info hidden"></div>
</div>
<details class="generator-html-details" id="html-preview-wrap" open>
<summary>Plattformvorschau <span>HTML-Code jederzeit umschaltbar</span></summary>
<div class="html-view-toolbar">
<div class="html-view-tabs" role="tablist" aria-label="Vorschauansicht">
<button class="html-view-tab is-active" type="button" data-html-scope="generator" data-html-view="preview">Plattformvorschau</button>
<button class="html-view-tab" type="button" data-html-scope="generator" data-html-view="code">HTML-Code</button>
</div>
<div class="generator-html-actions">
<button class="copy-btn" id="copy-desc-html" type="button">Editor-HTML kopieren</button>
<button class="copy-btn" id="copy-platform-html" type="button">Plattform-HTML kopieren</button>
<button class="copy-btn" id="format-html-source" type="button">Code bereinigen</button>
</div>
</div>
<div class="html-switch-stage">
<div id="generator-preview-view" class="html-switch-view is-active" data-html-panel="preview">
<div class="generator-html-pane-head"><strong>Plattformvorschau</strong><span id="generator-html-sync-status">Synchron</span></div>
<iframe id="html-preview" class="html-preview html-preview-frame" sandbox title="Plattformvorschau"></iframe>
</div>
<div id="generator-code-view" class="html-switch-view" data-html-panel="code">
<div class="generator-html-pane-head"><strong>HTML-Code</strong><span>Direkt editierbar · live synchronisiert</span></div>
<textarea id="html-source" class="result-textarea html-source" rows="14" spellcheck="false" aria-label="HTML-Code der Beschreibung"></textarea>
</div>
</div>
</details>
<div class="result-actions generator-result-actions">
<button id="copy-all-btn" class="secondary-btn">Alles kopieren</button>
<span>Speichern ist dauerhaft oben erreichbar.</span>
</div>
</div>
</aside>
</div>
</section>
<!-- LISTINGS / HISTORIE -->
<section id="history" class="tab-content listings-page">
<header class="page-heading listings-heading">
<div>
<p class="eyebrow">Listing-Verwaltung</p>
<h2>Artikel</h2>
<p>Überblick über alle erstellten, geplanten und veröffentlichten Artikel.</p>
</div>
<div class="listings-heading-actions">
<div class="history-export-wrap">
<button id="history-export-toggle" class="vd-button secondary" type="button" aria-expanded="false">
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3v12"/><path d="m7 10 5 5 5-5"/><path d="M5 21h14"/></svg>
Exportieren
<span aria-hidden="true"></span>
</button>
<div id="history-export-menu" class="history-popover history-export-menu hidden">
<button id="export-csv-btn" type="button">CSV exportieren</button>
<button id="export-json-btn" type="button">JSON exportieren</button>
</div>
</div>
<div class="history-columns-wrap">
<button id="history-columns-btn" class="vd-button secondary" type="button" aria-expanded="false">
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4 5h16M4 12h16M4 19h16"/><path d="M8 3v4M15 10v4M11 17v4"/></svg>
Spalten anpassen
</button>
<div id="history-columns-panel" class="history-popover history-columns-panel hidden">
<strong>Sichtbare Spalten</strong>
<label><input type="checkbox" data-history-column="platform" checked> Plattform</label>
<label><input type="checkbox" data-history-column="provider" checked> AI-Provider</label>
<label><input type="checkbox" data-history-column="price" checked> Preis</label>
<label><input type="checkbox" data-history-column="status" checked> Status</label>
<label><input type="checkbox" data-history-column="location" checked> Lagerort</label>
<label><input type="checkbox" data-history-column="published" checked> Veröffentlicht</label>
</div>
</div>
</div>
</header>
<div class="history-filterbar" aria-label="Listing-Filter">
<label class="history-search-field">
<svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"><circle cx="11" cy="11" r="7"/><path d="m20 20-4-4"/></svg>
<input type="search" id="search-input" placeholder="Titel, SKU, Marke oder Beschreibung">
</label>
<label class="history-filter-field">
<span>Plattform</span>
<select id="filter-platform"><option value="">Alle</option></select>
</label>
<label class="history-filter-field">
<span>Status</span>
<select id="filter-status">
<option value="">Alle</option>
<option value="active">Aktiv</option>
<option value="sold">Verkauft</option>
<option value="reserved">Reserviert</option>
</select>
</label>
<label class="history-filter-field history-period-field">
<span>Zeitraum</span>
<select id="history-period">
<option value="90">Letzte 90 Tage</option>
<option value="30">Letzte 30 Tage</option>
<option value="7">Letzte 7 Tage</option>
<option value="year">Dieses Jahr</option>
<option value="all">Gesamter Zeitraum</option>
<option value="custom">Benutzerdefiniert</option>
</select>
</label>
<div id="history-custom-dates" class="history-custom-dates hidden">
<label><span>Von</span><input type="date" id="filter-date-from" title="Von Datum"></label>
<label><span>Bis</span><input type="date" id="filter-date-to" title="Bis Datum"></label>
</div>
<button id="history-reset-filters" class="vd-button ghost" type="button">
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12a9 9 0 1 0 3-6.7"/><path d="M3 4v6h6"/></svg>
Filter zurücksetzen
</button>
</div>
<div class="history-table-shell">
<div id="history-batch-bar" class="history-batch-bar">
<label class="history-select-all-wrap">
<input type="checkbox" id="history-select-all">
<span id="history-selected-count">0 ausgewählt</span>
</label>
<div class="history-batch-actions">
<button id="history-publish-selected" class="vd-button compact" disabled>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="m22 2-7 20-4-9-9-4Z"/><path d="M22 2 11 13"/></svg>
Veröffentlichen
</button>
<button id="history-edit-selected" class="vd-button compact" disabled>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20h9"/><path d="M16.5 3.5a2.1 2.1 0 0 1 3 3L7 19l-4 1 1-4Z"/></svg>
Nachbearbeiten
</button>
<button id="history-price-selected" class="vd-button compact" disabled>Preis aktualisieren</button>
<button id="history-bulk-status" class="vd-button compact" disabled>Status ändern</button>
<button id="history-duplicate-selected" class="vd-button compact" disabled>Duplizieren</button>
<button id="history-print-labels" class="vd-button compact" disabled>Etiketten</button>
<button id="history-delete-selected" class="vd-button compact danger" disabled>Löschen</button>
</div>
<button id="history-clear-selection" class="history-clear-selection hidden" type="button">Auswahl aufheben</button>
</div>
<div id="history-table" class="history-table" role="table" aria-label="Artikel">
<div class="history-table-head" role="row">
<div class="history-cell history-cell-select" role="columnheader"><span class="sr-only">Auswahl</span></div>
<div class="history-cell history-cell-article" role="columnheader">Artikel</div>
<div class="history-cell history-cell-platform" data-column="platform" role="columnheader">Plattform</div>
<div class="history-cell history-cell-provider" data-column="provider" role="columnheader">AI-Provider</div>
<div class="history-cell history-cell-price" data-column="price" role="columnheader">Preis</div>
<div class="history-cell history-cell-status" data-column="status" role="columnheader">Status</div>
<div class="history-cell history-cell-location" data-column="location" role="columnheader">Lagerort</div>
<div class="history-cell history-cell-published" data-column="published" role="columnheader">Veröffentlicht</div>
<div class="history-cell history-cell-menu" role="columnheader"><span class="sr-only">Aktionen</span></div>
</div>
<div id="history-list" class="history-list" role="rowgroup"></div>
</div>
<div class="history-table-footer" id="history-pagination-bottom">
<label class="history-page-size">
<span>Zeige</span>
<select id="history-page-size-select">
<option value="10">10</option>
<option value="20">20</option>
<option value="50">50</option>
<option value="0">Alle</option>
</select>
<span id="history-total-info">von 0 Einträgen</span>
</label>
<div class="pagination-nav history-pagination-nav">
<button class="page-nav-btn" id="history-prev-bottom" disabled aria-label="Vorherige Seite"></button>
<div id="history-page-buttons" class="history-page-buttons"></div>
<button class="page-nav-btn" id="history-next-bottom" disabled aria-label="Nächste Seite"></button>
</div>
</div>
</div>
<div class="pagination-bar hidden" id="history-pagination-top">
<div class="pagination-nav">
<button class="page-nav-btn" id="history-prev" disabled>Zurück</button>
<span class="page-info" id="history-page-info">Seite 1 von 1</span>
<button class="page-nav-btn" id="history-next" disabled>Weiter</button>
</div>
</div>
<span class="page-info hidden" id="history-page-info-bottom">Seite 1 von 1</span>
<button id="history-delete-all" class="hidden" type="button">Alle löschen</button>
<div id="history-detail" class="history-detail hidden">
<button id="back-to-list" class="secondary-btn">Zurück zur Übersicht</button>
<div id="detail-content"></div>
</div>
</section>
<!-- VORLAGEN -->
<section id="templates" class="tab-content">
<div class="templates-header">
<h2>Listing-Vorlagen</h2>
<button id="add-template-btn" class="primary-btn">Neue Vorlage</button>
</div>
<div id="template-list" class="template-list"></div>
<div id="template-form" class="template-form hidden">
<h3 id="template-form-title">Neue Vorlage</h3>
<div class="setting-group">
<label>Name</label>
<input type="text" id="tpl-name" placeholder="z.B. Sneaker-Template">
</div>
<div class="setting-group">
<label>Plattform</label>
<select id="tpl-platform"><option value="">Alle</option></select>
</div>
<div class="setting-group">
<label>Sprache</label>
<select id="tpl-language">
<option value="de">Deutsch</option>
<option value="en">English</option>
<option value="fr">Français</option>
</select>
</div>
<div class="setting-group">
<label>Verkäufernotizen</label>
<div id="tpl-notes-editor" style="min-height:100px"></div>
</div>
<div class="setting-group">
<label>Standard-Tags (kommagetrennt)</label>
<input type="text" id="tpl-tags" placeholder="#vintage, #secondhand">
</div>
<div class="result-actions">
<button id="save-template-btn" class="primary-btn">Speichern</button>
<button id="cancel-template-btn" class="secondary-btn">Abbrechen</button>
</div>
</div>
</section>
<!-- VERÖFFENTLICHEN -->
<section id="quality-center" class="tab-content quality-center-page">
<header class="page-heading quality-center-heading">
<div><p class="eyebrow">Artikel Quality Center</p><h2>Qualitätscenter</h2><p>Prüfe Inhalte, Bilder, Pflichtfelder, mögliche Duplikate und Plattformtauglichkeit vor dem Veröffentlichen.</p></div>
<div class="page-heading-actions"><button type="button" class="vd-button" id="quality-refresh">Aktualisieren</button><button type="button" class="primary-btn" id="quality-analyze-visible">Sichtbare prüfen</button></div>
</header>
<div class="quality-summary-grid">
<article><span>Durchschnitt</span><strong id="quality-summary-average"></strong><small>Qualitätsscore</small></article>
<article><span>Bereit</span><strong id="quality-summary-ready"></strong><small>ohne Blocker</small></article>
<article><span>Blockiert</span><strong id="quality-summary-blocked"></strong><small>harte Fehler</small></article>
<article><span>Artikel</span><strong id="quality-summary-total"></strong><small>im Bestand</small></article>
</div>
<div class="quality-toolbar card">
<label class="quality-search"><span>Suchen</span><input type="search" id="quality-search" placeholder="Titel, SKU oder Plattform"></label>
<label><span>Status</span><select id="quality-status"><option value="all">Alle</option><option value="blocked">Blockiert</option><option value="review">Prüfen</option><option value="ready">Bereit</option></select></label>
<label><span>Note</span><select id="quality-grade"><option value="all">Alle Noten</option><option value="A">A</option><option value="B">B</option><option value="C">C</option><option value="D">D</option><option value="E">E</option></select></label>
<label><span>Pro Seite</span><select id="quality-page-size"><option value="5">5</option><option value="10" selected>10</option><option value="15">15</option><option value="25">25</option></select></label>
</div>
<div class="quality-workspace">
<section class="quality-list-panel card">
<div class="section-title-row"><div><p class="eyebrow">Prüfliste</p><h3>Artikelqualität</h3></div><span id="quality-list-range">0 Artikel</span></div>
<div id="quality-list" class="quality-list"><div class="empty-state"><p>Qualitätsdaten werden geladen …</p></div></div>
<div class="quality-pagination"><button type="button" class="page-nav-btn" id="quality-prev"></button><span id="quality-page-info">Seite 1 von 1</span><button type="button" class="page-nav-btn" id="quality-next"></button></div>
</section>
<aside class="quality-detail-panel card" id="quality-detail-panel">
<div class="quality-detail-empty" id="quality-detail-empty"><div class="quality-empty-icon"></div><h3>Artikel auswählen</h3><p>Öffne eine Qualitätsprüfung, um Blocker, Empfehlungen, Bilder und Verbesserungsvorschläge zu sehen.</p></div>
<div class="quality-detail-content hidden" id="quality-detail-content">
<header class="quality-detail-head">
<div class="quality-score-ring" id="quality-score-ring"><strong id="quality-detail-score">0</strong><span>/ 100</span></div>
<div><p class="eyebrow" id="quality-detail-platform">Plattform</p><h3 id="quality-detail-title">Artikel</h3><p id="quality-detail-meta"></p></div>
</header>
<div class="quality-readiness" id="quality-readiness"></div>
<div class="quality-detail-actions"><button type="button" class="primary-btn" id="quality-run-analysis">Neu analysieren</button><button type="button" class="vd-button" id="quality-open-article">Artikel bearbeiten</button><button type="button" class="vd-button accent" id="quality-open-ai">Mit AI verbessern</button></div>
<div class="quality-financials" id="quality-financials"></div>
<div class="quality-issue-tabs" role="tablist"><button type="button" class="active" data-quality-issue-filter="all">Alle</button><button type="button" data-quality-issue-filter="error">Blocker</button><button type="button" data-quality-issue-filter="warning">Warnungen</button><button type="button" data-quality-issue-filter="recommendation">Empfehlungen</button></div>
<div id="quality-issues" class="quality-issues"></div>
<section class="quality-duplicates"><div class="section-title-row"><h4>Mögliche Duplikate</h4></div><div id="quality-duplicates"></div></section>
<section class="quality-images"><div class="section-title-row"><h4>Bildprüfung</h4></div><div id="quality-images"></div></section>
<section class="quality-history"><div class="section-title-row"><h4>Score-Verlauf</h4><span id="quality-score-delta"></span></div><div id="quality-history"></div></section>
</div>
</aside>
</div>
</section>
<section id="publish" class="tab-content publish-center-page">
<header class="page-heading publish-center-heading">
<div>
<p class="eyebrow">Commerce Control</p>
<h2>Publish-Center</h2>
<p>Bereite Artikel für den Verkauf vor und veröffentliche sie sicher auf deinen Marktplätzen.</p>
</div>
<div class="publish-heading-actions">
<button id="publish-refresh" class="vd-button" type="button">Aktualisieren</button>
<button id="publish-add-selected-ebay" class="vd-button primary" type="button" disabled>Zur Publishing-Queue</button>
</div>
</header>
<nav class="publish-view-tabs" aria-label="Publish-Bereiche">
<button class="publish-view-tab active" type="button" data-publish-view="smart">
Smart Copy <span class="publish-tab-badge">Manuell</span>
</button>
<button class="publish-view-tab" type="button" data-publish-view="direct">
Direkt veröffentlichen <span class="publish-tab-count" id="publish-direct-count">0</span>
</button>
<button class="publish-view-tab" type="button" data-publish-view="queue">
Publishing-Queue <span class="publish-tab-count" id="publish-queue-count">0</span>
</button>
<button class="publish-view-tab" type="button" data-publish-view="errors">
Fehler &amp; Verlauf <span class="publish-tab-count" id="publish-error-count">0</span>
</button>
<button class="publish-view-tab" type="button" data-publish-view="scheduled">
Geplante Veröffentlichungen <span class="publish-tab-count" id="publish-scheduled-count">0</span>
</button>
</nav>
<div class="publish-center-grid">
<aside class="publish-list-panel" aria-label="Artikel-Auswahl">
<div class="publish-list-panel-head">
<div>
<span class="publish-panel-kicker">Bereit zur Bearbeitung</span>
<h3>Artikel <span id="publish-list-count">0</span></h3>
</div>
<select id="publish-sort" aria-label="Artikel sortieren">
<option value="newest">Neueste zuerst</option>
<option value="oldest">Älteste zuerst</option>
<option value="price-desc">Preis absteigend</option>
<option value="price-asc">Preis aufsteigend</option>
<option value="title">Titel AZ</option>
</select>
</div>
<div class="publish-list-filters">
<label class="publish-search-field">
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="11" cy="11" r="7"/><path d="m20 20-4-4"/></svg>
<input type="search" id="publish-search" placeholder="Titel, SKU oder Marke …">
</label>
<div class="publish-filter-row">
<select id="publish-filter-platform"><option value="">Alle Plattformen</option></select>
<select id="publish-filter-status">
<option value="">Alle Status</option>
<option value="active">Aktiv</option>
<option value="reserved">Reserviert</option>
<option value="sold">Verkauft</option>
</select>
</div>
</div>
<div class="publish-selection-bar">
<label><input type="checkbox" id="publish-select-all"> Alle</label>
<span id="publish-selected-count">0 ausgewählt</span>
</div>
<div id="publish-list" class="publish-list" aria-live="polite"></div>
<div class="publish-batch-bar">
<button id="publish-batch-copy" class="vd-button compact" disabled>Smart Copy</button>
<button id="publish-batch-ebay" class="vd-button compact" disabled>Publishing-Queue</button>
<button id="publish-batch-schedule" class="vd-button compact" disabled>Planen</button>
<button id="publish-download-photos" class="vd-button compact" disabled>Fotos</button>
<button id="publish-batch-etsy" class="vd-button compact" disabled>Etsy</button>
</div>
</aside>
<section class="publish-workspace-panel" aria-live="polite">
<div id="publish-workspace" class="publish-workspace"></div>
</section>
<aside class="publish-status-rail" aria-label="Publish-Status">
<section class="publish-rail-section">
<div class="publish-rail-heading">
<div>
<span class="publish-panel-kicker">Live-Übersicht</span>
<h3>Queue-Status</h3>
</div>
<button id="publish-status-refresh" class="icon-button" type="button" aria-label="Status aktualisieren"></button>
</div>
<div class="publish-status-list">
<button class="publish-status-row" type="button" data-status-target="queue">
<span class="publish-status-icon pending"></span><span><strong>Ausstehend</strong><small>Wartet auf Verarbeitung</small></span><b id="publish-status-pending">0</b>
</button>
<button class="publish-status-row" type="button" data-status-target="queue">
<span class="publish-status-icon processing"></span><span><strong>In Bearbeitung</strong><small>Aktiver Upload</small></span><b id="publish-status-processing">0</b>
</button>
<button class="publish-status-row" type="button" data-status-target="queue">
<span class="publish-status-icon success"></span><span><strong>Veröffentlicht</strong><small>Erfolgreich live</small></span><b id="publish-status-published">0</b>
</button>
<button class="publish-status-row" type="button" data-status-target="errors">
<span class="publish-status-icon danger">!</span><span><strong>Fehlgeschlagen</strong><small>Aktion erforderlich</small></span><b id="publish-status-failed">0</b>
</button>
<button class="publish-status-row" type="button" data-status-target="scheduled">
<span class="publish-status-icon scheduled"></span><span><strong>Geplant</strong><small>Zukünftige Veröffentlichungen</small></span><b id="publish-status-scheduled">0</b>
</button>
</div>
</section>
<section class="publish-rail-section">
<div class="publish-rail-heading"><div><span class="publish-panel-kicker">Direktzugriff</span><h3>Schnellaktionen</h3></div></div>
<div class="publish-quick-actions">
<button id="publish-ebay-queue-process" class="publish-quick-action primary" type="button"><strong>Queue öffnen</strong><small>Alle Plattformen und Status</small></button>
<button id="publish-ebay-queue-retry" class="publish-quick-action" type="button"><strong>Fehlerzentrale öffnen</strong><small id="publish-retry-caption">Keine Fehler</small></button>
<button id="publish-schedule-overview" class="publish-quick-action" type="button"><strong>Geplante öffnen</strong><small id="publish-schedule-caption">Keine Planungen</small></button>
<button id="publish-ebay-queue-btn" class="publish-quick-action" type="button"><strong>Publishing-Protokoll</strong><small>IDs, Links und Ereignisse prüfen</small></button>
</div>
</section>
<section class="publish-rail-section publish-activity-section">
<div class="publish-rail-heading"><div><span class="publish-panel-kicker">Verlauf</span><h3>Aktivität</h3></div></div>
<div id="publish-activity" class="publish-activity-list"></div>
</section>
</aside>
</div>
<div id="schedule-modal" class="modal-overlay hidden publish-schedule-overlay">
<div class="modal publish-schedule-dialog">
<div class="modal-header">
<div><span class="publish-panel-kicker">Zeitsteuerung</span><h3 id="schedule-modal-title">Veröffentlichung planen</h3></div>
<button id="schedule-modal-close" class="modal-close" aria-label="Schließen">&times;</button>
</div>
<div class="modal-body">
<div class="publish-schedule-summary" id="schedule-listing-summary"></div>
<div class="publish-schedule-grid">
<label>Plattform
<select id="schedule-platform">
<option value="ebay-de">eBay.de</option>
<option value="etsy">Etsy</option>
<option value="vinted">Vinted</option>
<option value="ebay-ka">Kleinanzeigen</option>
</select>
</label>
<label>Datum &amp; Uhrzeit
<input type="datetime-local" id="schedule-datetime">
</label>
</div>
<div class="publish-schedule-actions">
<button id="schedule-cancel" class="vd-button">Abbrechen</button>
<button id="schedule-confirm" class="vd-button primary">Veröffentlichung planen</button>
</div>
</div>
</div>
</div>
</section>
<!-- PAPIERKORB -->
<section id="trash" class="tab-content">
<div class="trash-header">
<h2>Papierkorb</h2>
<div class="trash-actions-bar">
<span id="trash-info" class="trash-info-text">Einträge werden nach 30 Tagen automatisch gelöscht</span>
<button id="empty-trash-btn" class="small-btn danger-btn">Papierkorb leeren</button>
</div>
</div>
<div id="trash-list" class="trash-list"></div>
</section>
<!-- LAGERVERWALTUNG -->
<section id="inventory" class="tab-content">
<div class="inventory-header">
<h2>Lagerverwaltung</h2>
<div class="inventory-actions-bar">
<button id="inv-add-location-btn" class="primary-btn">+ Lagerort</button>
</div>
</div>
<div id="inv-stats" class="inventory-stats"></div>
<div id="inv-locations" class="inventory-locations"></div>
<div id="inv-detail" class="inventory-detail hidden">
<button id="inv-back" class="secondary-btn">&larr; Übersicht</button>
<h3 id="inv-detail-title"></h3>
<div class="inventory-detail-actions">
<button id="inv-rename-btn" class="small-btn">Umbenennen</button>
<button id="inv-move-btn" class="small-btn">Artikel verschieben</button>
</div>
<div id="inv-detail-list" class="history-list"></div>
</div>
</section>
<!-- GEBÜHRENRECHNER -->
<section id="fees" class="tab-content">
<div class="page-heading fee-heading">
<div><p class="eyebrow">Verkäufererlös</p><h2>Gebührenrechner</h2><p>Aktuelle Orientierung für private Verkäufer in Deutschland. Etsy wird als Shop-Plattform separat kalkuliert; optionale Werbung, Zusatzleistungen, Steuern und internationale Sonderfälle sind nicht pauschal eingerechnet.</p></div>
<span class="fee-verified-badge">Stand 08.07.2026</span>
</div>
<div class="setting-group">
<label>Verkaufspreis (€)</label>
<input type="number" id="fee-price" min="0" step="0.5" value="25" class="result-input" style="max-width:200px">
</div>
<div id="fee-results" class="fee-results"></div>
</section>
<!-- ADMIN -->
<section id="admin" class="tab-content">
<div class="admin-wrap">
<div class="admin-header">
<h2>Benutzer &amp; Sicherheit</h2>
<button class="primary-btn" id="invite-user-btn">+ User einladen</button>
</div>
<div class="admin-tabs">
<button class="admin-tab active" data-admin-tab="users">Benutzer</button>
<button class="admin-tab" data-admin-tab="roles">Rollen</button>
<button class="admin-tab" data-admin-tab="sessions">Sessions</button>
<button class="admin-tab" data-admin-tab="smtp">E-Mail / SMTP</button>
<button class="admin-tab" data-admin-tab="system">System</button>
<button class="admin-tab" data-admin-tab="modules">Module</button>
<button class="admin-tab" data-admin-tab="security">Sicherheit</button>
<button class="admin-tab" data-admin-tab="audit">Audit Log</button>
</div>
<!-- Users Tab -->
<div class="admin-panel active" id="admin-users-panel">
<div id="users-list" class="users-list"></div>
<section class="invitation-admin-section">
<div class="security-panel-heading"><div><p class="eyebrow">Testzugänge</p><h3>Einladungen</h3><p>Offene, abgelaufene und widerrufene Einladungen. Standardrolle ist Leser; höhere Rechte müssen bewusst gewählt werden.</p></div></div>
<div id="invitations-list" class="invitation-admin-list"><div class="empty-state">Einladungen werden geladen …</div></div>
</section>
</div>
<!-- Roles Tab -->
<div class="admin-panel" id="admin-roles-panel">
<div class="security-panel-heading">
<div><p class="eyebrow">RBAC</p><h3>Rollen und Berechtigungen</h3><p>Verbindliche Rollenprofile für Artikel, Medien, Publishing und Administration.</p></div>
</div>
<div id="role-cards" class="role-cards"><div class="empty-state">Rollen werden geladen …</div></div>
<div id="role-permission-matrix" class="role-permission-matrix"></div>
</div>
<!-- Sessions Tab -->
<div class="admin-panel" id="admin-sessions-panel">
<div id="sessions-list" class="sessions-list"></div>
</div>
<!-- SMTP Tab -->
<div class="admin-panel" id="admin-smtp-panel">
<div class="smtp-config-form">
<div class="smtp-status-bar" id="smtp-status-bar">
<span class="smtp-status-dot" id="smtp-status-dot"></span>
<span id="smtp-status-text">Lade...</span>
</div>
<div class="form-group">
<label>SMTP Host</label>
<input type="text" id="smtp-host" placeholder="smtp.gmail.com">
</div>
<div class="form-group">
<label>SMTP Port</label>
<input type="number" id="smtp-port" placeholder="587" value="587">
</div>
<div class="form-group">
<label>SMTP Benutzer</label>
<input type="text" id="smtp-user" placeholder="user@example.com">
</div>
<div class="form-group">
<label>SMTP Passwort</label>
<div class="key-input-wrap">
<input type="password" id="smtp-pass" placeholder="Passwort">
<button class="toggle-visibility" id="smtp-pass-toggle">Zeigen</button>
</div>
</div>
<div class="form-group">
<label>Absender (From)</label>
<input type="text" id="smtp-from" placeholder="noreply@example.com">
<small>E-Mail-Adresse, die als Absender angezeigt wird</small>
</div>
<div class="smtp-actions">
<button class="primary-btn" id="smtp-save-btn">SMTP speichern</button>
<button class="secondary-btn" id="smtp-test-btn">Verbindung testen</button>
</div>
</div>
</div>
<!-- System Tab -->
<div class="admin-panel" id="admin-system-panel">
<div class="system-panel-heading">
<div>
<p class="eyebrow">Runtime &amp; Integrität</p>
<h3>Systemprüfung</h3>
<p>Prüft Datenbank, Schreibrechte, UI-Dateien, Browser-Extensions und die optionale ComfyUI-Verbindung ohne API-Schlüssel offenzulegen.</p>
</div>
<div class="system-panel-actions">
<button class="primary-btn" id="system-diagnostics-btn" type="button">Systemprüfung starten</button>
<button class="secondary-btn" id="system-diagnostics-copy" type="button" disabled>Diagnose kopieren</button>
</div>
</div>
<div id="system-diagnostics-summary" class="diagnostics-summary is-idle">Noch keine Systemprüfung ausgeführt.</div>
<div id="system-diagnostics-grid" class="diagnostics-grid" aria-live="polite"></div>
<div id="system-info-cards" class="system-info-grid"></div>
<div class="system-actions" style="margin-top:20px;display:flex;gap:8px;flex-wrap:wrap">
<button class="secondary-btn" id="system-cleanup-btn">Abgelaufene Sessions bereinigen</button>
</div>
<section class="operations-center" aria-labelledby="operations-center-title">
<header class="operations-center-head">
<div><p class="eyebrow">Sicherung, Updates &amp; Browser</p><h3 id="operations-center-title">Betriebszentrale</h3><p>Verifizierte Backups, sichere Wiederherstellung, Update-Staging und Extension-Diagnose an einem Ort.</p></div>
<button type="button" class="secondary-btn" id="operations-refresh-btn"><span data-vd-icon="refresh-cw"></span> Aktualisieren</button>
</header>
<div id="operations-pending-banner" class="operations-pending hidden" role="status"></div>
<div class="operations-tabs" role="tablist" aria-label="Betriebsbereiche">
<button type="button" class="operations-tab active" data-operations-tab="backup">Backup &amp; Restore</button>
<button type="button" class="operations-tab" data-operations-tab="updates">Update Center</button>
<button type="button" class="operations-tab" data-operations-tab="extensions">Extension-Diagnose</button>
</div>
<div class="operations-panel active" id="operations-backup-panel">
<div class="operations-grid">
<article class="operations-card operations-create-card">
<header><span data-vd-icon="database-backup"></span><div><h4>Neues Backup</h4><p>Datenbank wird als konsistenter SQLite-Snapshot gesichert.</p></div></header>
<label class="operation-field"><span>Bezeichnung</span><input id="operations-backup-label" type="text" maxlength="60" placeholder="z. B. vor großem Import"></label>
<label class="operation-check"><input id="operations-backup-uploads" type="checkbox" checked><span><strong>Bilder und Uploads einschließen</strong><small>Empfohlen für eine vollständige Wiederherstellung.</small></span></label>
<label class="operation-check warning"><input id="operations-backup-config" type="checkbox"><span><strong>.env mit Zugangsdaten einschließen</strong><small>Nur für verschlüsselt oder sicher aufbewahrte Backups.</small></span></label>
<button type="button" class="primary-btn" id="operations-backup-create"><span data-vd-icon="archive"></span> Backup erstellen und prüfen</button>
</article>
<article class="operations-card">
<header><span data-vd-icon="calendar-clock"></span><div><h4>Automatische Sicherung</h4><p>Ein tägliches rotierendes Backup, solange Vendoo läuft.</p></div></header>
<label class="operation-check"><input id="operations-auto-enabled" type="checkbox"><span><strong>Tägliches Backup aktivieren</strong><small>Zugangsdaten werden nie automatisch gesichert.</small></span></label>
<div class="operation-inline-fields">
<label class="operation-field"><span>Uhrzeit</span><select id="operations-auto-hour"></select></label>
<label class="operation-field"><span>Aufbewahren</span><select id="operations-auto-retention"><option value="3">3 Backups</option><option value="7">7 Backups</option><option value="14">14 Backups</option><option value="30">30 Backups</option></select></label>
</div>
<label class="operation-check"><input id="operations-auto-uploads" type="checkbox" checked><span><strong>Uploads einschließen</strong><small>Kann bei großen Bildbeständen mehr Speicher benötigen.</small></span></label>
<button type="button" class="secondary-btn" id="operations-settings-save">Zeitplan speichern</button>
</article>
<article class="operations-card operations-restore-card">
<header><span data-vd-icon="rotate-ccw"></span><div><h4>Wiederherstellung vorbereiten</h4><p>Das Backup wird vollständig geprüft. Vorher entsteht automatisch eine Sicherheitssicherung.</p></div></header>
<label class="operation-dropzone" for="operations-restore-input"><span data-vd-icon="upload-cloud"></span><strong>Vendoo-Backup auswählen</strong><small>Nur verifizierte ZIP-Backups aus dieser Betriebszentrale.</small></label>
<input type="file" id="operations-restore-input" accept=".zip" hidden>
<div id="operations-restore-file" class="operation-file-state">Keine Datei ausgewählt.</div>
<button type="button" class="secondary-btn danger" id="operations-restore-stage" disabled>Wiederherstellung prüfen und vorbereiten</button>
</article>
</div>
<div class="operations-list-head"><div><h4>Vorhandene Backups</h4><p id="operations-backup-summary">Backups werden geladen …</p></div></div>
<div id="operations-backup-list" class="operations-backup-list"><div class="empty-state">Backups werden geladen …</div></div>
</div>
<div class="operations-panel" id="operations-updates-panel">
<div class="operations-grid operations-update-grid">
<article class="operations-card">
<header><span data-vd-icon="badge-check"></span><div><h4>Installierter Stand</h4><p>Version, Migrationen und letzte Systemoperation.</p></div></header>
<div id="operations-version-card" class="operation-version-card"><strong>Vendoo —</strong><span>Wird geladen …</span></div>
<div id="operations-migration-list" class="operation-migration-list"></div>
</article>
<article class="operations-card">
<header><span data-vd-icon="radio-tower"></span><div><h4>Online-Updateprüfung</h4><p>Optional über eine selbst konfigurierte öffentliche Manifest-URL.</p></div></header>
<label class="operation-field"><span>Update-Manifest-URL</span><input id="operations-update-url" type="url" placeholder="https://example.org/vendoo/latest.json"></label>
<div class="operation-card-actions"><button type="button" class="secondary-btn" id="operations-update-url-save">URL speichern</button><button type="button" class="secondary-btn" id="operations-update-check">Jetzt prüfen</button></div>
<div id="operations-update-check-result" class="operation-result">Noch nicht geprüft.</div>
</article>
<article class="operations-card operations-production-card">
<header><span data-vd-icon="activity"></span><div><h4>Produktionsstatus</h4><p>Live-Überblick über Version, Readiness, Datenbank, Speicher und FLUX-Grenze.</p></div></header>
<div id="deployment-production-overview" class="deployment-production-overview"><div class="empty-state">Produktionsstatus wird geladen …</div></div>
<div class="operation-card-actions"><button type="button" class="secondary-btn" id="deployment-production-check">Produktionscheck ausführen</button></div>
<div id="deployment-production-check-result" class="operation-result">Noch kein Produktionscheck ausgeführt.</div>
</article>
<article class="operations-card operations-deployment-card">
<header><span data-vd-icon="cloud-cog"></span><div><h4>Coolify &amp; GitHub Deployment</h4><p>Kontrolliertes Deployment ohne Docker-Socket und ohne selbständernden Produktivcontainer.</p></div></header>
<label class="operation-field"><span>Provider</span><select id="deployment-provider"><option value="none">Nicht konfiguriert</option><option value="coolify">Coolify</option></select></label>
<label class="operation-field"><span>Coolify URL</span><input id="deployment-coolify-url" type="url" placeholder="https://coolify.example.de"></label>
<label class="operation-field"><span>Resource UUID</span><input id="deployment-resource-uuid" type="text" placeholder="Coolify Application UUID"></label>
<label class="operation-field"><span>Trigger</span><select id="deployment-trigger-mode"><option value="webhook">Deploy-Webhook</option><option value="api">Coolify API mit Statusabfrage</option></select></label>
<label class="operation-field"><span>Deployment-Status-Endpunkt</span><input id="deployment-status-endpoint" type="text" value="/api/v1/deployments/{deployment_id}"></label>
<div class="operation-inline-fields">
<label class="operation-field"><span>Zeitlimit (Sek.)</span><input id="deployment-timeout-seconds" type="number" min="60" max="7200" value="900"></label>
<label class="operation-field"><span>Prüfintervall (Sek.)</span><input id="deployment-poll-seconds" type="number" min="5" max="300" value="15"></label>
</div>
<label class="operation-field"><span>Deploy-Webhook</span><input id="deployment-webhook-url" type="password" autocomplete="new-password" placeholder="Nur neu eingeben, wenn er geändert werden soll"></label>
<label class="operation-field"><span>API-Token</span><input id="deployment-api-token" type="password" autocomplete="new-password" placeholder="Nur für API-Modus"></label>
<div class="operation-card-actions"><button type="button" class="secondary-btn" id="deployment-save">Konfiguration speichern</button><button type="button" class="secondary-btn" id="deployment-test">Verbindung prüfen</button></div>
<div id="deployment-status" class="operation-result">Deployment-Konfiguration wird geladen …</div>
</article>
<article class="operations-card operations-deploy-action-card">
<header><span data-vd-icon="rocket"></span><div><h4>GitHub-Stand kontrolliert ausrollen</h4><p>Vorab-Backup, Doppelstartschutz, Statusverfolgung, Readiness und Zielversion sind Bestandteil eines Auftrags.</p></div></header>
<label class="operation-field"><span>GitHub Repository</span><input id="deployment-github-repository" type="text" value="Masterluke77/vendoo"></label>
<label class="operation-field"><span>Produktionsbranch</span><input id="deployment-github-branch" type="text" value="main"></label>
<div class="operation-inline-fields">
<label class="operation-field"><span>Update-Kanal</span><select id="deployment-update-channel"><option value="stable">Stable</option><option value="beta">Beta</option></select></label>
<label class="operation-field"><span>Zielversion</span><input id="deployment-target-version" type="text" placeholder="z. B. 1.43.0"></label>
</div>
<label class="operation-check"><input id="deployment-backup-before" type="checkbox" checked><span>Vor dem Deployment ein verifiziertes Backup mit Konfiguration erstellen</span></label>
<label class="operation-check"><input id="deployment-backup-uploads" type="checkbox"><span>Uploads zusätzlich in das Vorab-Backup aufnehmen</span></label>
<div class="operation-card-actions"><button type="button" class="secondary-btn" id="deployment-update-check">Version prüfen</button><button type="button" class="primary-btn" id="deployment-trigger">Coolify-Deployment starten</button></div>
<div id="deployment-action-result" class="operation-result">Noch kein Deployment aus dem Webinterface angefordert.</div>
</article>
<article class="operations-card operations-deployment-history-card">
<header><span data-vd-icon="history"></span><div><h4>Deployment-Verlauf</h4><p>Persistente Aufträge und Ereignisse bleiben auch nach einem Neustart nachvollziehbar.</p></div></header>
<div id="deployment-run-list" class="deployment-run-list"><div class="empty-state">Keine Deployment-Aufträge vorhanden.</div></div>
</article>
<article class="operations-card operations-update-upload">
<header><span data-vd-icon="package-open"></span><div><h4>Update-Paket vorbereiten</h4><p>Prüft Version, Pflichtdateien und verbotene Laufzeitdaten. Vorher wird automatisch gesichert.</p></div></header>
<label class="operation-dropzone" for="operations-update-input"><span data-vd-icon="file-archive"></span><strong>Vendoo-Update-ZIP auswählen</strong><small>Vollständiges Drüberkopier-Paket mit neuerer Version.</small></label>
<input type="file" id="operations-update-input" accept=".zip" hidden>
<div id="operations-update-file" class="operation-file-state">Keine Datei ausgewählt.</div>
<button type="button" class="primary-btn" id="operations-update-stage" disabled>Update prüfen und vorbereiten</button>
</article>
</div>
<div class="operations-instruction"><span data-vd-icon="shield-alert"></span><div><strong>Bewusster Neustart statt riskanter Live-Aktualisierung</strong><p>Vorbereitete Updates und Wiederherstellungen werden erst bei beendetem Vendoo über Setup-Menüpunkt 11 angewendet. Menüpunkt 12 stellt den vorherigen Programmstand wieder her.</p></div></div>
</div>
<div class="operations-panel" id="operations-extensions-panel">
<div class="operations-extension-summary" id="operations-extension-summary"><div class="empty-state">Extension-Diagnose wird geladen …</div></div>
<div id="operations-extension-packages" class="operations-extension-packages"></div>
<div class="operations-list-head"><div><h4>Zuletzt verbundene Browser</h4><p>Live gilt eine Verbindung, wenn sie sich in den letzten drei Minuten gemeldet hat.</p></div><button type="button" class="secondary-btn" id="operations-extension-refresh">Diagnose aktualisieren</button></div>
<div id="operations-extension-clients" class="operations-extension-clients"><div class="empty-state">Noch keine Extension-Verbindung gemeldet.</div></div>
</div>
</section>
</div>
<!-- Modules Tab -->
<div class="admin-panel" id="admin-modules-panel">
<div class="module-manager-head">
<div><p class="eyebrow">Plattform &amp; Erweiterungen</p><h3>Modulmanager</h3><p>Vendoo-Module sicher aktivieren, deaktivieren, exportieren, installieren und sofern zulässig entfernen.</p></div>
<div class="module-manager-actions"><button type="button" class="secondary-btn" id="module-manager-refresh">Aktualisieren</button></div>
</div>
<div id="module-manager-summary" class="module-manager-summary"></div>
<div id="module-manager-safety" class="module-safety-card"></div>
<section class="module-install-card">
<h4>Modulpaket installieren</h4>
<p>Akzeptiert werden geprüfte <code>.vmod</code>-Pakete. Deklarative Module dürfen keinen ausführbaren Code enthalten. Ausführbare Fremdmodule bleiben bis zum isolierten Extension-Host in Quarantäne.</p>
<div class="module-install-row"><label><span>Modulpaket auswählen</span><input id="module-manager-file" type="file" accept=".vmod,application/vnd.vendoo.module+json,application/json"></label><button type="button" class="primary-btn" id="module-manager-install">Prüfen und installieren</button></div>
</section>
<div class="module-filter-row"><input id="module-manager-search" type="search" placeholder="Module suchen …"></div>
<div id="module-manager-list" class="module-list"><div class="module-empty">Module werden geladen …</div></div>
</div>
<!-- Security Tab -->
<div class="admin-panel" id="admin-security-panel">
<div class="security-panel-heading">
<div><p class="eyebrow">Serverbetrieb</p><h3>Sicherheitszentrale</h3><p>HTTPS, verschlüsselte Secrets, CSP, Request-Telemetrie, Sitzungen, Rate Limits und Bearbeitungssperren.</p></div>
<button type="button" class="secondary-btn" id="security-refresh-btn"><span data-vd-icon="refresh-cw"></span> Aktualisieren</button>
</div>
<div id="security-status-summary" class="security-status-summary"></div>
<div id="security-warning-list" class="security-warning-list"></div>
<div class="security-grid">
<article class="security-card"><h4>Netzwerk &amp; HTTPS</h4><div id="security-network-info"></div></article>
<article class="security-card"><h4>Sessions &amp; Limits</h4><div id="security-session-info"></div></article>
<article class="security-card"><h4>Secret-Speicher</h4><div id="security-secret-info"></div></article>
<article class="security-card"><h4>Requests &amp; CSP</h4><div id="security-request-info"></div></article>
</div>
<div class="security-lock-head"><div><h4>Aktive Bearbeitungssperren</h4><p>Verhindert, dass zwei Benutzer denselben Artikel gleichzeitig überschreiben.</p></div></div>
<div id="security-lock-list" class="security-lock-list"><div class="empty-state">Keine aktiven Sperren.</div></div>
<div class="security-env-guide">
<h4>Empfohlene Server-Konfiguration</h4>
<pre>VENDOO_BIND_HOST=127.0.0.1
VENDOO_ALLOWED_HOSTS=vendoo.example.de
VENDOO_ALLOWED_ORIGINS=https://vendoo.example.de
VENDOO_TRUST_PROXY=true
PUBLIC_BASE_URL=https://vendoo.example.de</pre>
<p>Für LAN-Zugriff <code>VENDOO_BIND_HOST=0.0.0.0</code> verwenden. Öffentlichen Zugriff ausschließlich hinter einem HTTPS-Reverse-Proxy freigeben.</p>
</div>
</div>
<!-- Audit Tab -->
<div class="admin-panel" id="admin-audit-panel">
<div class="audit-toolbar">
<input type="search" id="audit-search" placeholder="Benutzer, Aktion, Ziel oder IP suchen">
<input type="text" id="audit-action-filter" placeholder="Aktion, z. B. listing">
<input type="date" id="audit-from">
<input type="date" id="audit-to">
<select id="audit-page-size"><option value="50">50 Einträge</option><option value="100" selected>100 Einträge</option><option value="200">200 Einträge</option></select>
<button type="button" class="secondary-btn" id="audit-filter-btn">Filtern</button>
<button type="button" class="secondary-btn" id="audit-export-btn"><span data-vd-icon="download"></span> CSV exportieren</button>
</div>
<div id="audit-summary" class="audit-summary"></div>
<div id="audit-list" class="audit-list"></div>
<div class="audit-pagination"><button type="button" class="page-nav-btn" id="audit-prev">Zurück</button><span id="audit-page-info">Seite 1</span><button type="button" class="page-nav-btn" id="audit-next">Weiter</button></div>
</div>
</div>
<!-- Invite Modal -->
<div id="invite-modal" class="modal-overlay hidden">
<div class="modal" style="max-width:440px">
<div class="modal-header">
<h3>User einladen</h3>
<button class="modal-close" data-close-target="invite-modal">&times;</button>
</div>
<div class="modal-body">
<div class="form-group">
<label>E-Mail *</label>
<input type="email" id="invite-email" placeholder="user@example.com" required>
</div>
<div class="form-group">
<label>Name</label>
<input type="text" id="invite-name" placeholder="Max Mustermann">
</div>
<div class="form-group">
<label>Rolle</label>
<select id="invite-role" class="model-select">
<option value="viewer" selected>Leser</option>
<option value="publisher">Publisher</option>
<option value="editor">Editor</option>
<option value="manager">Manager</option>
<option value="admin">Administrator</option>
</select>
</div>
<div class="form-group">
<label>Einladungsmethode</label>
<div class="invite-method-radios">
<label class="radio-label">
<input type="radio" name="invite-method" value="magic_link" checked>
<span>Magic Link <small>(User setzt Passwort)</small></span>
</label>
<label class="radio-label">
<input type="radio" name="invite-method" value="auto_password">
<span>Auto-Passwort generieren</span>
</label>
</div>
</div>
<div class="form-group hidden" id="invite-result-wrap">
<label>Generiertes Passwort</label>
<div class="key-input-wrap">
<input type="text" id="invite-result-password" readonly>
<button class="toggle-visibility" id="invite-copy-pw" type="button">Kopieren</button>
</div>
<small>Dieses Passwort wurde an den User gesendet. Notiere es bei Bedarf.</small>
</div>
</div>
<div class="modal-footer">
<button class="secondary-btn" data-close-target="invite-modal">Abbrechen</button>
<button class="primary-btn" id="invite-send-btn">Einladung senden</button>
</div>
</div>
</div>
<!-- Edit User Modal -->
<div id="edit-user-modal" class="modal-overlay hidden">
<div class="modal" style="max-width:440px">
<div class="modal-header">
<h3>User bearbeiten</h3>
<button class="modal-close" data-close-target="edit-user-modal">&times;</button>
</div>
<div class="modal-body">
<div class="form-group">
<label>E-Mail</label>
<input type="email" id="edit-user-email" readonly aria-readonly="true">
<small>Die Login-Adresse bleibt unverändert. Für eine andere Adresse bitte einen neuen Benutzer anlegen.</small>
</div>
<div class="form-group">
<label>Name</label>
<input type="text" id="edit-user-name">
</div>
<div class="form-group">
<label>Rolle</label>
<select id="edit-user-role" class="model-select">
<option value="viewer">Leser</option>
<option value="publisher">Publisher</option>
<option value="editor" selected>Editor</option>
<option value="manager">Manager</option>
<option value="admin">Administrator</option>
</select>
</div>
<div class="form-group">
<label>Status</label>
<select id="edit-user-active" class="model-select">
<option value="1">Aktiv</option>
<option value="0">Deaktiviert</option>
</select>
</div>
<div class="form-group">
<label>Neues Passwort setzen</label>
<div class="key-input-wrap">
<input type="password" id="edit-user-password" placeholder="Leer lassen = nicht ändern" minlength="10">
<button type="button" class="toggle-visibility" id="edit-user-pw-toggle">Zeigen</button>
</div>
<small>Mindestens 10 Zeichen mit Groß-/Kleinbuchstaben, Zahl und Sonderzeichen. Nur ausfüllen, wenn du das Passwort ändern möchtest.</small>
</div>
<div class="form-group" id="edit-user-password-status-wrap">
<label>Passwort-Status</label>
<span id="edit-user-pw-status" class="pw-status-badge"></span>
</div>
<div class="form-group">
<label>Login-Verlauf</label>
<button class="small-btn" id="edit-user-show-history" type="button">Login-Verlauf anzeigen</button>
<div id="edit-user-login-history" class="login-history-list hidden"></div>
</div>
<input type="hidden" id="edit-user-id">
</div>
<div class="modal-footer">
<button class="secondary-btn" data-close-target="edit-user-modal">Abbrechen</button>
<button type="button" class="primary-btn" id="edit-user-save-btn">Speichern</button>
</div>
</div>
</div>
<!-- My Sessions Modal -->
<div id="my-sessions-modal" class="modal-overlay hidden">
<div class="modal" style="max-width:520px">
<div class="modal-header">
<h3>Meine aktiven Sessions</h3>
<button class="modal-close" data-close-target="my-sessions-modal">&times;</button>
</div>
<div class="modal-body" id="my-sessions-list"></div>
</div>
</div>
</section>
<!-- EINSTELLUNGEN -->
<section id="flux-studio" class="tab-content flux-studio-page">
<header class="page-heading flux-studio-heading">
<div>
<p class="eyebrow">Lokale Bildgenerierung · Studio Pro</p>
<h2>FLUX Studio Pro</h2>
<p>Erzeuge 1, 2 oder 4 Prompt-Varianten, verwalte echte ComfyUI-Aufträge und greife jederzeit auf Verlauf, Parameter und Favoriten zurück.</p>
</div>
<div class="flux-studio-engine-actions">
<span id="flux-studio-engine-chip" class="settings-status-chip is-disabled">Wird geprüft</span>
<button type="button" class="vd-button" id="flux-studio-reset"><span data-vd-icon="rotate-ccw"></span> Arbeitsbereich zurücksetzen</button>
<button type="button" class="vd-button" id="flux-studio-refresh-engine">System prüfen</button>
<button type="button" class="vd-button" id="flux-studio-start-engine">FLUX starten</button>
<button type="button" class="vd-button" id="flux-studio-stop-engine">Stoppen</button>
</div>
</header>
<div class="flux-studio-layout flux-studio-pro-layout">
<div class="flux-studio-left-stack">
<article class="flux-studio-card flux-studio-controls">
<div class="flux-studio-card-head"><div><span>01</span><h3>Prompt &amp; Auftrag</h3></div><small>Reiner Text-zu-Bild-Workflow</small></div>
<label class="flux-studio-prompt-field">
<span>Bildbeschreibung</span>
<textarea id="flux-studio-prompt" rows="8" maxlength="2000" placeholder="Beispiel: Hochwertige Produktaufnahme eines minimalistischen Arbeitsplatzes, weiches Tageslicht, heller Hintergrund, fotorealistisch …"></textarea>
<small><b id="flux-studio-prompt-count">0</b> / 2.000 Zeichen</small>
</label>
<div class="flux-prompt-toolbar">
<div class="flux-studio-template-row" aria-label="Prompt-Vorlagen">
<button type="button" data-flux-template="product">Produktfoto</button>
<button type="button" data-flux-template="social">Social Media</button>
<button type="button" data-flux-template="background">Hintergrund</button>
<button type="button" data-flux-template="editorial">Editorial</button>
<button type="button" data-flux-template="lifestyle">Lifestyle</button>
</div>
<button type="button" class="vd-button flux-optimize-button" id="flux-studio-optimize-prompt"><span></span> Prompt Lab</button>
</div>
<div class="flux-prompt-quality" id="flux-prompt-quality" data-level="empty">
<span><i></i><strong>Prompt-Check</strong></span><p id="flux-prompt-quality-copy">Beschreibe zuerst Motiv, Umgebung, Licht und Perspektive.</p>
</div>
<div class="flux-order-options">
<div class="flux-option-block">
<span class="flux-option-label">Bildvarianten</span>
<div class="flux-segmented" id="flux-studio-variant-selector" role="group" aria-label="Anzahl der Bildvarianten">
<button type="button" data-flux-variants="1" class="active">1 Bild</button>
<button type="button" data-flux-variants="2">2 Bilder</button>
<button type="button" data-flux-variants="4">4 Bilder</button>
</div>
<input type="hidden" id="flux-studio-variants" value="1">
</div>
<label class="flux-lock-toggle">
<input type="checkbox" id="flux-studio-seed-lock">
<span><strong>Seed Lock</strong><small>Seed-Reihe bei Wiederholung exakt beibehalten</small></span>
</label>
</div>
<div class="flux-profile-strip" aria-label="Qualitätsprofile">
<button type="button" data-flux-profile="fast"><strong>Schnell</strong><small>768 px · 4 Schritte</small></button>
<button type="button" data-flux-profile="balanced" class="active"><strong>Ausgewogen</strong><small>bis 1024 px · 4 Schritte</small></button>
<button type="button" data-flux-profile="quality"><strong>Detail</strong><small>1024 px · 6 Schritte</small></button>
<button type="button" data-flux-profile="custom"><strong>Eigene Werte</strong><small>Format &amp; Schritte frei</small></button>
</div>
<input type="hidden" id="flux-studio-profile" value="balanced">
<div class="flux-studio-fields">
<label>Prompt-Modus
<select id="flux-studio-prompt-mode"><option value="precise" selected>Präzise</option><option value="creative">Kreativ</option><option value="raw">Unverändert</option></select>
</label>
<label>Stil
<select id="flux-studio-style">
<option value="none">Prompt unverändert</option>
<option value="photorealistic" selected>Fotorealistisch</option>
<option value="product">Produktfotografie</option>
<option value="editorial">Editorial</option>
<option value="cinematic">Cinematic</option>
<option value="illustration">Illustration</option>
<option value="social">Social Media</option>
</select>
</label>
<label>Format
<select id="flux-studio-format">
<option value="768x768">Quadrat · 768 × 768</option>
<option value="1024x1024">Quadrat · 1024 × 1024</option>
<option value="768x1024">Hochformat · 768 × 1024</option>
<option value="1024x768">Querformat · 1024 × 768</option>
</select>
</label>
<label>Schritte
<select id="flux-studio-steps">
<option value="4" selected>Empfohlen für Schnell · 4</option>
<option value="6">Mehr Details · 6</option>
<option value="8">Experimentell · 8</option>
</select>
</label>
<label>Start-Seed
<div class="flux-seed-input"><input id="flux-studio-seed" type="number" min="0" max="2147483647" value="42"><button type="button" id="flux-studio-random-seed" title="Zufälligen Seed erzeugen"></button></div>
</label>
</div>
<div class="flux-studio-run-row">
<button type="button" class="vd-button primary" id="flux-studio-generate">Auftrag starten</button>
<span id="flux-studio-status">Bereit.</span>
</div>
<div id="flux-studio-progress" class="flux-studio-progress hidden" aria-live="polite">
<div><span id="flux-studio-progress-label">Warteschlange</span><strong id="flux-studio-progress-value">Phase</strong></div>
<div class="flux-indeterminate-track"><i id="flux-studio-progress-bar"></i></div>
</div>
</article>
<article class="flux-studio-card flux-runtime-card">
<div class="flux-studio-card-head"><div><span>02</span><h3>System &amp; ComfyUI</h3></div><button type="button" class="small-btn" id="flux-runtime-refresh">Aktualisieren</button></div>
<div id="flux-runtime-summary" class="flux-runtime-summary"><div class="empty-state">Systemdaten werden geladen …</div></div>
</article>
</div>
<div class="flux-studio-side-stack">
<article class="flux-studio-card flux-studio-preview-card">
<div class="flux-studio-card-head"><div><span>03</span><h3>Auswahl &amp; Varianten</h3></div><small id="flux-studio-preview-meta">Noch kein Bild</small></div>
<div id="flux-studio-variant-results" class="flux-variant-results hidden"></div>
<div id="flux-studio-preview" class="flux-studio-preview">
<div id="flux-studio-preview-empty" class="flux-studio-preview-empty"><b></b><strong>Dein FLUX-Bild erscheint hier</strong><span>Prompt eingeben und Auftrag starten.</span></div>
<img id="flux-studio-preview-image" class="hidden" alt="FLUX-Vorschau">
</div>
<div id="flux-studio-preview-actions" class="flux-studio-preview-actions hidden">
<button type="button" class="vd-button primary" id="flux-studio-edit">Bild bearbeiten</button>
<button type="button" class="vd-button" id="flux-studio-similar">Ähnlich erneut erzeugen</button>
<button type="button" class="vd-button" id="flux-studio-favorite">☆ Favorit</button>
<a class="vd-button" id="flux-studio-download" download>Herunterladen</a>
<button type="button" class="vd-button" id="flux-studio-use-in-generator">Als Produktfoto übernehmen</button>
<button type="button" class="vd-button danger" id="flux-studio-delete">Löschen</button>
</div>
</article>
</div>
</div>
<section class="flux-job-center">
<div class="flux-job-center-head">
<div><p class="eyebrow">Produktionszentrale</p><h3>FLUX Job-Center</h3><p>Aktive Aufträge, Verlauf und Archiv mit kontrollierter Bereinigung.</p></div>
<div class="flux-job-center-actions">
<div class="flux-job-view-switch" role="group" aria-label="Job-Center Bereich">
<button type="button" class="active" id="flux-job-view-active">Aufträge</button>
<button type="button" id="flux-job-view-archive">Archiv <span id="flux-job-archive-count">0</span></button>
</div>
<select id="flux-job-filter" aria-label="Jobstatus filtern"><option value="">Alle Aufträge</option><option value="active">Laufend &amp; wartend</option><option value="completed">Erfolgreich</option><option value="failed">Fehlgeschlagen</option><option value="cancelled">Abgebrochen</option></select>
<select id="flux-job-page-size" aria-label="Aufträge pro Seite"><option value="5">5 / Seite</option><option value="10" selected>10 / Seite</option><option value="15">15 / Seite</option></select>
<button type="button" class="vd-button" id="flux-job-collapse-all">Alle einklappen</button>
<button type="button" class="vd-button" id="flux-job-refresh">Aktualisieren</button>
<button type="button" class="vd-button danger" id="flux-job-clear-queue">Warteschlange leeren</button>
<button type="button" class="vd-button flux-job-center-toggle" id="flux-job-center-toggle" aria-expanded="true">Aufträge einklappen</button>
</div>
</div>
<div id="flux-job-center-body" class="flux-job-center-body">
<div id="flux-job-summary" class="flux-job-summary"></div>
<div id="flux-job-bulkbar" class="flux-job-bulkbar">
<label><input type="checkbox" id="flux-job-select-page"> <span id="flux-job-selected-count">0 ausgewählt</span></label>
<div>
<button type="button" class="vd-button compact" id="flux-job-archive-selected" disabled>Auswahl archivieren</button>
<button type="button" class="vd-button compact hidden" id="flux-job-restore-selected" disabled>Wiederherstellen</button>
<button type="button" class="vd-button compact danger hidden" id="flux-job-delete-selected" disabled>Auswahl löschen</button>
<button type="button" class="vd-button compact danger hidden" id="flux-job-delete-all-archive">Archiv komplett löschen</button>
</div>
</div>
<div id="flux-job-list" class="flux-job-list"><div class="empty-state">Aufträge werden geladen …</div></div>
<div id="flux-job-pagination" class="flux-job-pagination">
<button type="button" class="page-nav-btn" id="flux-job-prev"></button>
<span id="flux-job-page-info">Seite 1 von 1</span>
<button type="button" class="page-nav-btn" id="flux-job-next"></button>
</div>
</div>
</section>
<section class="flux-studio-history-section">
<div class="flux-studio-history-head">
<div><p class="eyebrow">Bildbibliothek</p><h3>Ergebnisse &amp; Favoriten</h3></div>
<div class="flux-library-actions"><label><input type="checkbox" id="flux-studio-favorites-only"> Nur Favoriten</label><select id="flux-history-page-size" aria-label="Bilder pro Seite"><option value="5" selected>5 / Seite</option><option value="10">10 / Seite</option><option value="15">15 / Seite</option></select><button type="button" class="vd-button" id="flux-studio-refresh-history">Aktualisieren</button></div>
</div>
<div id="flux-studio-history" class="flux-studio-history"><div class="empty-state">Noch keine FLUX-Bilder gespeichert.</div></div>
<div class="flux-history-pagination"><button type="button" class="page-nav-btn" id="flux-history-prev"></button><span id="flux-history-page-info">Seite 1 von 1</span><button type="button" class="page-nav-btn" id="flux-history-next"></button></div>
</section>
</section>
<section id="media-library" class="tab-content media-library-page">
<header class="page-heading media-library-heading">
<div><p class="eyebrow">Zentrale Medienverwaltung</p><h2>Bildergalerie</h2><p>FLUX-, AI-, bearbeitete und in Artikeln verwendete Bilder gemeinsam durchsuchen, prüfen und verwalten.</p></div>
<div class="media-heading-actions">
<button type="button" class="vd-button" id="media-refresh">Aktualisieren</button>
<button type="button" class="vd-button primary" data-tab-target="flux-studio">Neues FLUX-Bild</button>
</div>
</header>
<section class="media-summary" aria-label="Medienübersicht">
<button type="button" data-media-source="all" class="active"><span>Gesamt</span><strong id="media-count-total">0</strong></button>
<button type="button" data-media-source="flux"><span>FLUX</span><strong id="media-count-flux">0</strong></button>
<button type="button" data-media-source="edited"><span>Bearbeitet</span><strong id="media-count-edited">0</strong></button>
<button type="button" data-media-source="batch"><span>Produktion</span><strong id="media-count-batch">0</strong></button>
<button type="button" data-media-source="ai"><span>AI-Bilder</span><strong id="media-count-ai">0</strong></button>
<button type="button" data-media-source="listing"><span>Artikel</span><strong id="media-count-listing">0</strong></button>
</section>
<div class="media-toolbar">
<label class="media-search"><span data-vd-icon="zoom-in"></span><input type="search" id="media-search" placeholder="Prompt, Titel oder Dateiname suchen"></label>
<select id="media-source"><option value="all">Alle Quellen</option><option value="flux">FLUX</option><option value="edited">Bearbeitet</option><option value="batch">Bildproduktion</option><option value="ai">AI-Bilder</option><option value="listing">Artikelbilder</option></select>
<select id="media-sort"><option value="newest">Neueste zuerst</option><option value="oldest">Älteste zuerst</option><option value="name">Name AZ</option></select>
<label class="media-check"><input type="checkbox" id="media-favorites-only"> Nur Favoriten</label>
<select id="media-page-size"><option value="24">24 / Seite</option><option value="48">48 / Seite</option><option value="96">96 / Seite</option></select>
<div class="media-view-switch"><button type="button" class="active" id="media-view-grid" title="Rasteransicht" aria-label="Rasteransicht"><span data-vd-icon="image"></span></button><button type="button" id="media-view-list" title="Listenansicht" aria-label="Listenansicht"><span data-vd-icon="list"></span></button></div>
</div>
<div class="media-batchbar">
<label><input type="checkbox" id="media-select-page"> <span id="media-selected-count">0 ausgewählt</span></label>
<div><button type="button" class="vd-button compact" id="media-send-to-factory" disabled>Bildproduktion</button><button type="button" class="vd-button compact" id="media-download-selected" disabled>Download / ZIP</button><button type="button" class="vd-button compact danger" id="media-delete-selected" disabled>Löschen</button></div>
</div>
<div class="media-pagination media-pagination-top" data-media-pagination aria-label="Seitennavigation oberhalb der Bildergalerie">
<div class="media-pagination-summary" data-media-page-range>0 Bilder</div>
<div class="media-pagination-controls">
<button type="button" class="page-nav-btn" data-media-page-action="prev" aria-label="Vorherige Galerieseite"></button>
<label class="media-page-jump">Seite <select data-media-page-jump aria-label="Galerieseite auswählen"><option value="1">1</option></select></label>
<span data-media-page-info>von 1</span>
<button type="button" class="page-nav-btn" data-media-page-action="next" aria-label="Nächste Galerieseite"></button>
</div>
</div>
<div id="media-grid" class="media-grid"><div class="empty-state">Bildergalerie wird geladen …</div></div>
<div class="media-pagination media-pagination-bottom" data-media-pagination aria-label="Seitennavigation unterhalb der Bildergalerie">
<div class="media-pagination-summary" data-media-page-range>0 Bilder</div>
<div class="media-pagination-controls">
<button type="button" class="page-nav-btn" data-media-page-action="prev" aria-label="Vorherige Galerieseite"></button>
<label class="media-page-jump">Seite <select data-media-page-jump aria-label="Galerieseite auswählen"><option value="1">1</option></select></label>
<span data-media-page-info>von 1</span>
<button type="button" class="page-nav-btn" data-media-page-action="next" aria-label="Nächste Galerieseite"></button>
</div>
</div>
</section>
<section id="image-factory" class="tab-content image-factory-page">
<header class="page-heading image-factory-heading">
<div><p class="eyebrow">Batch Image Factory</p><h2>Bildproduktion</h2><p>Erzeuge aus mehreren Quellbildern automatisch optimierte Varianten für Marktplätze, Webshops und Social Media.</p></div>
<div class="image-factory-heading-actions"><button type="button" class="vd-button" id="image-factory-refresh">Aktualisieren</button><button type="button" class="vd-button primary" id="image-factory-start">Produktion starten</button></div>
</header>
<div class="image-factory-layout">
<section class="image-factory-config surface-card">
<div class="section-title-row"><div><p class="eyebrow">Auftrag</p><h3>Quellen und Ausgabeprofile</h3></div><span class="image-factory-selection" id="image-factory-selection-count">0 Bilder · 0 Profile</span></div>
<label class="field"><span>Auftragsname</span><input type="text" id="image-factory-name" maxlength="100" placeholder="z. B. Sommerkollektion eBay + Vinted"></label>
<div class="image-factory-source-head"><div><strong>Quellbilder</strong><span>Aus der zentralen Bildergalerie auswählen</span></div><div class="image-factory-source-tools"><input type="search" id="image-factory-source-search" placeholder="Bilder suchen"><select id="image-factory-source-filter"><option value="all">Alle Quellen</option><option value="listing">Artikel</option><option value="flux">FLUX</option><option value="batch">Produktion</option><option value="edited">Bearbeitet</option><option value="ai">AI</option></select><button type="button" class="vd-button compact" id="image-factory-select-visible">Sichtbare wählen</button><button type="button" class="vd-button compact" id="image-factory-clear-sources">Leeren</button></div></div>
<div id="image-factory-source-grid" class="image-factory-source-grid"><div class="empty-state">Bilder werden geladen …</div></div>
<div class="image-factory-profile-head"><div><strong>Produktionsprofile</strong><span>Ein Auftrag kann mehrere Ausgaben pro Bild erzeugen</span></div><button type="button" class="vd-button compact" id="image-factory-new-profile">Eigenes Profil</button></div>
<div id="image-factory-profile-grid" class="image-factory-profile-grid"><div class="empty-state">Profile werden geladen …</div></div>
<details class="image-factory-options">
<summary>Zusätzliche Verarbeitung</summary>
<div class="image-factory-options-grid">
<label class="toggle-row"><input type="checkbox" id="image-factory-remove-bg"><span><strong>Hintergrund entfernen</strong><small>Transparente Ausgabe; Intensität regelbar</small></span></label>
<label class="field"><span>Entfernungsintensität <output id="image-factory-bg-value">45</output></span><input type="range" id="image-factory-bg-sensitivity" min="0" max="100" value="45"></label>
<label class="toggle-row"><input type="checkbox" id="image-factory-watermark"><span><strong>Wasserzeichen</strong><small>Auf alle erzeugten Varianten anwenden</small></span></label>
<label class="field"><span>Wasserzeichentext</span><input type="text" id="image-factory-watermark-text" value="Vendoo" maxlength="80"></label>
<label class="field"><span>Position</span><select id="image-factory-watermark-position"><option value="bottom-right">Unten rechts</option><option value="bottom-left">Unten links</option><option value="top-right">Oben rechts</option><option value="top-left">Oben links</option><option value="center">Mitte</option></select></label>
<label class="field"><span>Deckkraft <output id="image-factory-watermark-value">40 %</output></span><input type="range" id="image-factory-watermark-opacity" min="10" max="100" value="40"></label>
</div>
</details>
<div class="image-factory-submit"><div><strong id="image-factory-output-estimate">Noch keine Ausgabe geplant</strong><span>Originalbilder bleiben unverändert. Jede Ausgabe wird als neue Version gespeichert.</span></div><button type="button" class="primary-btn" id="image-factory-submit">Bildproduktion starten</button></div>
</section>
<aside class="image-factory-status surface-card">
<p class="eyebrow">Übersicht</p><h3>Produktionsstatus</h3>
<div class="image-factory-stat-grid" id="image-factory-summary">
<div><span>Wartend</span><strong data-batch-summary="queued">0</strong></div><div><span>Laufend</span><strong data-batch-summary="running">0</strong></div><div><span>Pausiert</span><strong data-batch-summary="paused">0</strong></div><div><span>Fertig</span><strong data-batch-summary="completed">0</strong></div><div><span>Teilweise</span><strong data-batch-summary="partial">0</strong></div><div><span>Fehler</span><strong data-batch-summary="failed">0</strong></div>
</div>
<div class="image-factory-help"><strong>Neustartsicher</strong><p>Wartende Aufträge werden nach einem Vendoo-Neustart fortgesetzt. Pausierte Aufträge bleiben pausiert.</p></div>
</aside>
</div>
<section class="image-factory-jobs surface-card">
<div class="section-title-row"><div><p class="eyebrow">Job-Center</p><h3>Produktionsaufträge</h3></div><div class="image-factory-job-tools"><select id="image-factory-job-page-size"><option value="5">5 / Seite</option><option value="10" selected>10 / Seite</option><option value="15">15 / Seite</option></select><button type="button" class="vd-button compact" id="image-factory-jobs-refresh">Aktualisieren</button></div></div>
<div id="image-factory-jobs" class="image-factory-job-list"><div class="empty-state">Noch keine Produktionsaufträge.</div></div>
<div class="image-factory-pagination"><button type="button" class="page-nav-btn" id="image-factory-job-prev"></button><span id="image-factory-job-page-info">Seite 1 von 1</span><button type="button" class="page-nav-btn" id="image-factory-job-next"></button></div>
</section>
</section>
<div class="modal-overlay hidden" id="image-factory-profile-modal" aria-hidden="true">
<div class="modal image-factory-profile-modal" role="dialog" aria-modal="true" aria-labelledby="image-factory-profile-title">
<div class="modal-header"><div><p class="eyebrow">Eigenes Ausgabeprofil</p><h3 id="image-factory-profile-title">Produktionsprofil anlegen</h3></div><button type="button" class="modal-close" id="image-factory-profile-close" aria-label="Schließen">×</button></div>
<div class="modal-body image-factory-profile-form">
<label class="field"><span>Name</span><input type="text" id="image-factory-profile-name" maxlength="80" placeholder="Mein Shop-Format"></label>
<label class="field"><span>Beschreibung</span><input type="text" id="image-factory-profile-description" maxlength="300" placeholder="Wofür wird dieses Profil verwendet?"></label>
<div class="form-grid two"><label class="field"><span>Breite</span><input type="number" id="image-factory-profile-width" min="0" max="12000" value="1600"></label><label class="field"><span>Höhe</span><input type="number" id="image-factory-profile-height" min="0" max="12000" value="1600"></label></div>
<div class="form-grid two"><label class="field"><span>Anpassung</span><select id="image-factory-profile-fit"><option value="contain">Einpassen mit Rand</option><option value="cover">Format füllen / zuschneiden</option><option value="inside">Nur verkleinern</option></select></label><label class="field"><span>Hintergrund</span><input type="color" id="image-factory-profile-background" value="#ffffff"></label></div>
<div class="form-grid two"><label class="field"><span>Format</span><select id="image-factory-profile-format"><option value="jpeg">JPEG</option><option value="webp">WebP</option><option value="png">PNG</option></select></label><label class="field"><span>Qualität</span><input type="number" id="image-factory-profile-quality" min="40" max="100" value="90"></label></div>
<label class="field"><span>Dateinamensschema</span><input type="text" id="image-factory-profile-pattern" value="{name}-{profile}-{index}"><small>Platzhalter: {name}, {profile}, {index}</small></label>
</div>
<div class="modal-footer"><button type="button" class="vd-button" id="image-factory-profile-cancel">Abbrechen</button><button type="button" class="vd-button primary" id="image-factory-profile-save">Profil speichern</button></div>
</div>
</div>
<section id="extensions" class="tab-content extensions-page">
<header class="page-heading extensions-heading">
<div><p class="eyebrow">Browser-Integration</p><h2>Vendoo Link Extensions</h2><p>Bereite die passende Browser-Erweiterung vor, öffne den Installationsordner und folge der kurzen Anleitung. Der Browser verlangt aus Sicherheitsgründen immer eine abschließende Bestätigung.</p></div>
<div class="extensions-heading-actions">
<div class="extensions-active-browser" id="extensions-active-browser"><span>Aktiver Browser</span><strong>Wird erkannt …</strong></div>
<button type="button" class="vd-button primary" id="extensions-prepare-active"><span data-vd-icon="puzzle"></span> Aktiven Browser vorbereiten</button>
</div>
</header>
<div class="extensions-notice"><span data-vd-icon="shield-check"></span><div><strong>Sicher statt versteckt</strong><p>Vendoo installiert keine Erweiterung unbemerkt. Ein Klick bereitet alles automatisch vor; die letzte Freigabe erfolgt bewusst in Chrome, Edge, Firefox oder Safari.</p></div></div>
<div id="extensions-grid" class="extensions-grid" aria-live="polite"></div>
<section class="extensions-help-card">
<div><span data-vd-icon="circle-help"></span><div><strong>So funktioniert die Ein-Klick-Vorbereitung</strong><p>Vendoo erkennt deinen Browser, öffnet den richtigen Erweiterungsordner und kopiert den Pfad. Danach musst du im Browser nur noch „Entpackte Erweiterung laden“ beziehungsweise die passende Firefox-/Safari-Aktion bestätigen.</p></div></div>
<ol><li>Bei deinem Browser auf <b>Installation vorbereiten</b> klicken.</li><li>Die geöffnete Erweiterungsverwaltung verwenden.</li><li>Den bereits kopierten Ordner auswählen und Vendoo Link anheften.</li></ol>
</section>
</section>
<section id="settings" class="tab-content settings-workspace">
<div class="settings-hero">
<div class="settings-hero-copy">
<span class="settings-eyebrow">Systemzentrale</span>
<h2>Einstellungen</h2>
<p>Sauber getrennte Bereiche für Grundeinstellungen, AI-Dienste, Marktplätze und den lokalen FLUX-Bildserver.</p>
</div>
<div class="settings-hero-status">
<div class="settings-status-chip" id="settings-ai-status-chip">
<span class="settings-status-dot"></span>
<div><small>AI-System</small><strong id="settings-ai-status-text">Wird geprüft …</strong></div>
</div>
<div class="settings-status-chip" id="settings-flux-status-chip">
<span class="settings-status-dot"></span>
<div><small>Lokales FLUX</small><strong id="settings-flux-status-text">Wird geprüft …</strong></div>
</div>
</div>
</div>
<div class="settings-shell">
<nav class="settings-nav" aria-label="Einstellungsbereiche">
<button type="button" class="settings-nav-item active" data-settings-panel="general">
<span class="settings-nav-icon"></span><span><strong>Allgemein</strong><small>Standards &amp; Netzwerk</small></span>
</button>
<button type="button" class="settings-nav-item" data-settings-panel="appearance">
<span class="settings-nav-icon"></span><span><strong>Darstellung</strong><small>Themes &amp; Barrierefreiheit</small></span>
</button>
<button type="button" class="settings-nav-item" data-settings-panel="ai">
<span class="settings-nav-icon"></span><span><strong>AI &amp; APIs</strong><small>Provider &amp; Bildlogik</small></span>
</button>
<button type="button" class="settings-nav-item" data-settings-panel="marketplaces">
<span class="settings-nav-icon"></span><span><strong>Marktplätze</strong><small>Etsy &amp; eBay</small></span>
</button>
<button type="button" class="settings-nav-item" data-settings-panel="flux">
<span class="settings-nav-icon"></span><span><strong>Lokales FLUX</strong><small>Server &amp; Installation</small></span>
</button>
</nav>
<div class="settings-panels">
<section class="settings-panel active" data-settings-panel-content="general">
<div class="settings-panel-head">
<div><span>01</span><h3>Allgemeine Einstellungen</h3><p>Die Standards, mit denen Vendoo im Alltag startet.</p></div>
</div>
<div class="settings-card-grid two-cols">
<article class="settings-card">
<div class="settings-card-head"><div><strong>Arbeitsstandard</strong><small>Vorauswahl im Generator</small></div></div>
<div class="settings-field-grid">
<div class="setting-group"><label for="setting-default-platform">Standard-Plattform</label><select id="setting-default-platform"></select></div>
<div class="setting-group"><label for="setting-default-ai">Standard AI Provider</label><select id="setting-default-ai"></select></div>
<div class="setting-group"><label for="setting-default-language">Standard-Sprache</label><select id="setting-default-language"><option value="de">Deutsch</option><option value="en">English</option><option value="fr">Français</option><option value="nl">Nederlands</option><option value="pl">Polski</option><option value="es">Español</option><option value="it">Italiano</option><option value="pt">Português</option></select></div>
</div>
</article>
<article class="settings-card">
<div class="settings-card-head"><div><strong>Netzwerk &amp; Smartphone</strong><small>QR-Upload im lokalen Netz</small></div></div>
<div class="setting-group">
<label for="setting-public-base-url">Vendoo LAN-Adresse</label>
<div class="inline-input-actions"><input type="text" id="setting-public-base-url" placeholder="http://192.168.178.50:8124"><button type="button" class="secondary-btn compact-inline" id="detect-public-base-url-btn">LAN-IP erkennen</button></div>
<small>Smartphone und Vendoo-PC müssen im selben Netzwerk sein.</small>
<div id="public-base-url-status" class="ai-models-status">Noch keine LAN-Adresse geprüft.</div>
</div>
</article>
</div>
<article class="settings-card">
<div class="settings-card-head"><div><strong>Verkäufernotizen</strong><small>Automatischer Zusatz für neue Listing-Texte</small></div></div>
<div class="setting-group"><textarea id="setting-seller-notes" rows="5" placeholder="z. B. Versand: 23 Werktage, tierfreier Nichtraucherhaushalt …"></textarea><small>Wird automatisch in jede Listing-Beschreibung eingebaut.</small></div>
</article>
</section>
<section class="settings-panel" data-settings-panel-content="appearance" id="theme-manager-root">
<div class="settings-panel-head"><div><span>02</span><h3>Theme Manager</h3><p>Darstellung sicher über Design Tokens anpassen ohne freies CSS und ohne Dateibearbeitung.</p></div></div>
<article class="settings-card vd-card theme-manager-grid">
<div class="settings-card-head split"><div><strong>Meine Darstellung</strong><small>Persönliches Theme, Dichte und Bewegung</small></div><span class="settings-status-chip"><span class="settings-status-dot"></span><strong>Live-Vorschau</strong></span></div>
<div class="theme-choice-grid" id="theme-choice-grid" aria-label="Theme auswählen"></div>
<div class="theme-manager-toolbar">
<div class="setting-group"><label for="theme-density">UI-Dichte</label><select id="theme-density"><option value="compact">Kompakt</option><option value="comfortable">Ausgewogen</option><option value="spacious">Großzügig</option></select></div>
<div class="setting-group"><label for="theme-reduced-motion">Animationen</label><select id="theme-reduced-motion"><option value="system">Systemeinstellung</option><option value="reduce">Reduzieren</option><option value="allow">Zulassen</option></select></div>
<button type="button" class="vd-button primary" id="theme-preference-save">Meine Darstellung speichern</button>
</div>
</article>
<article class="settings-card vd-card theme-admin-only">
<div class="settings-card-head split"><div><strong>Systemstandard</strong><small>Vorgabe für neue Benutzer und „Systemstandard“</small></div><button type="button" class="vd-button" id="theme-system-save">Systemstandard speichern</button></div>
<div class="settings-field-grid three-cols">
<div class="setting-group"><label for="theme-system-default">Standard-Theme</label><select id="theme-system-default"><option value="system">Betriebssystem</option><option value="light">Hell</option><option value="dark">Dunkel</option><option value="contrast">Hoher Kontrast</option></select></div>
<div class="setting-group"><label for="theme-system-density">Standard-Dichte</label><select id="theme-system-density"><option value="compact">Kompakt</option><option value="comfortable">Ausgewogen</option><option value="spacious">Großzügig</option></select></div>
<div class="setting-group"><label for="theme-system-motion">Animationen</label><select id="theme-system-motion"><option value="system">Systemeinstellung</option><option value="reduce">Reduzieren</option><option value="allow">Zulassen</option></select></div>
</div>
</article>
<div class="theme-editor-layout theme-admin-only">
<article class="settings-card vd-card">
<div class="settings-card-head split"><div><strong id="theme-editor-title">Neues Theme</strong><small>Nur freigegebene Tokenwerte kein CSS oder JavaScript</small></div><div><button type="button" class="vd-button compact" id="theme-new-btn">Neu</button><label class="vd-button compact" for="theme-import-input">Import</label><input type="file" id="theme-import-input" accept="application/json,.json" hidden></div></div>
<div class="settings-field-grid two-cols">
<div class="setting-group"><label for="theme-editor-name">Name</label><input class="vd-input" id="theme-editor-name" maxlength="80" placeholder="z. B. Vendoo Orange Pro"></div>
<div class="setting-group"><label for="theme-editor-base">Basis-Theme</label><select id="theme-editor-base"><option value="light">Hell</option><option value="dark">Dunkel</option><option value="contrast">Hoher Kontrast</option></select></div>
</div>
<div class="theme-token-groups" id="theme-token-groups"></div>
<div class="theme-preview-actions"><button type="button" class="vd-button" id="theme-validate-btn">Prüfen</button><button type="button" class="vd-button primary" id="theme-save-btn">Theme speichern</button><button type="button" class="vd-button danger" id="theme-delete-btn" hidden>Löschen</button></div>
</article>
<aside class="theme-preview">
<article class="settings-card vd-card">
<div class="settings-card-head"><div><strong>Live-Vorschau</strong><small id="theme-preview-name">Theme-Vorschau</small></div></div>
<div class="theme-preview-stage">
<div class="theme-preview-card"><strong>Produktkarte</strong><p>Text, Flächen, Linien und Abstände werden live geprüft.</p></div>
<div class="theme-preview-actions"><button type="button" class="vd-button primary">Primäraktion</button><button type="button" class="vd-button">Sekundär</button></div>
<label class="setting-group"><span>Eingabefeld</span><input class="vd-input" value="Sichere Token-Vorschau" readonly></label>
</div>
<button type="button" class="vd-button" id="theme-preview-reset">Vorschau zurücksetzen</button>
</article>
<article class="settings-card vd-card"><div class="settings-card-head"><div><strong>Kontrastprüfung</strong><small>WCAG-orientierte Kernpaare</small></div></div><div class="theme-contrast-list" id="theme-contrast-list"></div></article>
<article class="settings-card vd-card"><div class="settings-card-head"><div><strong>Eigene Themes</strong><small>Bearbeiten oder exportieren</small></div></div><div class="theme-profile-list" id="theme-profile-list"></div></article>
</aside>
</div>
<div class="theme-manager-status" id="theme-manager-status" role="status" aria-live="polite">Theme Manager wird geladen …</div>
</section>
<section class="settings-panel" data-settings-panel-content="ai">
<div class="settings-panel-head"><div><span>02</span><h3>AI &amp; API-Dienste</h3><p>Textanalyse, Bildprovider und die Genauigkeit der Produktreferenz.</p></div></div>
<article class="settings-card">
<div class="settings-card-head"><div><strong>API-Zugänge</strong><small>Keys bleiben lokal in deiner Vendoo-Installation</small></div></div>
<div class="settings-card-grid three-cols">
<div class="setting-group"><label for="setting-anthropic-key">Anthropic API Key</label><div class="key-input-wrap"><input type="password" id="setting-anthropic-key" placeholder="sk-ant-..."><button class="toggle-visibility">Zeigen</button></div><small>Claude für Listing-Texte.</small></div>
<div class="setting-group"><label for="setting-openai-key">OpenAI API Key</label><div class="key-input-wrap"><input type="password" id="setting-openai-key" placeholder="sk-..."><button class="toggle-visibility">Zeigen</button></div><small>Analyse, Moderation und Bild-Fallback.</small></div>
<div class="setting-group"><label for="setting-openrouter-key">OpenRouter API Key</label><div class="key-input-wrap"><input type="password" id="setting-openrouter-key" placeholder="sk-or-..."><button class="toggle-visibility">Zeigen</button></div><small>Optionale kostenlose Bildmodelle.</small></div>
</div>
<div class="setting-group compact-top"><label for="setting-ollama-url">Ollama URL</label><input type="text" id="setting-ollama-url" placeholder="http://localhost:11434"><small>Lokale Text-AI via Ollama.</small></div>
</article>
<article class="settings-card ai-settings-card">
<div class="settings-card-head split"><div><strong>Lokale Bildwerkzeuge</strong><small>Ghost Mannequin, Flatlay und optionale Cloud-Fallbacks</small></div><label class="premium-switch"><input type="checkbox" id="setting-ai-model-photo-enabled"><span></span><b>Feature aktiv</b></label></div>
<div class="settings-field-grid four-cols">
<div class="setting-group"><label for="setting-ai-model-photo-provider">Bild-Provider</label><select id="setting-ai-model-photo-provider"><option value="auto">Auto: Lokal → OpenRouter → OpenAI</option><option value="local">Nur lokales FLUX</option><option value="openrouter">Nur OpenRouter</option><option value="openai">Nur OpenAI</option></select></div>
<div class="setting-group"><label for="setting-ai-model-photo-mode">Standard-Modus</label><select id="setting-ai-model-photo-mode"><option value="ghost_mannequin">Ghost Mannequin</option><option value="flatlay">Flatlay</option></select></div>
<div class="setting-group"><label for="setting-ai-model-photo-variants">Bilder pro Auftrag</label><select id="setting-ai-model-photo-variants"><option value="1">1 Bild</option><option value="2">2 Bilder</option><option value="3">3 Bilder</option></select></div>
<div class="setting-group"><label for="setting-ai-model-photo-preset">Standard-Look</label><select id="setting-ai-model-photo-preset"><option value="mixed">Mix</option><option value="studio">Studio</option><option value="indoor">Indoor</option><option value="outdoor">Outdoor</option></select></div>
<div class="setting-group"><label for="setting-ai-model-photo-local-resolution">Lokale Bildgröße</label><select id="setting-ai-model-photo-local-resolution"><option value="768">Schnell · 768 × 768</option><option value="1024">Qualität · 1024 × 1024</option></select><small>768 ist deutlich schneller und für Marktplatzbilder meist ausreichend.</small></div>
</div>
<div class="reference-control-card">
<div class="reference-control-copy"><span class="reference-icon"></span><div><strong>Produktfotos verbindlich verwenden</strong><small>Diese Referenzsteuerung gilt für Ghost Mannequin und Flatlay. Der freie FLUX-Generator arbeitet unabhängig davon nur mit Texteingaben.</small></div></div>
<label class="premium-switch"><input type="checkbox" id="setting-ai-model-photo-use-source-reference"><span></span><b>Referenz aktiv</b></label>
<div class="reference-strength-row"><label for="setting-ai-model-photo-reference-strength">Referenztreue</label><input type="range" id="setting-ai-model-photo-reference-strength" min="30" max="90" step="5" value="70"><output id="setting-ai-model-photo-reference-strength-value">70%</output></div>
</div>
<div class="setting-inline-checks modern-checks">
<label><input type="checkbox" id="setting-ai-model-photo-free-only"><span>Nur kostenlose OpenRouter-Modelle</span></label>
<label><input type="checkbox" id="setting-ai-model-photo-block-underwear"><span>Unterwäsche/Bademode blockieren</span></label>
<label><input type="checkbox" id="setting-ai-model-photo-block-kids"><span>Kinderkleidung blockieren</span></label>
<label><input type="checkbox" id="setting-ai-model-photo-preserve-logos"><span>Logos, Prints und Brustaufdrucke strikt schützen</span></label>
</div>
<details class="settings-disclosure">
<summary><span>Cloud-Bildprovider konfigurieren</span><small>OpenRouter und OpenAI</small></summary>
<div class="settings-card-grid two-cols disclosure-body">
<div class="setting-group"><label for="setting-ai-model-photo-openrouter-model">OpenRouter-Modell</label><div class="inline-input-actions"><select id="setting-ai-model-photo-openrouter-model"></select><button type="button" class="secondary-btn compact-inline" id="refresh-openrouter-models-btn">Modelle laden</button></div><small>Leer lassen für automatische Auswahl.</small></div>
<div class="setting-group"><label for="setting-ai-model-photo-openai-model">OpenAI-Fallback-Modell</label><input type="text" id="setting-ai-model-photo-openai-model" placeholder="gpt-image-1"></div>
<div id="openrouter-models-status" class="ai-models-status full-span">Noch keine OpenRouter-Modelle geladen.</div>
<div id="openrouter-models-preview" class="openrouter-models-preview hidden full-span"></div>
</div>
</details>
</article>
</section>
<section class="settings-panel" data-settings-panel-content="marketplaces">
<div class="settings-panel-head"><div><span>03</span><h3>Marktplätze</h3><p>API-Verbindungen für Etsy und eBay übersichtlich an einem Ort.</p></div></div>
<div class="settings-card-grid two-cols">
<article class="settings-card">
<div class="settings-card-head"><div><strong>Etsy</strong><small>API-Key und Verbindung</small></div><span id="etsy-status-badge" class="etsy-status"></span></div>
<div class="setting-group"><label for="setting-etsy-key">Etsy API Key</label><div class="key-input-wrap"><input type="password" id="setting-etsy-key" placeholder="xxxxxxxx"><button class="toggle-visibility">Zeigen</button></div><small>Key unter etsy.com/developers erstellen.</small></div>
<div id="etsy-connect-wrap" class="etsy-connect-wrap hidden"><button id="etsy-connect-btn" class="secondary-btn">Mit Etsy verbinden</button></div>
</article>
<article class="settings-card">
<div class="settings-card-head"><div><strong>eBay.de</strong><small>Developer-Zugang und OAuth</small></div><span id="ebay-status-badge" class="etsy-status"></span></div>
<div class="setting-group"><label for="setting-ebay-client-id">Client ID</label><div class="key-input-wrap"><input type="password" id="setting-ebay-client-id" placeholder="eBay-App-..."><button class="toggle-visibility">Zeigen</button></div></div>
<div class="setting-group"><label for="setting-ebay-client-secret">Client Secret</label><div class="key-input-wrap"><input type="password" id="setting-ebay-client-secret" placeholder="eBay-Cert-..."><button class="toggle-visibility">Zeigen</button></div></div>
<div class="setting-group"><label for="setting-ebay-ru-name">RuName</label><input type="text" id="setting-ebay-ru-name" class="meta-input" placeholder="Dein_RuName"></div>
<label class="checkbox-line"><input type="checkbox" id="setting-ebay-sandbox"><span>Sandbox-Modus verwenden</span></label>
<div id="ebay-connect-wrap" class="etsy-connect-wrap hidden"><button id="ebay-connect-btn" class="secondary-btn">Mit eBay verbinden</button></div>
</article>
</div>
</section>
<section class="settings-panel" data-settings-panel-content="flux">
<div class="settings-panel-head"><div><span>04</span><h3>Lokales FLUX / ComfyUI</h3><p>Installation, Aktivierung, Serverstatus und Wartung ohne Technik-Chaos.</p></div></div>
<article class="flux-command-card">
<div class="flux-command-main">
<div class="flux-orb" id="local-flux-orb"><span>FLUX</span></div>
<div class="flux-command-copy"><span id="local-flux-engine-kicker">Lokale Bild-Engine</span><h3 id="local-flux-engine-title">Status wird geprüft …</h3><p id="local-flux-engine-detail">Vendoo prüft Installation, Modell und laufenden Bildserver.</p></div>
</div>
<label class="premium-switch large"><input type="checkbox" id="setting-ai-model-photo-local-enabled"><span></span><b id="local-flux-enable-label">Aktivieren</b></label>
<div class="flux-command-actions">
<button type="button" class="primary-btn compact-inline" id="start-local-image-provider-btn">Server starten</button>
<button type="button" class="secondary-btn compact-inline" id="stop-local-image-provider-btn">Server stoppen</button>
<button type="button" class="secondary-btn compact-inline" id="test-local-image-provider-btn">Neu prüfen</button>
<button type="button" class="primary-btn compact-inline" id="open-flux-studio-page-btn">FLUX Studio öffnen</button>
</div>
</article>
<div class="flux-health-grid">
<div><span>Installation</span><strong id="local-flux-health-install">Wird geprüft</strong></div>
<div><span>FLUX-Modell</span><strong id="local-flux-health-model">Wird geprüft</strong></div>
<div><span>Bildserver</span><strong id="local-flux-health-server">Wird geprüft</strong></div>
<div><span>Prompt-Modus</span><strong id="local-flux-health-reference">Ohne Produktfoto</strong></div>
</div>
<article class="settings-card flux-performance-card">
<div class="settings-card-head"><div><strong>Leistung &amp; Standardausgabe</strong><small>Optimiert Startverhalten und neue FLUX-Aufträge.</small></div></div>
<div class="settings-field-grid four-cols">
<div class="setting-group"><label for="setting-flux-runtime-profile">Serverprofil</label><select id="setting-flux-runtime-profile"><option value="auto">Automatisch nach VRAM</option><option value="fast">Schnell · ab ca. 12 GB VRAM</option><option value="balanced">Ausgewogen</option><option value="lowvram">Wenig VRAM</option></select></div>
<div class="setting-group"><label for="setting-flux-default-profile">Bildprofil</label><select id="setting-flux-default-profile"><option value="fast">Schnell</option><option value="balanced">Ausgewogen</option><option value="quality">Detail</option><option value="custom">Eigene Werte</option></select></div>
<div class="setting-group"><label for="setting-flux-default-style">Standardstil</label><select id="setting-flux-default-style"><option value="none">Prompt unverändert</option><option value="photorealistic">Fotorealistisch</option><option value="product">Produktfotografie</option><option value="editorial">Editorial</option><option value="cinematic">Cinematic</option><option value="illustration">Illustration</option><option value="social">Social Media</option></select></div>
<div class="setting-group"><label for="setting-flux-default-format">Standardformat</label><select id="setting-flux-default-format"><option value="768x768">768 × 768</option><option value="1024x1024">1024 × 1024</option><option value="768x1024">768 × 1024</option><option value="1024x768">1024 × 768</option></select></div>
<div class="setting-group"><label for="setting-flux-default-variants">Standardvarianten</label><select id="setting-flux-default-variants"><option value="1">1 Bild</option><option value="2">2 Bilder</option><option value="4">4 Bilder</option></select></div>
<div class="setting-group"><label for="setting-flux-max-parallel-jobs">GPU-Parallelität</label><select id="setting-flux-max-parallel-jobs"><option value="1">1 Auftrag gleichzeitig · empfohlen</option><option value="2">2 gleichzeitig</option><option value="3">3 gleichzeitig</option><option value="4">4 gleichzeitig</option></select></div>
</div>
<label class="checkbox-line"><input type="checkbox" id="setting-flux-prompt-assistant"><span>Prompt-Assistent automatisch verwenden</span></label>
<label class="checkbox-line"><input type="checkbox" id="setting-flux-seed-lock"><span>Seed Lock für neue Aufträge standardmäßig aktivieren</span></label>
<div class="settings-inline-note"><strong>Hinweis</strong><span>Das Serverprofil wird beim nächsten FLUX-Start aktiv. Schnell hält Modelle bevorzugt im VRAM; Wenig VRAM spart Speicher, ist aber langsamer.</span></div>
</article>
<article class="settings-card">
<div class="settings-card-head split"><div><strong>Installation &amp; Wartung</strong><small>Nur die Aktion wählen Vendoo erledigt den Rest.</small></div><span id="local-flux-engine-badge" class="flux-state-badge">Wird geprüft</span></div>
<div class="local-flux-install-options modern-checks">
<label><input type="checkbox" id="local-flux-install-model" checked><span>FLUX.1-schnell FP8 mitinstallieren</span></label>
<label><input type="checkbox" id="local-flux-enable-autostart" checked><span>Bei Windows-Anmeldung starten</span></label>
<label><input type="checkbox" id="local-flux-start-now" checked><span>Nach Installation sofort starten</span></label>
</div>
<div class="local-flux-actions command-actions">
<button type="button" class="primary-btn compact-inline" id="install-local-image-provider-btn">Installieren / reparieren</button>
<button type="button" class="secondary-btn compact-inline" id="update-local-image-provider-btn">ComfyUI aktualisieren</button>
<button type="button" class="danger-btn compact-inline" id="uninstall-local-image-provider-btn">FLUX deinstallieren</button>
</div>
<div id="local-image-provider-status" class="ai-models-status">Lokaler FLUX/ComfyUI-Status wird geprüft.</div>
</article>
<section class="local-flux-status-panel" aria-live="polite">
<div class="local-flux-status-head"><div><strong>Technischer Installationsstatus</strong><span id="local-flux-phase-label">Noch nicht gestartet</span></div><span id="local-flux-updated-at"></span></div>
<div class="local-flux-progress" id="local-flux-progress-wrap"><div class="local-flux-progress-head"><strong id="local-flux-progress-label">Installation</strong><span id="local-flux-progress-value">0%</span></div><div class="local-flux-progress-track"><div id="local-flux-progress-bar"></div></div></div>
<div id="local-flux-live-metrics" class="local-flux-live-metrics"><div><span>Installer</span><strong id="local-flux-installer-state">Bereit</strong></div><div><span>Laufzeit</span><strong id="local-flux-elapsed">0 s</strong></div><div><span>Entpackt</span><strong id="local-flux-extract-files">0 Dateien</strong></div><div><span>Datenmenge</span><strong id="local-flux-extract-size">0 MB</strong></div><div><span>Heartbeat</span><strong id="local-flux-heartbeat"></strong></div></div>
<div id="local-flux-checks" class="local-flux-checks"></div>
<div id="local-flux-error" class="local-flux-error hidden"></div>
<details class="local-flux-log-details"><summary>Installationsprotokoll anzeigen</summary><pre id="local-flux-log-tail">Noch kein Installationsprotokoll vorhanden.</pre></details>
<details class="local-flux-log-details"><summary>7-Zip-Ausgabe anzeigen</summary><pre id="local-flux-7zip-tail">Noch keine 7-Zip-Ausgabe vorhanden.</pre></details>
</section>
<details class="settings-disclosure">
<summary><span>Erweiterte lokale Konfiguration</span><small>URL, Token und Pfade</small></summary>
<div class="settings-card-grid two-cols disclosure-body">
<div class="setting-group"><label for="setting-ai-model-photo-local-url">ComfyUI URL</label><input type="text" id="setting-ai-model-photo-local-url" placeholder="http://127.0.0.1:8188"></div>
<div class="setting-group"><label for="setting-ai-model-photo-local-token">Lokaler Zugriffstoken</label><div class="inline-input-actions"><input type="text" id="setting-ai-model-photo-local-token" placeholder="Token gesetzt"><button type="button" class="secondary-btn compact-inline" id="regenerate-local-image-token-btn">Token neu</button></div></div>
<div class="setting-group"><label for="setting-ai-model-photo-local-workflow-path">Workflow-Pfad Standard</label><input type="text" id="setting-ai-model-photo-local-workflow-path" placeholder="local-ai/workflows/vendoo_flux_schnell_api.json"></div>
<div class="setting-group"><label for="setting-ai-model-photo-local-install-path">Installationspfad</label><input type="text" id="setting-ai-model-photo-local-install-path" placeholder="local-ai/comfyui"></div>
<label class="checkbox-line full-span"><input type="checkbox" id="setting-ai-model-photo-local-require-token"><span>Token für lokalen Zugriff verlangen</span></label>
</div>
</details>
</section>
</div>
</div>
<div class="settings-savebar">
<div><strong id="settings-save-title">Änderungen werden lokal gespeichert</strong><small id="settings-save-copy">Konfigurationen gelten direkt nach dem Speichern.</small></div>
<button id="save-settings-btn" class="primary-btn">Einstellungen speichern</button>
</div>
</section>
</main>
<!-- Advanced Image Editor -->
<div id="photo-editor-overlay" class="photo-editor-overlay hidden" aria-hidden="true">
<div class="photo-editor" role="dialog" aria-modal="true" aria-labelledby="photo-editor-title">
<header class="photo-editor-header">
<div>
<span class="photo-editor-kicker">Advanced Image Editor</span>
<h3 id="photo-editor-title">Bild nicht destruktiv bearbeiten</h3>
<small id="pe-image-meta">Original wird niemals überschrieben.</small>
</div>
<button id="photo-editor-close" class="modal-close" type="button" aria-label="Editor schließen">&times;</button>
</header>
<div class="photo-editor-toolbar" role="toolbar" aria-label="Bearbeitungsschritte">
<button class="small-btn" id="pe-undo" type="button" disabled>↶ Undo</button>
<button class="small-btn" id="pe-redo" type="button" disabled>↷ Redo</button>
<button class="small-btn" id="pe-compare" type="button" aria-pressed="false">◫ Vorher / Nachher</button>
<button class="small-btn" id="pe-restore-original" type="button">Original wiederherstellen</button>
<span id="pe-history-status" class="pe-history-status">Schritt 1 von 1</span>
</div>
<div class="photo-editor-workspace">
<section class="photo-editor-stage" aria-label="Bildvorschau">
<div id="pe-before-pane" class="pe-preview-pane pe-before-pane hidden">
<span>Original</span>
<canvas id="photo-editor-before-canvas"></canvas>
</div>
<div class="pe-preview-pane pe-after-pane">
<span>Bearbeitung</span>
<div id="photo-editor-canvas-wrap" class="photo-editor-canvas-wrap">
<canvas id="photo-editor-canvas"></canvas>
<canvas id="photo-editor-crop-overlay" class="crop-overlay hidden"></canvas>
</div>
</div>
<div class="pe-stage-footer">
<span id="pe-output-dimensions"></span>
<span id="pe-crop-hint">Zuschnitt ist nicht aktiv.</span>
</div>
</section>
<aside class="photo-editor-sidebar">
<details class="pe-control-group" open>
<summary>Geometrie & Zuschnitt</summary>
<div class="pe-control-body">
<div class="pe-button-grid">
<button class="small-btn" id="pe-rotate-left" type="button">↶ 90°</button>
<button class="small-btn" id="pe-rotate-right" type="button">↷ 90°</button>
<button class="small-btn" id="pe-flip-h" type="button">↔ Horizontal</button>
<button class="small-btn" id="pe-flip-v" type="button">↕ Vertikal</button>
</div>
<div class="editor-row">
<label for="pe-straighten">Begradigen</label>
<input type="range" id="pe-straighten" min="-15" max="15" step="0.1" value="0">
<span class="range-val" id="pe-straighten-val">0,0°</span>
</div>
<div class="pe-crop-controls">
<label for="pe-crop-ratio">Seitenverhältnis</label>
<select id="pe-crop-ratio">
<option value="free">Frei</option>
<option value="original">Original</option>
<option value="1:1">1:1</option>
<option value="4:5">4:5</option>
<option value="3:4">3:4</option>
<option value="16:9">16:9</option>
</select>
<div class="pe-button-grid three">
<button class="small-btn" id="pe-crop-toggle" type="button">✂ Auswahl starten</button>
<button class="small-btn hidden" id="pe-crop-apply" type="button">✓ Anwenden</button>
<button class="small-btn hidden" id="pe-crop-cancel" type="button">Abbrechen</button>
</div>
</div>
</div>
</details>
<details class="pe-control-group" open>
<summary>Licht & Farbe</summary>
<div class="pe-control-body">
<div class="editor-row"><label for="pe-exposure">Belichtung</label><input type="range" id="pe-exposure" min="-2" max="2" step="0.1" value="0"><span class="range-val" id="pe-exposure-val">0,0</span></div>
<div class="editor-row"><label for="pe-brightness">Helligkeit</label><input type="range" id="pe-brightness" min="-100" max="100" value="0"><span class="range-val" id="pe-brightness-val">0</span></div>
<div class="editor-row"><label for="pe-contrast">Kontrast</label><input type="range" id="pe-contrast" min="-100" max="100" value="0"><span class="range-val" id="pe-contrast-val">0</span></div>
<div class="editor-row"><label for="pe-highlights">Lichter</label><input type="range" id="pe-highlights" min="-100" max="100" value="0"><span class="range-val" id="pe-highlights-val">0</span></div>
<div class="editor-row"><label for="pe-shadows">Schatten</label><input type="range" id="pe-shadows" min="-100" max="100" value="0"><span class="range-val" id="pe-shadows-val">0</span></div>
<div class="editor-row"><label for="pe-temperature">Temperatur</label><input type="range" id="pe-temperature" min="-100" max="100" value="0"><span class="range-val" id="pe-temperature-val">0</span></div>
<div class="editor-row"><label for="pe-saturation">Sättigung</label><input type="range" id="pe-saturation" min="-100" max="100" value="0"><span class="range-val" id="pe-saturation-val">0</span></div>
<div class="editor-row"><label for="pe-sharpness">Schärfe</label><input type="range" id="pe-sharpness" min="0" max="100" value="0"><span class="range-val" id="pe-sharpness-val">0</span></div>
<button class="small-btn full" id="pe-reset-adjustments" type="button">Licht & Farbe zurücksetzen</button>
</div>
</details>
<details class="pe-control-group" open>
<summary>Freistellen &amp; Wasserzeichen</summary>
<div class="pe-control-body pe-special-tools">
<label class="pe-tool-toggle">
<input type="checkbox" id="pe-remove-background">
<span><strong>Hintergrund entfernen</strong><small>Entfernt einen gleichmäßigen Randhintergrund nicht destruktiv. Für Transparenz wird PNG empfohlen.</small></span>
</label>
<div class="pe-background-strength">
<label for="pe-background-sensitivity">Entfernungsintensität</label>
<div class="pe-inline-control"><input type="range" id="pe-background-sensitivity" min="0" max="100" value="45"><span class="range-val" id="pe-background-sensitivity-val">45%</span></div><small class="pe-sensitivity-help">Niedrig schützt feine Kanten; hoch entfernt mehr ähnliche Hintergrundfarben.</small>
</div>
<div class="pe-watermark-tools">
<label class="pe-tool-toggle">
<input type="checkbox" id="pe-watermark-enabled">
<span><strong>Wasserzeichen hinzufügen</strong><small>Text, Position und Deckkraft werden erst beim Speichern eingebrannt.</small></span>
</label>
<label for="pe-watermark-text">Wasserzeichentext</label>
<input id="pe-watermark-text" type="text" maxlength="80" value="Vendoo" placeholder="Vendoo">
<label for="pe-watermark-position">Position</label>
<select id="pe-watermark-position">
<option value="bottom-right" selected>Unten rechts</option>
<option value="bottom-left">Unten links</option>
<option value="top-right">Oben rechts</option>
<option value="top-left">Oben links</option>
<option value="center">Mittig</option>
</select>
<label for="pe-watermark-opacity">Deckkraft</label>
<div class="pe-inline-control"><input type="range" id="pe-watermark-opacity" min="10" max="100" value="40"><span class="range-val" id="pe-watermark-opacity-val">40%</span></div>
</div>
</div>
</details>
<details class="pe-control-group" open>
<summary>Export</summary>
<div class="pe-control-body pe-export-grid">
<label for="pe-format">Format</label>
<select id="pe-format"><option value="jpeg">JPEG</option><option value="webp">WebP</option><option value="png">PNG</option></select>
<label for="pe-quality">Qualität</label>
<div class="pe-inline-control"><input type="range" id="pe-quality" min="40" max="100" value="90"><span class="range-val" id="pe-quality-val">90%</span></div>
<label for="pe-target-size">Zielgröße</label>
<select id="pe-target-size"><option value="original">Originalgröße</option><option value="2048">max. 2048 px</option><option value="1600">max. 1600 px</option><option value="1200">max. 1200 px</option><option value="custom">Benutzerdefiniert</option></select>
<div id="pe-custom-size" class="pe-custom-size hidden">
<input id="pe-target-width" type="number" min="1" max="12000" placeholder="Breite">
<span>×</span>
<input id="pe-target-height" type="number" min="1" max="12000" placeholder="Höhe">
</div>
</div>
</details>
<details class="pe-control-group pe-version-group" open>
<summary>Gespeicherte Versionen <span id="pe-version-count">0</span></summary>
<div id="pe-version-list" class="pe-version-list"><div class="empty-state">Noch keine Bearbeitungsversion.</div></div>
</details>
</aside>
</div>
<footer class="photo-editor-actions">
<div><strong>Nicht destruktiv</strong><small>Speichern erzeugt immer eine neue Datei und Version.</small></div>
<button id="pe-cancel" class="secondary-btn" type="button">Abbrechen</button>
<button id="pe-apply" class="primary-btn" type="button">Als neue Version speichern</button>
</footer>
</div>
</div>
<div id="mobile-upload-overlay" class="modal-overlay mobile-upload-overlay hidden" aria-hidden="true">
<div class="mobile-upload-dialog" role="dialog" aria-modal="true" aria-labelledby="mobile-upload-title">
<header>
<div class="mobile-upload-dialog-brand"><span class="mobile-upload-dialog-icon">QR</span><div><span>Mobiler Foto-Upload</span><h3 id="mobile-upload-title">Fotos direkt vom Handy</h3></div></div>
<button id="mobile-upload-close" class="modal-close" type="button" aria-label="Schließen">×</button>
</header>
<div class="mobile-upload-dialog-grid">
<div class="mobile-upload-qr-card">
<canvas id="mobile-upload-qr"></canvas>
<span id="mobile-upload-session-state" class="mobile-upload-session-state"><i></i>Link wird vorbereitet …</span>
</div>
<div class="mobile-upload-dialog-copy">
<span class="eyebrow">Smartphone verbinden</span>
<h4>QR-Code mit der Kamera scannen</h4>
<ol>
<li>QR-Code mit dem Smartphone öffnen</li>
<li>Produktfotos aufnehmen oder auswählen</li>
<li>Bilder erscheinen automatisch in Vendoo</li>
</ol>
<div class="mobile-upload-link-wrap"><input id="mobile-upload-link" type="text" readonly><button id="mobile-upload-copy-link" type="button">Kopieren</button></div>
<p id="mobile-upload-network-note">Das Smartphone muss diese Vendoo-Adresse erreichen können.</p>
<div class="mobile-upload-live"><strong id="mobile-upload-file-count">0 Bilder empfangen</strong><span id="mobile-upload-expiry"></span></div>
</div>
</div>
<footer><button id="mobile-upload-new-session" class="secondary-btn" type="button">Neuen QR-Code erzeugen</button><button id="mobile-upload-done" class="primary-btn" type="button">Fertig</button></footer>
</div>
</div>
<div id="ai-prompt-modal" class="ai-prompt-modal hidden" aria-hidden="true">
<div class="ai-prompt-backdrop" data-ai-prompt-close></div>
<section class="ai-prompt-shell" role="dialog" aria-modal="true" aria-labelledby="ai-prompt-title">
<header class="ai-prompt-header">
<div>
<span class="print-studio-kicker">Vendoo AI Prompt</span>
<h2 id="ai-prompt-title">Eigene Bildanweisung</h2>
<p id="ai-prompt-scope-copy">Feinschliff für AI-Model-Fotos</p>
</div>
<button type="button" class="print-studio-close" data-ai-prompt-close aria-label="Schließen">×</button>
</header>
<div class="ai-prompt-body">
<div class="ai-prompt-summary">
<span class="ai-prompt-chip" id="ai-prompt-mode-chip">Modus: —</span>
<span class="ai-prompt-chip" id="ai-prompt-look-chip">Look: —</span>
<span class="ai-prompt-chip" id="ai-prompt-variants-chip">Varianten: —</span>
</div>
<label class="ai-prompt-field">
<span>Zusätzliche Prompt-Anweisung</span>
<textarea id="ai-prompt-textarea" rows="7" placeholder="z. B. neutrales Model, klare Frontalansicht, beide Ärmel sichtbar, Kapuze sauber am Rücken, natürlicher Stand, Produkt dominant..."></textarea>
<small>Optional. Vendoo ergänzt diese Anweisung zur sicheren Standardlogik.</small>
</label>
<label class="checkbox-line full-span ai-prompt-check"><input type="checkbox" id="ai-prompt-preserve-logos" checked><span>Logos, Prints und Aufdrucke strikt erhalten</span></label>
</div>
<footer class="ai-prompt-footer">
<button type="button" class="vd-button" id="ai-prompt-reset-btn">Zurücksetzen</button>
<div class="ai-prompt-footer-actions">
<button type="button" class="vd-button" data-ai-prompt-close>Schließen</button>
<button type="button" class="vd-button primary" id="ai-prompt-run-btn">Speichern &amp; Generieren</button>
</div>
</footer>
</section>
</div>
<div id="smart-copy-modal" class="smart-copy-modal hidden" aria-hidden="true">
<button type="button" class="smart-copy-modal-backdrop" data-smart-copy-close aria-label="Smart Copy schließen"></button>
<section class="smart-copy-modal-dialog" role="dialog" aria-modal="true" aria-labelledby="smart-copy-modal-title">
<header><div><p class="eyebrow">Publish Assistant</p><h2 id="smart-copy-modal-title">Smart Copy</h2><p>Alle Verkaufsdaten kompakt kopieren und die Zielplattform direkt öffnen.</p></div><button type="button" class="modal-close" data-smart-copy-close aria-label="Schließen">×</button></header>
<div id="smart-copy-modal-content" class="smart-copy-modal-content"></div>
</section>
</div>
<div id="flux-prompt-lab" class="flux-prompt-lab hidden" aria-hidden="true">
<button type="button" class="flux-prompt-lab-backdrop" data-flux-prompt-lab-close aria-label="Prompt Lab schließen"></button>
<section class="flux-prompt-lab-dialog" role="dialog" aria-modal="true" aria-labelledby="flux-prompt-lab-title">
<header>
<div><p class="eyebrow">FLUX Prompt Director</p><h2 id="flux-prompt-lab-title">Prompt Lab</h2><p>Lokal strukturieren oder mit dem aktuell aktiven AI-Provider professionell veredeln.</p></div>
<button type="button" class="modal-close" data-flux-prompt-lab-close aria-label="Schließen">×</button>
</header>
<div class="flux-prompt-lab-body">
<div class="flux-prompt-lab-provider"><span>Aktiver AI-Provider</span><strong id="flux-prompt-lab-provider"></strong></div>
<label class="flux-prompt-lab-field"><span>Ausgangsprompt</span><textarea id="flux-prompt-lab-original" rows="6"></textarea></label>
<div class="flux-prompt-lab-options">
<label>Zielprofil<select id="flux-prompt-lab-goal"><option value="product" selected>Produktfotografie & Marketplace</option><option value="precise">Präzise & technisch</option><option value="creative">Kreativ & aufmerksamkeitsstark</option><option value="cinematic">Cinematisch & atmosphärisch</option></select></label>
<label class="flux-prompt-lab-check"><input type="checkbox" id="flux-prompt-lab-preserve" checked><span>Motiv und Produktmerkmale strikt erhalten</span></label>
<label class="flux-prompt-lab-check"><input type="checkbox" id="flux-prompt-lab-avoid-text" checked><span>Keine erfundene Schrift, Logos oder Wasserzeichen</span></label>
</div>
<div class="flux-prompt-lab-actions"><button type="button" class="vd-button" id="flux-prompt-lab-local">Lokal strukturieren</button><button type="button" class="vd-button primary" id="flux-prompt-lab-ai">Mit AI veredeln</button></div>
<div id="flux-prompt-lab-status" class="flux-prompt-lab-status">Bereit.</div>
<label class="flux-prompt-lab-field"><span>Optimierter Prompt</span><textarea id="flux-prompt-lab-result" rows="9" placeholder="Hier erscheint der optimierte FLUX-Prompt …"></textarea></label>
<p id="flux-prompt-lab-notes" class="flux-prompt-lab-notes"></p>
</div>
<footer><button type="button" class="vd-button" data-flux-prompt-lab-close>Abbrechen</button><button type="button" class="vd-button primary" id="flux-prompt-lab-apply">Prompt übernehmen</button></footer>
</section>
</div>
<div id="media-lightbox" class="media-lightbox hidden" aria-hidden="true">
<button type="button" class="media-lightbox-backdrop" data-media-lightbox-close aria-label="Vorschau schließen"></button>
<section class="media-lightbox-dialog" role="dialog" aria-modal="true" aria-labelledby="media-lightbox-title">
<header><div><p class="eyebrow">Bildvorschau</p><h3 id="media-lightbox-title">Bild</h3></div><button type="button" class="icon-button media-lightbox-close" data-media-lightbox-close aria-label="Vorschau schließen"><span data-vd-icon="x"></span></button></header>
<div class="media-lightbox-toolbar" aria-label="Zoomsteuerung">
<button type="button" class="icon-button" id="media-zoom-out" aria-label="Verkleinern" title="Verkleinern"><span data-vd-icon="zoom-out"></span></button>
<input type="range" id="media-zoom-range" min="10" max="400" step="5" value="100" aria-label="Zoomstufe">
<button type="button" class="icon-button" id="media-zoom-in" aria-label="Vergrößern" title="Vergrößern"><span data-vd-icon="zoom-in"></span></button>
<button type="button" class="vd-button compact" id="media-zoom-fit"><span data-vd-icon="maximize"></span> Einpassen</button>
<button type="button" class="vd-button compact" id="media-zoom-original">100 %</button>
<output id="media-zoom-value">100 %</output>
</div>
<div class="media-lightbox-body"><div class="media-lightbox-stage" id="media-lightbox-stage"><div class="media-lightbox-canvas" id="media-lightbox-canvas"><img id="media-lightbox-image" alt="Bildvorschau" draggable="false"></div></div><aside id="media-lightbox-meta"></aside></div>
<footer><button type="button" class="vd-button primary" id="media-lightbox-edit"><span data-vd-icon="pencil"></span> Im Editor öffnen</button><a class="vd-button" id="media-lightbox-download" download><span data-vd-icon="download"></span> Herunterladen</a><button type="button" class="vd-button" id="media-lightbox-favorite"><span data-vd-icon="heart"></span> Favorit</button><button type="button" class="vd-button danger" id="media-lightbox-delete"><span data-vd-icon="trash-2"></span> Löschen</button></footer>
</section>
</div>
<div class="modal-overlay hidden" id="quality-ai-modal" role="dialog" aria-modal="true" aria-labelledby="quality-ai-title">
<div class="modal quality-ai-modal">
<header><div><p class="eyebrow">Bestätigte AI-Verbesserung</p><h2 id="quality-ai-title">Artikel verbessern</h2><p>Die AI erstellt nur Vorschläge. Übernommen wird erst nach deiner Bestätigung.</p></div><button type="button" class="modal-close" id="quality-ai-close" aria-label="Schließen">×</button></header>
<div class="quality-ai-options">
<label><input type="checkbox" id="quality-ai-field-title" checked> Titel</label>
<label><input type="checkbox" id="quality-ai-field-description" checked> Beschreibung</label>
<label><input type="checkbox" id="quality-ai-field-tags" checked> Tags</label>
<label class="quality-ai-mode"><span>Profil</span><select id="quality-ai-mode"><option value="balanced">Ausgewogen</option><option value="concise">Kompakt</option><option value="sales">Verkaufsstark</option><option value="seo">Suchoptimiert</option></select></label>
</div>
<div class="quality-ai-status" id="quality-ai-status">Wähle die Felder und erstelle einen Vorschlag.</div>
<div class="quality-ai-compare hidden" id="quality-ai-compare">
<section><h3>Original</h3><label>Titel<textarea id="quality-ai-original-title" readonly></textarea></label><label>Beschreibung<textarea id="quality-ai-original-description" readonly></textarea></label><label>Tags<textarea id="quality-ai-original-tags" readonly></textarea></label></section>
<section><h3>Vorschlag</h3><label>Titel<textarea id="quality-ai-suggested-title"></textarea></label><label>Beschreibung<textarea id="quality-ai-suggested-description"></textarea></label><label>Tags<textarea id="quality-ai-suggested-tags"></textarea></label></section>
</div>
<div class="quality-ai-reasons" id="quality-ai-reasons"></div>
<footer><button type="button" class="vd-button" id="quality-ai-cancel">Abbrechen</button><button type="button" class="vd-button accent" id="quality-ai-generate">Vorschlag erstellen</button><button type="button" class="primary-btn hidden" id="quality-ai-apply">Bestätigt übernehmen</button></footer>
</div>
</div>
<div id="toast" class="toast"></div>
<script src="https://cdn.jsdelivr.net/npm/quill@2.0.3/dist/quill.js"></script>
<script src="https://cdn.jsdelivr.net/npm/qrious@4.0.2/dist/qrious.min.js"></script>
<script src="design-system/theme-runtime.js?v=1.43.0"></script>
<script src="vendoo-icons.js?v=1.43.0"></script>
<script src="app.js?v=1.43.0"></script>
<script type="module" src="modules/theme-manager/theme-manager.js?v=1.43.0"></script>
<script type="module" src="modules/module-manager/module-manager.js?v=1.43.0"></script>
</body>
</html>