""" Z-Image-Turbo: Ultra-fast AI image generation powered by diffusion models. A Gradio-based web application for generating images using the Tongyi-MAI/Z-Image-Turbo model. Features a modern dark UI with purple/violet accent theme. """ import torch import spaces import gradio as gr from diffusers import DiffusionPipeline # ============================================================================= # CONFIGURATION CONSTANTS # ============================================================================= ASPECT_RATIOS = { "1:1 Square": (1024, 1024), "16:9 Landscape": (1344, 768), "9:16 Portrait": (768, 1344), "4:3 Standard": (1152, 896), "3:4 Portrait": (896, 1152), "21:9 Cinematic": (1536, 640), "Custom": None, } EXAMPLE_PROMPTS = [ ["Young Chinese woman in red Hanfu, intricate embroidery. Impeccable makeup, red floral forehead pattern. Elaborate high bun, golden phoenix headdress, red flowers, beads. Holds round folding fan with lady, trees, bird. Neon lightning-bolt lamp, bright yellow glow, above extended left palm. Soft-lit outdoor night background, silhouetted tiered pagoda, blurred colorful distant lights."], ["A majestic dragon soaring through clouds at sunset, scales shimmering with iridescent colors, detailed fantasy art style"], ["Cozy coffee shop interior, warm lighting, rain on windows, plants on shelves, vintage aesthetic, photorealistic"], ["Astronaut riding a horse on Mars, cinematic lighting, sci-fi concept art, highly detailed"], ["Portrait of a wise old wizard with a long white beard, holding a glowing crystal staff, magical forest background"], ["Cyberpunk street scene at night, neon signs reflecting in rain puddles, flying cars overhead, blade runner aesthetic"], ["Serene Japanese zen garden with cherry blossoms, koi pond, wooden bridge, morning mist, traditional painting style"], ["Steampunk mechanical owl with brass gears and glowing amber eyes, perched on old leather-bound books, warm candlelight"], ] DEFAULT_SETTINGS = { "height": 1024, "width": 1024, "inference_steps": 9, "guidance_scale": 0.0, "seed": 42, } # ============================================================================= # THEME CONFIGURATION # ============================================================================= def create_theme(): """Create the modern dark theme with purple/violet accents.""" return gr.themes.Base( primary_hue="violet", secondary_hue="purple", neutral_hue="slate", font=gr.themes.GoogleFont("Inter"), text_size="lg", spacing_size="md", radius_size="lg" ).set( # Dark mode colors body_background_fill="*neutral_950", body_background_fill_dark="*neutral_950", background_fill_primary="*neutral_900", background_fill_primary_dark="*neutral_900", background_fill_secondary="*neutral_800", background_fill_secondary_dark="*neutral_800", # Text colors body_text_color="*neutral_100", body_text_color_dark="*neutral_100", body_text_color_subdued="*neutral_400", body_text_color_subdued_dark="*neutral_400", # Border styling border_color_primary="*neutral_700", border_color_primary_dark="*neutral_700", block_border_width="1px", # Button styling button_primary_background_fill="linear-gradient(135deg, *primary_500 0%, *secondary_600 100%)", button_primary_background_fill_hover="linear-gradient(135deg, *primary_400 0%, *secondary_500 100%)", button_primary_text_color="white", button_primary_border_color="transparent", # Input styling input_background_fill="*neutral_800", input_background_fill_dark="*neutral_800", input_border_color="*neutral_600", input_border_color_dark="*neutral_600", input_border_color_focus="*primary_500", input_border_color_focus_dark="*primary_500", # Block styling block_background_fill="*neutral_900", block_background_fill_dark="*neutral_900", block_label_background_fill="*neutral_800", block_label_text_color="*neutral_200", block_title_text_weight="600", block_label_text_weight="500", # Shadow and depth shadow_drop="0 4px 20px rgba(0, 0, 0, 0.3)", shadow_drop_lg="0 8px 40px rgba(0, 0, 0, 0.4)", ) # ============================================================================= # CUSTOM CSS # ============================================================================= CUSTOM_CSS = """ /* ===== ROOT VARIABLES ===== */ :root { --accent-primary: #8b5cf6; --accent-secondary: #a855f7; --accent-glow: rgba(139, 92, 246, 0.4); --bg-dark: #0a0a0f; --bg-card: #111118; --bg-elevated: #1a1a24; --text-primary: #f1f5f9; --text-secondary: #94a3b8; --text-muted: #64748b; --border-subtle: rgba(148, 163, 184, 0.1); --border-hover: rgba(139, 92, 246, 0.3); --gradient-primary: linear-gradient(135deg, #8b5cf6 0%, #a855f7 50%, #d946ef 100%); --gradient-hero: linear-gradient(135deg, #0f0f1a 0%, #1a1025 50%, #0f0f1a 100%); } /* ===== BASE STYLES ===== */ .gradio-container { max-width: 1400px !important; margin: 0 auto !important; background: var(--bg-dark) !important; } .dark { --background-fill-primary: var(--bg-dark) !important; } /* ===== HERO SECTION ===== */ .hero-section { position: relative; padding: 3rem 2rem; text-align: center; overflow: hidden; border-radius: 20px; margin-bottom: 2rem; background: var(--gradient-hero); } .hero-background { position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: radial-gradient(ellipse at 20% 50%, rgba(139, 92, 246, 0.15) 0%, transparent 50%), radial-gradient(ellipse at 80% 50%, rgba(168, 85, 247, 0.15) 0%, transparent 50%), radial-gradient(ellipse at 50% 100%, rgba(217, 70, 239, 0.1) 0%, transparent 50%); animation: pulse-glow 8s ease-in-out infinite; } @keyframes pulse-glow { 0%, 100% { opacity: 0.7; } 50% { opacity: 1; } } .hero-content { position: relative; z-index: 1; } .logo-badge { display: inline-flex; align-items: center; justify-content: center; width: 64px; height: 64px; background: var(--gradient-primary); border-radius: 16px; margin-bottom: 1rem; box-shadow: 0 8px 32px var(--accent-glow); } .logo-icon { font-size: 2rem; font-weight: 800; color: white; font-family: 'Inter', sans-serif; } .hero-title { font-size: 3rem; font-weight: 800; margin: 0.5rem 0; background: var(--gradient-primary); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; letter-spacing: -0.02em; } .hero-subtitle { font-size: 1.1rem; color: var(--text-secondary); margin: 0.5rem 0 1.5rem; font-weight: 400; } .hero-stats { display: inline-flex; align-items: center; gap: 1.5rem; padding: 1rem 2rem; background: rgba(255, 255, 255, 0.03); border: 1px solid var(--border-subtle); border-radius: 100px; backdrop-filter: blur(10px); } .stat-item { display: flex; flex-direction: column; align-items: center; gap: 0.25rem; } .stat-value { font-size: 1.25rem; font-weight: 700; color: var(--accent-primary); } .stat-label { font-size: 0.75rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.05em; } .stat-divider { width: 1px; height: 32px; background: var(--border-subtle); } /* ===== MAIN CONTAINER ===== */ .main-container { gap: 2rem !important; } /* ===== SECTION HEADERS ===== */ .section-header { display: flex; align-items: center; gap: 0.5rem; font-size: 0.875rem; font-weight: 600; color: var(--text-secondary); text-transform: uppercase; letter-spacing: 0.08em; margin-bottom: 0.75rem; padding-left: 0.25rem; } .section-icon { font-size: 1rem; color: var(--accent-primary); } /* ===== CONTROLS COLUMN ===== */ .controls-column { padding: 0 !important; } /* ===== PROMPT INPUT ===== */ .prompt-input textarea { background: var(--bg-card) !important; border: 2px solid var(--border-subtle) !important; border-radius: 16px !important; padding: 1rem !important; font-size: 1rem !important; color: var(--text-primary) !important; transition: all 0.3s ease !important; min-height: 120px !important; } .prompt-input textarea:focus { border-color: var(--accent-primary) !important; box-shadow: 0 0 0 4px var(--accent-glow), 0 4px 20px rgba(0, 0, 0, 0.3) !important; } .prompt-input textarea::placeholder { color: var(--text-muted) !important; } /* ===== QUICK ACTIONS ===== */ .quick-actions { gap: 0.5rem !important; margin-top: 0.5rem !important; margin-bottom: 1.5rem !important; } .action-btn { flex: 1; } .action-btn button { width: 100% !important; background: var(--bg-elevated) !important; border: 1px solid var(--border-subtle) !important; color: var(--text-secondary) !important; border-radius: 10px !important; font-size: 0.875rem !important; padding: 0.5rem 1rem !important; transition: all 0.2s ease !important; } .action-btn button:hover { background: var(--bg-card) !important; border-color: var(--border-hover) !important; color: var(--text-primary) !important; } /* ===== ASPECT RATIO SELECTOR ===== */ .aspect-radio { margin-bottom: 1rem !important; } .aspect-radio .wrap { display: grid !important; grid-template-columns: repeat(4, 1fr) !important; gap: 0.5rem !important; } .aspect-radio label { display: flex !important; align-items: center !important; justify-content: center !important; padding: 0.625rem 0.5rem !important; background: var(--bg-card) !important; border: 1px solid var(--border-subtle) !important; border-radius: 10px !important; cursor: pointer !important; transition: all 0.2s ease !important; font-size: 0.75rem !important; color: var(--text-secondary) !important; text-align: center !important; } .aspect-radio label:hover { border-color: var(--border-hover) !important; background: var(--bg-elevated) !important; } .aspect-radio label.selected, .aspect-radio input:checked + label { background: var(--accent-primary) !important; border-color: var(--accent-primary) !important; color: white !important; } /* ===== DIMENSION SLIDERS ===== */ .dimension-row { gap: 1rem !important; margin-bottom: 1rem !important; } .dimension-slider { flex: 1; } .dimension-slider input[type="range"] { accent-color: var(--accent-primary) !important; } /* ===== ADVANCED ACCORDION ===== */ .advanced-accordion { margin-bottom: 1.5rem !important; } .advanced-accordion > .label-wrap { background: var(--bg-card) !important; border: 1px solid var(--border-subtle) !important; border-radius: 12px !important; padding: 0.75rem 1rem !important; } .advanced-accordion .icon { color: var(--accent-primary) !important; } /* ===== GENERATE BUTTON ===== */ .generate-btn button { width: 100% !important; background: var(--gradient-primary) !important; border: none !important; border-radius: 14px !important; padding: 1rem 2rem !important; font-size: 1.1rem !important; font-weight: 600 !important; color: white !important; cursor: pointer !important; transition: all 0.3s ease !important; box-shadow: 0 4px 20px var(--accent-glow) !important; position: relative; overflow: hidden; } .generate-btn button::before { content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent); transition: left 0.5s ease; } .generate-btn button:hover { transform: translateY(-2px) !important; box-shadow: 0 8px 32px var(--accent-glow) !important; } .generate-btn button:hover::before { left: 100%; } .generate-btn button:active { transform: translateY(0) !important; } /* ===== EXAMPLES GALLERY ===== */ #examples-gallery { margin-top: 0.5rem; } #examples-gallery .gallery { display: grid !important; grid-template-columns: repeat(2, 1fr) !important; gap: 0.5rem !important; } #examples-gallery .gallery button { background: var(--bg-card) !important; border: 1px solid var(--border-subtle) !important; border-radius: 10px !important; padding: 0.75rem !important; text-align: left !important; font-size: 0.75rem !important; color: var(--text-secondary) !important; line-height: 1.4 !important; transition: all 0.2s ease !important; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; } #examples-gallery .gallery button:hover { border-color: var(--border-hover) !important; color: var(--text-primary) !important; background: var(--bg-elevated) !important; } /* ===== OUTPUT COLUMN ===== */ .output-column { background: var(--bg-card) !important; border-radius: 20px !important; padding: 1.5rem !important; border: 1px solid var(--border-subtle) !important; } .output-image { border-radius: 16px !important; overflow: hidden !important; background: var(--bg-elevated) !important; border: 1px solid var(--border-subtle) !important; } .output-image img { border-radius: 16px !important; } .output-image .icon-buttons { background: rgba(0, 0, 0, 0.6) !important; backdrop-filter: blur(10px) !important; border-radius: 10px !important; } /* ===== IMAGE INFO BAR ===== */ .image-info-bar { margin-top: 1rem !important; padding-top: 1rem !important; border-top: 1px solid var(--border-subtle) !important; } .seed-display input { background: var(--bg-elevated) !important; border: 1px solid var(--border-subtle) !important; border-radius: 8px !important; color: var(--text-secondary) !important; font-family: 'JetBrains Mono', monospace !important; } /* ===== FOOTER ===== */ .app-footer { margin-top: 2rem; padding: 1.5rem; border-top: 1px solid var(--border-subtle); } .footer-content { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 1rem; } .footer-links { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; } .footer-link { display: inline-flex; align-items: center; gap: 0.375rem; color: var(--text-secondary); text-decoration: none; font-size: 0.875rem; transition: color 0.2s ease; } .footer-link:hover { color: var(--accent-primary); } .link-icon { font-size: 1rem; } .footer-divider { color: var(--text-muted); } .footer-text { color: var(--text-muted); font-size: 0.875rem; } .footer-badge { display: inline-block; padding: 0.375rem 0.75rem; background: var(--bg-elevated); border: 1px solid var(--border-subtle); border-radius: 100px; font-size: 0.75rem; color: var(--text-muted); } /* ===== RESPONSIVE DESIGN ===== */ @media (max-width: 768px) { .hero-section { padding: 2rem 1rem; } .hero-title { font-size: 2rem; } .hero-subtitle { font-size: 0.95rem; } .hero-stats { flex-wrap: wrap; padding: 0.75rem 1rem; gap: 1rem; } .stat-divider { display: none; } .main-container { flex-direction: column !important; } .output-column { order: -1; } .aspect-radio .wrap { grid-template-columns: repeat(2, 1fr) !important; } #examples-gallery .gallery { grid-template-columns: 1fr !important; } .footer-content { flex-direction: column; text-align: center; } } /* ===== LOADING STATE ===== */ .generating .output-image { position: relative; } .generating .output-image::after { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: linear-gradient( 90deg, transparent, rgba(139, 92, 246, 0.1), transparent ); animation: shimmer 1.5s infinite; } @keyframes shimmer { 0% { transform: translateX(-100%); } 100% { transform: translateX(100%); } } /* ===== SCROLLBAR ===== */ ::-webkit-scrollbar { width: 8px; height: 8px; } ::-webkit-scrollbar-track { background: var(--bg-dark); } ::-webkit-scrollbar-thumb { background: var(--border-subtle); border-radius: 4px; } ::-webkit-scrollbar-thumb:hover { background: var(--text-muted); } /* ===== ANIMATIONS ===== */ @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } .controls-column, .output-column { animation: fadeIn 0.5s ease-out; } .output-column { animation-delay: 0.1s; } """ # ============================================================================= # HTML TEMPLATES # ============================================================================= HERO_HTML = """
Ultra-fast AI image generation powered by state-of-the-art diffusion