Ivaylo77 commited on
Commit
ad5c45a
·
verified ·
1 Parent(s): 3238a8c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +194 -410
app.py CHANGED
@@ -1,226 +1,8 @@
1
- import io
2
- import tempfile
3
- import zipfile
4
-
5
- import random
6
  import torch
7
  import spaces
8
  import gradio as gr
9
- from diffusers import ZImagePipeline
10
- MAX_SEED = 2**32 - 1
11
-
12
 
13
- # ===== Custom aesthetic =====
14
- # Neo-noir dusk palette with cyan + amber accents, glass panels, and subtle grain.
15
- CUSTOM_CSS = """
16
- @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap');
17
- :root {
18
- /* Light Mode (Professional & Clean) */
19
- --bg: #fdfdfd;
20
- --panel: rgba(255, 255, 255, 0.95);
21
- --card: #ffffff;
22
- --border: #e5e7eb;
23
- --border-hover: #d1d5db;
24
- --text: #111827;
25
- --text-secondary: #4b5563;
26
- --muted: #9ca3af;
27
- --accent: #0f172a; /* Dark sleek accent for professionalism */
28
- --accent-hover: #1e293b;
29
- --accent-text: #ffffff;
30
- --primary-gradient: linear-gradient(135deg, #0f172a 0%, #334155 100%);
31
- --glow: 0 0 0 transparent;
32
- --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
33
- --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -1px rgba(0, 0, 0, 0.03);
34
- --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.05), 0 4px 6px -2px rgba(0, 0, 0, 0.03);
35
- --radius: 12px;
36
- --input-bg: #ffffff;
37
- --input-border: #e2e8f0;
38
- --checkbox-bg: #f1f5f9;
39
- --body-bg: #f8fafc; /* Very subtle cool gray */
40
- --font-heading: 'Inter', -apple-system, sans-serif;
41
- --font-body: 'Inter', -apple-system, sans-serif;
42
- }
43
- .dark {
44
- /* Dark Mode (Neo-Noir Polished) */
45
- --bg: #05080f;
46
- --panel: rgba(12, 18, 32, 0.85);
47
- --card: rgba(18, 28, 46, 0.70);
48
- --border: rgba(36, 224, 194, 0.15);
49
- --border-hover: rgba(36, 224, 194, 0.3);
50
- --text: #e9f3ff;
51
- --text-secondary: #94a3b8;
52
- --muted: #64748b;
53
- --accent: #24e0c2;
54
- --accent-hover: #18cdb0;
55
- --accent-text: #041019;
56
- --primary-gradient: linear-gradient(120deg, #24e0c2 0%, #ffb347 100%);
57
- --glow: 0 8px 32px rgba(36, 224, 194, 0.12);
58
- --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.2);
59
- --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.3);
60
- --shadow-lg: 0 20px 40px -5px rgba(0, 0, 0, 0.4);
61
- --radius: 16px;
62
- --input-bg: rgba(255,255,255,0.03);
63
- --input-border: rgba(255,255,255,0.08);
64
- --checkbox-bg: #0d1829;
65
- --body-bg: radial-gradient(circle at 20% 20%, rgba(36, 224, 194, 0.06), transparent 35%),
66
- radial-gradient(circle at 82% 12%, rgba(0, 156, 196, 0.06), transparent 35%),
67
- linear-gradient(145deg, #05080f 0%, #080f1e 100%);
68
- --font-heading: 'Inter', -apple-system, sans-serif;
69
- --font-body: 'Inter', -apple-system, sans-serif;
70
- }
71
- body, .gradio-container {
72
- font-family: var(--font-body) !important;
73
- background: var(--body-bg) !important;
74
- color: var(--text);
75
- min-height: 100vh;
76
- }
77
- /* Titles & Typography */
78
- .gradio-container .prose h1,
79
- .gradio-container .prose h2,
80
- .gradio-container .prose h3 {
81
- font-family: var(--font-heading);
82
- letter-spacing: -0.025em;
83
- font-weight: 700;
84
- color: var(--text);
85
- }
86
- .gradio-container .prose h1 {
87
- font-size: 2.25rem;
88
- margin-bottom: 0.5rem;
89
- background: var(--primary-gradient);
90
- -webkit-background-clip: text;
91
- -webkit-text-fill-color: transparent;
92
- background-clip: text;
93
- display: inline-block;
94
- }
95
- .gradio-container * { letter-spacing: -0.01em; }
96
- /* Panels & Cards */
97
- .gr-block, .gr-panel, .gr-group {
98
- background: var(--panel);
99
- border: 1px solid var(--border);
100
- border-radius: var(--radius);
101
- box-shadow: var(--shadow-sm);
102
- backdrop-filter: blur(8px);
103
- transition: box-shadow 0.2s ease, border-color 0.2s ease;
104
- }
105
- .hero-card {
106
- background: var(--card);
107
- border: 1px solid var(--border);
108
- padding: 24px;
109
- border-radius: var(--radius);
110
- box-shadow: var(--shadow-md);
111
- position: relative;
112
- overflow: hidden;
113
- }
114
- .tagline {
115
- display: inline-flex;
116
- align-items: center;
117
- gap: 8px;
118
- padding: 6px 14px;
119
- background: var(--input-bg);
120
- border: 1px solid var(--border);
121
- border-radius: 999px;
122
- font-size: 0.875rem;
123
- font-weight: 500;
124
- color: var(--text-secondary);
125
- margin-bottom: 12px;
126
- }
127
- .hero-card p {
128
- color: var(--text-secondary);
129
- font-size: 1.05rem;
130
- line-height: 1.6;
131
- max-width: 65ch;
132
- }
133
- /* Inputs */
134
- textarea, input:not([type='checkbox']):not([type='radio']),
135
- .gr-input, .gr-textbox, .gr-number, .gr-slider input {
136
- background: var(--input-bg) !important;
137
- border: 1px solid var(--input-border) !important;
138
- border-radius: 10px !important;
139
- color: var(--text) !important;
140
- font-family: var(--font-body);
141
- transition: all 0.2s ease;
142
- }
143
- textarea:focus, input:focus, .gr-input:focus-within {
144
- border-color: var(--text-secondary) !important;
145
- box-shadow: 0 0 0 2px rgba(var(--accent), 0.1);
146
- }
147
- label, .gr-box label {
148
- color: var(--text-secondary) !important;
149
- font-weight: 600;
150
- font-size: 0.875rem;
151
- margin-bottom: 6px;
152
- text-transform: none !important;
153
- }
154
- /* Sliders */
155
- .gr-slider input[type='range'] {
156
- accent-color: var(--accent);
157
- }
158
- /* Buttons */
159
- .gr-button-primary, button.primary {
160
- background: var(--primary-gradient) !important;
161
- color: var(--accent-text) !important;
162
- font-weight: 600 !important;
163
- border: 1px solid rgba(255,255,255,0.1) !important;
164
- box-shadow: var(--shadow-md);
165
- border-radius: 10px !important;
166
- padding: 10px 24px;
167
- transition: transform 0.1s, box-shadow 0.2s;
168
- }
169
- .gr-button-primary:hover {
170
- transform: translateY(-1px);
171
- box-shadow: var(--shadow-lg);
172
- filter: brightness(1.1);
173
- }
174
- .gr-button-secondary, button.secondary, .gr-downloadbutton {
175
- background: var(--input-bg) !important;
176
- border: 1px solid var(--border) !important;
177
- color: var(--text) !important;
178
- font-weight: 500;
179
- border-radius: 10px !important;
180
- box-shadow: var(--shadow-sm);
181
- }
182
- .gr-button-secondary:hover {
183
- border-color: var(--border-hover) !important;
184
- background: var(--card) !important;
185
- }
186
- .gr-downloadbutton, .gr-downloadbutton > button { width: 100%; }
187
- /* Gallery */
188
- .gr-gallery {
189
- background: var(--input-bg);
190
- border-radius: var(--radius);
191
- border: 1px solid var(--border);
192
- padding: 8px;
193
- }
194
- .gr-gallery .thumbnail-item {
195
- border-radius: 8px;
196
- overflow: hidden;
197
- box-shadow: var(--shadow-sm);
198
- border: 1px solid transparent;
199
- transition: all 0.2s;
200
- }
201
- .gr-gallery .thumbnail-item:hover {
202
- box-shadow: var(--shadow-md);
203
- transform: scale(1.02);
204
- }
205
- .gr-gallery img { object-fit: cover; }
206
- /* Footer */
207
- .footer-note {
208
- color: var(--muted);
209
- font-size: 0.875rem;
210
- text-align: center;
211
- margin-top: 2rem;
212
- opacity: 0.8;
213
- }
214
- .footer-note a {
215
- color: var(--text-secondary);
216
- text-decoration: none;
217
- border-bottom: 1px dotted var(--muted);
218
- }
219
- .footer-note a:hover {
220
- color: var(--accent);
221
- border-bottom-style: solid;
222
- }
223
- """
224
  # Load the pipeline once at startup
225
  print("Loading Z-Image-Turbo pipeline...")
226
  pipe = DiffusionPipeline.from_pretrained(
@@ -237,239 +19,241 @@ pipe.to("cuda")
237
  print("Pipeline loaded!")
238
 
239
  @spaces.GPU
240
- def generate_image(
241
- prompt,
242
- negative_prompt,
243
- height,
244
- width,
245
- images_count,
246
- num_inference_steps,
247
- guidance_scale,
248
- seed,
249
- randomize_seed,
250
- progress=gr.Progress(track_tqdm=True),
251
- ):
252
- """Generate N images using a deterministic seed cascade (x1..xN)."""
253
  if randomize_seed:
254
- seed = random.randint(0, MAX_SEED)
255
-
256
- base_seed = int(seed) % MAX_SEED
257
- if base_seed < 0:
258
- base_seed += MAX_SEED
259
-
260
- # Cap to prevent excessive VRAM usage / latency spikes on the demo space
261
- images_count = max(1, min(int(images_count), 12))
262
-
263
- seeds = [(base_seed * i) % MAX_SEED for i in range(1, images_count + 1)]
264
-
265
- neg_prompt = None
266
- if isinstance(negative_prompt, str) and negative_prompt.strip():
267
- neg_prompt = negative_prompt
268
-
269
- images = []
270
- image_paths = []
271
- for s in seeds:
272
- generator = torch.Generator("cuda").manual_seed(int(s))
273
- image = pipe(
274
- prompt=prompt,
275
- negative_prompt=neg_prompt,
276
- height=int(height),
277
- width=int(width),
278
- num_inference_steps=int(num_inference_steps),
279
- guidance_scale=float(guidance_scale), # 0.0 is recommended default for Turbo
280
- generator=generator,
281
- ).images[0]
282
- images.append(image)
283
- tmp_img = tempfile.NamedTemporaryFile(delete=False, suffix=".png")
284
- image.save(tmp_img.name, format="PNG")
285
- image_paths.append(tmp_img.name)
286
-
287
- return images, ", ".join(str(s) for s in seeds), image_paths, base_seed
288
-
289
-
290
-
291
- def append_history(new_images, history):
292
- """Append new images to the history state."""
293
- if history is None:
294
- history = []
295
- updated_history = history + new_images
296
- return updated_history, updated_history
297
-
298
-
299
- def package_zip(image_paths):
300
- """Pack the current image list into a ZIP file for download."""
301
- if not image_paths:
302
- raise gr.Error("No images in history to download.")
303
-
304
- tmp = tempfile.NamedTemporaryFile(delete=False, suffix=".zip")
305
- with zipfile.ZipFile(tmp, "w", zipfile.ZIP_DEFLATED) as zf:
306
- for idx, path in enumerate(image_paths, start=1):
307
- # Store as image_001.png, image_002.png, ...
308
- zf.write(path, arcname=f"image_{idx:03d}.png")
309
-
310
- tmp.flush()
311
- return tmp.name
312
-
313
 
314
  # Example prompts
315
  examples = [
316
- ["Astronaut riding a horse on Mars, cinematic lighting, sci-fi concept art, highly detailed"],
317
- ["Portrait of a wise old wizard with a long white beard, holding a glowing crystal staff, magical forest background"],
 
 
 
318
  ]
319
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
320
  # Build the Gradio interface
321
- # Build the Gradio interface
322
- with gr.Blocks(title="Z-Image-Turbo Demo", css=CUSTOM_CSS, analytics_enabled=False) as demo:
323
- image_state = gr.State([])
324
- history_state = gr.State([])
325
  gr.Markdown(
326
  """
327
- <div class="hero-card">
328
- <div class="tagline">⚡ Turbo diffusion · 8 steps · CUDA ready</div>
329
- <h1>Z‑Image Turbo Studio</h1>
330
- <p>Draft up to twelve stylized candidates in one pass. Neo‑noir gradients, glass panels, and crisp typography keep the tooling out of your way while you explore ideas.</p>
331
- </div>
332
  """,
333
- sanitize_html=False,
334
  )
335
 
336
- with gr.Row():
337
- with gr.Column(scale=1):
 
338
  prompt = gr.Textbox(
339
- label="Prompt",
340
- placeholder="e.g. bioluminescent reef city at dusk, cinematic, anamorphic glow",
341
- lines=4,
342
- )
343
-
344
- negative_prompt = gr.Textbox(
345
- label="Negative Prompt",
346
- placeholder="noise, blur, extra limbs, text watermark",
347
- lines=3,
348
  )
349
-
350
- with gr.Row():
351
- height = gr.Slider(
352
- minimum=512,
353
- maximum=2048,
354
- value=1024,
355
- step=64,
356
- label="Height",
357
- )
358
- width = gr.Slider(
359
- minimum=512,
360
- maximum=2048,
361
- value=1024,
362
- step=64,
363
- label="Width",
364
- )
365
-
366
- with gr.Row():
 
 
367
  num_inference_steps = gr.Slider(
368
  minimum=1,
369
  maximum=20,
370
  value=9,
371
  step=1,
372
  label="Inference Steps",
373
- info="9 steps 8 DiT forwards",
374
- )
375
-
376
- images_count = gr.Slider(
377
- minimum=1,
378
- maximum=12,
379
- value=4,
380
- step=1,
381
- label="Images",
382
- info="1–12 (higher counts use more VRAM)",
383
- )
384
-
385
- guidance_scale = gr.Slider(
386
- minimum=0.0,
387
- maximum=7.0,
388
- value=0.0,
389
- step=0.1,
390
- label="CFG Guidance Scale",
391
- info="0 = no CFG (recommended for Turbo models)",
392
- )
393
-
394
- with gr.Row():
395
- seed = gr.Number(
396
- label="Base Seed",
397
- value=42,
398
- precision=0,
399
  )
400
- randomize_seed = gr.Checkbox(
401
- label="Randomize",
402
- value=True,
403
- interactive=True,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
404
  )
405
 
406
- generate_btn = gr.Button("🚀 Generate", variant="primary", size="lg")
407
-
408
- with gr.Column(scale=1):
409
- output_images = gr.Gallery(
410
- label="Generated Grid",
411
- columns=4,
412
- rows=None,
413
- preview=True,
414
  )
415
- used_seeds = gr.Textbox(
416
- label="Seed Cascade (x1 · x2 · ... · xN)",
417
- interactive=False,
 
 
 
 
418
  )
419
- history_gallery = gr.Gallery(
420
- label="History",
421
- columns=6,
422
- rows=None,
423
- preview=True,
424
- object_fit="cover"
 
 
 
 
425
  )
426
- download_btn = gr.DownloadButton(
427
- label="📦 Download All History (ZIP)",
 
 
 
428
  )
429
 
430
- gr.Markdown("### 💡 Quick Prompts")
431
- gr.Examples(
432
- examples=examples,
433
- inputs=[prompt],
434
- cache_examples=False,
435
- )
436
-
437
  gr.Markdown(
438
  """
439
- <div class="footer-note">
440
- Model: Tongyi-MAI/Z-Image-Turbo (Apache 2.0). Demo by <a href="https://z-image-turbo.tech" target="_blank">https://z-image-turbo.tech</a>
 
 
 
 
441
  </div>
442
  """,
443
- sanitize_html=False,
444
  )
445
 
446
  # Connect the generate button
447
  generate_btn.click(
448
  fn=generate_image,
449
- inputs=[prompt, negative_prompt, height, width, images_count, num_inference_steps, guidance_scale, seed, randomize_seed],
450
- outputs=[output_images, used_seeds, image_state, seed],
451
- ).success(
452
- fn=append_history,
453
- inputs=[image_state, history_state],
454
- outputs=[history_state, history_gallery],
455
  )
456
 
457
  # Also allow generating by pressing Enter in the prompt box
458
  prompt.submit(
459
  fn=generate_image,
460
- inputs=[prompt, negative_prompt, height, width, images_count, num_inference_steps, guidance_scale, seed, randomize_seed],
461
- outputs=[output_images, used_seeds, image_state, seed],
462
- ).success(
463
- fn=append_history,
464
- inputs=[image_state, history_state],
465
- outputs=[history_state, history_gallery],
466
- )
467
-
468
- download_btn.click(
469
- fn=package_zip,
470
- inputs=[history_state],
471
- outputs=[download_btn],
472
  )
473
 
474
  if __name__ == "__main__":
475
- demo.launch(mcp_server=True, show_error=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import torch
2
  import spaces
3
  import gradio as gr
4
+ from diffusers import DiffusionPipeline
 
 
5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  # Load the pipeline once at startup
7
  print("Loading Z-Image-Turbo pipeline...")
8
  pipe = DiffusionPipeline.from_pretrained(
 
19
  print("Pipeline loaded!")
20
 
21
  @spaces.GPU
22
+ def generate_image(prompt, height, width, num_inference_steps, seed, randomize_seed, progress=gr.Progress(track_tqdm=True)):
23
+ """Generate an image from the given prompt."""
 
 
 
 
 
 
 
 
 
 
 
24
  if randomize_seed:
25
+ seed = torch.randint(0, 2**32 - 1, (1,)).item()
26
+
27
+ generator = torch.Generator("cuda").manual_seed(int(seed))
28
+ image = pipe(
29
+ prompt=prompt,
30
+ height=int(height),
31
+ width=int(width),
32
+ num_inference_steps=int(num_inference_steps),
33
+ guidance_scale=0.0,
34
+ generator=generator,
35
+ ).images[0]
36
+
37
+ return image, seed
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
 
39
  # Example prompts
40
  examples = [
41
+
42
+
43
+
44
+
45
+
46
  ]
47
 
48
+ # Custom theme with modern aesthetics (Gradio 6)
49
+ custom_theme = gr.themes.Soft(
50
+ primary_hue="green",
51
+ secondary_hue="amber",
52
+ neutral_hue="slate",
53
+ font=gr.themes.GoogleFont("Inter"),
54
+ text_size="lg",
55
+ spacing_size="md",
56
+ radius_size="lg"
57
+ ).set(
58
+ button_primary_background_fill="*primary_500",
59
+ button_primary_background_fill_hover="*primary_600",
60
+ block_title_text_weight="600",
61
+ )
62
+
63
  # Build the Gradio interface
64
+ with gr.Blocks(fill_height=True) as demo:
65
+ # Header
 
 
66
  gr.Markdown(
67
  """
68
+ # Z-Image-Turbo
 
 
 
 
69
  """,
70
+ elem_classes="header-text"
71
  )
72
 
73
+ with gr.Row(equal_height=False):
74
+ # Left column - Input controls
75
+ with gr.Column(scale=1, min_width=600):
76
  prompt = gr.Textbox(
77
+ label="✨ Your Prompt",
78
+ placeholder="Describe the image you want to create...",
79
+ lines=5,
80
+ max_lines=10,
81
+ autofocus=True,
 
 
 
 
82
  )
83
+
84
+ with gr.Accordion("⚙️ Advanced Settings", open=True):
85
+ with gr.Row():
86
+ height = gr.Slider(
87
+ minimum=512,
88
+ maximum=2048,
89
+ value=1024,
90
+ step=64,
91
+ label="Height",
92
+ info="Pixels_______________________"
93
+ )
94
+ width = gr.Slider(
95
+ minimum=512,
96
+ maximum=2048,
97
+ value=1024,
98
+ step=64,
99
+ label="Width",
100
+ info="Pixels________________________"
101
+ )
102
+
103
  num_inference_steps = gr.Slider(
104
  minimum=1,
105
  maximum=20,
106
  value=9,
107
  step=1,
108
  label="Inference Steps",
109
+ info="9 steps = 8 DiT (recommended)"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110
  )
111
+
112
+ with gr.Row():
113
+ randomize_seed = gr.Checkbox(
114
+ label="🎲 Random Seed",
115
+ value=True,
116
+ )
117
+ seed = gr.Number(
118
+ label="Seed",
119
+ value=42,
120
+ precision=0,
121
+ visible=False,
122
+ )
123
+
124
+ def toggle_seed(randomize):
125
+ return gr.Number(visible=not randomize)
126
+
127
+ randomize_seed.change(
128
+ toggle_seed,
129
+ inputs=[randomize_seed],
130
+ outputs=[seed]
131
  )
132
 
133
+ generate_btn = gr.Button(
134
+ "🚀 Generate Image",
135
+ variant="primary",
136
+ size="lg",
137
+ scale=1
 
 
 
138
  )
139
+
140
+ # Example prompts
141
+ gr.Examples(
142
+ examples=examples,
143
+ inputs=[prompt],
144
+ label=" ",
145
+ examples_per_page=5,
146
  )
147
+
148
+ # Right column - Output
149
+ with gr.Column(scale=1, min_width=320):
150
+ output_image = gr.Image(
151
+ label="Generated Image",
152
+ type="pil",
153
+ format="png",
154
+ show_label=False,
155
+ height=600,
156
+ buttons=["download", "share"],
157
  )
158
+
159
+ used_seed = gr.Number(
160
+ label="🎲 Seed Used",
161
+ interactive=False,
162
+ container=True,
163
  )
164
 
165
+ # Footer credits
 
 
 
 
 
 
166
  gr.Markdown(
167
  """
168
+ ---
169
+ <div style="text-align: center; opacity: 0.7; font-size: 0.9em; margin-top: 1rem;">
170
+ <strong>Model:</strong> <a href="https://huggingface.co/Tongyi-MAI/Z-Image-Turbo" target="_blank">Tongyi-MAI/Z-Image-Turbo</a> (Apache 2.0 License) •
171
+
172
+
173
+
174
  </div>
175
  """,
176
+ elem_classes="footer-text"
177
  )
178
 
179
  # Connect the generate button
180
  generate_btn.click(
181
  fn=generate_image,
182
+ inputs=[prompt, height, width, num_inference_steps, seed, randomize_seed],
183
+ outputs=[output_image, used_seed],
 
 
 
 
184
  )
185
 
186
  # Also allow generating by pressing Enter in the prompt box
187
  prompt.submit(
188
  fn=generate_image,
189
+ inputs=[prompt, height, width, num_inference_steps, seed, randomize_seed],
190
+ outputs=[output_image, used_seed],
 
 
 
 
 
 
 
 
 
 
191
  )
192
 
193
  if __name__ == "__main__":
194
+ demo.launch(
195
+ theme=custom_theme,
196
+ css="""
197
+ .header-text h1 {
198
+ font-size: 2.5rem !important;
199
+ font-weight: 700 !important;
200
+ margin-bottom: 0.5rem !important;
201
+ background: linear-gradient(135deg, #fbbf24 0%, #f59e0b 100%);
202
+ -webkit-background-clip: text;
203
+ -webkit-text-fill-color: transparent;
204
+ background-clip: text;
205
+ }
206
+
207
+ .header-text p {
208
+ font-size: 1.1rem !important;
209
+ color: #64748b !important;
210
+ margin-top: 0 !important;
211
+ }
212
+
213
+ .footer-text {
214
+ padding: 1rem 0;
215
+ }
216
+
217
+ .footer-text a {
218
+ color: #f59e0b !important;
219
+ text-decoration: none !important;
220
+ font-weight: 500;
221
+ }
222
+
223
+ .footer-text a:hover {
224
+ text-decoration: underline !important;
225
+ }
226
+
227
+ /* Mobile optimizations */
228
+ @media (max-width: 768px) {
229
+ .header-text h1 {
230
+ font-size: 1.8rem !important;
231
+ }
232
+
233
+ .header-text p {
234
+ font-size: 1rem !important;
235
+ }
236
+ }
237
+
238
+ /* Smooth transitions */
239
+ button, .gr-button {
240
+ transition: all 0.2s ease !important;
241
+ }
242
+
243
+ button:hover, .gr-button:hover {
244
+ transform: translateY(-1px);
245
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15) !important;
246
+ }
247
+
248
+ /* Better spacing */
249
+ .gradio-container {
250
+ max-width: 1400px !important;
251
+ margin: 0 auto !important;
252
+ }
253
+ """,
254
+ footer_links=[
255
+ "api",
256
+ "gradio"
257
+ ],
258
+ mcp_server=True
259
+ )