# AI Image Creator: Enhanced UI and UX # Part 1: Core Setup, Model Classes and API Configuration import gradio as gr import logging import sys import random import time import os from huggingface_hub import InferenceClient from PIL import Image import io import base64 # Set up logging logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', handlers=[logging.StreamHandler(sys.stdout)] ) logger = logging.getLogger("ai_image_creator") # =============== MODEL CLIENTS SETUP =============== def setup_client(api_key, provider=None): """Initialize and return API client""" try: if provider: client = InferenceClient(provider=provider, api_key=api_key) logger.info(f"{provider} client initialized successfully") else: client = InferenceClient(api_key=api_key) logger.info("Hugging Face client initialized successfully") return client except Exception as e: logger.error(f"Error initializing client: {str(e)}") return None # Initialize clients try: # Replace with your actual HF API key hf_api_key = os.getenv("HF_API_KEY1") hf_client = setup_client(hf_api_key) logger.info("Hugging Face client created successfully") # Set up Llama client if API key is provided llama_api_key = os.getenv("HF_API_KEY2") # Replace with actual key if available try: llama_client = setup_client(llama_api_key, "sambanova") use_llama = True logger.info("Llama client created successfully") except Exception as e: logger.warning(f"Llama client not available: {str(e)}. Will use fallback enhancement.") llama_client = None use_llama = False except Exception as e: logger.error(f"Failed to create Hugging Face client: {str(e)}") hf_client = None llama_client = None use_llama = False # =============== DATA MODELS =============== # Image Models with friendly names, descriptions and icons IMAGE_MODELS = { "stabilityai/stable-diffusion-xl-base-1.0": { "display_name": "SDXL 1.0", "description": "Best overall quality, slower generation", "icon": "โญ", "speed": "slow", "quality": "excellent" }, "runwayml/stable-diffusion-v1-5": { "display_name": "SD 1.5", "description": "Good for general purpose, faster generation", "icon": "๐", "speed": "fast", "quality": "good" }, "stabilityai/stable-diffusion-2-1": { "display_name": "SD 2.1", "description": "Improved details, balanced speed and quality", "icon": "โจ", "speed": "medium", "quality": "very good" }, "prompthero/openjourney": { "display_name": "OpenJourney", "description": "Midjourney-like stylized results", "icon": "๐จ", "speed": "medium", "quality": "stylized" }, "dreamlike-art/dreamlike-diffusion-1.0": { "display_name": "Dreamlike", "description": "Artistic style with dreamy aesthetics", "icon": "๐ซ", "speed": "medium", "quality": "artistic" } } # Creation types with icons and detailed descriptions CREATION_TYPES = { "Realistic Photo": { "description": "Create a photorealistic image with natural details and lighting", "icon": "๐ท", "prompt_hint": "Try to include details about lighting, time of day, and environment" }, "Digital Art": { "description": "Create colorful digital artwork with clean lines and vibrant colors", "icon": "๐๏ธ", "prompt_hint": "Consider specifying color palette and mood for better results" }, "Fantasy Illustration": { "description": "Create magical and fantastical scenes with otherworldly elements", "icon": "๐ง", "prompt_hint": "Describe magical elements, creatures, and environments in detail" }, "Concept Art": { "description": "Create professional concept art for characters, environments or objects", "icon": "๐ฎ", "prompt_hint": "Include details about perspective, purpose, and design influences" }, "Anime/Manga": { "description": "Create Japanese anime or manga style illustration", "icon": "๐", "prompt_hint": "Specify anime aesthetics like shading style and character features" }, "Oil Painting": { "description": "Create an image with oil painting textures and artistic brushstrokes", "icon": "๐ผ๏ธ", "prompt_hint": "Consider describing texture, brushwork style, and canvas feel" }, "Watercolor": { "description": "Create a soft watercolor illustration with subtle color blending", "icon": "๐ง", "prompt_hint": "Mention color blending, paper texture, and watercolor-specific effects" }, "Sketch": { "description": "Create a detailed sketch or drawing with line art focus", "icon": "โ๏ธ", "prompt_hint": "Describe line weight, hatching style, and sketch medium (pencil, charcoal, etc.)" }, "3D Rendering": { "description": "Create an image that looks like a 3D rendered scene with realistic lighting", "icon": "๐ป", "prompt_hint": "Include details about lighting setup, materials, and camera perspective" }, "Pixel Art": { "description": "Create retro-style pixel art with limited color palette", "icon": "๐พ", "prompt_hint": "Specify resolution, color limitations, and pixel art style (e.g., 16-bit, 8-bit)" } } # Art styles with icons and detailed descriptions ART_STYLES = { "Photorealistic": { "description": "Detailed realistic style that resembles a photograph with accurate lighting and textures", "icon": "๐ธ", "examples": "Works by Chuck Close, Richard Estes, or modern 3D renderings" }, "Impressionist": { "description": "Soft brushstrokes that capture light and atmosphere over precise details, like Monet", "icon": "๐", "examples": "Claude Monet, Pierre-Auguste Renoir, Camille Pissarro" }, "Surrealist": { "description": "Dreamlike quality with impossible or irrational scenes, like Salvador Dali", "icon": "๐", "examples": "Salvador Dali, Renรฉ Magritte, Frida Kahlo" }, "Pop Art": { "description": "Bold colors, sharp lines and popular culture references, like Andy Warhol", "icon": "๐ญ", "examples": "Andy Warhol, Roy Lichtenstein, Keith Haring" }, "Minimalist": { "description": "Simplified forms, limited color palette, and clean composition with minimal elements", "icon": "โฌ", "examples": "Piet Mondrian, Kazimir Malevich, Agnes Martin" }, "Abstract": { "description": "Non-representational style using shapes, colors, and forms to express ideas", "icon": "๐ถ", "examples": "Wassily Kandinsky, Jackson Pollock, Mark Rothko" }, "Cubist": { "description": "Geometric shapes and multiple perspectives shown simultaneously, like Picasso", "icon": "๐", "examples": "Pablo Picasso, Georges Braque, Juan Gris" }, "Art Nouveau": { "description": "Ornate, flowing lines inspired by natural forms with decorative elegance", "icon": "๐ฟ", "examples": "Alphonse Mucha, Gustav Klimt, Antoni Gaudรญ" }, "Gothic": { "description": "Dark, medieval-inspired aesthetic with dramatic lighting and architectural elements", "icon": "๐ฐ", "examples": "Zdzisลaw Beksiลski, H.R. Giger, medieval architecture" }, "Cyberpunk": { "description": "Futuristic dystopian style with neon colors, technology, and urban decay", "icon": "๐ค", "examples": "Blade Runner, Ghost in the Shell, Akira" }, "Steampunk": { "description": "Victorian-era aesthetic combined with steam-powered technology and brass elements", "icon": "โ๏ธ", "examples": "Works by James Ng, Keith Thompson, retrofuturistic Jules Verne adaptations" }, "Retro/Vintage": { "description": "Nostalgic style reminiscent of past decades with period-appropriate elements", "icon": "๐บ", "examples": "1950s advertisements, vintage travel posters, pulp magazine covers" }, "Art Deco": { "description": "Geometric patterns, bold colors, and luxurious materials in a symmetrical style", "icon": "๐ข", "examples": "Works from the 1920s-30s, Chrysler Building, Tamara de Lempicka paintings" }, "Baroque": { "description": "Dramatic, ornate style with rich details, contrast, and dynamic composition", "icon": "๐", "examples": "Caravaggio, Rembrandt, Peter Paul Rubens" }, "Ukiyo-e": { "description": "Traditional Japanese woodblock print style with flat areas of color and strong outlines", "icon": "๐", "examples": "Hokusai's Great Wave, Hiroshige's landscapes, traditional Japanese prints" }, "Comic Book": { "description": "Bold outlines, bright colors, and action-oriented composition like classic comics", "icon": "๐ฅ", "examples": "Jack Kirby, Steve Ditko, modern Marvel/DC art styles" }, "Psychedelic": { "description": "Vibrant, swirling colors with abstract patterns inspired by 1960s art", "icon": "๐", "examples": "1960s concert posters, Peter Max, Alex Grey" }, "Vaporwave": { "description": "Glitch aesthetics with pastel colors, 80s/90s nostalgia and digital elements", "icon": "๐ผ", "examples": "Retrowave aesthetics, 80s digital graphics, glitch art" }, "Studio Ghibli": { "description": "Whimsical, detailed animation style inspired by Japanese animated films", "icon": "๐", "examples": "Spirited Away, My Neighbor Totoro, Howl's Moving Castle" }, "Hyperrealism": { "description": "Extremely detailed realism that exceeds photograph-like precision", "icon": "๐", "examples": "Works by Roberto Bernardi, Denis Peterson, Gottfried Helnwein" } } # Moods with icons and descriptions MOODS = { "Happy": { "description": "Bright, cheerful atmosphere with warm colors", "icon": "๐", "color_palette": "Warm and vibrant colors: yellows, bright oranges, light blues" }, "Sad": { "description": "Melancholic atmosphere with muted colors", "icon": "๐ข", "color_palette": "Muted blues, grays, desaturated colors, cool tones" }, "Mysterious": { "description": "Enigmatic atmosphere with shadows and hidden elements", "icon": "๐ฎ", "color_palette": "Deep purples, dark blues, hints of teal, selective lighting" }, "Peaceful": { "description": "Serene, calm atmosphere with gentle lighting", "icon": "๐๏ธ", "color_palette": "Soft blues, gentle greens, pastel colors, balanced light" }, "Tense": { "description": "Suspenseful atmosphere with dramatic lighting", "icon": "๐ฐ", "color_palette": "High contrast, dark shadows, selective reds, strong highlights" }, "Whimsical": { "description": "Playful, imaginative atmosphere with fanciful elements", "icon": "๐ฆ", "color_palette": "Pastels, candy colors, unexpected color combinations" }, "Dark": { "description": "Gloomy atmosphere with deep shadows and low lighting", "icon": "๐", "color_palette": "Dark blues, blacks, deep greens, minimal highlights" }, "Energetic": { "description": "Dynamic, vibrant atmosphere with strong colors and movement", "icon": "โก", "color_palette": "Saturated primary colors, bold contrasts, vibrant hues" }, "Romantic": { "description": "Soft, dreamy atmosphere with warm, gentle lighting", "icon": "โค๏ธ", "color_palette": "Soft pinks, gentle reds, golden highlights, warm tones" }, "Epic": { "description": "Grand, impressive atmosphere with dramatic scale and lighting", "icon": "๐๏ธ", "color_palette": "Bold colors, dramatic contrast, atmospheric lighting, expansive scale" } } # Example prompts with rich metadata EXAMPLE_PROMPTS = [ { "text": "A serene lake at sunset with mountains in the background and a small wooden boat floating nearby", "thumbnail_desc": "Peaceful lake scene at sunset", "creation_type": "Realistic Photo", "art_style": "Photorealistic", "mood": "Peaceful", "tags": ["nature", "landscape", "water", "sunset"] }, { "text": "A futuristic cityscape with flying cars, neon lights, and tall skyscrapers under a night sky with two moons", "thumbnail_desc": "Futuristic city with flying cars", "creation_type": "Concept Art", "art_style": "Cyberpunk", "mood": "Mysterious", "tags": ["scifi", "future", "urban", "night"] }, { "text": "A close-up portrait of an elderly craftsman with weathered hands working on an intricate wooden carving in his workshop", "thumbnail_desc": "Elderly craftsman working with wood", "creation_type": "Oil Painting", "art_style": "Hyperrealism", "mood": "Peaceful", "tags": ["portrait", "craftsmanship", "elderly", "detail"] }, { "text": "A magical forest with glowing mushrooms, fairy lights, and a small cottage with smoke coming from the chimney", "thumbnail_desc": "Magical forest with glowing elements", "creation_type": "Fantasy Illustration", "art_style": "Studio Ghibli", "mood": "Whimsical", "tags": ["fantasy", "forest", "magic", "cottage"] }, { "text": "A cybernetic samurai with glowing blue circuits standing in a rainy Tokyo street at night", "thumbnail_desc": "Cybernetic samurai in rainy Tokyo", "creation_type": "Digital Art", "art_style": "Cyberpunk", "mood": "Dark", "tags": ["character", "cyberpunk", "samurai", "rain"] }, { "text": "A cute cat with dragon wings and tiny horns sleeping on a pile of gold coins", "thumbnail_desc": "Cat with dragon features on gold", "creation_type": "Fantasy Illustration", "art_style": "Comic Book", "mood": "Whimsical", "tags": ["creature", "fantasy", "cute", "treasure"] }, { "text": "An ancient temple covered in vines and moss, partially sunken into a crystal-clear cenote in the jungle", "thumbnail_desc": "Ancient temple in jungle cenote", "creation_type": "Concept Art", "art_style": "Photorealistic", "mood": "Mysterious", "tags": ["architecture", "ruins", "jungle", "water"] }, { "text": "A cozy coffee shop interior with rain falling outside the windows, soft lighting, and a few people reading books", "thumbnail_desc": "Cozy rainy day in coffee shop", "creation_type": "Digital Art", "art_style": "Impressionist", "mood": "Peaceful", "tags": ["interior", "rainy", "cozy", "urban"] } ] # CSS for enhanced UI styling - Will be included in part 2 # =============== HELPER FUNCTIONS =============== # Helper function to format dropdown choices with icons def format_dropdown_choices(options_dict): return [f"{options_dict[key].get('icon', 'โข')} {key}" for key in options_dict.keys()] # Helper function to extract the key from formatted choice def extract_key(formatted_choice): # Skip the icon and space at the beginning parts = formatted_choice.split(' ', 1) if len(parts) > 1: return parts[1] return formatted_choice # Function to load example prompt def load_example(example_index): if example_index < 0 or example_index >= len(EXAMPLE_PROMPTS): return "", "", "", "" example = EXAMPLE_PROMPTS[example_index] creation = f"{CREATION_TYPES[example['creation_type']]['icon']} {example['creation_type']}" art = f"{ART_STYLES[example['art_style']]['icon']} {example['art_style']}" mood = f"{MOODS[example['mood']]['icon']} {example['mood']}" return example["text"], creation, art, mood # Get model key from formatted display name def get_model_key(formatted_name): # Extract display name without the icon if ' ' in formatted_name: display_name = formatted_name.split(' ', 1)[1] # Find the corresponding key for key, info in IMAGE_MODELS.items(): if info['display_name'] == display_name: return key return list(IMAGE_MODELS.keys())[0] # Default to first model if not found # AI Image Creator: Enhanced UI and UX # Part 2: Enhanced UI Components and Styling # CSS for styling the interface - Comprehensive styling for modern UI css = """ /* Main theme colors with CSS variables for better customization */ :root { --primary-color: #4F46E5; --primary-hover: #4338CA; --secondary-color: #7C3AED; --secondary-hover: #6D28D9; --background-color: #F8FAFC; --card-color: #FFFFFF; --text-color: #1E293B; --text-muted: #64748B; --accent-color: #3B82F6; --success-color: #10B981; --success-hover: #059669; --warning-color: #F59E0B; --error-color: #EF4444; --error-hover: #DC2626; --border-color: #E2E8F0; --border-hover: #CBD5E1; --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05); --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); --radius-sm: 0.375rem; --radius: 0.5rem; --radius-lg: 0.75rem; --radius-xl: 1rem; --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; } /* Global styles and resets */ body, html { font-family: var(--font-sans); color: var(--text-color); background-color: var(--background-color); line-height: 1.5; margin: 0; padding: 0; } /* Container with responsive padding */ .container { max-width: 1400px; margin: 0 auto; padding: 1rem; } @media (max-width: 640px) { .container { padding: 0.5rem; } } /* Card styling with elevation and hover effects */ .gr-panel { border-radius: var(--radius) !important; border: 1px solid var(--border-color) !important; box-shadow: var(--shadow) !important; overflow: hidden; transition: transform 0.2s, box-shadow 0.2s; background-color: var(--card-color) !important; } .gr-panel:hover { transform: translateY(-2px); box-shadow: var(--shadow-lg) !important; } /* Button styling with gradient and hover states */ button.primary { background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)) !important; color: white !important; border: none !important; border-radius: var(--radius) !important; font-weight: 600 !important; letter-spacing: 0.025em !important; padding: 0.75rem 1.5rem !important; transition: all 0.3s ease !important; box-shadow: var(--shadow-sm) !important; outline: none !important; text-transform: none !important; } button.primary:hover { transform: translateY(-1px); box-shadow: var(--shadow) !important; opacity: 0.9; } button.primary:active { transform: translateY(0); opacity: 0.8; } button.primary[disabled], button.primary[disabled]:hover { opacity: 0.5; cursor: not-allowed; transform: none; } /* Secondary button styling */ button.secondary { background-color: transparent !important; color: var(--primary-color) !important; border: 1px solid var(--primary-color) !important; border-radius: var(--radius) !important; font-weight: 500 !important; padding: 0.625rem 1.25rem !important; transition: all 0.2s ease !important; text-transform: none !important; } button.secondary:hover { background-color: rgba(79, 70, 229, 0.05) !important; border-color: var(--primary-hover) !important; } /* Style for the example buttons */ .example-button { font-size: 0.875rem !important; padding: 0.5rem 0.75rem !important; background-color: transparent !important; border: 1px solid var(--border-color) !important; border-radius: var(--radius) !important; transition: all 0.2s !important; text-align: left !important; justify-content: flex-start !important; height: auto !important; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; width: 100%; color: var(--text-color) !important; } .example-button:hover { background-color: rgba(79, 70, 229, 0.05) !important; border-color: var(--primary-color) !important; transform: translateY(-1px); } /* Form controls styling */ .gr-input, .gr-textarea, .gr-dropdown { border-radius: var(--radius) !important; border: 1px solid var(--border-color) !important; transition: border-color 0.2s, box-shadow 0.2s !important; font-family: var(--font-sans) !important; color: var(--text-color) !important; } .gr-input:focus, .gr-textarea:focus, .gr-dropdown:focus-within { border-color: var(--primary-color) !important; box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.2) !important; outline: none !important; } .gr-form { gap: 1rem !important; } .gr-input-label, .gr-dropdown-label, .gr-textarea-label, .gr-checkbox-label, .gr-radio-label { font-size: 0.875rem !important; font-weight: 500 !important; color: var(--text-color) !important; margin-bottom: 0.25rem !important; } /* Input placeholder styling */ .gr-input::placeholder, .gr-textarea::placeholder { color: var(--text-muted) !important; opacity: 0.7; } /* Input and textarea styling */ textarea, input[type="text"] { border-radius: var(--radius) !important; border: 1px solid var(--border-color) !important; padding: 0.75rem 1rem !important; transition: border-color 0.2s, box-shadow 0.2s !important; font-family: var(--font-sans) !important; } textarea:focus, input[type="text"]:focus { border-color: var(--primary-color) !important; box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.2) !important; outline: none !important; } /* Dropdown styling */ .gr-dropdown { border-radius: var(--radius) !important; border: 1px solid var(--border-color) !important; background-color: var(--card-color) !important; } .gr-dropdown > div { border-radius: var(--radius) !important; min-height: 38px !important; } .gr-dropdown > div > span { font-size: 0.9375rem !important; } /* Dropdown menu styling */ .gr-dropdown ul { background-color: var(--card-color) !important; border: 1px solid var(--border-color) !important; border-radius: var(--radius) !important; box-shadow: var(--shadow) !important; } .gr-dropdown ul li { padding: 0.5rem 0.75rem !important; } .gr-dropdown ul li:hover { background-color: rgba(79, 70, 229, 0.05) !important; } /* Custom header with gradient background */ .app-header { text-align: center; padding: 1.75rem 1rem; margin-bottom: 2rem; background: linear-gradient(135deg, rgba(79, 70, 229, 0.08), rgba(124, 58, 237, 0.08)); border-radius: var(--radius-lg); border-bottom: 3px solid var(--primary-color); position: relative; overflow: hidden; } .app-header::before { content: ''; position: absolute; top: -50px; left: -50px; right: -50px; height: 100px; background: linear-gradient(135deg, rgba(79, 70, 229, 0.2), rgba(124, 58, 237, 0.2)); transform: rotate(-5deg); z-index: 0; } .app-header h1 { font-size: 2.5rem !important; font-weight: 800 !important; background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); -webkit-background-clip: text; -webkit-text-fill-color: transparent; margin-bottom: 0.5rem !important; position: relative; z-index: 1; } .app-header p { font-size: 1.25rem !important; color: var(--text-color); opacity: 0.8; max-width: 40rem; margin: 0 auto; position: relative; z-index: 1; } /* Responsive header */ @media (max-width: 640px) { .app-header h1 { font-size: 2rem !important; } .app-header p { font-size: 1rem !important; } } /* Examples gallery with grid layout */ .example-gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 1rem; margin: 1rem 0; } .example-item { border-radius: var(--radius); overflow: hidden; cursor: pointer; border: 2px solid transparent; transition: all 0.2s; display: flex; flex-direction: column; background-color: var(--card-color); } .example-item:hover { transform: translateY(-2px); border-color: var(--accent-color); box-shadow: var(--shadow); } .example-item:active { transform: translateY(0); } .example-item-image { width: 100%; aspect-ratio: 1; background-color: #f0f0f0; display: flex; align-items: center; justify-content: center; color: var(--text-muted); font-size: 1.5rem; border-bottom: 1px solid var(--border-color); } .example-item-caption { padding: 0.5rem; font-size: 0.75rem; line-height: 1.25; color: var(--text-color); overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; } /* Loading indicator with animation */ .loading-indicator { display: flex; align-items: center; justify-content: center; height: 100%; width: 100%; position: absolute; top: 0; left: 0; background-color: rgba(255, 255, 255, 0.8); z-index: 1000; backdrop-filter: blur(2px); border-radius: var(--radius); } .spinner { width: 40px; height: 40px; border: 4px solid rgba(79, 70, 229, 0.2); border-radius: 50%; border-top-color: var(--primary-color); animation: spin 1s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } /* Info cards with subtle styling */ .info-card { background-color: var(--card-color); border-radius: var(--radius); padding: 1rem; border: 1px solid var(--border-color); margin-bottom: 1rem; transition: all 0.2s; } .info-card:hover { border-color: var(--border-hover); box-shadow: var(--shadow-sm); } .info-card h3 { margin-top: 0; margin-bottom: 0.5rem; font-size: 1rem; font-weight: 600; color: var(--primary-color); display: flex; align-items: center; gap: 0.5rem; } .info-card p { margin: 0; font-size: 0.875rem; color: var(--text-muted); line-height: 1.5; } /* Model info panel with branded styling */ .model-info { background-color: rgba(79, 70, 229, 0.05); border-left: 3px solid var(--primary-color); padding: 0.75rem 1rem; border-radius: 0 var(--radius) var(--radius) 0; margin: 1rem 0; } .model-info h3 { display: flex; align-items: center; gap: 0.5rem; margin-top: 0; margin-bottom: 0.5rem; font-size: 1rem; font-weight: 600; color: var(--primary-color); } .model-info p { margin: 0 0 0.5rem 0; font-size: 0.875rem; color: var(--text-color); } .model-info .model-id { font-size: 0.75rem; color: var(--text-muted); font-family: monospace; background-color: rgba(0, 0, 0, 0.03); padding: 0.25rem 0.5rem; border-radius: 4px; margin-top: 0.5rem; word-break: break-all; } /* Parameter pills for displaying selections */ .parameter-pill { display: inline-flex; align-items: center; background-color: rgba(79, 70, 229, 0.1); color: var(--primary-color); border-radius: 16px; padding: 0.25rem 0.75rem; margin-right: 0.5rem; margin-bottom: 0.5rem; font-size: 0.75rem; font-weight: 500; user-select: none; } .parameter-pill .icon { margin-right: 0.25rem; } /* Badge for showing model speed/quality */ .badge { display: inline-flex; align-items: center; justify-content: center; border-radius: 9999px; padding: 0.125rem 0.5rem; font-size: 0.75rem; font-weight: 500; margin-left: 0.5rem; } .badge-success { background-color: rgba(16, 185, 129, 0.1); color: var(--success-color); } .badge-warning { background-color: rgba(245, 158, 11, 0.1); color: var(--warning-color); } .badge-error { background-color: rgba(239, 68, 68, 0.1); color: var(--error-color); } .badge-info { background-color: rgba(59, 130, 246, 0.1); color: var(--accent-color); } /* Enhanced accordion styling */ .gr-accordion { border: 1px solid var(--border-color) !important; border-radius: var(--radius) !important; margin-bottom: 1rem !important; overflow: hidden; } .gr-accordion > div:first-child { padding: 0.75rem 1rem !important; background-color: rgba(0, 0, 0, 0.02) !important; font-weight: 600 !important; color: var(--text-color) !important; font-size: 0.9375rem !important; } .gr-accordion > div:last-child { padding: 1rem !important; } /* Tooltip styling */ .tooltip { position: relative; display: inline-block; cursor: help; } .tooltip .tooltiptext { visibility: hidden; width: 200px; background-color: var(--text-color); color: white; text-align: center; border-radius: var(--radius-sm); padding: 0.5rem 0.75rem; position: absolute; z-index: 1000; bottom: 125%; left: 50%; transform: translateX(-50%); opacity: 0; transition: opacity 0.3s; font-size: 0.75rem; box-shadow: var(--shadow); pointer-events: none; } .tooltip .tooltiptext::after { content: ""; position: absolute; top: 100%; left: 50%; margin-left: -5px; border-width: 5px; border-style: solid; border-color: var(--text-color) transparent transparent transparent; } .tooltip:hover .tooltiptext { visibility: visible; opacity: 1; } /* History item styling */ .history-item { display: flex; align-items: center; padding: 0.75rem; border-radius: var(--radius); margin-bottom: 0.75rem; background-color: var(--card-color); border: 1px solid var(--border-color); cursor: pointer; transition: all 0.2s; } .history-item:hover { background-color: rgba(79, 70, 229, 0.05); transform: translateY(-1px); } .history-item-image { width: 48px; height: 48px; border-radius: var(--radius-sm); object-fit: cover; margin-right: 0.75rem; background-color: #f0f0f0; display: flex; align-items: center; justify-content: center; color: var(--text-muted); font-size: 1.25rem; } .history-item-content { flex: 1; overflow: hidden; } .history-item-title { margin: 0; font-size: 0.875rem; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--text-color); } .history-item-subtitle { margin: 0; font-size: 0.75rem; color: var(--text-muted); margin-top: 0.25rem; } /* Tabs styling */ .tabs { display: flex; border-bottom: 1px solid var(--border-color); margin-bottom: 1rem; } .tab { padding: 0.75rem 1rem; cursor: pointer; border-bottom: 2px solid transparent; font-weight: 500; font-size: 0.9375rem; color: var(--text-muted); transition: all 0.2s; } .tab:hover { color: var(--primary-color); } .tab.active { color: var(--primary-color); border-bottom-color: var(--primary-color); } /* Progress bar */ .progress-container { width: 100%; height: 8px; background-color: rgba(79, 70, 229, 0.1); border-radius: 4px; overflow: hidden; margin: 0.5rem 0; } .progress-bar { height: 100%; background: linear-gradient(to right, var(--primary-color), var(--secondary-color)); width: 0%; transition: width 0.3s ease; border-radius: 4px; } /* Image output container */ .image-output-container { position: relative; border-radius: var(--radius); overflow: hidden; transition: all 0.2s; background-color: #f5f5f5; min-height: 300px; } .image-output-container img { width: 100%; display: block; border-radius: var(--radius); } .image-placeholder { position: absolute; top: 0; left: 0; width: 100%; height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; color: var(--text-muted); font-size: 1rem; text-align: center; padding: 1rem; } .image-placeholder .icon { font-size: 3rem; margin-bottom: 1rem; opacity: 0.6; } /* Image controls overlay */ .image-controls { position: absolute; bottom: 0; left: 0; right: 0; padding: 0.75rem; background: linear-gradient(to top, rgba(0,0,0,0.7), rgba(0,0,0,0)); display: flex; justify-content: flex-end; opacity: 0; transition: opacity 0.2s; } .image-output-container:hover .image-controls { opacity: 1; } .image-control-button { background-color: rgba(255, 255, 255, 0.9); border: none; border-radius: 50%; width: 36px; height: 36px; display: flex; align-items: center; justify-content: center; cursor: pointer; margin-left: 0.5rem; color: var(--text-color); transition: all 0.2s; } .image-control-button:hover { background-color: white; transform: translateY(-2px); box-shadow: var(--shadow); } /* Character counter */ .character-counter { text-align: right; font-size: 0.75rem; color: var(--text-muted); margin-top: 0.25rem; transition: color 0.2s; } .character-counter.warning { color: var(--warning-color); } .character-counter.error { color: var(--error-color); } /* Status message */ .status-message { padding: 0.75rem 1rem; border-radius: var(--radius); margin: 1rem 0; font-size: 0.875rem; display: flex; align-items: center; } .status-message .icon { margin-right: 0.75rem; font-size: 1.25rem; } .status-success { background-color: rgba(16, 185, 129, 0.1); color: var(--success-color); border-left: 3px solid var(--success-color); } .status-error { background-color: rgba(239, 68, 68, 0.1); color: var(--error-color); border-left: 3px solid var(--error-color); } .status-warning { background-color: rgba(245, 158, 11, 0.1); color: var(--warning-color); border-left: 3px solid var(--warning-color); } .status-info { background-color: rgba(59, 130, 246, 0.1); color: var(--accent-color); border-left: 3px solid var(--accent-color); } /* Responsive adjustments */ @media (max-width: 768px) { .example-gallery { grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); } .gr-panel { padding: 0.75rem !important; } .gr-accordion > div:first-child { padding: 0.625rem 0.75rem !important; } .gr-accordion > div:last-child { padding: 0.75rem !important; } button.primary { padding: 0.625rem 1.25rem !important; } } """ # =============== ENHANCED UI COMPONENTS =============== # Function to create and show application UI def create_ui(): with gr.Blocks(title="", css=css) as interface: # Custom header with branding with gr.Row(elem_classes="app-header"): with gr.Column(): gr.HTML("""
Capture the magic of your imagination and watch it come to life.๐ช
""") # Main content area with gr.Row(equal_height=False): # Left column - Input controls with gr.Column(scale=1, min_width=380): # Description input with character counter with gr.Group(elem_classes="input-group"): description_input = gr.Textbox( label="Describe what you want to see", placeholder="Be detailed and specific about colors, composition, lighting, and subject...", lines=4, max_lines=8, elem_id="description-input" ) # Character counter with dynamic updates char_counter = gr.HTML( value="Images are generated using Stable Diffusion, a latent text-to-image diffusion model. Your text prompt is:
Different models have different strengths:
{info['description']}
๐ก {info['prompt_hint']}
{info['description']}
๐จ Examples: {info['examples']}
{info['description']}