Spaces:
Sleeping
Sleeping
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>ImageEditter - Hybrid Local Image Studio</title> | |
| <meta name="description" content="A premium local image editing studio with prompt editing, inpainting, generation, style transfer, background replacement, and upscale flows."> | |
| <link rel="preconnect" href="https://fonts.googleapis.com"> | |
| <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | |
| <link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;700;800&family=Space+Grotesk:wght@500;700&display=swap" rel="stylesheet"> | |
| <link rel="stylesheet" href="/static/style.css"> | |
| </head> | |
| <body> | |
| <div class="ambient ambient-1"></div> | |
| <div class="ambient ambient-2"></div> | |
| <div class="ambient ambient-3"></div> | |
| <div class="shell"> | |
| <header class="topbar"> | |
| <div class="brand"> | |
| <div class="brand-mark"> | |
| <svg width="34" height="34" viewBox="0 0 34 34" fill="none"> | |
| <rect x="3" y="3" width="28" height="28" rx="8" stroke="url(#brandStroke)" stroke-width="2.4"/> | |
| <path d="M9 22L15 15L19 19L24 12L26 15" stroke="url(#brandStroke)" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/> | |
| <circle cx="13" cy="11" r="2.6" fill="url(#brandFill)"/> | |
| <defs> | |
| <linearGradient id="brandStroke" x1="0" y1="0" x2="34" y2="34"> | |
| <stop stop-color="#ffb36a"/> | |
| <stop offset="0.52" stop-color="#f36f5e"/> | |
| <stop offset="1" stop-color="#2ac3c3"/> | |
| </linearGradient> | |
| <linearGradient id="brandFill" x1="0" y1="0" x2="34" y2="34"> | |
| <stop stop-color="#ffe09c"/> | |
| <stop offset="1" stop-color="#2ac3c3"/> | |
| </linearGradient> | |
| </defs> | |
| </svg> | |
| </div> | |
| <div> | |
| <h1>ImageEditter</h1> | |
| <p id="mode-blurb">Hybrid local image studio with CV planning and optional diffusion harmonization.</p> | |
| </div> | |
| </div> | |
| <div class="status-cluster"> | |
| <div class="status-pill" id="server-status"> | |
| <span class="status-dot" id="status-dot"></span> | |
| <span id="status-text">Connecting...</span> | |
| </div> | |
| <div class="metric-pill"> | |
| <span class="metric-label">Capabilities</span> | |
| <strong id="capability-count">0</strong> | |
| </div> | |
| <div class="metric-pill"> | |
| <span class="metric-label">Presets</span> | |
| <strong id="preset-count">0</strong> | |
| </div> | |
| </div> | |
| </header> | |
| <main class="layout"> | |
| <aside class="left-rail"> | |
| <section class="glass card mode-card"> | |
| <div class="card-head"> | |
| <div> | |
| <span class="eyebrow">Modes</span> | |
| <h2>Studio Flow</h2> | |
| </div> | |
| </div> | |
| <div class="mode-grid" id="mode-tabs"> | |
| <button class="mode-tab active" data-mode="edit">Edit</button> | |
| <button class="mode-tab" data-mode="generate">Generate</button> | |
| <button class="mode-tab" data-mode="inpaint">Inpaint</button> | |
| <button class="mode-tab" data-mode="style">Style</button> | |
| <button class="mode-tab" data-mode="background">Background</button> | |
| <button class="mode-tab" data-mode="upscale">Upscale</button> | |
| <button class="mode-tab wide" data-mode="batch">Batch</button> | |
| </div> | |
| <p class="mode-copy" id="mode-copy">Prompt-driven image editing with multi-step local planning.</p> | |
| </section> | |
| <section class="glass card upload-card"> | |
| <div class="card-head"> | |
| <div> | |
| <span class="eyebrow">Assets</span> | |
| <h2>Inputs</h2> | |
| </div> | |
| <button class="ghost-button" id="btn-clear-all" type="button">Clear</button> | |
| </div> | |
| <div class="upload-stack"> | |
| <button class="upload-tile primary" id="source-drop" type="button"> | |
| <span class="tile-label">Source Image</span> | |
| <span class="tile-meta" id="source-meta">Drop or browse PNG, JPG, WebP</span> | |
| </button> | |
| <button class="upload-tile" id="reference-drop" type="button"> | |
| <span class="tile-label">Reference Image</span> | |
| <span class="tile-meta" id="reference-meta">Used for style transfer</span> | |
| </button> | |
| <button class="upload-tile" id="background-drop" type="button"> | |
| <span class="tile-label">Background Image</span> | |
| <span class="tile-meta" id="background-meta">Optional replacement backdrop</span> | |
| </button> | |
| <button class="upload-tile" id="batch-drop" type="button"> | |
| <span class="tile-label">Batch Images</span> | |
| <span class="tile-meta" id="batch-meta">Multiple inputs for batch mode</span> | |
| </button> | |
| </div> | |
| <input type="file" id="source-input" accept="image/*" hidden> | |
| <input type="file" id="reference-input" accept="image/*" hidden> | |
| <input type="file" id="background-input" accept="image/*" hidden> | |
| <input type="file" id="batch-input" accept="image/*" multiple hidden> | |
| <div class="mask-panel" id="mask-panel"> | |
| <div class="mask-head"> | |
| <span class="eyebrow">Mask</span> | |
| <div class="mask-actions"> | |
| <button class="tool-chip active" id="mask-brush" type="button">Brush</button> | |
| <button class="tool-chip" id="mask-erase" type="button">Erase</button> | |
| <button class="tool-chip" id="mask-magic" type="button" style="background: rgba(255, 179, 106, 0.08); border-color: rgba(255, 179, 106, 0.35);">🪄 Magic Select</button> | |
| <button class="tool-chip" id="mask-fill" type="button">Fill</button> | |
| <button class="tool-chip" id="mask-clear" type="button">Clear</button> | |
| </div> | |
| </div> | |
| <label class="range-field"> | |
| <span>Brush Size</span> | |
| <input type="range" id="mask-size" min="4" max="80" value="24"> | |
| <strong id="mask-size-value">24</strong> | |
| </label> | |
| </div> | |
| </section> | |
| <section class="glass card batch-card" id="batch-panel"> | |
| <div class="card-head"> | |
| <div> | |
| <span class="eyebrow">Batch</span> | |
| <h2>Queue</h2> | |
| </div> | |
| </div> | |
| <div class="thumb-grid" id="batch-source-grid"></div> | |
| <div class="thumb-grid results" id="batch-result-grid"></div> | |
| </section> | |
| </aside> | |
| <section class="center-stage"> | |
| <section class="glass hero"> | |
| <div class="hero-top"> | |
| <div> | |
| <span class="eyebrow">Canvas</span> | |
| <h2>Comparison Stage</h2> | |
| </div> | |
| <div class="hero-actions"> | |
| <button class="ghost-button" id="btn-view-toggle" type="button">Compare</button> | |
| <button class="ghost-button" id="btn-download" type="button" disabled>Download</button> | |
| <button class="ghost-button" id="btn-fullscreen" type="button">Fullscreen</button> | |
| </div> | |
| </div> | |
| <div class="compare-wrap" id="compare-wrap"> | |
| <div class="stage-frame" id="stage-frame"> | |
| <div class="stage-media" id="stage-media"> | |
| <img id="result-preview" class="stage-image" alt="Edited or generated result" hidden> | |
| <div class="compare-overlay" id="compare-overlay"> | |
| <img id="source-preview" class="stage-image" alt="Source preview" hidden> | |
| <canvas id="mask-canvas" hidden></canvas> | |
| </div> | |
| <div class="stage-empty" id="stage-empty"> | |
| <div class="empty-badge">Hybrid Local Studio</div> | |
| <h3>Build cinematic edits, repairs, styles, and backgrounds locally.</h3> | |
| <p id="prompt-hint-text">Loading editor capabilities...</p> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="compare-controls"> | |
| <span>Result</span> | |
| <input type="range" id="compare-slider" min="0" max="100" value="50"> | |
| <span>Source</span> | |
| </div> | |
| </div> | |
| <div class="progress-strip"> | |
| <div class="progress-pill" id="progress-pill">Idle</div> | |
| <div class="steps-row" id="pipeline-steps"></div> | |
| </div> | |
| </section> | |
| <section class="glass composer"> | |
| <div class="card-head"> | |
| <div> | |
| <span class="eyebrow">Prompt</span> | |
| <h2>Direction</h2> | |
| </div> | |
| <div class="chip-row" id="capability-tags"></div> | |
| </div> | |
| <div class="composer-body"> | |
| <textarea | |
| id="prompt-input" | |
| class="prompt-input" | |
| placeholder="Describe the edit, scene, repair, or style you want..." | |
| maxlength="500" | |
| ></textarea> | |
| <div class="action-row"> | |
| <button class="primary-button" id="run-button" type="button">Run Mode</button> | |
| <button class="secondary-button" id="btn-undo" type="button">Undo</button> | |
| <button class="secondary-button" id="btn-redo" type="button">Redo</button> | |
| </div> | |
| <p class="response-banner" id="response-banner" hidden></p> | |
| <div class="mode-controls"> | |
| <div class="control-group dual" id="generate-controls"> | |
| <label class="field"> | |
| <span>Width</span> | |
| <input type="number" id="generate-width" value="768" min="128" max="2048"> | |
| </label> | |
| <label class="field"> | |
| <span>Height</span> | |
| <input type="number" id="generate-height" value="768" min="128" max="2048"> | |
| </label> | |
| </div> | |
| <div class="control-group" id="upscale-controls"> | |
| <label class="range-field"> | |
| <span>Upscale Factor</span> | |
| <input type="range" id="upscale-scale" min="1" max="4" value="2" step="0.1"> | |
| <strong id="upscale-scale-value">2.0x</strong> | |
| </label> | |
| </div> | |
| <div class="control-group advanced"> | |
| <label class="range-field"> | |
| <span>Planning / Steps</span> | |
| <input type="range" id="steps-slider" min="1" max="100" value="36"> | |
| <strong id="steps-value">36</strong> | |
| </label> | |
| <label class="range-field"> | |
| <span>Text Guidance</span> | |
| <input type="range" id="text-scale-slider" min="0" max="20" value="7.5" step="0.5"> | |
| <strong id="text-scale-value">7.5</strong> | |
| </label> | |
| <label class="range-field"> | |
| <span>Image Guidance</span> | |
| <input type="range" id="image-scale-slider" min="0" max="5" value="1.5" step="0.1"> | |
| <strong id="image-scale-value">1.5</strong> | |
| </label> | |
| <label class="field"> | |
| <span>Seed</span> | |
| <input type="number" id="seed-input" placeholder="Random" min="0"> | |
| </label> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| </section> | |
| <aside class="right-rail"> | |
| <section class="glass card adjustment-card" id="adjustment-panel"> | |
| <div class="card-head"> | |
| <div> | |
| <span class="eyebrow">Fine-tune</span> | |
| <h2>Manual Adjustments</h2> | |
| </div> | |
| <button class="ghost-button" id="btn-reset-adjust" type="button">Reset</button> | |
| </div> | |
| <div class="adjust-sliders-stack" style="display: flex; flex-direction: column; gap: 1rem; margin-top: 1rem;"> | |
| <label class="range-field"> | |
| <span>Warmth (WB Temp)</span> | |
| <input type="range" id="adjust-warmth" min="0.5" max="1.5" value="1.0" step="0.02"> | |
| <strong id="adjust-warmth-value">1.00</strong> | |
| </label> | |
| <label class="range-field"> | |
| <span>Exposure (Brightness)</span> | |
| <input type="range" id="adjust-brightness" min="0.5" max="1.5" value="1.0" step="0.02"> | |
| <strong id="adjust-brightness-value">1.00</strong> | |
| </label> | |
| <label class="range-field"> | |
| <span>Contrast</span> | |
| <input type="range" id="adjust-contrast" min="0.5" max="1.5" value="1.0" step="0.02"> | |
| <strong id="adjust-contrast-value">1.00</strong> | |
| </label> | |
| <label class="range-field"> | |
| <span>Clarity</span> | |
| <input type="range" id="adjust-clarity" min="1.0" max="2.0" value="1.0" step="0.05"> | |
| <strong id="adjust-clarity-value">1.00</strong> | |
| </label> | |
| <label class="range-field"> | |
| <span>Sharpness</span> | |
| <input type="range" id="adjust-sharpness" min="0.0" max="2.0" value="0.0" step="0.05"> | |
| <strong id="adjust-sharpness-value">0.00</strong> | |
| </label> | |
| <label class="range-field"> | |
| <span>Vignette</span> | |
| <input type="range" id="adjust-vignette" min="0.0" max="1.0" value="0.0" step="0.05"> | |
| <strong id="adjust-vignette-value">0.00</strong> | |
| </label> | |
| <label class="range-field"> | |
| <span>Bloom Glow</span> | |
| <input type="range" id="adjust-bloom" min="0.0" max="1.0" value="0.0" step="0.05"> | |
| <strong id="adjust-bloom-value">0.00</strong> | |
| </label> | |
| </div> | |
| </section> | |
| <section class="glass card presets-card"> | |
| <div class="card-head"> | |
| <div> | |
| <span class="eyebrow">Looks</span> | |
| <h2>Preset Gallery</h2> | |
| </div> | |
| </div> | |
| <div class="preset-grid" id="preset-grid"></div> | |
| </section> | |
| <section class="glass card history-card"> | |
| <div class="card-head"> | |
| <div> | |
| <span class="eyebrow">Timeline</span> | |
| <h2>Edit History</h2> | |
| </div> | |
| </div> | |
| <div class="history-list" id="history-list"></div> | |
| </section> | |
| <section class="glass card layers-card"> | |
| <div class="card-head"> | |
| <div> | |
| <span class="eyebrow">Pipeline</span> | |
| <h2>Layer Steps</h2> | |
| </div> | |
| </div> | |
| <div class="layer-list" id="layer-list"></div> | |
| </section> | |
| </aside> | |
| </main> | |
| </div> | |
| <div class="toast-stack" id="toast-stack"></div> | |
| <script src="/static/app.js"></script> | |
| </body> | |
| </html> | |