diff --git "a/auto_diffusers/ui/gradio_interface.py" "b/auto_diffusers/ui/gradio_interface.py" new file mode 100644--- /dev/null +++ "b/auto_diffusers/ui/gradio_interface.py" @@ -0,0 +1,2680 @@ +import os +import logging +import argparse +import gradio as gr +from dotenv import load_dotenv +import google.generativeai as genai +from ..core.generator import AutoDiffusersGenerator +from ..hardware.memory_calculator import SimpleMemoryCalculator +from ..hardware.detector import HardwareDetector + +load_dotenv() + +# Configure logging for Gradio app +logger = logging.getLogger(__name__) + +class GradioAutodiffusers: + def __init__(self): + logger.info("Initializing GradioAutodiffusers") + + self.api_key = os.getenv('GOOGLE_API_KEY') + if not self.api_key: + logger.error("GOOGLE_API_KEY not found in environment variables") + raise ValueError("GOOGLE_API_KEY not found in .env file") + + logger.debug(f"API key found, length: {len(self.api_key)}") + + try: + self.generator = AutoDiffusersGenerator(self.api_key) + logger.info("AutoDiffusersGenerator initialized successfully") + except Exception as e: + logger.error(f"Failed to initialize AutoDiffusersGenerator: {e}") + raise + + try: + self.memory_calculator = SimpleMemoryCalculator() + logger.info("SimpleMemoryCalculator initialized successfully") + except Exception as e: + logger.error(f"Failed to initialize SimpleMemoryCalculator: {e}") + raise + + # Default settings + self.current_model = 'gemini-2.5-flash-preview-05-20' + self.temperature = 0.7 + self.max_output_tokens = 8192 + self.top_p = 0.9 + self.top_k = 40 + + logger.debug(f"Default model settings: {self.current_model}, temp={self.temperature}") + + def update_model_settings(self, model_name, temperature, max_output_tokens, top_p, top_k): + """Update Gemini model settings.""" + logger.info(f"Updating model settings: {model_name}") + logger.debug(f"New settings: temp={temperature}, max_tokens={max_output_tokens}, top_p={top_p}, top_k={top_k}") + + try: + self.current_model = model_name + self.temperature = temperature + self.max_output_tokens = max_output_tokens + self.top_p = top_p + self.top_k = top_k + + # Update the generator's model with new settings + genai.configure(api_key=self.api_key) + generation_config = genai.types.GenerationConfig( + temperature=temperature, + max_output_tokens=max_output_tokens, + top_p=top_p, + top_k=top_k + ) + self.generator.model = genai.GenerativeModel(model_name, generation_config=generation_config) + + logger.info("Model settings updated successfully") + return f"✅ Model updated to {model_name} with new settings" + + except Exception as e: + logger.error(f"Failed to update model settings: {e}") + return f"❌ Failed to update model: {str(e)}" + + def get_generation_prompt(self, model_name, prompt_text, image_size, num_inference_steps, hardware_specs, optimization_profile): + """Get the actual prompt that will be sent to Gemini API.""" + return self.generator._create_generation_prompt( + model_name, prompt_text, image_size, num_inference_steps, + hardware_specs, optimization_profile + ) + + def analyze_model_memory(self, model_name, vram_gb): + """Analyze model memory requirements and provide recommendations.""" + try: + if not vram_gb: + vram_gb = 8 # Default + + memory_info = self.memory_calculator.get_model_memory_requirements(model_name) + recommendations = self.memory_calculator.get_memory_recommendation(model_name, float(vram_gb)) + formatted_info = self.memory_calculator.format_memory_info(model_name) + + return memory_info, recommendations, formatted_info + + except Exception as e: + error_msg = f"Error analyzing model memory: {str(e)}" + return {'error': error_msg}, {'error': error_msg}, error_msg + + def generate_code_with_manual_specs(self, + gpu_name, + vram_gb, + ram_gb, + platform, + model_name, + prompt_text, + dtype_selection, + width, + height, + inference_steps, + memory_analysis=None): + """Generate optimized code with manual hardware specifications.""" + + try: + # Create manual hardware specs + # Parse dtype selection + if dtype_selection == "Auto": + user_dtype = None + else: + user_dtype = f"torch.{dtype_selection}" + + manual_specs = { + 'platform': platform, + 'architecture': 'manual_input', + 'cpu_count': 8, # Default + 'python_version': '3.11', + 'cuda_available': 'nvidia' in gpu_name.lower() if gpu_name else False, + 'mps_available': platform == 'Darwin' and 'apple' in gpu_name.lower() if gpu_name else False, + 'torch_version': '2.0+', + 'manual_input': True, + 'ram_gb': int(ram_gb) if ram_gb else 16, + 'user_dtype': user_dtype + } + + # Add GPU info if provided + if gpu_name and vram_gb: + manual_specs['gpu_info'] = [{ + 'name': gpu_name, + 'memory_mb': int(vram_gb) * 1024 + }] + + if 'nvidia' in gpu_name.lower(): + manual_specs['cuda_available'] = True + manual_specs['cuda_device_count'] = 1 + manual_specs['cuda_device_name'] = gpu_name + manual_specs['cuda_memory'] = int(vram_gb) + else: + manual_specs['gpu_info'] = None + + # Generate optimized code with manual specs and memory analysis + optimized_code = self.generator.generate_optimized_code( + model_name=model_name, + prompt_text=prompt_text, + image_size=(int(height), int(width)), + num_inference_steps=int(inference_steps), + use_manual_specs=True, + manual_specs=manual_specs, + memory_analysis=memory_analysis + ) + + # Clean up any markdown formatting + if optimized_code.startswith('```python'): + optimized_code = optimized_code[9:] + if optimized_code.endswith('```'): + optimized_code = optimized_code[:-3] + + return optimized_code.strip() + + except Exception as e: + return f"Error generating code: {str(e)}" + + +def create_gradio_interface(auto_hardware_detection=False): + """Create and configure the Gradio interface. + + Args: + auto_hardware_detection (bool): Whether to enable automatic hardware detection on startup + """ + + app = GradioAutodiffusers() + + with gr.Blocks( + title="Auto-Diffusers Code Generator", + theme=gr.themes.Soft( + primary_hue="violet", + secondary_hue="blue", + neutral_hue="slate", + radius_size=gr.themes.sizes.radius_lg, + font=[gr.themes.GoogleFont("Poppins"), gr.themes.GoogleFont("Inter"), "system-ui", "sans-serif"] + ).set( + background_fill_primary="*neutral_25", + background_fill_secondary="*neutral_50", + block_background_fill="rgba(255, 255, 255, 0.95)", + block_border_width="0px", + block_shadow="0 8px 32px rgba(0, 0, 0, 0.08)", + panel_background_fill="rgba(255, 255, 255, 0.9)", + button_primary_background_fill="*primary_500", + button_primary_background_fill_hover="*primary_600", + button_secondary_background_fill="rgba(255, 255, 255, 0.8)", + button_secondary_background_fill_hover="rgba(255, 255, 255, 0.95)" + ), + css=""" + /* Global Styles */ + .gradio-container { + background: #fef7f5 !important; + min-height: 100vh; + font-family: 'Georgia', 'Times New Roman', serif !important; + } + + /* Dark mode global background */ + @media (prefers-color-scheme: dark) { + .gradio-container { + background: #1a1a1a !important; + } + } + + .dark, + .gradio-container.dark, + html.dark, + body.dark { + background: #1a1a1a !important; + } + + .dark .gradio-container, + .gradio-container.dark, + html.dark .gradio-container, + body.dark .gradio-container { + background: #1a1a1a !important; + } + + /* Remove main tag margin and center */ + main { + margin: 0 auto !important; + max-width: 100% !important; + } + + .main-container { + max-width: 1400px; + margin: 0 auto; + padding: 0.5rem 0.1rem; + /* Removed position: relative that can interfere with dropdown positioning */ + } + + + /* Paper Card Effects */ + .glass-card { + background: #fefcfa !important; + border: 1px solid #f4e6e1 !important; + border-radius: 12px !important; + margin-bottom: 0.5rem !important; + padding: 0.5rem !important; + border-top: 3px solid #f0c5b8 !important; + } + + .ultra-glass { + background: #fefcfa !important; + border: 1px solid #f4e6e1 !important; + border-radius: 12px !important; + margin-bottom: 0.5rem !important; + padding: 0.5rem !important; + border-left: 4px solid #f0c5b8 !important; + } + + /* Dark mode group cards */ + @media (prefers-color-scheme: dark) { + .glass-card { + background: #2a2a2a !important; + border: 1px solid #404040 !important; + border-top: 3px solid #666 !important; + } + + .ultra-glass { + background: #2a2a2a !important; + border: 1px solid #404040 !important; + border-left: 4px solid #666 !important; + } + } + + .dark .glass-card, + .gradio-container.dark .glass-card, + html.dark .glass-card, + body.dark .glass-card { + background: #2a2a2a !important; + border: 1px solid #404040 !important; + border-top: 3px solid #666 !important; + } + + .dark .ultra-glass, + .gradio-container.dark .ultra-glass, + html.dark .ultra-glass, + body.dark .ultra-glass { + background: #2a2a2a !important; + border: 1px solid #404040 !important; + border-left: 4px solid #666 !important; + } + + /* Paper Header */ + .hero-header { + background: #fdf5f3 !important; + border: 2px solid #f4e6e1 !important; + border-radius: 16px !important; + margin-bottom: 1rem !important; + position: relative; + overflow: hidden; + width: 100% !important; + max-width: 100% !important; + box-sizing: border-box !important; + } + + /* Dark mode hero header */ + @media (prefers-color-scheme: dark) { + .hero-header { + background: #2a2a2a !important; + border: 2px solid #404040 !important; + } + } + + .dark .hero-header, + .gradio-container.dark .hero-header, + html.dark .hero-header, + body.dark .hero-header { + background: #2a2a2a !important; + border: 2px solid #404040 !important; + } + + /* Dark mode hero header text */ + @media (prefers-color-scheme: dark) { + .hero-header h1 { + color: #e5e5e5 !important; + } + + .hero-header h2 { + color: #b3b3b3 !important; + } + + .hero-header span { + background: #2a2a2a !important; + color: #e5e5e5 !important; + border: 1px solid #404040 !important; + } + } + + .dark .hero-header h1, + .gradio-container.dark .hero-header h1, + html.dark .hero-header h1, + body.dark .hero-header h1 { + color: #e5e5e5 !important; + } + + .dark .hero-header h2, + .gradio-container.dark .hero-header h2, + html.dark .hero-header h2, + body.dark .hero-header h2 { + color: #b3b3b3 !important; + } + + .dark .hero-header span, + .gradio-container.dark .hero-header span, + html.dark .hero-header span, + body.dark .hero-header span { + background: #2a2a2a !important; + color: #e5e5e5 !important; + border: 1px solid #404040 !important; + } + + + /* Paper Buttons */ + .generate-btn { + background: #e67e5a !important; + border: 2px solid #d96b47 !important; + color: #fefcfa !important; + font-weight: 600 !important; + font-size: 1.3rem !important; + padding: 1.2rem 2.5rem !important; + border-radius: 12px !important; + transition: all 0.3s ease !important; + font-family: 'Georgia', serif !important; + letter-spacing: 0.5px !important; + } + + /* View Prompt Button */ + .view-prompt-btn { + background: #f4e6e1 !important; + border: 1px solid #e8a491 !important; + color: #5a3a2a !important; + font-weight: 500 !important; + font-size: 0.9rem !important; + padding: 0.5rem 1rem !important; + border-radius: 8px !important; + transition: all 0.2s ease !important; + font-family: 'Georgia', serif !important; + margin-bottom: 0.5rem !important; + } + + .view-prompt-btn:hover { + background: #f0c5b8 !important; + } + + /* Modal Overlay - simple approach */ + .modal-overlay { + position: fixed !important; + top: 0 !important; + left: 0 !important; + width: 100vw !important; + height: 100vh !important; + background: rgba(0, 0, 0, 0.5) !important; + z-index: 9999 !important; + justify-content: center !important; + align-items: center !important; + padding: 2rem !important; + box-sizing: border-box !important; + } + + /* Show as flex only when visible class is present */ + .modal-overlay.visible { + display: flex !important; + } + + /* Modal Content - with dark mode support */ + .modal-content { + background: #fefcfa !important; + border: 2px solid #f0c5b8 !important; + border-radius: 16px !important; + max-width: 90vw !important; + max-height: 80vh !important; + width: 800px !important; + padding: 2rem !important; + box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5) !important; + overflow: hidden !important; + flex-direction: column !important; + color: #2d3748 !important; + } + + /* Modal Header */ + .modal-header { + justify-content: space-between !important; + align-items: center !important; + margin-bottom: 1rem !important; + padding-bottom: 1rem !important; + border-bottom: 1px solid #f0c5b8 !important; + } + + .modal-header h3 { + color: #2d3748 !important; + margin: 0 !important; + } + + /* Modal Close Button */ + .modal-close-btn { + background: #f4e6e1 !important; + border: 1px solid #e8a491 !important; + color: #5a3a2a !important; + font-weight: 700 !important; + font-size: 1.2rem !important; + padding: 0.4rem 0.6rem !important; + border-radius: 6px !important; + min-width: 2rem !important; + height: 2rem !important; + align-items: center !important; + justify-content: center !important; + } + + .modal-close-btn:hover { + background: #f0c5b8 !important; + } + + /* Prompt Container */ + .prompt-container { + background: #fcf3f0 !important; + border: 1px solid #f0c5b8 !important; + border-radius: 8px !important; + max-height: 400px !important; + overflow-y: auto !important; + flex: 1 !important; + } + + /* Dark mode overrides for system dark mode */ + @media (prefers-color-scheme: dark) { + .modal-content { + background: #1a1a1a !important; + border: 2px solid #404040 !important; + color: #e5e5e5 !important; + } + + .modal-header { + border-bottom: 1px solid #404040 !important; + } + + .modal-header h3 { + color: #e5e5e5 !important; + } + + .modal-close-btn { + background: #404040 !important; + border: 1px solid #666 !important; + color: #e5e5e5 !important; + } + + .modal-close-btn:hover { + background: #555 !important; + } + + .prompt-container { + background: #2a2a2a !important; + border: 1px solid #404040 !important; + } + } + + /* Gradio dark mode overrides */ + .dark .modal-content, + .gradio-container.dark .modal-content, + html.dark .modal-content, + body.dark .modal-content { + background: #1a1a1a !important; + border: 2px solid #404040 !important; + color: #e5e5e5 !important; + } + + .dark .modal-header, + .gradio-container.dark .modal-header, + html.dark .modal-header, + body.dark .modal-header { + border-bottom: 1px solid #404040 !important; + } + + .dark .modal-header h3, + .gradio-container.dark .modal-header h3, + html.dark .modal-header h3, + body.dark .modal-header h3 { + color: #e5e5e5 !important; + } + + .dark .modal-close-btn, + .gradio-container.dark .modal-close-btn, + html.dark .modal-close-btn, + body.dark .modal-close-btn { + background: #404040 !important; + border: 1px solid #666 !important; + color: #e5e5e5 !important; + } + + .dark .modal-close-btn:hover, + .gradio-container.dark .modal-close-btn:hover, + html.dark .modal-close-btn:hover, + body.dark .modal-close-btn:hover { + background: #555 !important; + } + + .dark .prompt-container, + .gradio-container.dark .prompt-container, + html.dark .prompt-container, + body.dark .prompt-container { + background: #2a2a2a !important; + border: 1px solid #404040 !important; + } + + + + .generate-btn:hover { + background: #d96b47 !important; + transform: translateY(-1px) !important; + } + + .generate-btn:active { + transform: translateY(0px) !important; + } + + /* Paper Section Headers */ + .section-header { + background: #f9f0ec !important; + border: 1px solid #f0c5b8 !important; + border-radius: 8px !important; + padding: 0.7rem !important; + margin-bottom: 0.5rem !important; + } + + /* Dark mode section headers */ + @media (prefers-color-scheme: dark) { + .section-header { + background: #333333 !important; + border: 1px solid #555 !important; + } + } + + .dark .section-header, + .gradio-container.dark .section-header, + html.dark .section-header, + body.dark .section-header { + background: #333333 !important; + border: 1px solid #555 !important; + } + + /* Dark mode section header text */ + @media (prefers-color-scheme: dark) { + .section-header p { + color: #f0f0f0 !important; + } + } + + .dark .section-header p, + .gradio-container.dark .section-header p, + html.dark .section-header p, + body.dark .section-header p { + color: #f0f0f0 !important; + } + + /* Paper Inputs */ + input[type="text"], + input[type="number"], + textarea { + background: #fefcfa !important; + border: 2px solid #f4e6e1 !important; + border-radius: 8px !important; + padding: 0.8rem 1.2rem !important; + font-weight: 500 !important; + color: #5a3a2a !important; + font-family: 'Georgia', serif !important; + font-size: 1rem !important; + } + + input[type="text"]:focus, + input[type="number"]:focus, + textarea:focus { + background: #fefcfa !important; + border-color: #e8a491 !important; + outline: none !important; + } + + /* Dark mode inputs */ + @media (prefers-color-scheme: dark) { + input[type="text"], + input[type="number"], + textarea { + background: #2a2a2a !important; + border: 2px solid #404040 !important; + color: #e5e5e5 !important; + } + + input[type="text"]:focus, + input[type="number"]:focus, + textarea:focus { + background: #2a2a2a !important; + border-color: #666 !important; + } + } + + .dark input[type="text"], + .dark input[type="number"], + .dark textarea, + .gradio-container.dark input[type="text"], + .gradio-container.dark input[type="number"], + .gradio-container.dark textarea, + html.dark input[type="text"], + html.dark input[type="number"], + html.dark textarea, + body.dark input[type="text"], + body.dark input[type="number"], + body.dark textarea { + background: #2a2a2a !important; + border: 2px solid #404040 !important; + color: #e5e5e5 !important; + } + + .dark input[type="text"]:focus, + .dark input[type="number"]:focus, + .dark textarea:focus, + .gradio-container.dark input[type="text"]:focus, + .gradio-container.dark input[type="number"]:focus, + .gradio-container.dark textarea:focus, + html.dark input[type="text"]:focus, + html.dark input[type="number"]:focus, + html.dark textarea:focus, + body.dark input[type="text"]:focus, + body.dark input[type="number"]:focus, + body.dark textarea:focus { + background: #2a2a2a !important; + border-color: #666 !important; + } + + /* CRITICAL: Reset all problematic CSS for dropdowns */ + label:has(+ [data-testid="dropdown"]), + div:has([data-testid="dropdown"]), + [data-testid="dropdown"], + [data-testid="dropdown"] *, + .gradio-dropdown, + .gradio-dropdown * { + position: static !important; + transform: none !important; + backdrop-filter: none !important; + filter: none !important; + } + + /* AGGRESSIVE FIX: Override ALL possible transparency sources */ + * { + --dropdown-bg: #ffffff !important; + --dropdown-opacity: 1 !important; + } + + /* Target every possible dropdown element with maximum specificity */ + .gradio-container [data-testid="dropdown"] div[role="listbox"], + .gradio-container .gradio-dropdown .dropdown-content, + .gradio-container .dropdown-menu, + .gradio-container div[role="listbox"], + .gradio-container .svelte-1gfkn6j, + body [data-testid="dropdown"] div[role="listbox"], + body .dropdown-menu, + body div[role="listbox"], + html [data-testid="dropdown"] div[role="listbox"] { + background: #ffffff !important; + background-color: #ffffff !important; + opacity: 1 !important; + position: absolute !important; + z-index: 99999 !important; + border: 2px solid #d1d5db !important; + border-radius: 8px !important; + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25) !important; + max-height: 200px !important; + overflow-y: auto !important; + backdrop-filter: none !important; + filter: none !important; + background-image: none !important; + background-blend-mode: normal !important; + /* Force solid with CSS variables */ + background: var(--dropdown-bg, #ffffff) !important; + opacity: var(--dropdown-opacity, 1) !important; + } + + /* Aggressive option styling */ + .gradio-container [data-testid="dropdown"] div[role="listbox"] > *, + .gradio-container .dropdown-menu > *, + .gradio-container div[role="listbox"] > *, + body [data-testid="dropdown"] div[role="listbox"] > *, + body .dropdown-menu > *, + body div[role="listbox"] > * { + background: #ffffff !important; + background-color: #ffffff !important; + padding: 0.75rem 1rem !important; + color: #1f2937 !important; + cursor: pointer !important; + opacity: 1 !important; + border: none !important; + margin: 0 !important; + display: block !important; + width: 100% !important; + text-align: left !important; + } + + /* Ensure dropdown menus appear correctly with SOLID background */ + [data-testid="dropdown"] div[role="listbox"], + .gradio-dropdown .dropdown-content, + .dropdown-menu, + div[role="listbox"], + .svelte-1gfkn6j, + .gradio-container div[role="listbox"] { + position: absolute !important; + z-index: 9999 !important; + background: #ffffff !important; + background-color: #ffffff !important; + opacity: 1 !important; + border: 1px solid #d1d5db !important; + border-radius: 8px !important; + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15) !important; + max-height: 200px !important; + overflow-y: auto !important; + backdrop-filter: none !important; + /* Force solid background */ + background-image: none !important; + background-blend-mode: normal !important; + } + + /* Dropdown option styling - SOLID background for each option */ + [data-testid="dropdown"] div[role="listbox"] > *, + .dropdown-menu > *, + div[role="listbox"] > *, + .svelte-1gfkn6j > * { + background: #ffffff !important; + background-color: #ffffff !important; + padding: 0.5rem 0.75rem !important; + color: #374151 !important; + cursor: pointer !important; + transition: background-color 0.2s ease !important; + opacity: 1 !important; + } + + /* Dropdown option hover effect */ + [data-testid="dropdown"] div[role="listbox"] > *:hover, + .dropdown-menu > *:hover, + div[role="listbox"] > *:hover { + background: #f3f4f6 !important; + color: #1f2937 !important; + } + + /* Dropdown option selected state */ + [data-testid="dropdown"] div[role="listbox"] > *[aria-selected="true"], + .dropdown-menu > *.selected, + div[role="listbox"] > *[aria-selected="true"] { + background: #e0e7ff !important; + color: #3730a3 !important; + } + + + /* Paper Code Areas */ + .code-container { + background: #f9f0ec !important; + border: 1px solid #f0c5b8 !important; + border-radius: 8px !important; + overflow: hidden !important; + } + + /* Dark mode code container */ + @media (prefers-color-scheme: dark) { + .code-container { + background: #1a1a1a !important; + border: 1px solid #404040 !important; + } + } + + .dark .code-container, + .gradio-container.dark .code-container, + html.dark .code-container, + body.dark .code-container { + background: #1a1a1a !important; + border: 1px solid #404040 !important; + } + + /* Force text selection on ALL code elements */ + .code-container, + .code-container *, + .code-container textarea, + .code-container input, + .code-container .cm-editor, + .code-container .cm-content, + .code-container .cm-line { + user-select: text !important; + -webkit-user-select: text !important; + -moz-user-select: text !important; + -ms-user-select: text !important; + cursor: text !important; + } + + /* Make selection visible */ + .code-container .cm-editor ::selection { + background: #3b82f6 !important; + color: white !important; + } + + .code-container .cm-editor ::-moz-selection { + background: #3b82f6 !important; + color: white !important; + } + + /* Make cursor visible */ + .code-container .cm-cursor { + border-color: #3b82f6 !important; + border-width: 2px !important; + opacity: 1 !important; + visibility: visible !important; + } + + /* Ensure selection works in CodeMirror */ + .code-container .cm-selectionBackground { + background: #3b82f6 !important; + opacity: 0.3 !important; + } + + /* Make sure focused state is visible */ + .code-container .cm-focused { + outline: 2px solid #3b82f6 !important; + outline-offset: 2px !important; + } + + /* Code textbox styling */ + .code-container textarea { + background: #ffffff !important; + border: none !important; + border-radius: 4px !important; + font-family: 'SF Mono', 'Monaco', 'Inconsolata', 'Roboto Mono', 'Fira Code', monospace !important; + font-size: 14px !important; + line-height: 1.5 !important; + padding: 1.5rem !important; + color: #2d3748 !important; + font-weight: 500 !important; + resize: vertical !important; + white-space: pre !important; + overflow-wrap: normal !important; + word-break: normal !important; + } + + /* Dark mode code textbox styling */ + @media (prefers-color-scheme: dark) { + .code-container textarea { + background: #2a2a2a !important; + color: #e5e5e5 !important; + } + } + + .dark .code-container textarea, + .gradio-container.dark .code-container textarea, + html.dark .code-container textarea, + body.dark .code-container textarea { + background: #2a2a2a !important; + color: #e5e5e5 !important; + } + + /* Enable soft wrapping for code content */ + .code-container .cm-content { + white-space: pre-wrap !important; + padding: 1.5rem !important; + color: #5a3a2a !important; + font-size: 14px !important; + font-weight: 500 !important; + } + + .code-container .cm-focused { + outline: none !important; + box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.3) !important; + } + + .code-container .cm-line { + padding-left: 0.5rem !important; + white-space: pre-wrap !important; + word-wrap: break-word !important; + overflow-wrap: break-word !important; + } + + /* Force wrapping ONLY - NO SCROLLING */ + .code-container .cm-editor { + white-space: pre-wrap !important; + overflow-x: hidden !important; + } + + .code-container .cm-scroller { + overflow-x: hidden !important; + width: 100% !important; + } + + .code-container .cm-editor .cm-content { + white-space: pre-wrap !important; + word-break: break-all !important; + overflow-wrap: anywhere !important; + width: 100% !important; + max-width: 100% !important; + } + + .code-container .cm-editor .cm-line { + white-space: pre-wrap !important; + word-break: break-all !important; + overflow-wrap: anywhere !important; + width: 100% !important; + max-width: 100% !important; + box-sizing: border-box !important; + } + + /* Force the entire code container to have no horizontal overflow */ + .code-container, + .code-container * { + overflow-x: hidden !important; + max-width: 100% !important; + } + + /* Moderate syntax highlighting for Python */ + .code-container .cm-keyword { color: #7c3aed !important; } + .code-container .cm-string { color: #059669 !important; } + .code-container .cm-comment { color: #6b7280 !important; font-style: italic !important; } + .code-container .cm-number { color: #dc2626 !important; } + .code-container .cm-variable { color: #1e40af !important; } + .code-container .cm-function { color: #7c2d12 !important; } + .code-container .cm-operator { color: #374151 !important; } + + /* Paper Code header */ + .code-container label { + background: #f5e6e0 !important; + color: #5a3a2a !important; + padding: 0.75rem 1.25rem !important; + border-radius: 8px 8px 0 0 !important; + font-weight: 700 !important; + font-size: 1.1rem !important; + margin: 0 !important; + border: none !important; + border-bottom: 1px solid #f0c5b8 !important; + font-family: 'Georgia', serif !important; + } + + /* Dark mode code header */ + @media (prefers-color-scheme: dark) { + .code-container label { + background: #404040 !important; + color: #e5e5e5 !important; + border-bottom: 1px solid #666 !important; + } + } + + .dark .code-container label, + .gradio-container.dark .code-container label, + html.dark .code-container label, + body.dark .code-container label { + background: #404040 !important; + color: #e5e5e5 !important; + border-bottom: 1px solid #666 !important; + } + + + /* Custom scrollbar for code area */ + .code-container .cm-scroller::-webkit-scrollbar { + width: 6px !important; + height: 6px !important; + } + + .code-container .cm-scroller::-webkit-scrollbar-track { + background: rgba(243, 244, 246, 0.8) !important; + border-radius: 3px !important; + } + + .code-container .cm-scroller::-webkit-scrollbar-thumb { + background: rgba(156, 163, 175, 0.8) !important; + border-radius: 3px !important; + } + + .code-container .cm-scroller::-webkit-scrollbar-thumb:hover { + background: rgba(107, 114, 128, 0.9) !important; + } + + /* Paper Line numbers */ + .code-container .cm-lineNumbers { + background: #f5e6e0 !important; + color: #b8847a !important; + border-right: 1px solid #f0c5b8 !important; + padding-right: 0.5rem !important; + } + + .code-container .cm-lineNumbers .cm-gutterElement { + color: #b8847a !important; + font-weight: 400 !important; + } + + /* Paper Memory Cards */ + .memory-card { + background: #fcf3f0 !important; + border: 1px solid #f4e6e1 !important; + border-radius: 12px !important; + padding: 0.7rem !important; + border-left: 4px solid #e8a491 !important; + } + + /* Dark mode memory cards */ + @media (prefers-color-scheme: dark) { + .memory-card { + background: #2a2a2a !important; + border: 1px solid #404040 !important; + border-left: 4px solid #666 !important; + } + } + + .dark .memory-card, + .gradio-container.dark .memory-card, + html.dark .memory-card, + body.dark .memory-card { + background: #2a2a2a !important; + border: 1px solid #404040 !important; + border-left: 4px solid #666 !important; + } + + /* Paper Labels */ + label { + font-weight: 600 !important; + color: #5a3a2a !important; + font-size: 1.1rem !important; + font-family: 'Georgia', serif !important; + } + + /* Dark mode labels */ + @media (prefers-color-scheme: dark) { + label { + color: #e5e5e5 !important; + } + } + + .dark label, + .gradio-container.dark label, + html.dark label, + body.dark label { + color: #e5e5e5 !important; + } + + /* Memory Analysis Spacing */ + .memory-analysis-spacing { + padding-top: 1rem !important; + border-top: 1px solid rgba(226, 232, 240, 0.6) !important; + } + + + /* FINAL OVERRIDE: Nuclear option for dropdown transparency */ + [role="listbox"] { + background: white !important; + opacity: 1 !important; + } + + [role="listbox"] > * { + background: white !important; + opacity: 1 !important; + } + + /* Gradio-specific nuclear option */ + .gradio-app [role="listbox"], + .gradio-app [role="listbox"] > * { + background: #ffffff !important; + background-color: #ffffff !important; + opacity: 1 !important; + } + + /* Last resort: override all possible transparent backgrounds */ + div[style*="background"] { + background: unset !important; + } + + [role="listbox"][style*="background"] { + background: #ffffff !important; + } + + /* Dark mode dropdown styling - enhanced for dropdown items */ + @media (prefers-color-scheme: dark) { + [data-testid="dropdown"] div[role="listbox"], + .dropdown-menu, + div[role="listbox"], + div[id*="dropdown-options"], + div[aria-labelledby*="dropdown"] { + background: #2a2a2a !important; + background-color: #2a2a2a !important; + border: 2px solid #404040 !important; + } + + [data-testid="dropdown"] div[role="listbox"] > *, + .dropdown-menu > *, + div[role="listbox"] > *, + div[id*="dropdown-options"] > *, + div[aria-labelledby*="dropdown"] > *, + div[role="option"], + [role="option"] { + background: #2a2a2a !important; + background-color: #2a2a2a !important; + color: #e5e5e5 !important; + } + + [data-testid="dropdown"] div[role="listbox"] > *:hover, + .dropdown-menu > *:hover, + div[role="listbox"] > *:hover, + div[id*="dropdown-options"] > *:hover, + div[aria-labelledby*="dropdown"] > *:hover, + div[role="option"]:hover, + [role="option"]:hover { + background: #404040 !important; + color: #ffffff !important; + } + + [role="listbox"][style*="background"] { + background: #2a2a2a !important; + } + } + + /* Gradio dark mode dropdown styling - enhanced for dropdown items */ + .dark [data-testid="dropdown"] div[role="listbox"], + .dark .dropdown-menu, + .dark div[role="listbox"], + .dark div[id*="dropdown-options"], + .dark div[aria-labelledby*="dropdown"], + .gradio-container.dark [data-testid="dropdown"] div[role="listbox"], + .gradio-container.dark .dropdown-menu, + .gradio-container.dark div[role="listbox"], + .gradio-container.dark div[id*="dropdown-options"], + .gradio-container.dark div[aria-labelledby*="dropdown"], + html.dark [data-testid="dropdown"] div[role="listbox"], + html.dark .dropdown-menu, + html.dark div[role="listbox"], + html.dark div[id*="dropdown-options"], + html.dark div[aria-labelledby*="dropdown"], + body.dark [data-testid="dropdown"] div[role="listbox"], + body.dark .dropdown-menu, + body.dark div[role="listbox"], + body.dark div[id*="dropdown-options"], + body.dark div[aria-labelledby*="dropdown"] { + background: #2a2a2a !important; + background-color: #2a2a2a !important; + border: 2px solid #404040 !important; + } + + .dark [data-testid="dropdown"] div[role="listbox"] > *, + .dark .dropdown-menu > *, + .dark div[role="listbox"] > *, + .dark div[id*="dropdown-options"] > *, + .dark div[aria-labelledby*="dropdown"] > *, + .dark div[role="option"], + .dark [role="option"], + .gradio-container.dark [data-testid="dropdown"] div[role="listbox"] > *, + .gradio-container.dark .dropdown-menu > *, + .gradio-container.dark div[role="listbox"] > *, + .gradio-container.dark div[id*="dropdown-options"] > *, + .gradio-container.dark div[aria-labelledby*="dropdown"] > *, + .gradio-container.dark div[role="option"], + .gradio-container.dark [role="option"], + html.dark [data-testid="dropdown"] div[role="listbox"] > *, + html.dark .dropdown-menu > *, + html.dark div[role="listbox"] > *, + html.dark div[id*="dropdown-options"] > *, + html.dark div[aria-labelledby*="dropdown"] > *, + html.dark div[role="option"], + html.dark [role="option"], + body.dark [data-testid="dropdown"] div[role="listbox"] > *, + body.dark .dropdown-menu > *, + body.dark div[role="listbox"] > *, + body.dark div[id*="dropdown-options"] > *, + body.dark div[aria-labelledby*="dropdown"] > *, + body.dark div[role="option"], + body.dark [role="option"] { + background: #2a2a2a !important; + background-color: #2a2a2a !important; + color: #e5e5e5 !important; + } + + .dark [data-testid="dropdown"] div[role="listbox"] > *:hover, + .dark .dropdown-menu > *:hover, + .dark div[role="listbox"] > *:hover, + .dark div[id*="dropdown-options"] > *:hover, + .dark div[aria-labelledby*="dropdown"] > *:hover, + .dark div[role="option"]:hover, + .dark [role="option"]:hover, + .gradio-container.dark [data-testid="dropdown"] div[role="listbox"] > *:hover, + .gradio-container.dark .dropdown-menu > *:hover, + .gradio-container.dark div[role="listbox"] > *:hover, + .gradio-container.dark div[id*="dropdown-options"] > *:hover, + .gradio-container.dark div[aria-labelledby*="dropdown"] > *:hover, + .gradio-container.dark div[role="option"]:hover, + .gradio-container.dark [role="option"]:hover, + html.dark [data-testid="dropdown"] div[role="listbox"] > *:hover, + html.dark .dropdown-menu > *:hover, + html.dark div[role="listbox"] > *:hover, + html.dark div[id*="dropdown-options"] > *:hover, + html.dark div[aria-labelledby*="dropdown"] > *:hover, + html.dark div[role="option"]:hover, + html.dark [role="option"]:hover, + body.dark [data-testid="dropdown"] div[role="listbox"] > *:hover, + body.dark .dropdown-menu > *:hover, + body.dark div[role="listbox"] > *:hover, + body.dark div[id*="dropdown-options"] > *:hover, + body.dark div[aria-labelledby*="dropdown"] > *:hover, + body.dark div[role="option"]:hover, + body.dark [role="option"]:hover { + background: #404040 !important; + color: #ffffff !important; + } + + .dark [role="listbox"][style*="background"], + .gradio-container.dark [role="listbox"][style*="background"], + html.dark [role="listbox"][style*="background"], + body.dark [role="listbox"][style*="background"] { + background: #2a2a2a !important; + } + + /* Dark mode dropdown trigger/button styling */ + @media (prefers-color-scheme: dark) { + [data-testid="dropdown"], + .gradio-dropdown, + select { + background: #2a2a2a !important; + border: 2px solid #404040 !important; + color: #e5e5e5 !important; + } + + [data-testid="dropdown"] button, + .gradio-dropdown button, + [data-testid="dropdown"] > div, + .gradio-dropdown > div { + background: #2a2a2a !important; + color: #e5e5e5 !important; + border: 2px solid #404040 !important; + } + } + + .dark [data-testid="dropdown"], + .dark .gradio-dropdown, + .dark select, + .gradio-container.dark [data-testid="dropdown"], + .gradio-container.dark .gradio-dropdown, + .gradio-container.dark select, + html.dark [data-testid="dropdown"], + html.dark .gradio-dropdown, + html.dark select, + body.dark [data-testid="dropdown"], + body.dark .gradio-dropdown, + body.dark select { + background: #2a2a2a !important; + border: 2px solid #404040 !important; + color: #e5e5e5 !important; + } + + .dark [data-testid="dropdown"] button, + .dark .gradio-dropdown button, + .dark [data-testid="dropdown"] > div, + .dark .gradio-dropdown > div, + .gradio-container.dark [data-testid="dropdown"] button, + .gradio-container.dark .gradio-dropdown button, + .gradio-container.dark [data-testid="dropdown"] > div, + .gradio-container.dark .gradio-dropdown > div, + html.dark [data-testid="dropdown"] button, + html.dark .gradio-dropdown button, + html.dark [data-testid="dropdown"] > div, + html.dark .gradio-dropdown > div, + body.dark [data-testid="dropdown"] button, + body.dark .gradio-dropdown button, + body.dark [data-testid="dropdown"] > div, + body.dark .gradio-dropdown > div { + background: #2a2a2a !important; + color: #e5e5e5 !important; + border: 2px solid #404040 !important; + } + + /* Specific dropdown structure targeting - system dark mode */ + @media (prefers-color-scheme: dark) { + .wrap.svelte-1hfxrpf, + .wrap-inner.svelte-1hfxrpf, + .secondary-wrap.svelte-1hfxrpf, + input[role="listbox"].svelte-1hfxrpf { + background: #2a2a2a !important; + color: #e5e5e5 !important; + border-color: #404040 !important; + } + } + + /* Specific dropdown structure targeting - Gradio dark mode */ + .dark .wrap.svelte-1hfxrpf, + .dark .wrap-inner.svelte-1hfxrpf, + .dark .secondary-wrap.svelte-1hfxrpf, + .dark input[role="listbox"].svelte-1hfxrpf, + .gradio-container.dark .wrap.svelte-1hfxrpf, + .gradio-container.dark .wrap-inner.svelte-1hfxrpf, + .gradio-container.dark .secondary-wrap.svelte-1hfxrpf, + .gradio-container.dark input[role="listbox"].svelte-1hfxrpf, + html.dark .wrap.svelte-1hfxrpf, + html.dark .wrap-inner.svelte-1hfxrpf, + html.dark .secondary-wrap.svelte-1hfxrpf, + html.dark input[role="listbox"].svelte-1hfxrpf, + body.dark .wrap.svelte-1hfxrpf, + body.dark .wrap-inner.svelte-1hfxrpf, + body.dark .secondary-wrap.svelte-1hfxrpf, + body.dark input[role="listbox"].svelte-1hfxrpf { + background: #2a2a2a !important; + color: #e5e5e5 !important; + border-color: #404040 !important; + } + + + + +