Xenova HF Staff commited on
Commit
789c461
·
verified ·
1 Parent(s): 40f3980

Upload 2 files

Browse files
Files changed (2) hide show
  1. assets/index-Dt2nXeN6.js +0 -0
  2. index.html +1322 -18
assets/index-Dt2nXeN6.js ADDED
The diff for this file is too large to render. See raw diff
 
index.html CHANGED
@@ -1,19 +1,1323 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  </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">
6
+ <title>Bonsai · image generation</title>
7
+ <link rel="preconnect" href="https://fonts.googleapis.com">
8
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
9
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&family=Geist:wght@300;400;500;600&family=Geist+Mono:wght@400;500&display=swap">
10
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🌳</text></svg>">
11
+ <style>
12
+ :root {
13
+ --bg: #0c0a08;
14
+ --surface: #14110f;
15
+ --border: #231f1c;
16
+ --border2: #1a1714;
17
+ --faint: #5a5048;
18
+ --dim: #7a6f63;
19
+ --muted: #9a8f81;
20
+ --cream: #f4ecde;
21
+ --amber: #e8a55e;
22
+ }
23
+
24
+ * { box-sizing: border-box; }
25
+ html, body { margin: 0; padding: 0; }
26
+
27
+ body {
28
+ background: var(--bg);
29
+ color: var(--cream);
30
+ font-family: 'Geist', system-ui, sans-serif;
31
+ -webkit-font-smoothing: antialiased;
32
+ min-height: 100vh;
33
+ opacity: 0;
34
+ transition: opacity 0.35s ease;
35
+ }
36
+ body.loaded { opacity: 1; }
37
+
38
+ [hidden] { display: none !important; }
39
+
40
+ .section {
41
+ min-height: 100vh;
42
+ display: flex;
43
+ flex-direction: column;
44
+ align-items: center;
45
+ justify-content: center;
46
+ padding: 4rem 1.5rem;
47
+ }
48
+
49
+ .gate-inner {
50
+ width: 100%;
51
+ max-width: 540px;
52
+ display: flex;
53
+ flex-direction: column;
54
+ gap: 2rem;
55
+ opacity: 0;
56
+ transform: translateY(8px);
57
+ transition: opacity 0.7s cubic-bezier(0.2, 0.7, 0.2, 1) 0.1s,
58
+ transform 0.7s cubic-bezier(0.2, 0.7, 0.2, 1) 0.1s;
59
+ }
60
+ body.loaded .gate-inner { opacity: 1; transform: translateY(0); }
61
+
62
+ .brand {
63
+ font-family: 'Instrument Serif', serif;
64
+ font-size: 34px;
65
+ letter-spacing: -0.5px;
66
+ margin: 0 0 0.25rem 0;
67
+ color: var(--cream);
68
+ }
69
+ .brand em {
70
+ font-style: italic;
71
+ color: var(--amber);
72
+ }
73
+ .brand-sub {
74
+ margin: 0 0 1rem 0;
75
+ font-family: 'Geist Mono', monospace;
76
+ font-size: 11px;
77
+ text-transform: uppercase;
78
+ letter-spacing: 0.22em;
79
+ color: var(--dim);
80
+ }
81
+
82
+ .disclaimer {
83
+ display: flex;
84
+ gap: 0.875rem;
85
+ padding: 1rem 1.125rem;
86
+ background: rgba(232, 165, 94, 0.04);
87
+ border: 1px solid rgba(232, 165, 94, 0.18);
88
+ border-radius: 6px;
89
+ }
90
+ .disclaimer .icon { color: var(--amber); flex-shrink: 0; margin-top: 2px; }
91
+ .disclaimer-content { flex: 1; min-width: 0; }
92
+ .disclaimer-title {
93
+ margin: 0 0 0.375rem 0;
94
+ font-family: 'Geist Mono', monospace;
95
+ font-size: 11px;
96
+ text-transform: uppercase;
97
+ letter-spacing: 0.18em;
98
+ color: var(--amber);
99
+ }
100
+ .disclaimer-body {
101
+ margin: 0;
102
+ font-size: 14px;
103
+ color: var(--muted);
104
+ line-height: 1.55;
105
+ }
106
+ .flag-name {
107
+ font-family: 'Geist Mono', monospace;
108
+ font-size: 12.5px;
109
+ color: var(--amber);
110
+ }
111
+ .flag-copy {
112
+ display: flex;
113
+ align-items: center;
114
+ gap: 0.5rem;
115
+ margin-top: 0.5rem;
116
+ padding: 6px 6px 6px 10px;
117
+ background: rgba(232, 165, 94, 0.06);
118
+ border: 1px solid rgba(232, 165, 94, 0.18);
119
+ border-radius: 4px;
120
+ }
121
+ .flag-url {
122
+ flex: 1;
123
+ font-family: 'Geist Mono', monospace;
124
+ font-size: 12px;
125
+ color: var(--cream);
126
+ user-select: all;
127
+ overflow: hidden;
128
+ text-overflow: ellipsis;
129
+ white-space: nowrap;
130
+ }
131
+ .flag-copy-btn {
132
+ background: transparent;
133
+ border: none;
134
+ cursor: pointer;
135
+ color: var(--dim);
136
+ padding: 4px 6px;
137
+ display: inline-flex;
138
+ align-items: center;
139
+ justify-content: center;
140
+ border-radius: 3px;
141
+ transition: color 0.15s ease, background 0.15s ease;
142
+ flex-shrink: 0;
143
+ }
144
+ .flag-copy-btn:hover { color: var(--cream); background: rgba(232, 165, 94, 0.08); }
145
+
146
+ .token-group {
147
+ display: flex;
148
+ flex-direction: column;
149
+ gap: 0.625rem;
150
+ }
151
+ .token-label {
152
+ font-family: 'Geist Mono', monospace;
153
+ font-size: 12px;
154
+ text-transform: uppercase;
155
+ letter-spacing: 0.1em;
156
+ color: var(--dim);
157
+ }
158
+ .token-input-wrap {
159
+ display: flex;
160
+ align-items: center;
161
+ background: var(--surface);
162
+ border: 1px solid var(--border);
163
+ border-radius: 6px;
164
+ padding-right: 4px;
165
+ transition: border-color 0.15s ease;
166
+ }
167
+ .token-input-wrap:focus-within { border-color: var(--faint); }
168
+ .token-input-wrap.error { border-color: rgba(232, 165, 94, 0.5); }
169
+ .token-input {
170
+ flex: 1;
171
+ background: transparent;
172
+ border: none;
173
+ outline: none;
174
+ color: var(--cream);
175
+ font-family: 'Geist Mono', monospace;
176
+ font-size: 14px;
177
+ padding: 12px 16px;
178
+ min-width: 0;
179
+ }
180
+ .token-input::placeholder { color: var(--faint); }
181
+ .token-toggle {
182
+ background: transparent;
183
+ border: none;
184
+ cursor: pointer;
185
+ color: var(--dim);
186
+ font-family: 'Geist Mono', monospace;
187
+ font-size: 11px;
188
+ text-transform: uppercase;
189
+ letter-spacing: 0.1em;
190
+ padding: 8px 12px;
191
+ transition: color 0.15s ease;
192
+ flex-shrink: 0;
193
+ }
194
+ .token-toggle:hover { color: var(--cream); }
195
+
196
+ .token-help {
197
+ margin: 0;
198
+ font-family: 'Geist Mono', monospace;
199
+ font-size: 11px;
200
+ line-height: 1.55;
201
+ color: var(--dim);
202
+ }
203
+ .token-help .model-id {
204
+ color: var(--muted);
205
+ text-decoration: none;
206
+ transition: color 0.15s ease;
207
+ }
208
+ .token-help .model-id:hover { color: var(--cream); text-decoration: underline; }
209
+ .token-help.error { color: var(--amber); }
210
+
211
+ .loading-inner {
212
+ width: 100%;
213
+ max-width: 420px;
214
+ display: flex;
215
+ flex-direction: column;
216
+ align-items: center;
217
+ gap: 1.25rem;
218
+ }
219
+ .loading-title {
220
+ font-family: 'Geist Mono', monospace;
221
+ font-size: 11px;
222
+ text-transform: uppercase;
223
+ letter-spacing: 0.18em;
224
+ color: var(--amber);
225
+ margin: 0;
226
+ }
227
+ .loading-status {
228
+ font-size: 14px;
229
+ color: var(--muted);
230
+ margin: 0;
231
+ text-align: center;
232
+ min-height: 1.2em;
233
+ }
234
+ .loading-bar {
235
+ width: 100%;
236
+ height: 4px;
237
+ background: var(--border);
238
+ border-radius: 2px;
239
+ overflow: hidden;
240
+ }
241
+ .loading-bar-fill {
242
+ height: 100%;
243
+ width: 0%;
244
+ background: var(--amber);
245
+ transition: width 0.2s ease;
246
+ }
247
+ .loading-spinner { color: var(--amber); }
248
+
249
+ .landing {
250
+ position: relative;
251
+ overflow: hidden;
252
+ padding: 0;
253
+ align-items: flex-start;
254
+ justify-content: center;
255
+ }
256
+ .hero-scene {
257
+ position: absolute;
258
+ inset: 0;
259
+ z-index: 0;
260
+ background:
261
+ radial-gradient(ellipse 55% 60% at 62% 50%,
262
+ rgba(232, 165, 94, 0.18) 0%,
263
+ rgba(232, 120, 60, 0.08) 28%,
264
+ rgba(12, 10, 8, 0) 60%),
265
+ radial-gradient(ellipse 90% 80% at 62% 50%,
266
+ rgba(40, 25, 15, 0.55) 0%,
267
+ rgba(12, 10, 8, 0) 70%);
268
+ }
269
+ .hero-scene #root { width: 100%; height: 100%; }
270
+
271
+ .landing-inner {
272
+ position: relative;
273
+ z-index: 10;
274
+ width: 100%;
275
+ max-width: 620px;
276
+ padding: 2rem clamp(2rem, 6vw, 5rem) 2rem clamp(3rem, 11vw, 9rem);
277
+ display: flex;
278
+ flex-direction: column;
279
+ align-items: flex-start;
280
+ gap: 1.25rem;
281
+ opacity: 0;
282
+ transform: translateY(8px);
283
+ transition: opacity 0.8s cubic-bezier(0.2, 0.7, 0.2, 1) 0.15s,
284
+ transform 0.8s cubic-bezier(0.2, 0.7, 0.2, 1) 0.15s;
285
+ }
286
+ body.loaded .landing-inner { opacity: 1; transform: translateY(0); }
287
+
288
+ .landing.leaving { transition: opacity 0.5s ease; opacity: 0; pointer-events: none; }
289
+
290
+ .landing-eyebrow {
291
+ font-family: 'Geist Mono', monospace;
292
+ font-size: 11px;
293
+ font-weight: 500;
294
+ text-transform: uppercase;
295
+ letter-spacing: 0.22em;
296
+ color: var(--amber);
297
+ margin: 0;
298
+ display: flex;
299
+ align-items: center;
300
+ gap: 12px;
301
+ }
302
+ .landing-eyebrow::before {
303
+ content: '';
304
+ width: 24px;
305
+ height: 1px;
306
+ background: var(--amber);
307
+ }
308
+ .landing-title {
309
+ font-family: 'Instrument Serif', serif;
310
+ font-size: clamp(40px, 5.5vw, 64px);
311
+ font-weight: 400;
312
+ line-height: 1.05;
313
+ letter-spacing: -1.5px;
314
+ color: var(--cream);
315
+ margin: 0;
316
+ }
317
+ .landing-title em {
318
+ font-style: italic;
319
+ color: var(--amber);
320
+ }
321
+ .landing-tagline {
322
+ font-size: 15px;
323
+ line-height: 1.6;
324
+ color: var(--muted);
325
+ max-width: 420px;
326
+ margin: 0;
327
+ }
328
+ .cta-group {
329
+ position: relative;
330
+ margin-top: 0.75rem;
331
+ display: inline-flex;
332
+ align-items: stretch;
333
+ gap: 2px;
334
+ }
335
+ .landing-cta {
336
+ background: var(--cream);
337
+ color: var(--bg);
338
+ border: none;
339
+ font-family: 'Geist Mono', monospace;
340
+ font-size: 13px;
341
+ text-transform: uppercase;
342
+ letter-spacing: 0.18em;
343
+ cursor: pointer;
344
+ display: inline-flex;
345
+ align-items: center;
346
+ gap: 10px;
347
+ transition: transform 0.2s ease, background 0.2s ease;
348
+ }
349
+ .landing-cta:hover { background: #fff5e3; }
350
+ .landing-cta-main {
351
+ border-radius: 9999px 0 0 9999px;
352
+ padding: 12px 24px 12px 28px;
353
+ }
354
+ .landing-cta-main:hover { transform: translateY(-1px); }
355
+ .landing-cta-main svg { transition: transform 0.2s ease; }
356
+ .landing-cta-main:hover svg { transform: translateX(3px); }
357
+ .landing-cta-toggle {
358
+ border-radius: 0 9999px 9999px 0;
359
+ padding: 12px 16px;
360
+ }
361
+ .landing-cta-toggle svg { transition: transform 0.2s ease; }
362
+ .landing-cta-toggle[aria-expanded="true"] svg { transform: rotate(-180deg); }
363
+
364
+ .model-menu {
365
+ position: absolute;
366
+ bottom: calc(100% + 10px);
367
+ left: 0;
368
+ z-index: 20;
369
+ width: clamp(320px, 32rem, 480px);
370
+ background: var(--surface);
371
+ border: 1px solid var(--border);
372
+ border-radius: 10px;
373
+ padding: 1rem;
374
+ box-shadow: 0 24px 60px -16px rgba(0, 0, 0, 0.6);
375
+ display: flex;
376
+ flex-direction: column;
377
+ gap: 0.75rem;
378
+ }
379
+ .model-menu-title {
380
+ margin: 0 0 0.25rem 0;
381
+ font-family: 'Geist Mono', monospace;
382
+ font-size: 11px;
383
+ text-transform: uppercase;
384
+ letter-spacing: 0.18em;
385
+ color: var(--dim);
386
+ }
387
+ .model-menu-item {
388
+ all: unset;
389
+ cursor: pointer;
390
+ display: flex;
391
+ gap: 0.75rem;
392
+ padding: 0.875rem;
393
+ border-radius: 8px;
394
+ border: 1px solid var(--border);
395
+ background: transparent;
396
+ transition: border-color 0.15s ease, background 0.15s ease;
397
+ }
398
+ .model-menu-item:hover {
399
+ border-color: var(--faint);
400
+ background: rgba(232, 165, 94, 0.04);
401
+ }
402
+ .model-menu-item.selected {
403
+ border-color: rgba(232, 165, 94, 0.5);
404
+ background: rgba(232, 165, 94, 0.06);
405
+ }
406
+ .model-menu-radio {
407
+ flex-shrink: 0;
408
+ width: 14px;
409
+ height: 14px;
410
+ margin-top: 4px;
411
+ border-radius: 50%;
412
+ border: 1.5px solid var(--faint);
413
+ background: transparent;
414
+ transition: border-color 0.15s ease, background 0.15s ease, box-shadow 0.15s ease;
415
+ }
416
+ .model-menu-item.selected .model-menu-radio {
417
+ border-color: var(--amber);
418
+ background: var(--amber);
419
+ box-shadow: inset 0 0 0 3px var(--surface);
420
+ }
421
+ .model-menu-text { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
422
+ .model-menu-name {
423
+ font-family: 'Geist Mono', monospace;
424
+ font-size: 12.5px;
425
+ color: var(--cream);
426
+ letter-spacing: 0.04em;
427
+ display: inline-flex;
428
+ align-items: center;
429
+ gap: 0.5rem;
430
+ }
431
+ .model-menu-tag {
432
+ font-size: 9.5px;
433
+ text-transform: uppercase;
434
+ letter-spacing: 0.15em;
435
+ color: var(--amber);
436
+ background: rgba(232, 165, 94, 0.1);
437
+ border: 1px solid rgba(232, 165, 94, 0.25);
438
+ padding: 2px 6px;
439
+ border-radius: 9999px;
440
+ }
441
+ .model-menu-desc {
442
+ font-family: 'Geist', system-ui, sans-serif;
443
+ font-size: 12.5px;
444
+ line-height: 1.5;
445
+ color: var(--muted);
446
+ }
447
+ .model-menu-meta {
448
+ font-family: 'Geist Mono', monospace;
449
+ font-size: 11px;
450
+ color: var(--dim);
451
+ letter-spacing: 0.08em;
452
+ }
453
+ .model-menu-footnote {
454
+ margin: 0;
455
+ padding-top: 0.625rem;
456
+ border-top: 1px solid var(--border2);
457
+ font-family: 'Geist Mono', monospace;
458
+ font-size: 11px;
459
+ line-height: 1.55;
460
+ color: var(--dim);
461
+ }
462
+
463
+ .hero-inner {
464
+ position: relative;
465
+ z-index: 10;
466
+ width: 100%;
467
+ max-width: 560px;
468
+ display: flex;
469
+ flex-direction: column;
470
+ gap: 2rem;
471
+ opacity: 0;
472
+ transform: translateY(8px);
473
+ transition: opacity 0.7s cubic-bezier(0.2, 0.7, 0.2, 1) 0.1s,
474
+ transform 0.7s cubic-bezier(0.2, 0.7, 0.2, 1) 0.1s;
475
+ }
476
+ body.loaded .hero-inner { opacity: 1; transform: translateY(0); }
477
+
478
+ .hero-eyebrow {
479
+ font-family: 'Geist Mono', monospace;
480
+ font-size: 11px;
481
+ font-weight: 500;
482
+ text-transform: uppercase;
483
+ letter-spacing: 0.22em;
484
+ color: var(--amber);
485
+ margin: 0;
486
+ display: flex;
487
+ align-items: center;
488
+ gap: 12px;
489
+ }
490
+ .hero-eyebrow::before {
491
+ content: '';
492
+ width: 24px;
493
+ height: 1px;
494
+ background: var(--amber);
495
+ }
496
+
497
+ .prompt {
498
+ width: 100%;
499
+ background: transparent;
500
+ border: none;
501
+ outline: none;
502
+ resize: none;
503
+ color: var(--cream);
504
+ font-family: 'Instrument Serif', serif;
505
+ font-style: italic;
506
+ font-size: 2.25rem;
507
+ line-height: 1.25;
508
+ padding: 0;
509
+ }
510
+ .prompt::placeholder { color: var(--faint); }
511
+ @media (max-width: 540px) { .prompt { font-size: 1.875rem; } }
512
+
513
+ .example-link {
514
+ align-self: flex-end;
515
+ display: inline-flex;
516
+ align-items: center;
517
+ gap: 6px;
518
+ background: transparent;
519
+ border: none;
520
+ cursor: pointer;
521
+ color: var(--dim);
522
+ font-family: 'Geist Mono', monospace;
523
+ font-size: 12px;
524
+ text-transform: uppercase;
525
+ letter-spacing: 0.1em;
526
+ padding: 4px 0;
527
+ transition: color 0.15s ease;
528
+ }
529
+ .example-link:hover { color: var(--cream); }
530
+
531
+ .controls {
532
+ display: flex;
533
+ flex-direction: column;
534
+ gap: 1.5rem;
535
+ padding-top: 1.5rem;
536
+ border-top: 1px solid var(--border2);
537
+ }
538
+ .size-group {
539
+ display: flex;
540
+ flex-direction: column;
541
+ gap: 0.875rem;
542
+ }
543
+ .size-label {
544
+ color: var(--dim);
545
+ text-transform: uppercase;
546
+ letter-spacing: 0.1em;
547
+ font-size: 12px;
548
+ font-family: 'Geist Mono', monospace;
549
+ }
550
+ .presets {
551
+ display: flex;
552
+ flex-wrap: wrap;
553
+ gap: 0.4rem;
554
+ }
555
+ .preset {
556
+ background: transparent;
557
+ border: 1px solid var(--border);
558
+ color: var(--dim);
559
+ font-family: 'Geist Mono', monospace;
560
+ font-size: 12px;
561
+ letter-spacing: 0.05em;
562
+ padding: 7px 14px;
563
+ border-radius: 9999px;
564
+ cursor: pointer;
565
+ transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease;
566
+ }
567
+ .preset:hover { color: var(--cream); border-color: var(--faint); }
568
+ .preset.active {
569
+ background: var(--cream);
570
+ color: var(--bg);
571
+ border-color: var(--cream);
572
+ }
573
+ .slider-row {
574
+ display: grid;
575
+ grid-template-columns: 22px 1fr 4ch;
576
+ align-items: center;
577
+ gap: 0.875rem;
578
+ font-family: 'Geist Mono', ui-monospace, monospace;
579
+ font-size: 13px;
580
+ }
581
+ .slider-row .sub-label {
582
+ color: var(--dim);
583
+ text-transform: uppercase;
584
+ letter-spacing: 0.1em;
585
+ font-size: 12px;
586
+ }
587
+ .slider-row .sub-value {
588
+ color: var(--cream);
589
+ font-variant-numeric: tabular-nums;
590
+ text-align: right;
591
+ }
592
+ .seed-row {
593
+ display: grid;
594
+ grid-template-columns: 60px 1fr auto;
595
+ align-items: center;
596
+ gap: 1rem;
597
+ font-family: 'Geist Mono', ui-monospace, monospace;
598
+ font-size: 13px;
599
+ }
600
+ .seed-row .seed-label {
601
+ color: var(--dim);
602
+ text-transform: uppercase;
603
+ letter-spacing: 0.1em;
604
+ font-size: 12px;
605
+ }
606
+ .seed-input {
607
+ width: 100%;
608
+ background: transparent;
609
+ border: none;
610
+ outline: none;
611
+ color: var(--cream);
612
+ font-family: inherit;
613
+ font-size: 14px;
614
+ padding: 4px 0;
615
+ font-variant-numeric: tabular-nums;
616
+ }
617
+ .seed-input::placeholder { color: var(--faint); }
618
+
619
+ input[type="range"] {
620
+ -webkit-appearance: none;
621
+ appearance: none;
622
+ width: 100%;
623
+ background: transparent;
624
+ cursor: pointer;
625
+ margin: 0;
626
+ }
627
+ input[type="range"]::-webkit-slider-runnable-track { height: 1px; background: var(--border); }
628
+ input[type="range"]::-moz-range-track { height: 1px; background: var(--border); }
629
+ input[type="range"]::-webkit-slider-thumb {
630
+ -webkit-appearance: none;
631
+ appearance: none;
632
+ width: 14px;
633
+ height: 14px;
634
+ border-radius: 50%;
635
+ background: var(--cream);
636
+ border: none;
637
+ margin-top: -6.5px;
638
+ cursor: grab;
639
+ transition: transform 0.15s ease;
640
+ }
641
+ input[type="range"]::-webkit-slider-thumb:hover { transform: scale(1.15); }
642
+ input[type="range"]::-webkit-slider-thumb:active { cursor: grabbing; transform: scale(1.1); }
643
+ input[type="range"]::-moz-range-thumb {
644
+ width: 14px;
645
+ height: 14px;
646
+ border-radius: 50%;
647
+ background: var(--cream);
648
+ border: none;
649
+ cursor: grab;
650
+ }
651
+
652
+ .icon-btn-sm {
653
+ width: 28px;
654
+ height: 28px;
655
+ display: inline-flex;
656
+ align-items: center;
657
+ justify-content: center;
658
+ background: transparent;
659
+ border: 1px solid var(--border);
660
+ border-radius: 6px;
661
+ color: var(--dim);
662
+ cursor: pointer;
663
+ transition: color 0.15s ease, border-color 0.15s ease;
664
+ flex-shrink: 0;
665
+ padding: 0;
666
+ }
667
+ .icon-btn-sm:hover { color: var(--cream); border-color: var(--faint); }
668
+
669
+ .generate {
670
+ width: 100%;
671
+ background: var(--cream);
672
+ color: var(--bg);
673
+ border: none;
674
+ border-radius: 9999px;
675
+ padding: 14px 24px;
676
+ font-family: 'Geist Mono', monospace;
677
+ font-size: 14px;
678
+ text-transform: uppercase;
679
+ letter-spacing: 0.15em;
680
+ cursor: pointer;
681
+ display: inline-flex;
682
+ align-items: center;
683
+ justify-content: center;
684
+ gap: 10px;
685
+ transition: opacity 0.15s ease;
686
+ margin-top: 0.5rem;
687
+ }
688
+ .generate:disabled {
689
+ background: var(--surface);
690
+ color: var(--faint);
691
+ cursor: not-allowed;
692
+ }
693
+
694
+ .gallery-link {
695
+ position: absolute;
696
+ bottom: 1.5rem;
697
+ left: 50%;
698
+ transform: translateX(-50%);
699
+ background: transparent;
700
+ border: none;
701
+ cursor: pointer;
702
+ color: var(--faint);
703
+ font-family: 'Geist Mono', monospace;
704
+ font-size: 12px;
705
+ text-transform: uppercase;
706
+ letter-spacing: 0.15em;
707
+ transition: color 0.15s ease;
708
+ z-index: 10;
709
+ }
710
+ .gallery-link:hover { color: var(--cream); }
711
+
712
+ .gallery-header {
713
+ position: sticky;
714
+ top: 0;
715
+ z-index: 20;
716
+ background: rgba(12, 10, 8, 0.78);
717
+ backdrop-filter: blur(20px);
718
+ -webkit-backdrop-filter: blur(20px);
719
+ border-bottom: 1px solid var(--border2);
720
+ padding: 0.875rem 1.5rem;
721
+ display: flex;
722
+ align-items: center;
723
+ justify-content: space-between;
724
+ }
725
+ .image-count {
726
+ font-family: 'Geist Mono', monospace;
727
+ font-size: 12px;
728
+ text-transform: uppercase;
729
+ letter-spacing: 0.15em;
730
+ color: var(--faint);
731
+ }
732
+ .header-actions { display: flex; align-items: center; gap: 0.5rem; }
733
+
734
+ .pill-btn {
735
+ background: transparent;
736
+ border: 1px solid var(--border);
737
+ border-radius: 9999px;
738
+ color: var(--muted);
739
+ font-family: 'Geist Mono', monospace;
740
+ font-size: 11px;
741
+ text-transform: uppercase;
742
+ letter-spacing: 0.15em;
743
+ padding: 7px 14px;
744
+ cursor: pointer;
745
+ display: inline-flex;
746
+ align-items: center;
747
+ gap: 6px;
748
+ transition: color 0.15s ease, border-color 0.15s ease;
749
+ }
750
+ .pill-btn:hover { color: var(--cream); border-color: var(--faint); }
751
+ .text-btn {
752
+ background: transparent;
753
+ border: none;
754
+ cursor: pointer;
755
+ color: var(--faint);
756
+ font-family: 'Geist Mono', monospace;
757
+ font-size: 11px;
758
+ text-transform: uppercase;
759
+ letter-spacing: 0.15em;
760
+ padding: 6px 10px;
761
+ transition: color 0.15s ease;
762
+ }
763
+ .text-btn:hover { color: var(--cream); }
764
+
765
+ .grid {
766
+ display: grid;
767
+ grid-template-columns: 1fr;
768
+ gap: 2px;
769
+ padding: 2px;
770
+ }
771
+ @media (min-width: 640px) { .grid { grid-template-columns: repeat(2, 1fr); } }
772
+ @media (min-width: 1024px) { .grid { grid-template-columns: repeat(3, 1fr); } }
773
+
774
+ .grid-item {
775
+ aspect-ratio: 1 / 1;
776
+ position: relative;
777
+ overflow: hidden;
778
+ background: var(--surface);
779
+ border: none;
780
+ padding: 0;
781
+ cursor: pointer;
782
+ }
783
+ .grid-img {
784
+ width: 100%;
785
+ height: 100%;
786
+ object-fit: cover;
787
+ transition: opacity 0.7s ease, transform 1s ease;
788
+ }
789
+ .grid-item:hover .grid-img { transform: scale(1.04); }
790
+ .grid-overlay {
791
+ position: absolute;
792
+ inset: 0;
793
+ background: linear-gradient(180deg, transparent 40%, rgba(12, 10, 8, 0.92) 100%);
794
+ display: flex;
795
+ align-items: flex-end;
796
+ padding: 1rem;
797
+ opacity: 0;
798
+ transition: opacity 0.3s ease;
799
+ pointer-events: none;
800
+ }
801
+ .grid-item:hover .grid-overlay { opacity: 1; }
802
+ .grid-prompt {
803
+ margin: 0;
804
+ font-family: 'Instrument Serif', serif;
805
+ font-style: italic;
806
+ color: var(--cream);
807
+ font-size: 1.1rem;
808
+ line-height: 1.25;
809
+ display: -webkit-box;
810
+ -webkit-line-clamp: 3;
811
+ line-clamp: 3;
812
+ -webkit-box-orient: vertical;
813
+ overflow: hidden;
814
+ }
815
+ .grid-share {
816
+ position: absolute;
817
+ top: 0.75rem;
818
+ right: 0.75rem;
819
+ width: 32px;
820
+ height: 32px;
821
+ display: inline-flex;
822
+ align-items: center;
823
+ justify-content: center;
824
+ border-radius: 9999px;
825
+ background: rgba(12, 10, 8, 0.6);
826
+ border: 1px solid rgba(244, 236, 222, 0.15);
827
+ color: var(--cream);
828
+ cursor: pointer;
829
+ padding: 0;
830
+ opacity: 0;
831
+ transition: opacity 0.2s ease, background 0.15s ease, color 0.15s ease;
832
+ pointer-events: auto;
833
+ backdrop-filter: blur(4px);
834
+ -webkit-backdrop-filter: blur(4px);
835
+ }
836
+ .grid-item:hover .grid-share { opacity: 1; }
837
+ .grid-share:hover { background: rgba(232, 165, 94, 0.16); color: var(--amber); }
838
+ .grid-fail {
839
+ position: absolute;
840
+ inset: 0;
841
+ display: flex;
842
+ align-items: center;
843
+ justify-content: center;
844
+ color: var(--faint);
845
+ font-family: 'Geist Mono', monospace;
846
+ font-size: 11px;
847
+ text-transform: uppercase;
848
+ letter-spacing: 0.15em;
849
+ }
850
+
851
+ .load-more {
852
+ height: 6rem;
853
+ display: flex;
854
+ align-items: center;
855
+ justify-content: center;
856
+ color: var(--faint);
857
+ }
858
+
859
+ @keyframes shimmer {
860
+ 0% { background-position: -200% 0; }
861
+ 100% { background-position: 200% 0; }
862
+ }
863
+ .shimmer {
864
+ position: absolute;
865
+ inset: 0;
866
+ background: linear-gradient(90deg, var(--surface) 0%, #211d19 50%, var(--surface) 100%);
867
+ background-size: 200% 100%;
868
+ animation: shimmer 1.4s linear infinite;
869
+ }
870
+
871
+ @keyframes spin {
872
+ from { transform: rotate(0deg); }
873
+ to { transform: rotate(360deg); }
874
+ }
875
+ .spin { animation: spin 1s linear infinite; }
876
+
877
+ @keyframes fadeUp {
878
+ from { opacity: 0; transform: translateY(8px); }
879
+ to { opacity: 1; transform: translateY(0); }
880
+ }
881
+ .fade-up { animation: fadeUp 0.6s cubic-bezier(0.2, 0.7, 0.2, 1) backwards; }
882
+
883
+ .modal {
884
+ position: fixed;
885
+ inset: 0;
886
+ z-index: 50;
887
+ background: rgba(8, 7, 6, 0.96);
888
+ backdrop-filter: blur(20px);
889
+ -webkit-backdrop-filter: blur(20px);
890
+ display: flex;
891
+ align-items: center;
892
+ justify-content: center;
893
+ padding: 1.5rem;
894
+ }
895
+ .icon-btn {
896
+ width: 40px;
897
+ height: 40px;
898
+ border-radius: 9999px;
899
+ background: var(--surface);
900
+ border: 1px solid var(--border);
901
+ color: var(--cream);
902
+ cursor: pointer;
903
+ display: inline-flex;
904
+ align-items: center;
905
+ justify-content: center;
906
+ padding: 0;
907
+ transition: background 0.15s ease;
908
+ }
909
+ .icon-btn:hover { background: #1c1816; }
910
+ .modal-close { position: absolute; top: 1.5rem; right: 1.5rem; z-index: 10; }
911
+ .modal-prev { position: absolute; left: 1.5rem; top: 50%; transform: translateY(-50%); z-index: 10; }
912
+ .modal-next { position: absolute; right: 1.5rem; top: 50%; transform: translateY(-50%); z-index: 10; }
913
+
914
+ .modal-content {
915
+ width: 100%;
916
+ max-width: 1280px;
917
+ max-height: 100%;
918
+ display: flex;
919
+ gap: 2.5rem;
920
+ align-items: center;
921
+ }
922
+ @media (max-width: 900px) {
923
+ .modal-content { flex-direction: column; gap: 1.5rem; }
924
+ }
925
+ .modal-img-wrap {
926
+ flex: 1;
927
+ display: flex;
928
+ align-items: center;
929
+ justify-content: center;
930
+ position: relative;
931
+ min-width: 0;
932
+ }
933
+ .modal-loader {
934
+ position: absolute;
935
+ inset: 0;
936
+ display: flex;
937
+ align-items: center;
938
+ justify-content: center;
939
+ color: var(--faint);
940
+ }
941
+ .modal-img {
942
+ max-width: 100%;
943
+ max-height: 85vh;
944
+ object-fit: contain;
945
+ box-shadow: 0 30px 80px -20px rgba(0, 0, 0, 0.8);
946
+ transition: opacity 0.5s ease;
947
+ }
948
+ .modal-meta {
949
+ width: 18rem;
950
+ max-width: 100%;
951
+ max-height: 85vh;
952
+ overflow-y: auto;
953
+ flex-shrink: 0;
954
+ }
955
+
956
+ .prompt-block { position: relative; margin-bottom: 2.5rem; }
957
+ .prompt-header {
958
+ display: flex;
959
+ align-items: center;
960
+ justify-content: space-between;
961
+ margin-bottom: 0.75rem;
962
+ min-height: 28px;
963
+ }
964
+ .prompt-header .meta-label { margin: 0; }
965
+ .copy-btn {
966
+ opacity: 0;
967
+ transition: opacity 0.15s ease, color 0.15s ease, border-color 0.15s ease;
968
+ }
969
+ .prompt-block:hover .copy-btn,
970
+ .copy-btn:focus-visible { opacity: 1; }
971
+ .copy-btn.copied {
972
+ opacity: 1;
973
+ color: var(--cream);
974
+ border-color: var(--faint);
975
+ }
976
+
977
+ .meta-label {
978
+ margin: 0 0 0.75rem 0;
979
+ font-family: 'Geist Mono', monospace;
980
+ font-size: 11px;
981
+ text-transform: uppercase;
982
+ letter-spacing: 0.25em;
983
+ color: var(--dim);
984
+ }
985
+ .meta-prompt {
986
+ margin: 0;
987
+ font-family: 'Instrument Serif', serif;
988
+ font-style: italic;
989
+ color: var(--cream);
990
+ font-size: 1.875rem;
991
+ line-height: 1.25;
992
+ }
993
+ #metaParams { margin: 0 0 2.5rem 0; }
994
+ .meta-row {
995
+ display: flex;
996
+ justify-content: space-between;
997
+ align-items: baseline;
998
+ gap: 1rem;
999
+ padding: 0.625rem 0;
1000
+ border-bottom: 1px solid var(--border2);
1001
+ font-family: 'Geist Mono', monospace;
1002
+ font-size: 13px;
1003
+ }
1004
+ .meta-row dt {
1005
+ color: var(--dim);
1006
+ text-transform: uppercase;
1007
+ letter-spacing: 0.1em;
1008
+ font-size: 11px;
1009
+ }
1010
+ .meta-row dd { color: var(--cream); margin: 0; }
1011
+
1012
+ .meta-actions {
1013
+ display: flex;
1014
+ align-items: center;
1015
+ gap: 1.25rem;
1016
+ }
1017
+ .meta-share,
1018
+ .meta-delete {
1019
+ background: transparent;
1020
+ border: none;
1021
+ cursor: pointer;
1022
+ color: var(--dim);
1023
+ font-family: 'Geist Mono', monospace;
1024
+ font-size: 11px;
1025
+ text-transform: uppercase;
1026
+ letter-spacing: 0.15em;
1027
+ display: inline-flex;
1028
+ align-items: center;
1029
+ gap: 6px;
1030
+ padding: 0;
1031
+ transition: color 0.15s ease;
1032
+ }
1033
+ .meta-share:hover { color: var(--amber); }
1034
+ .meta-delete:hover { color: var(--cream); }
1035
+ .meta-share[disabled] { opacity: 0.4; cursor: default; }
1036
+
1037
+ ::-webkit-scrollbar { width: 8px; height: 8px; }
1038
+ ::-webkit-scrollbar-track { background: transparent; }
1039
+ ::-webkit-scrollbar-thumb { background: #2a2522; border-radius: 4px; }
1040
+ ::-webkit-scrollbar-thumb:hover { background: #3a3530; }
1041
+ </style>
1042
+ <script type="module" crossorigin src="/assets/index-Dt2nXeN6.js"></script>
1043
+ </head>
1044
+ <body>
1045
+
1046
+ <section class="section landing" id="landingSection">
1047
+ <div class="hero-scene">
1048
+ <div id="root"></div>
1049
+ </div>
1050
+
1051
+ <div class="landing-inner">
1052
+ <p class="landing-eyebrow">Bonsai Image · 4B</p>
1053
+ <h1 class="landing-title">State-of-the-art image generation,<br><em>in your browser.</em></h1>
1054
+ <p class="landing-tagline">
1055
+ A family of compressed image-generation models for high-quality diffusion on local hardware.
1056
+ </p>
1057
+
1058
+ <div class="cta-group" id="ctaGroup">
1059
+ <button class="landing-cta landing-cta-main" id="tryDemoBtn" type="button">
1060
+ <span>Load <span id="ctaModelLabel">Ternary</span> model</span>
1061
+ <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1062
+ <path d="M5 12h14"/><path d="m12 5 7 7-7 7"/>
1063
+ </svg>
1064
+ </button>
1065
+ <button class="landing-cta landing-cta-toggle" id="modelMenuToggle" type="button" aria-haspopup="menu" aria-expanded="false" aria-label="Choose model">
1066
+ <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1067
+ <path d="m6 9 6 6 6-6"/>
1068
+ </svg>
1069
+ </button>
1070
+
1071
+ <div class="model-menu" id="modelMenu" role="menu" hidden>
1072
+ <p class="model-menu-title">Choose a variant</p>
1073
+ <button class="model-menu-item" role="menuitemradio" data-model-id="prism-ml/bonsai-image-ternary-4B-mlx-2bit" type="button">
1074
+ <span class="model-menu-radio" aria-hidden="true"></span>
1075
+ <span class="model-menu-text">
1076
+ <span class="model-menu-name">Ternary Bonsai Image 4B<span class="model-menu-tag">recommended</span></span>
1077
+ <span class="model-menu-desc">
1078
+ {-1, 0, +1} weights with FP16 group-wise scale — ~1.7 bits/weight. The extra zero state improves visual quality and prompt fidelity while staying extremely compact.
1079
+ </span>
1080
+ <span class="model-menu-meta">3.3 GB</span>
1081
+ </span>
1082
+ </button>
1083
+ <button class="model-menu-item" role="menuitemradio" data-model-id="prism-ml/bonsai-image-binary-4B-mlx-1bit" type="button">
1084
+ <span class="model-menu-radio" aria-hidden="true"></span>
1085
+ <span class="model-menu-text">
1086
+ <span class="model-menu-name">1-bit Bonsai Image 4B</span>
1087
+ <span class="model-menu-desc">
1088
+ Binary {-1, +1} weights with FP16 group-wise scale — ~1.1 bits/weight. Targets maximum compression when memory pressure and deployment footprint are the priority.
1089
+ </span>
1090
+ <span class="model-menu-meta">2.86 GB</span>
1091
+ </span>
1092
+ </button>
1093
+ <p class="model-menu-footnote">
1094
+ Compressed from the original FLUX2-Klein 4B (15.97 GB).
1095
+ </p>
1096
+ </div>
1097
+ </div>
1098
+ </div>
1099
+
1100
+ </section>
1101
+
1102
+ <section class="section" id="gateSection" hidden>
1103
+ <div class="gate-inner">
1104
+ <div>
1105
+ <h1 class="brand">Bonsai Image · <em>4B</em></h1>
1106
+ <p class="brand-sub">Flux2-Klein · WebGPU</p>
1107
+ </div>
1108
+
1109
+ <div class="disclaimer">
1110
+ <svg class="icon" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1111
+ <path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z"/>
1112
+ <path d="M12 9v4"/>
1113
+ <path d="M12 17h.01"/>
1114
+ </svg>
1115
+ <div class="disclaimer-content">
1116
+ <p class="disclaimer-title">experimental</p>
1117
+ <p class="disclaimer-body">
1118
+ Research software, primarily tested on Apple M4 Max and M5 Max.
1119
+ It may not be optimized for your hardware.
1120
+ </p>
1121
+ <p class="disclaimer-body" style="margin-top: 0.625rem;">
1122
+ On Chrome/Edge, enable the
1123
+ <code class="flag-name">#enable-unsafe-webgpu</code>
1124
+ flag for best performance:
1125
+ </p>
1126
+ <div class="flag-copy">
1127
+ <code class="flag-url" id="flagUrl">chrome://flags/#enable-unsafe-webgpu</code>
1128
+ <button class="flag-copy-btn" id="flagCopyBtn" type="button" title="Copy URL">
1129
+ <span id="flagCopyIcon"></span>
1130
+ </button>
1131
+ </div>
1132
+ </div>
1133
+ </div>
1134
+
1135
+ <div class="token-group">
1136
+ <label class="token-label" for="tokenInput">HuggingFace Access Token</label>
1137
+ <div class="token-input-wrap" id="tokenInputWrap">
1138
+ <input
1139
+ type="password"
1140
+ id="tokenInput"
1141
+ class="token-input"
1142
+ placeholder="hf_..."
1143
+ autocomplete="off"
1144
+ spellcheck="false"
1145
+ >
1146
+ <button class="token-toggle" id="tokenToggleBtn" type="button">show</button>
1147
+ </div>
1148
+ <p class="token-help" id="tokenHelp"></p>
1149
+ </div>
1150
+
1151
+ <button class="generate" id="continueBtn" disabled>continue</button>
1152
+ </div>
1153
+ </section>
1154
+
1155
+ <section class="section" id="loadingSection" hidden>
1156
+ <div class="loading-inner">
1157
+ <svg class="spin loading-spinner" xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1158
+ <path d="M21 12a9 9 0 1 1-6.219-8.56"/>
1159
+ </svg>
1160
+ <p class="loading-title">loading model</p>
1161
+ <p class="loading-status" id="loadingStatus">preparing…</p>
1162
+ <div class="loading-bar"><div class="loading-bar-fill" id="loadingBarFill"></div></div>
1163
+ </div>
1164
+ </section>
1165
+
1166
+ <section class="section" id="hero" hidden>
1167
+ <div class="hero-inner">
1168
+ <p class="hero-eyebrow">enter a prompt</p>
1169
+
1170
+ <textarea
1171
+ class="prompt"
1172
+ id="prompt"
1173
+ placeholder="Describe your image..."
1174
+ rows="3"
1175
+ ></textarea>
1176
+
1177
+ <button class="example-link" id="exampleBtn" type="button" title="Try an example prompt">
1178
+ <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1179
+ <rect width="12" height="12" x="2" y="10" rx="2" ry="2"/>
1180
+ <path d="m17.92 14 3.5-3.5a2.24 2.24 0 0 0 0-3l-5-4.92a2.24 2.24 0 0 0-3 0L10 6"/>
1181
+ <path d="M6 18h.01"/><path d="M10 14h.01"/><path d="M15 6h.01"/><path d="M18 9h.01"/>
1182
+ </svg>
1183
+ try an example
1184
+ </button>
1185
+
1186
+ <div class="controls">
1187
+ <div class="size-group">
1188
+ <span class="size-label">Size</span>
1189
+ <div class="presets" id="presets">
1190
+ <button class="preset" data-ratio="1:1" data-rw="1" data-rh="1" type="button">1:1</button>
1191
+ <button class="preset" data-ratio="4:3" data-rw="4" data-rh="3" type="button">4:3</button>
1192
+ <button class="preset" data-ratio="3:4" data-rw="3" data-rh="4" type="button">3:4</button>
1193
+ <button class="preset" data-ratio="16:9" data-rw="16" data-rh="9" type="button">16:9</button>
1194
+ <button class="preset" data-ratio="9:16" data-rw="9" data-rh="16" type="button">9:16</button>
1195
+ </div>
1196
+ <div class="slider-row">
1197
+ <span class="sub-label">W</span>
1198
+ <input type="range" id="widthSlider" min="256" max="1024" step="16" value="512">
1199
+ <span class="sub-value" id="widthValue">512</span>
1200
+ </div>
1201
+ <div class="slider-row">
1202
+ <span class="sub-label">H</span>
1203
+ <input type="range" id="heightSlider" min="256" max="1024" step="16" value="512">
1204
+ <span class="sub-value" id="heightValue">512</span>
1205
+ </div>
1206
+ </div>
1207
+
1208
+ <div class="seed-row">
1209
+ <span class="seed-label">Steps</span>
1210
+ <input type="range" id="stepsSlider" min="1" max="50" step="1" value="4">
1211
+ <span class="sub-value" id="stepsValue">4</span>
1212
+ </div>
1213
+
1214
+ <div class="seed-row">
1215
+ <span class="seed-label">Seed</span>
1216
+ <input
1217
+ type="text"
1218
+ inputmode="numeric"
1219
+ id="seedInput"
1220
+ class="seed-input"
1221
+ placeholder="random"
1222
+ >
1223
+ <button class="icon-btn-sm" id="randomSeedBtn" type="button" title="Randomize seed">
1224
+ <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1225
+ <rect width="12" height="12" x="2" y="10" rx="2" ry="2"/>
1226
+ <path d="m17.92 14 3.5-3.5a2.24 2.24 0 0 0 0-3l-5-4.92a2.24 2.24 0 0 0-3 0L10 6"/>
1227
+ <path d="M6 18h.01"/><path d="M10 14h.01"/><path d="M15 6h.01"/><path d="M18 9h.01"/>
1228
+ </svg>
1229
+ </button>
1230
+ </div>
1231
+ </div>
1232
+
1233
+ <button class="generate" id="generateBtn" disabled>generate</button>
1234
+ </div>
1235
+
1236
+ <button class="gallery-link" id="galleryLink" hidden></button>
1237
+ </section>
1238
+
1239
+ <section id="gallerySection" hidden>
1240
+ <div class="gallery-header">
1241
+ <span class="image-count" id="imageCountTop"></span>
1242
+ <div class="header-actions">
1243
+ <button class="text-btn" id="clearAllBtn">clear all</button>
1244
+ <button class="pill-btn" id="newBtn">
1245
+ <svg xmlns="http://www.w3.org/2000/svg" width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1246
+ <path d="m5 12 7-7 7 7"/><path d="M12 19V5"/>
1247
+ </svg>
1248
+ new
1249
+ </button>
1250
+ </div>
1251
+ </div>
1252
+ <div class="grid" id="grid"></div>
1253
+ <div class="load-more" id="loadMoreSentinel"></div>
1254
+ </section>
1255
+
1256
+ <div class="modal" id="modal" hidden>
1257
+ <button class="icon-btn modal-close" id="modalClose" aria-label="Close">
1258
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1259
+ <path d="M18 6 6 18"/><path d="m6 6 12 12"/>
1260
+ </svg>
1261
+ </button>
1262
+ <button class="icon-btn modal-prev" id="modalPrev" aria-label="Previous">
1263
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1264
+ <path d="m15 18-6-6 6-6"/>
1265
+ </svg>
1266
+ </button>
1267
+ <button class="icon-btn modal-next" id="modalNext" aria-label="Next">
1268
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1269
+ <path d="m9 18 6-6-6-6"/>
1270
+ </svg>
1271
+ </button>
1272
+
1273
+ <div class="modal-content">
1274
+ <div class="modal-img-wrap">
1275
+ <div class="modal-loader" id="modalLoader">
1276
+ <svg class="spin" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1277
+ <path d="M21 12a9 9 0 1 1-6.219-8.56"/>
1278
+ </svg>
1279
+ </div>
1280
+ <img class="modal-img" id="modalImg" alt="">
1281
+ </div>
1282
+
1283
+ <aside class="modal-meta">
1284
+ <div class="prompt-block">
1285
+ <div class="prompt-header">
1286
+ <span class="meta-label">prompt</span>
1287
+ <button class="copy-btn icon-btn-sm" id="copyPromptBtn" type="button" title="Copy prompt">
1288
+ <span id="copyIcon"></span>
1289
+ </button>
1290
+ </div>
1291
+ <p class="meta-prompt" id="metaPrompt"></p>
1292
+ </div>
1293
+
1294
+ <p class="meta-label">parameters</p>
1295
+ <dl id="metaParams"></dl>
1296
+
1297
+ <div class="meta-actions">
1298
+ <button class="meta-share" id="modalShare" type="button" hidden>
1299
+ <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1300
+ <path d="M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8"/>
1301
+ <polyline points="16 6 12 2 8 6"/>
1302
+ <line x1="12" x2="12" y1="2" y2="15"/>
1303
+ </svg>
1304
+ share
1305
+ </button>
1306
+ <button class="meta-delete" id="modalDelete" type="button">
1307
+ <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1308
+ <path d="M3 6h18"/>
1309
+ <path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"/>
1310
+ <path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"/>
1311
+ <line x1="10" x2="10" y1="11" y2="17"/>
1312
+ <line x1="14" x2="14" y1="11" y2="17"/>
1313
+ </svg>
1314
+ delete
1315
+ </button>
1316
+ </div>
1317
+ </aside>
1318
+ </div>
1319
+ </div>
1320
+
1321
+
1322
+ </body>
1323
  </html>