Spaces:
Running
Running
File size: 7,273 Bytes
128021b 4850a92 128021b 6d2ed1e 4850a92 6d2ed1e 128021b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | <!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>BG Remove — Background Removal Tool</title>
<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=Newsreader:ital,wght@0,400;0,500;1,400&family=Geist+Mono:wght@400;500&family=DM+Sans:wght@300;400;500&display=swap" rel="stylesheet">
<link rel="stylesheet" href="styles.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script>
</head>
<body>
<nav>
<a class="nav-logo" href="#">BG<span>Remove</span></a>
<div class="nav-right">
<div class="tag"><div class="dot"></div>Browser-only</div>
<button class="theme-btn" id="themeToggle" aria-label="Toggle theme">
<svg id="iconSun" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round">
<circle cx="12" cy="12" r="4"/>
<line x1="12" y1="2" x2="12" y2="5"/><line x1="12" y1="19" x2="12" y2="22"/>
<line x1="2" y1="12" x2="5" y2="12"/><line x1="19" y1="12" x2="22" y2="12"/>
<line x1="4.22" y1="4.22" x2="6.34" y2="6.34"/><line x1="17.66" y1="17.66" x2="19.78" y2="19.78"/>
<line x1="4.22" y1="19.78" x2="6.34" y2="17.66"/><line x1="17.66" y1="6.34" x2="19.78" y2="4.22"/>
</svg>
<svg id="iconMoon" style="display:none" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round">
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/>
</svg>
</button>
</div>
</nav>
<main>
<div class="hero">
<h1>Remove backgrounds<br><em>instantly.</em></h1>
<p>Upload a portrait, product shot, or illustration and remove the background in a few seconds — entirely in your browser.</p>
</div>
<div class="upload-zone" id="uploadZone" role="button" tabindex="0">
<input type="file" id="fileInput" accept="image/png,image/jpeg,image/webp" multiple>
<svg class="upload-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
<polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/>
</svg>
<h3>Drop an image here or click to browse</h3>
<p id="uploadHint">Supports PNG, JPEG, and WebP — up to 20 MB.</p>
<div class="formats">
<span class="format-badge">.png</span>
<span class="format-badge">.jpg</span>
<span class="format-badge">.webp</span>
</div>
</div>
<div class="panel" id="panel">
<div class="img-card">
<div class="img-card-header">
<span id="originalLabel">Original</span>
<div class="status-badge ready"><div class="dot"></div>Loaded</div>
</div>
<div class="img-card-body">
<img id="originalImg" src="" alt="Original image">
</div>
</div>
<div class="img-card">
<div class="img-card-header">
<span>Result</span>
<div class="status-badge processing" id="resultStatus" style="display:none">
<div class="dot pulse"></div>Processing
</div>
</div>
<div class="img-card-body" id="resultBody">
<div class="result-empty">
<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2">
<rect x="3" y="3" width="18" height="18" rx="2"/>
<circle cx="8.5" cy="8.5" r="1.5"/><polyline points="21 15 16 10 5 21"/>
</svg>
<span>Your result will appear here</span>
</div>
</div>
</div>
<div class="controls-row">
<button class="btn btn-primary" id="processBtn">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
<path d="M12 2L2 7l10 5 10-5-10-5z"/>
<path d="M2 17l10 5 10-5"/><path d="M2 12l10 5 10-5"/>
</svg>
Remove Background
</button>
<div class="progress-wrap" id="progressWrap">
<div class="progress-bar-track"><div class="progress-bar-fill" id="progressFill"></div></div>
<span class="progress-label" id="progressLabel">Initializing...</span>
</div>
<button class="btn-reset" id="resetBtn">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" style="display:inline;margin-right:5px">
<polyline points="1 4 1 10 7 10"/><path d="M3.51 15a9 9 0 1 0 .49-3.51"/>
</svg>
Reset
</button>
</div>
<button class="icon-btn" id="downloadZipBtn" aria-label="Download ZIP archive" style="display:none;">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
<polyline points="7 10 12 15 17 10"/>
<line x1="12" y1="15" x2="12" y2="3"/>
<path d="M5 7h14"/>
</svg>
</button>
</div>
<section class="queue-history">
<div class="queue-panel">
<h4>Queue</h4>
<div id="queueList" class="list"></div>
</div>
<div class="history-panel">
<div class="history-header">
<h4>History</h4>
<div class="history-actions">
<button class="icon-btn" id="downloadHistoryZipBtn" aria-label="Download all history ZIP" style="display:none;">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
<polyline points="7 10 12 15 17 10"/>
<line x1="12" y1="15" x2="12" y2="3"/>
</svg>
</button>
<button class="icon-btn" id="clearHistoryBtn" aria-label="Clear history" style="display:none;">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M3 6h18"/>
<path d="M9 6V4a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2"/>
<path d="M8 11v7a2 2 0 0 0 2 2h4a2 2 0 0 0 2-2v-7"/>
<line x1="10" y1="14" x2="10" y2="18"/>
<line x1="14" y1="14" x2="14" y2="18"/>
</svg>
</button>
</div>
</div>
<div id="historyList" class="list"></div>
</div>
</section>
<div class="message-banner" id="messageBanner" role="status" aria-live="polite"></div>
<div class="foot-note">
<div class="foot-note-icon">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
<rect x="3" y="11" width="18" height="11" rx="2" ry="2"/>
<path d="M7 11V7a5 5 0 0 1 10 0v4"/>
</svg>
</div>
<p><strong>Private by design.</strong> Your images never leave your device. The AI model runs entirely in the browser using WebAssembly — no server, no uploads, no storage.</p>
</div>
</main>
<script type="module" src="app.js"></script>
</body>
</html> |