solarkyle commited on
Commit
c5ed891
·
verified ·
1 Parent(s): b4b9647

Add live-GPU banner + point CPU note to the GPU Space

Browse files
Files changed (2) hide show
  1. README.md +4 -2
  2. static/index.html +167 -166
README.md CHANGED
@@ -32,8 +32,10 @@ Upload a sprite, pick a vibe (or write your own), hit **Run**. PixelLock restyle
32
  the colors and shading while keeping the **exact silhouette** — pixel-perfect,
33
  *guaranteed by construction*.
34
 
35
- > This is a GPU Space that auto-sleeps. The first visit cold-starts the model
36
- > (~30–60s). If the first edit errors, the model is still waking — try again.
 
 
37
 
38
  ## 🔗 Links
39
 
 
32
  the colors and shading while keeping the **exact silhouette** — pixel-perfect,
33
  *guaranteed by construction*.
34
 
35
+ > ⚠️ **This Space runs on CPU** (the hackathon org has no dedicated-GPU credits), so
36
+ > live edits won't run *here*. **▶ Try it live on GPU
37
+ > https://huggingface.co/spaces/solarkyle/pixellock** (cold-starts ~60s) — or watch
38
+ > the 45-second demo video linked below.
39
 
40
  ## 🔗 Links
41
 
static/index.html CHANGED
@@ -1,166 +1,167 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
6
- <title>PixelLock — AI Pixel-Art Retexturing</title>
7
- <meta name="description" content="Footprint-locked AI pixel-art retexturing — keep the exact silhouette, change the style." />
8
- <link rel="preconnect" href="https://fonts.googleapis.com">
9
- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
10
- <link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;700&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet">
11
- <link rel="stylesheet" href="/static/styles.css" />
12
- <link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Crect width='16' height='16' rx='3' fill='%230b0b14'/%3E%3Crect x='3' y='3' width='4' height='4' fill='%23a06bff'/%3E%3Crect x='9' y='3' width='4' height='4' fill='%2300e5d4'/%3E%3Crect x='3' y='9' width='4' height='4' fill='%2300e5d4'/%3E%3Crect x='9' y='9' width='4' height='4' fill='%23a06bff'/%3E%3C/svg%3E" />
13
- </head>
14
- <body>
15
- <div class="bg-glow" aria-hidden="true"></div>
16
- <div class="scanlines" aria-hidden="true"></div>
17
-
18
- <header class="appbar">
19
- <div class="brand">
20
- <span class="logo" aria-hidden="true"><i></i><i></i><i></i><i></i></span>
21
- <h1 class="wordmark">Pixel<b>Lock</b></h1>
22
- <span class="brand-div">|</span>
23
- <span class="brand-sub">AI Pixel-Art Retexturing Tool</span>
24
- </div>
25
- <div class="fp-pill" title="Every edit keeps your sprite's exact shape, by construction">
26
- <svg viewBox="0 0 24 24" width="14" height="14"><path fill="currentColor" d="M12 1a5 5 0 0 0-5 5v3H6a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-9a2 2 0 0 0-2-2h-1V6a5 5 0 0 0-5-5m0 2a3 3 0 0 1 3 3v3H9V6a3 3 0 0 1 3-3"/></svg>
27
- Footprint-locked retexturing
28
- </div>
29
- <div class="appbar-right">
30
- <span class="server-pill"><span id="server-dot" class="dot down"></span><span id="server-label">connecting…</span></span>
31
- <a class="ghost-btn" href="https://github.com/ggml-org/llama.cpp" target="_blank" rel="noopener">⌁ GBNF · llama.cpp</a>
32
- </div>
33
- </header>
34
-
35
- <div class="howbar">
36
- <span class="how-tag">⚡ NOT an image generator</span>
37
- <span class="how-steps">your PNG a <b>text grid</b> (PALETTE&nbsp;+&nbsp;GRID) → a <b>fine-tuned text LLM</b> rewrites it under a <b>GBNF grammar</b> that locks the exact shape → pixel-perfect PNG. <em>It's language modeling, not diffusion.</em></span>
38
- </div>
39
-
40
- <section class="proofbar" aria-label="PixelLock guarantees">
41
- <div class="proof-card">
42
- <span class="proof-k">100%</span>
43
- <span class="proof-v">footprint constrained</span>
44
- </div>
45
- <div class="proof-card">
46
- <span class="proof-k">PNG → TEXT → PNG</span>
47
- <span class="proof-v">palette grid, not diffusion</span>
48
- </div>
49
- <div class="proof-card">
50
- <span class="proof-k">LLAMA.CPP + GBNF</span>
51
- <span class="proof-v">shape locked in the decoder</span>
52
- </div>
53
- </section>
54
-
55
- <main class="layout">
56
- <!-- LEFT: controls -->
57
- <aside class="controls">
58
- <section class="step">
59
- <h2><span class="num">01</span> Upload sprite</h2>
60
- <div id="dropzone" class="dropzone" tabindex="0" role="button" aria-label="Upload a sprite PNG">
61
- <input id="file" type="file" accept="image/png,image/*" hidden />
62
- <div id="dz-empty" class="dz-empty">
63
- <div class="dz-ico" aria-hidden="true">⬆</div>
64
- <p class="dz-main">Drop sprite PNG or <span class="link">click to upload</span></p>
65
- <p class="dz-hint">best for 16×16 64×64</p>
66
- <span class="dz-tag">PNG</span>
67
- </div>
68
- <div id="dz-loaded" class="dz-loaded" hidden>
69
- <img id="dz-preview" class="pixelated" alt="loaded sprite" />
70
- <div class="dz-meta"><span id="dz-name" class="dz-name">sprite.png</span>
71
- <button id="dz-clear" class="link-btn" type="button">change</button></div>
72
- </div>
73
- </div>
74
- </section>
75
-
76
- <section class="step starter-step">
77
- <h2><span class="num">01B</span> Starter sprites <span class="opt">click to load</span></h2>
78
- <div id="asset-strip" class="asset-strip" aria-label="Starter sprites"></div>
79
- </section>
80
-
81
- <section class="step">
82
- <h2><span class="num">02</span> Theme / vibe <span class="opt">optional</span></h2>
83
- <div id="chips" class="chips" role="listbox" aria-label="Theme presets"></div>
84
- </section>
85
-
86
- <section class="step">
87
- <h2><span class="num">03</span> Prompt <span class="opt">optional</span></h2>
88
- <textarea id="prompt" class="prompt" rows="3" spellcheck="false"
89
- placeholder="Restyle into… (the AI invents the colors; the shape stays locked)"></textarea>
90
- </section>
91
-
92
- <section class="step">
93
- <h2><span class="num">04</span> Mode</h2>
94
- <div id="mode-toggle" class="toggle" role="tablist" aria-label="Edit mode">
95
- <span id="toggle-glider" class="toggle-glider" aria-hidden="true"></span>
96
- <button class="toggle-opt active" data-mode="exact" role="tab" aria-selected="true">🎨 Retheme</button>
97
- <button class="toggle-opt" data-mode="upscale2x" role="tab" aria-selected="false"> Upscale 2×</button>
98
- </div>
99
- </section>
100
-
101
- <button id="run" class="run-btn" disabled>
102
- <span class="run-label">▶ RUN RETEXTURE</span>
103
- <span class="run-spinner" aria-hidden="true"></span>
104
- </button>
105
- <p id="run-hint" class="hint">load a sprite to begin</p>
106
- </aside>
107
-
108
- <!-- CENTER: stage -->
109
- <section class="stage lab">
110
- <div class="compare">
111
- <figure class="frame">
112
- <figcaption>INPUT <span>your sprite</span></figcaption>
113
- <div class="checker canvas"><img id="img-in" class="pixelated" alt="input sprite" /></div>
114
- </figure>
115
-
116
- <div class="arrow" aria-hidden="true">▶</div>
117
-
118
- <figure class="frame">
119
- <figcaption>OUTPUT <span>AI restyled</span></figcaption>
120
- <div class="checker canvas">
121
- <img id="img-out" class="pixelated" alt="restyled sprite" />
122
- <div id="frame-empty" class="frame-empty"><p>your restyled sprite<br/>appears here</p></div>
123
- <div id="frame-loader" class="frame-loader" hidden>
124
- <div class="loader-grid"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></div>
125
- <p id="loader-text">working…</p>
126
- </div>
127
- </div>
128
- </figure>
129
-
130
- <aside class="sil-panel">
131
- <div class="sil-head">
132
- <svg viewBox="0 0 24 24" width="12" height="12"><path fill="currentColor" d="M12 1a5 5 0 0 0-5 5v3H6a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-9a2 2 0 0 0-2-2h-1V6a5 5 0 0 0-5-5m0 2a3 3 0 0 1 3 3v3H9V6a3 3 0 0 1 3-3"/></svg>
133
- SILHOUETTE LOCKED
134
- </div>
135
- <div class="sil-art checker"><canvas id="sil-canvas" width="64" height="64"></canvas></div>
136
- <p class="sil-note">Exact footprint &amp; transparency preserved — guaranteed by the decoding grammar, not hoped for.</p>
137
- </aside>
138
- </div>
139
-
140
- <div class="statusbar">
141
- <span id="badge" class="badge ok" hidden>✓ silhouette preserved</span>
142
- <span id="status" class="status"></span>
143
- <a id="download" class="dl-btn" download hidden>⭳ Download PNG</a>
144
- </div>
145
-
146
- <details class="wire-reveal">
147
- <summary>⌖ see what the model actually <b>wrote</b> — it's text, not pixels</summary>
148
- <pre id="wire-out" class="wire">Run an edit, then peek here: the LLM literally writes a PALETTE block and a GRID of cells (K R R K …). The GBNF grammar forces every transparent cell to stay transparent that's why the shape can't break.</pre>
149
- </details>
150
-
151
- <section class="gallery-wrap" aria-label="Before and after examples">
152
- <div class="gallery-head"><h3>Before&nbsp;→&nbsp;After examples</h3><span class="hint-sm">click any card to load it</span></div>
153
- <div id="gallery" class="gallery"></div>
154
- </section>
155
- </section>
156
- </main>
157
-
158
- <footer class="site-foot">
159
- <span class="foot-strong">✦ Pixel-precise · AI-powered · your shape, any vibe</span>
160
- <span class="sep">·</span>
161
- <span class="foot-dim">fine-tuned Gemma-4-12B · GBNF footprint grammar · runs on llama.cpp · Build Small Hackathon</span>
162
- </footer>
163
-
164
- <script src="/static/app.js" defer></script>
165
- </body>
166
- </html>
 
 
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
6
+ <title>PixelLock — AI Pixel-Art Retexturing</title>
7
+ <meta name="description" content="Footprint-locked AI pixel-art retexturing — keep the exact silhouette, change the style." />
8
+ <link rel="preconnect" href="https://fonts.googleapis.com">
9
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
10
+ <link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;700&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet">
11
+ <link rel="stylesheet" href="/static/styles.css" />
12
+ <link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Crect width='16' height='16' rx='3' fill='%230b0b14'/%3E%3Crect x='3' y='3' width='4' height='4' fill='%23a06bff'/%3E%3Crect x='9' y='3' width='4' height='4' fill='%2300e5d4'/%3E%3Crect x='3' y='9' width='4' height='4' fill='%2300e5d4'/%3E%3Crect x='9' y='9' width='4' height='4' fill='%23a06bff'/%3E%3C/svg%3E" />
13
+ </head>
14
+ <body>
15
+ <a href="https://huggingface.co/spaces/solarkyle/pixellock" target="_blank" rel="noopener" style="display:block;text-decoration:none;background:linear-gradient(90deg,#a06bff,#00e5d4);color:#0b0b14;font-family:'Space Grotesk',system-ui,sans-serif;font-weight:700;text-align:center;padding:11px 16px;font-size:14.5px;letter-spacing:.2px;">⚡ This instance runs on CPU — click for the LIVE GPU version ▶ (or watch the 45s demo)</a>
16
+ <div class="bg-glow" aria-hidden="true"></div>
17
+ <div class="scanlines" aria-hidden="true"></div>
18
+
19
+ <header class="appbar">
20
+ <div class="brand">
21
+ <span class="logo" aria-hidden="true"><i></i><i></i><i></i><i></i></span>
22
+ <h1 class="wordmark">Pixel<b>Lock</b></h1>
23
+ <span class="brand-div">|</span>
24
+ <span class="brand-sub">AI Pixel-Art Retexturing Tool</span>
25
+ </div>
26
+ <div class="fp-pill" title="Every edit keeps your sprite's exact shape, by construction">
27
+ <svg viewBox="0 0 24 24" width="14" height="14"><path fill="currentColor" d="M12 1a5 5 0 0 0-5 5v3H6a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-9a2 2 0 0 0-2-2h-1V6a5 5 0 0 0-5-5m0 2a3 3 0 0 1 3 3v3H9V6a3 3 0 0 1 3-3"/></svg>
28
+ Footprint-locked retexturing
29
+ </div>
30
+ <div class="appbar-right">
31
+ <span class="server-pill"><span id="server-dot" class="dot down"></span><span id="server-label">connecting…</span></span>
32
+ <a class="ghost-btn" href="https://github.com/ggml-org/llama.cpp" target="_blank" rel="noopener">⌁ GBNF · llama.cpp</a>
33
+ </div>
34
+ </header>
35
+
36
+ <div class="howbar">
37
+ <span class="how-tag"> NOT an image generator</span>
38
+ <span class="how-steps">your PNG → a <b>text grid</b> (PALETTE&nbsp;+&nbsp;GRID) → a <b>fine-tuned text LLM</b> rewrites it under a <b>GBNF grammar</b> that locks the exact shape → pixel-perfect PNG. <em>It's language modeling, not diffusion.</em></span>
39
+ </div>
40
+
41
+ <section class="proofbar" aria-label="PixelLock guarantees">
42
+ <div class="proof-card">
43
+ <span class="proof-k">100%</span>
44
+ <span class="proof-v">footprint constrained</span>
45
+ </div>
46
+ <div class="proof-card">
47
+ <span class="proof-k">PNG TEXT → PNG</span>
48
+ <span class="proof-v">palette grid, not diffusion</span>
49
+ </div>
50
+ <div class="proof-card">
51
+ <span class="proof-k">LLAMA.CPP + GBNF</span>
52
+ <span class="proof-v">shape locked in the decoder</span>
53
+ </div>
54
+ </section>
55
+
56
+ <main class="layout">
57
+ <!-- LEFT: controls -->
58
+ <aside class="controls">
59
+ <section class="step">
60
+ <h2><span class="num">01</span> Upload sprite</h2>
61
+ <div id="dropzone" class="dropzone" tabindex="0" role="button" aria-label="Upload a sprite PNG">
62
+ <input id="file" type="file" accept="image/png,image/*" hidden />
63
+ <div id="dz-empty" class="dz-empty">
64
+ <div class="dz-ico" aria-hidden="true"></div>
65
+ <p class="dz-main">Drop sprite PNG or <span class="link">click to upload</span></p>
66
+ <p class="dz-hint">best for 16×16 – 64×64</p>
67
+ <span class="dz-tag">PNG</span>
68
+ </div>
69
+ <div id="dz-loaded" class="dz-loaded" hidden>
70
+ <img id="dz-preview" class="pixelated" alt="loaded sprite" />
71
+ <div class="dz-meta"><span id="dz-name" class="dz-name">sprite.png</span>
72
+ <button id="dz-clear" class="link-btn" type="button">change</button></div>
73
+ </div>
74
+ </div>
75
+ </section>
76
+
77
+ <section class="step starter-step">
78
+ <h2><span class="num">01B</span> Starter sprites <span class="opt">click to load</span></h2>
79
+ <div id="asset-strip" class="asset-strip" aria-label="Starter sprites"></div>
80
+ </section>
81
+
82
+ <section class="step">
83
+ <h2><span class="num">02</span> Theme / vibe <span class="opt">optional</span></h2>
84
+ <div id="chips" class="chips" role="listbox" aria-label="Theme presets"></div>
85
+ </section>
86
+
87
+ <section class="step">
88
+ <h2><span class="num">03</span> Prompt <span class="opt">optional</span></h2>
89
+ <textarea id="prompt" class="prompt" rows="3" spellcheck="false"
90
+ placeholder="Restyle into… (the AI invents the colors; the shape stays locked)"></textarea>
91
+ </section>
92
+
93
+ <section class="step">
94
+ <h2><span class="num">04</span> Mode</h2>
95
+ <div id="mode-toggle" class="toggle" role="tablist" aria-label="Edit mode">
96
+ <span id="toggle-glider" class="toggle-glider" aria-hidden="true"></span>
97
+ <button class="toggle-opt active" data-mode="exact" role="tab" aria-selected="true">🎨 Retheme</button>
98
+ <button class="toggle-opt" data-mode="upscale2x" role="tab" aria-selected="false">⤢ Upscale 2×</button>
99
+ </div>
100
+ </section>
101
+
102
+ <button id="run" class="run-btn" disabled>
103
+ <span class="run-label">▶ RUN RETEXTURE</span>
104
+ <span class="run-spinner" aria-hidden="true"></span>
105
+ </button>
106
+ <p id="run-hint" class="hint">load a sprite to begin</p>
107
+ </aside>
108
+
109
+ <!-- CENTER: stage -->
110
+ <section class="stage lab">
111
+ <div class="compare">
112
+ <figure class="frame">
113
+ <figcaption>INPUT <span>your sprite</span></figcaption>
114
+ <div class="checker canvas"><img id="img-in" class="pixelated" alt="input sprite" /></div>
115
+ </figure>
116
+
117
+ <div class="arrow" aria-hidden="true">▶</div>
118
+
119
+ <figure class="frame">
120
+ <figcaption>OUTPUT <span>AI restyled</span></figcaption>
121
+ <div class="checker canvas">
122
+ <img id="img-out" class="pixelated" alt="restyled sprite" />
123
+ <div id="frame-empty" class="frame-empty"><p>your restyled sprite<br/>appears here</p></div>
124
+ <div id="frame-loader" class="frame-loader" hidden>
125
+ <div class="loader-grid"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></div>
126
+ <p id="loader-text">working…</p>
127
+ </div>
128
+ </div>
129
+ </figure>
130
+
131
+ <aside class="sil-panel">
132
+ <div class="sil-head">
133
+ <svg viewBox="0 0 24 24" width="12" height="12"><path fill="currentColor" d="M12 1a5 5 0 0 0-5 5v3H6a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-9a2 2 0 0 0-2-2h-1V6a5 5 0 0 0-5-5m0 2a3 3 0 0 1 3 3v3H9V6a3 3 0 0 1 3-3"/></svg>
134
+ SILHOUETTE LOCKED
135
+ </div>
136
+ <div class="sil-art checker"><canvas id="sil-canvas" width="64" height="64"></canvas></div>
137
+ <p class="sil-note">Exact footprint &amp; transparency preserved — guaranteed by the decoding grammar, not hoped for.</p>
138
+ </aside>
139
+ </div>
140
+
141
+ <div class="statusbar">
142
+ <span id="badge" class="badge ok" hidden>✓ silhouette preserved</span>
143
+ <span id="status" class="status"></span>
144
+ <a id="download" class="dl-btn" download hidden>⭳ Download PNG</a>
145
+ </div>
146
+
147
+ <details class="wire-reveal">
148
+ <summary> see what the model actually <b>wrote</b>it's text, not pixels</summary>
149
+ <pre id="wire-out" class="wire">Run an edit, then peek here: the LLM literally writes a PALETTE block and a GRID of cells (K R R K …). The GBNF grammar forces every transparent cell to stay transparent — that's why the shape can't break.</pre>
150
+ </details>
151
+
152
+ <section class="gallery-wrap" aria-label="Before and after examples">
153
+ <div class="gallery-head"><h3>Before&nbsp;→&nbsp;After examples</h3><span class="hint-sm">click any card to load it</span></div>
154
+ <div id="gallery" class="gallery"></div>
155
+ </section>
156
+ </section>
157
+ </main>
158
+
159
+ <footer class="site-foot">
160
+ <span class="foot-strong">✦ Pixel-precise · AI-powered · your shape, any vibe</span>
161
+ <span class="sep">·</span>
162
+ <span class="foot-dim">fine-tuned Gemma-4-12B · GBNF footprint grammar · runs on llama.cpp · Build Small Hackathon</span>
163
+ </footer>
164
+
165
+ <script src="/static/app.js" defer></script>
166
+ </body>
167
+ </html>