diff --git "a/app_complex.py" "b/app_complex.py"
new file mode 100644--- /dev/null
+++ "b/app_complex.py"
@@ -0,0 +1,3945 @@
+import gradio as gr
+import os
+import json
+import requests
+import smtplib
+import sqlite3
+from datetime import datetime
+from email.mime.text import MIMEText
+from email.mime.multipart import MIMEMultipart
+
+# Get Hugging Face token from environment variable
+HF_TOKEN = os.getenv("HUGGINGFACE_TOKEN")
+
+# Database configuration
+DATABASE_FILE = "feedback.db"
+
+# Email configuration (private)
+FEEDBACK_EMAIL = "mahdi@brightmind-ai.com"
+SMTP_SERVER = "smtp.gmail.com"
+SMTP_PORT = 587
+SMTP_USERNAME = os.getenv("SMTP_USERNAME", "")
+SMTP_PASSWORD = os.getenv("SMTP_PASSWORD", "")
+
+# Debug token detection
+print(f"🔍 Token detection debug:")
+print(f" - HF_TOKEN exists: {HF_TOKEN is not None}")
+print(f" - HF_TOKEN length: {len(HF_TOKEN) if HF_TOKEN else 0}")
+print(f" - HF_TOKEN starts with hf_: {HF_TOKEN.startswith('hf_') if HF_TOKEN else False}")
+print(f" - SMTP configured: {SMTP_USERNAME != '' and SMTP_PASSWORD != ''}")
+
+def generate_lesson_plan_with_progress(topic, subject, grade_level, duration, difficulty="intermediate"):
+ """Generate a lesson plan with progress updates"""
+
+ # Show progress bar
+ progress_html = """
+
')
+
+ # Handle math symbols
+ latex_formula = latex_formula.replace('\\times', '×')
+ latex_formula = latex_formula.replace('\\rightarrow', '→')
+ latex_formula = latex_formula.replace('\\leftarrow', '←')
+ latex_formula = latex_formula.replace('\\leq', '≤')
+ latex_formula = latex_formula.replace('\\geq', '≥')
+ latex_formula = latex_formula.replace('\\neq', '≠')
+ latex_formula = latex_formula.replace('\\approx', '≈')
+ latex_formula = latex_formula.replace('\\pm', '±')
+ latex_formula = latex_formula.replace('\\sqrt{', '√(')
+ latex_formula = latex_formula.replace('\\pi', 'π')
+ latex_formula = latex_formula.replace('\\alpha', 'α')
+ latex_formula = latex_formula.replace('\\beta', 'β')
+ latex_formula = latex_formula.replace('\\gamma', 'γ')
+ latex_formula = latex_formula.replace('\\delta', 'δ')
+ latex_formula = latex_formula.replace('\\theta', 'θ')
+ latex_formula = latex_formula.replace('\\lambda', 'λ')
+ latex_formula = latex_formula.replace('\\mu', 'μ')
+ latex_formula = latex_formula.replace('\\sigma', 'σ')
+ latex_formula = latex_formula.replace('\\tau', 'τ')
+ latex_formula = latex_formula.replace('\\phi', 'φ')
+ latex_formula = latex_formula.replace('\\omega', 'ω')
+
+ # Handle superscripts and subscripts
+ latex_formula = re.sub(r'\^(\w+)', r'\1', latex_formula)
+ latex_formula = re.sub(r'_(\w+)', r'\1', latex_formula)
+
+ # Clean up any remaining unmatched braces
+ latex_formula = latex_formula.replace('{', '').replace('}', '')
+
+ return f'{latex_formula}
'
+
+ # Find LaTeX math formulas and convert them (both [formula] and (formula) formats)
+ # Updated patterns to be more specific to LaTeX commands
+ latex_patterns = [
+ re.compile(r'\[([^\[\]]*\\[a-zA-Z]+[^\[\]]*)\]', re.MULTILINE), # [formula with LaTeX commands]
+ re.compile(r'\(([^()]*\\[a-zA-Z]+[^()]*)\)', re.MULTILINE) # (formula with LaTeX commands)
+ ]
+
+ for pattern in latex_patterns:
+ content = pattern.sub(fix_latex_math, content)
+
+ # Find all IMAGE: description patterns (both [IMAGE: description] and IMAGE: description)
+ image_patterns = [
+ r'\[IMAGE:\s*([^\]]+)\]', # [IMAGE: description]
+ r'IMAGE:\s*([^\n<]+?)(?=\s*<|$|\n)', # IMAGE: description (standalone, stop at < or end)
+ ]
+
+ total_images = 0
+ for pattern in image_patterns:
+ images = re.findall(pattern, content, re.MULTILINE)
+ total_images += len(images)
+
+ print(f"🖼️ Found {len(images)} image placeholders with pattern: {pattern}")
+
+ # Replace with real images
+ for i, image_desc in enumerate(images):
+ print(f"🔍 Processing image: {image_desc.strip()}")
+ image_html = generate_real_image(image_desc.strip(), topic, content_type)
+
+ # Replace both formats
+ content = content.replace(f'[IMAGE: {image_desc}]', image_html)
+ content = content.replace(f'IMAGE: {image_desc}', image_html)
+
+ print(f"🖼️ Total images processed: {total_images}")
+
+ # Apply comprehensive styling to the content
+ content = apply_content_styling(content, content_type)
+
+ # Add multimedia enhancement sections
+ multimedia_section = f"""
+
+
🎨 Multimedia Enhancement
+
+
+
📸 Visual Aids
+
Interactive diagrams and illustrations to support learning
+
+
+
🎥 Video Content
+
Educational videos demonstrating key concepts
+
+
+
🔊 Audio Resources
+
Audio explanations and pronunciation guides
+
+
+
+"""
+
+ # Insert multimedia section before the end
+ if "## Additional Resources" in content:
+ content = content.replace("## Additional Resources", multimedia_section + "\n## Additional Resources")
+ else:
+ content += multimedia_section
+
+ return content
+
+def generate_albert_response(user_message, user_name, age_group, chat_history):
+ """Generate Albert's response using AI or fallback"""
+
+ # Try Hugging Face API first if token is available
+ if HF_TOKEN:
+ try:
+ # Create Albert's personality prompt based on age group
+ age_emojis = {
+ "K-2": "🌟",
+ "3-5": "🚀",
+ "6-8": "⚡",
+ "9-12": "🎓",
+ "Adult": "💡"
+ }
+
+ age_emoji = age_emojis.get(age_group, "🌟")
+
+ # Build context from chat history
+ context = ""
+ if chat_history and len(chat_history) > 1:
+ context = "\n\nPrevious conversation:\n"
+ for i, (user_msg, albert_msg) in enumerate(chat_history[-3:]): # Last 3 exchanges
+ if user_msg and albert_msg:
+ context += f"User: {user_msg}\nAlbert: {albert_msg}\n"
+
+ prompt = f"""You are Albert 🧠, a fun and encouraging educational chatbot!
+
+User Info:
+- Name: {user_name}
+- Age Group: {age_group} {age_emoji}
+
+Your personality:
+- Use lots of emojis and fun expressions! 😊
+- Be encouraging and positive
+- Explain things in a simple, engaging way
+- Ask follow-up questions to keep learning going
+- Use age-appropriate language for {age_group}
+- Be enthusiastic about learning!
+- Remember our conversation and build on previous topics!
+
+{context}
+Current question: {user_message}
+
+Respond as Albert with enthusiasm, emojis, and helpful explanations! Keep it concise (2-3 sentences max)."""
+
+ # Call Hugging Face API directly for Albert
+ ai_content = call_hugging_face_api(prompt)
+
+ if ai_content:
+ return ai_content
+ except Exception as e:
+ print(f"❌ Albert API error: {str(e)}")
+
+ # Fallback responses based on common questions
+ fallback_responses = {
+ "hello": f"Hi {user_name}! 🧠✨ I'm Albert, your learning buddy! What would you like to learn about today? 😊",
+ "hi": f"Hey there {user_name}! 🎉 Ready for some fun learning? Ask me anything! 🚀",
+ "help": f"Of course {user_name}! 🧠 I'm here to help you understand any topic! Just ask me a question and I'll explain it in a fun way! 😊✨",
+ "math": f"Math is awesome {user_name}! 🔢✨ Let me know what specific math topic you're curious about and I'll make it super fun to understand! 🎯",
+ "science": f"Science is fascinating {user_name}! 🔬🌟 Tell me what science topic you want to explore and I'll explain it with cool examples! 🚀",
+ "english": f"Language is powerful {user_name}! 📚💫 What English topic would you like to learn about? I'll make it engaging and fun! ✨",
+ "history": f"History is like a time machine {user_name}! ⏰🎭 What historical period or event interests you? I'll bring it to life! 🌟",
+ "art": f"Art is creativity in action {user_name}! 🎨✨ What kind of art or creative topic would you like to explore? Let's get creative! 🚀"
+ }
+
+ # Check for keywords in the message
+ message_lower = user_message.lower()
+ for keyword, response in fallback_responses.items():
+ if keyword in message_lower:
+ return response
+
+ # Default encouraging response
+ return f"That's a great question {user_name}! 🧠✨ I'd love to help you understand that! Can you tell me more about what specific part you'd like to learn about? I'm here to make learning fun! 😊🚀"
+
+def chat_with_albert(user_message, user_name, age_group, chat_history):
+ """Handle the chat conversation with Albert"""
+
+ if not user_message.strip():
+ return chat_history, ""
+
+ # Add user message to history
+ if chat_history is None:
+ chat_history = []
+
+ # Add user message
+ chat_history.append([user_message, None])
+
+ # Generate Albert's response
+ albert_response = generate_albert_response(user_message, user_name, age_group, chat_history)
+
+ # Add Albert's response
+ chat_history[-1][1] = f"🧠 Albert: {albert_response}"
+
+ return chat_history, ""
+
+# Initialize database on startup
+init_database()
+
+# Create Gradio interface with custom CSS
+with gr.Blocks(
+ title="BrightMind AI - Educational Content Generator",
+ theme=gr.themes.Soft(),
+ css="""
+ /* Modern UI Framework */
+ .gradio-container {
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
+ background: #ffffff;
+ min-height: 100vh;
+ position: relative;
+ overflow: hidden;
+ }
+
+ /* Animated Background */
+ .gradio-container::before {
+ content: '';
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background:
+ radial-gradient(circle at 20% 80%, rgba(120, 119, 198, 0.1) 0%, transparent 50%),
+ radial-gradient(circle at 80% 20%, rgba(255, 119, 198, 0.1) 0%, transparent 50%),
+ radial-gradient(circle at 40% 40%, rgba(120, 219, 255, 0.1) 0%, transparent 50%);
+ animation: backgroundShift 15s ease-in-out infinite;
+ z-index: -1;
+ pointer-events: none;
+ }
+
+ .gradio-container::after {
+ content: '';
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background-image:
+ radial-gradient(2px 2px at 20px 30px, #cbd5e0, transparent),
+ radial-gradient(2px 2px at 40px 70px, #a0aec0, transparent),
+ radial-gradient(1px 1px at 90px 40px, #e2e8f0, transparent),
+ radial-gradient(1px 1px at 130px 80px, #cbd5e0, transparent),
+ radial-gradient(2px 2px at 160px 30px, #a0aec0, transparent);
+ background-repeat: repeat;
+ background-size: 200px 100px;
+ animation: particleFloat 20s linear infinite;
+ z-index: -1;
+ pointer-events: none;
+ opacity: 0.6;
+ }
+
+ @keyframes backgroundShift {
+ 0%, 100% {
+ transform: translateX(0px) translateY(0px) scale(1);
+ filter: hue-rotate(0deg);
+ }
+ 25% {
+ transform: translateX(-20px) translateY(-10px) scale(1.02);
+ filter: hue-rotate(90deg);
+ }
+ 50% {
+ transform: translateX(10px) translateY(-20px) scale(0.98);
+ filter: hue-rotate(180deg);
+ }
+ 75% {
+ transform: translateX(-10px) translateY(10px) scale(1.01);
+ filter: hue-rotate(270deg);
+ }
+ }
+
+ @keyframes particleFloat {
+ 0% { transform: translateY(0px) translateX(0px); }
+ 25% { transform: translateY(-30px) translateX(10px); }
+ 50% { transform: translateY(-60px) translateX(-5px); }
+ 75% { transform: translateY(-30px) translateX(15px); }
+ 100% { transform: translateY(0px) translateX(0px); }
+ }
+
+ /* Modern Card System */
+ .modern-card {
+ background: linear-gradient(145deg, #ffffff 0%, #f8fafc 100%);
+ border-radius: 24px;
+ padding: 32px;
+ margin: 24px 0;
+ box-shadow: 0 25px 50px rgba(0, 0, 0, 0.1);
+ border: 1px solid rgba(255, 255, 255, 0.2);
+ backdrop-filter: blur(20px);
+ transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
+ position: relative;
+ overflow: hidden;
+ }
+
+ .modern-card::before {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ height: 4px;
+ background: linear-gradient(90deg, #667eea, #764ba2, #f093fb);
+ border-radius: 24px 24px 0 0;
+ }
+
+ .modern-card:hover {
+ transform: translateY(-8px) scale(1.02);
+ box-shadow: 0 35px 70px rgba(0, 0, 0, 0.15);
+ }
+
+ /* Enhanced Input Styling - Force Text Visibility */
+ .gradio-container input,
+ .gradio-container textarea,
+ .gradio-container select,
+ .gradio-container input[type="text"],
+ .gradio-container input[type="email"],
+ .gradio-container input[type="password"],
+ .gradio-container textarea,
+ .gradio-container select {
+ border-radius: 16px !important;
+ border: 2px solid #e2e8f0 !important;
+ padding: 16px 20px !important;
+ font-size: 15px !important;
+ font-weight: 500 !important;
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important;
+ background: #ffffff !important;
+ box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05) !important;
+ color: #1a202c !important;
+ }
+
+ .gradio-container input::placeholder,
+ .gradio-container textarea::placeholder {
+ color: #718096 !important;
+ opacity: 1 !important;
+ }
+
+ /* Dropdown and Select Styling - Black text on white background */
+ .gradio-container select,
+ .gradio-container select option,
+ .gradio-container .dropdown,
+ .gradio-container .dropdown *,
+ .gradio-container .dropdown .wrap,
+ .gradio-container .dropdown .wrap *,
+ .gradio-container .gr-dropdown,
+ .gradio-container .gr-dropdown *,
+ .gradio-container .gr-dropdown select,
+ .gradio-container .gr-dropdown select option {
+ color: #000000 !important;
+ background: #ffffff !important;
+ border: 1px solid #e2e8f0 !important;
+ }
+
+ /* Force dropdown text visibility with maximum specificity */
+ .gradio-container .dropdown span,
+ .gradio-container .dropdown div,
+ .gradio-container .dropdown p,
+ .gradio-container .dropdown li,
+ .gradio-container .dropdown a,
+ .gradio-container .gr-dropdown span,
+ .gradio-container .gr-dropdown div,
+ .gradio-container .gr-dropdown p,
+ .gradio-container .gr-dropdown li,
+ .gradio-container .gr-dropdown a {
+ color: #000000 !important;
+ background: transparent !important;
+ }
+
+ /* Dropdown hover states */
+ .gradio-container select:hover,
+ .gradio-container .dropdown:hover,
+ .gradio-container .gr-dropdown:hover {
+ background: #f8f9fa !important;
+ border: 1px solid #cbd5e0 !important;
+ }
+
+ /* Dropdown focus states */
+ .gradio-container select:focus,
+ .gradio-container .dropdown:focus,
+ .gradio-container .gr-dropdown:focus {
+ background: #ffffff !important;
+ border: 1px solid #667eea !important;
+ outline: none !important;
+ }
+
+ /* Dropdown options list */
+ .gradio-container .dropdown .options,
+ .gradio-container .dropdown .options *,
+ .gradio-container .gr-dropdown .options,
+ .gradio-container .gr-dropdown .options * {
+ color: #000000 !important;
+ background: #ffffff !important;
+ }
+
+ /* Force visibility for dropdown option text */
+ .gradio-container .dropdown .option,
+ .gradio-container .dropdown .option *,
+ .gradio-container .dropdown .item,
+ .gradio-container .dropdown .item *,
+ .gradio-container .gr-dropdown .option,
+ .gradio-container .gr-dropdown .option *,
+ .gradio-container .gr-dropdown .item,
+ .gradio-container .gr-dropdown .item * {
+ color: #000000 !important;
+ background: transparent !important;
+ }
+
+ /* Override any conflicting text colors */
+ .gradio-container .dropdown *[style*="color"],
+ .gradio-container .gr-dropdown *[style*="color"] {
+ color: #000000 !important;
+ }
+
+ /* Dropdown option hover */
+ .gradio-container .dropdown .options li:hover,
+ .gradio-container .gr-dropdown .options li:hover {
+ background: #f8f9fa !important;
+ color: #000000 !important;
+ }
+
+ /* Additional dropdown selectors for comprehensive coverage */
+ .gradio-container [class*="dropdown"],
+ .gradio-container [class*="select"],
+ .gradio-container [data-testid*="dropdown"],
+ .gradio-container [data-testid*="select"] {
+ color: #000000 !important;
+ background: #ffffff !important;
+ border: 1px solid #e2e8f0 !important;
+ }
+
+ .gradio-container [class*="dropdown"] *,
+ .gradio-container [class*="select"] *,
+ .gradio-container [data-testid*="dropdown"] *,
+ .gradio-container [data-testid*="select"] * {
+ color: #000000 !important;
+ background: #ffffff !important;
+ }
+
+ /* Force all form selects to be black on white */
+ .gradio-container form select,
+ .gradio-container form select option,
+ .gradio-container .form select,
+ .gradio-container .form select option {
+ color: #000000 !important;
+ background: #ffffff !important;
+ border: 1px solid #e2e8f0 !important;
+ }
+
+ /* Ultimate dropdown text visibility fix */
+ .gradio-container .dropdown,
+ .gradio-container .gr-dropdown,
+ .gradio-container select {
+ color: #000000 !important;
+ }
+
+ .gradio-container .dropdown *,
+ .gradio-container .gr-dropdown *,
+ .gradio-container select * {
+ color: #000000 !important;
+ }
+
+ /* Override any white or transparent text that might be invisible */
+ .gradio-container .dropdown *[style*="color: white"],
+ .gradio-container .dropdown *[style*="color: #fff"],
+ .gradio-container .dropdown *[style*="color: #ffffff"],
+ .gradio-container .dropdown *[style*="color: transparent"],
+ .gradio-container .gr-dropdown *[style*="color: white"],
+ .gradio-container .gr-dropdown *[style*="color: #fff"],
+ .gradio-container .gr-dropdown *[style*="color: #ffffff"],
+ .gradio-container .gr-dropdown *[style*="color: transparent"] {
+ color: #000000 !important;
+ opacity: 1 !important;
+ }
+
+ .gradio-container input:focus,
+ .gradio-container textarea:focus,
+ .gradio-container select:focus {
+ border-color: #667eea !important;
+ box-shadow: 0 0 0 4px rgba(102, 126, 234, 0.1), 0 8px 25px rgba(0, 0, 0, 0.1) !important;
+ outline: none !important;
+ transform: translateY(-2px) !important;
+ color: #1a202c !important;
+ background: #ffffff !important;
+ }
+
+ /* Force text visibility in all text elements */
+ .gradio-container * {
+ color: inherit !important;
+ }
+
+ .gradio-container input,
+ .gradio-container textarea,
+ .gradio-container select {
+ color: #1a202c !important;
+ }
+
+ /* Markdown and output text visibility */
+ .gradio-container .markdown,
+ .gradio-container .markdown *,
+ .gradio-container .prose,
+ .gradio-container .prose * {
+ color: #1a202c !important;
+ }
+
+ /* Chat message text visibility */
+ .gradio-container .chatbot .message,
+ .gradio-container .chatbot .message * {
+ color: #1a202c !important;
+ }
+
+ /* Override any conflicting styles */
+ .gradio-container .gr-textbox,
+ .gradio-container .gr-textbox input,
+ .gradio-container .gr-textarea,
+ .gradio-container .gr-textarea textarea,
+ .gradio-container .gr-dropdown,
+ .gradio-container .gr-dropdown select {
+ color: #1a202c !important;
+ background: #ffffff !important;
+ }
+
+ /* Force visibility for all generated content */
+ .gradio-container .gr-markdown,
+ .gradio-container .gr-markdown *,
+ .gradio-container .gr-html,
+ .gradio-container .gr-html *,
+ .gradio-container .output,
+ .gradio-container .output *,
+ .gradio-container .result,
+ .gradio-container .result * {
+ color: #1a202c !important;
+ }
+
+ /* Specific styling for lesson plan and quiz outputs */
+ .gradio-container .gr-markdown h1,
+ .gradio-container .gr-markdown h2,
+ .gradio-container .gr-markdown h3,
+ .gradio-container .gr-markdown h4,
+ .gradio-container .gr-markdown h5,
+ .gradio-container .gr-markdown h6 {
+ color: #1a202c !important;
+ }
+
+ .gradio-container .gr-markdown p,
+ .gradio-container .gr-markdown li,
+ .gradio-container .gr-markdown span,
+ .gradio-container .gr-markdown div {
+ color: #1a202c !important;
+ }
+
+ /* Chat output visibility */
+ .gradio-container .chatbot .message p,
+ .gradio-container .chatbot .message div,
+ .gradio-container .chatbot .message span {
+ color: #1a202c !important;
+ }
+
+ /* Dataset/Table text visibility */
+ .gradio-container .gr-dataset,
+ .gradio-container .gr-dataset *,
+ .gradio-container .gr-dataset table,
+ .gradio-container .gr-dataset table *,
+ .gradio-container .gr-dataset td,
+ .gradio-container .gr-dataset th,
+ .gradio-container .gr-dataset tr {
+ color: #1a202c !important;
+ background: #ffffff !important;
+ }
+
+ /* Table specific visibility fixes */
+ .gradio-container table,
+ .gradio-container table *,
+ .gradio-container table td,
+ .gradio-container table th,
+ .gradio-container table tr {
+ color: #1a202c !important;
+ background: #ffffff !important;
+ }
+
+ /* Examples table visibility */
+ .gradio-container .examples,
+ .gradio-container .examples *,
+ .gradio-container .examples table,
+ .gradio-container .examples table *,
+ .gradio-container .examples td,
+ .gradio-container .examples th {
+ color: #1a202c !important;
+ background: #ffffff !important;
+ }
+
+ /* Slider and form control visibility */
+ .gradio-container .gr-slider,
+ .gradio-container .gr-slider *,
+ .gradio-container .gr-checkbox,
+ .gradio-container .gr-checkbox *,
+ .gradio-container .gr-radio,
+ .gradio-container .gr-radio * {
+ color: #1a202c !important;
+ }
+
+ /* Label text visibility */
+ .gradio-container label,
+ .gradio-container .gr-label,
+ .gradio-container .gr-label * {
+ color: #1a202c !important;
+ }
+
+ /* Force all text to be visible */
+ .gradio-container div,
+ .gradio-container span,
+ .gradio-container p,
+ .gradio-container td,
+ .gradio-container th,
+ .gradio-container li {
+ color: #1a202c !important;
+ }
+
+ /* Override any white text that might be invisible */
+ .gradio-container *[style*="color: white"],
+ .gradio-container *[style*="color: #fff"],
+ .gradio-container *[style*="color: #ffffff"] {
+ color: #1a202c !important;
+ }
+
+ /* Ensure all interactive elements have visible text */
+ .gradio-container button,
+ .gradio-container .btn,
+ .gradio-container .gr-button {
+ color: #ffffff !important;
+ }
+
+ /* Table and dataset specific fixes */
+ .gradio-container table td,
+ .gradio-container table th,
+ .gradio-container .dataset table td,
+ .gradio-container .dataset table th {
+ color: #1a202c !important;
+ background: transparent !important;
+ }
+
+ /* Form element text visibility */
+ .gradio-container .form,
+ .gradio-container .form *,
+ .gradio-container .gr-form,
+ .gradio-container .gr-form * {
+ color: #1a202c !important;
+ }
+
+ /* Quiz Generator specific fixes */
+ .gradio-container .gr-slider .wrap,
+ .gradio-container .gr-slider .wrap *,
+ .gradio-container .gr-slider label,
+ .gradio-container .gr-slider .label,
+ .gradio-container .gr-slider .gr-label {
+ color: #1a202c !important;
+ }
+
+ /* Comprehensive Slider Visibility */
+ .gradio-container .gr-slider,
+ .gradio-container .gr-slider *,
+ .gradio-container [data-testid="slider"],
+ .gradio-container [data-testid="slider"] *,
+ .gradio-container .slider,
+ .gradio-container .slider * {
+ background: #ffffff !important;
+ border: 1px solid #e2e8f0 !important;
+ border-radius: 8px !important;
+ }
+
+ /* Slider track visibility */
+ .gradio-container .gr-slider .track,
+ .gradio-container .gr-slider .rail,
+ .gradio-container .gr-slider .slider-track,
+ .gradio-container [data-testid="slider"] .track,
+ .gradio-container [data-testid="slider"] .rail,
+ .gradio-container .slider .track,
+ .gradio-container .slider .rail {
+ background: #e2e8f0 !important;
+ border: 2px solid #cbd5e0 !important;
+ height: 8px !important;
+ border-radius: 4px !important;
+ }
+
+ /* Slider thumb visibility */
+ .gradio-container .gr-slider .thumb,
+ .gradio-container .gr-slider .handle,
+ .gradio-container .gr-slider .slider-thumb,
+ .gradio-container [data-testid="slider"] .thumb,
+ .gradio-container [data-testid="slider"] .handle,
+ .gradio-container .slider .thumb,
+ .gradio-container .slider .handle {
+ background: #000000 !important;
+ border: 3px solid #000000 !important;
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.5) !important;
+ width: 20px !important;
+ height: 20px !important;
+ border-radius: 50% !important;
+ }
+
+ /* Slider value display */
+ .gradio-container .gr-slider .value,
+ .gradio-container .gr-slider .gr-number,
+ .gradio-container .gr-slider input[type="number"],
+ .gradio-container [data-testid="slider"] .value,
+ .gradio-container [data-testid="slider"] input,
+ .gradio-container .slider .value,
+ .gradio-container .slider input {
+ color: #1a202c !important;
+ background: #ffffff !important;
+ border: 1px solid #cbd5e0 !important;
+ }
+
+ /* Force slider visibility with multiple selectors */
+ .gradio-container input[type="range"] {
+ -webkit-appearance: none !important;
+ appearance: none !important;
+ background: #e2e8f0 !important;
+ border: 2px solid #cbd5e0 !important;
+ height: 8px !important;
+ border-radius: 4px !important;
+ outline: none !important;
+ }
+
+ .gradio-container input[type="range"]::-webkit-slider-track {
+ -webkit-appearance: none !important;
+ appearance: none !important;
+ background: #e2e8f0 !important;
+ border: 2px solid #cbd5e0 !important;
+ height: 8px !important;
+ border-radius: 4px !important;
+ }
+
+ .gradio-container input[type="range"]::-webkit-slider-thumb {
+ -webkit-appearance: none !important;
+ appearance: none !important;
+ background: #000000 !important;
+ border: 3px solid #000000 !important;
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.5) !important;
+ width: 20px !important;
+ height: 20px !important;
+ border-radius: 50% !important;
+ cursor: pointer !important;
+ }
+
+ .gradio-container input[type="range"]::-moz-range-track {
+ background: #e2e8f0 !important;
+ border: 2px solid #cbd5e0 !important;
+ height: 8px !important;
+ border-radius: 4px !important;
+ }
+
+ .gradio-container input[type="range"]::-moz-range-thumb {
+ background: #000000 !important;
+ border: 3px solid #000000 !important;
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.5) !important;
+ width: 20px !important;
+ height: 20px !important;
+ border-radius: 50% !important;
+ cursor: pointer !important;
+ }
+
+ /* Microsoft Edge and IE */
+ .gradio-container input[type="range"]::-ms-track {
+ background: #e2e8f0 !important;
+ border: 2px solid #cbd5e0 !important;
+ height: 8px !important;
+ border-radius: 4px !important;
+ }
+
+ .gradio-container input[type="range"]::-ms-thumb {
+ background: #000000 !important;
+ border: 3px solid #000000 !important;
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.5) !important;
+ width: 20px !important;
+ height: 20px !important;
+ border-radius: 50% !important;
+ cursor: pointer !important;
+ }
+
+ /* Number input visibility */
+ .gradio-container .gr-number input,
+ .gradio-container .gr-number input[type="number"] {
+ color: #1a202c !important;
+ background: #ffffff !important;
+ border: 1px solid #cbd5e0 !important;
+ }
+
+ /* Checkbox and radio button labels */
+ .gradio-container .gr-checkbox label,
+ .gradio-container .gr-radio label,
+ .gradio-container .gr-checkbox .label,
+ .gradio-container .gr-radio .label {
+ color: #1a202c !important;
+ }
+
+ /* Radio button styling - selected state turns black */
+ .gradio-container .gr-radio input[type="radio"] {
+ appearance: none !important;
+ width: 20px !important;
+ height: 20px !important;
+ border: 2px solid #e2e8f0 !important;
+ border-radius: 50% !important;
+ background: #ffffff !important;
+ cursor: pointer !important;
+ position: relative !important;
+ }
+
+ .gradio-container .gr-radio input[type="radio"]:checked {
+ background: #000000 !important;
+ border: 2px solid #000000 !important;
+ }
+
+ .gradio-container .gr-radio input[type="radio"]:checked::after {
+ content: '' !important;
+ position: absolute !important;
+ top: 50% !important;
+ left: 50% !important;
+ width: 8px !important;
+ height: 8px !important;
+ background: #ffffff !important;
+ border-radius: 50% !important;
+ transform: translate(-50%, -50%) !important;
+ }
+
+ /* Radio button container styling */
+ .gradio-container .gr-radio {
+ background: #ffffff !important;
+ border: 1px solid #e2e8f0 !important;
+ border-radius: 12px !important;
+ padding: 16px !important;
+ margin: 8px !important;
+ transition: all 0.3s ease !important;
+ }
+
+ .gradio-container .gr-radio:hover {
+ background: #f8f9fa !important;
+ border: 1px solid #cbd5e0 !important;
+ transform: translateY(-2px) !important;
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1) !important;
+ }
+
+ .gradio-container .gr-radio:has(input[type="radio"]:checked) {
+ background: #000000 !important;
+ border: 1px solid #000000 !important;
+ color: #ffffff !important;
+ }
+
+ .gradio-container .gr-radio:has(input[type="radio"]:checked) label {
+ color: #ffffff !important;
+ }
+
+ /* Force all quiz form elements to have visible text */
+ .gradio-container .quiz-form,
+ .gradio-container .quiz-form *,
+ .gradio-container .quiz-form label,
+ .gradio-container .quiz-form .label,
+ .gradio-container .quiz-form .gr-label {
+ color: #1a202c !important;
+ }
+
+ /* Override any transparent or invisible text */
+ .gradio-container *[style*="opacity: 0"],
+ .gradio-container *[style*="opacity:0"],
+ .gradio-container .invisible,
+ .gradio-container .hidden {
+ opacity: 1 !important;
+ color: #1a202c !important;
+ }
+
+ /* Ensure all text in cards is visible */
+ .gradio-container .modern-card * {
+ color: #1a202c !important;
+ }
+
+ /* Specific fixes for quiz tab elements */
+ .gradio-container .tab-nav .tab-nav button[data-testid="tab-2"] ~ * .gr-slider,
+ .gradio-container .tab-nav .tab-nav button[data-testid="tab-2"] ~ * .gr-number,
+ .gradio-container .tab-nav .tab-nav button[data-testid="tab-2"] ~ * .gr-checkbox,
+ .gradio-container .tab-nav .tab-nav button[data-testid="tab-2"] ~ * .gr-radio {
+ color: #1a202c !important;
+ }
+
+ /* Force white background for all chat elements */
+ .gradio-container .gr-chatbot,
+ .gradio-container .gr-chatbot *,
+ .gradio-container .chatbot,
+ .gradio-container .chatbot *,
+ .gradio-container [data-testid="chatbot"],
+ .gradio-container [data-testid="chatbot"] * {
+ background: #ffffff !important;
+ }
+
+ /* Override any dark themes that might be applied */
+ .gradio-container .dark,
+ .gradio-container .dark *,
+ .gradio-container [data-theme="dark"],
+ .gradio-container [data-theme="dark"] * {
+ background: #ffffff !important;
+ color: #1a202c !important;
+ }
+
+ /* Force visibility for all text elements */
+ .gradio-container * {
+ color: #1a202c !important;
+ }
+
+ /* Override any white or transparent text */
+ .gradio-container *[style*="color: white"],
+ .gradio-container *[style*="color: #fff"],
+ .gradio-container *[style*="color: #ffffff"],
+ .gradio-container *[style*="color: transparent"],
+ .gradio-container *[style*="opacity: 0"] {
+ color: #1a202c !important;
+ opacity: 1 !important;
+ }
+
+ /* Ensure all interactive elements are visible */
+ .gradio-container .gr-component,
+ .gradio-container .gr-component * {
+ color: #1a202c !important;
+ background: #ffffff !important;
+ }
+
+ /* Specific fixes for lesson plan examples */
+ .gradio-container .lesson-examples,
+ .gradio-container .lesson-examples *,
+ .gradio-container .lesson-examples table,
+ .gradio-container .lesson-examples table * {
+ color: #1a202c !important;
+ background: #ffffff !important;
+ }
+
+ /* Additional slider targeting for all possible selectors */
+ .gradio-container .wrap .gr-slider,
+ .gradio-container .wrap .gr-slider *,
+ .gradio-container .form .gr-slider,
+ .gradio-container .form .gr-slider *,
+ .gradio-container .block .gr-slider,
+ .gradio-container .block .gr-slider *,
+ .gradio-container .component .gr-slider,
+ .gradio-container .component .gr-slider * {
+ background: #ffffff !important;
+ border: 1px solid #e2e8f0 !important;
+ }
+
+ /* Target slider elements by their actual HTML structure */
+ .gradio-container .gr-slider .wrap,
+ .gradio-container .gr-slider .wrap *,
+ .gradio-container .gr-slider .container,
+ .gradio-container .gr-slider .container * {
+ background: #e2e8f0 !important;
+ border: 2px solid #cbd5e0 !important;
+ }
+
+ /* Force visibility for any slider-like elements */
+ .gradio-container [class*="slider"],
+ .gradio-container [class*="range"],
+ .gradio-container [class*="track"] {
+ background: #e2e8f0 !important;
+ border: 2px solid #cbd5e0 !important;
+ }
+
+ .gradio-container [class*="thumb"],
+ .gradio-container [class*="handle"] {
+ background: #000000 !important;
+ border: 3px solid #000000 !important;
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.5) !important;
+ }
+
+ /* Premium Button Design */
+ .gradio-container .btn {
+ border-radius: 16px !important;
+ padding: 16px 32px !important;
+ font-weight: 700 !important;
+ font-size: 15px !important;
+ text-transform: uppercase !important;
+ letter-spacing: 0.5px !important;
+ transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1) !important;
+ border: none !important;
+ position: relative !important;
+ overflow: hidden !important;
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
+ color: white !important;
+ box-shadow: 0 8px 25px rgba(102, 126, 234, 0.3) !important;
+ }
+
+ .gradio-container .btn::before {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: -100%;
+ width: 100%;
+ height: 100%;
+ background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
+ transition: left 0.6s;
+ }
+
+ .gradio-container .btn:hover::before {
+ left: 100%;
+ }
+
+ .gradio-container .btn:hover {
+ transform: translateY(-4px) scale(1.05) !important;
+ box-shadow: 0 15px 35px rgba(102, 126, 234, 0.4) !important;
+ }
+
+ .gradio-container .btn:active {
+ transform: translateY(-2px) scale(1.02) !important;
+ }
+
+ /* Modern Tab Navigation */
+ .gradio-container .tab-nav {
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
+ border-radius: 20px !important;
+ padding: 12px !important;
+ margin-bottom: 32px !important;
+ box-shadow: 0 15px 35px rgba(102, 126, 234, 0.3) !important;
+ backdrop-filter: blur(20px) !important;
+ }
+
+
+ .gradio-container .tab-nav button {
+ border-radius: 16px !important;
+ padding: 16px 24px !important;
+ font-weight: 700 !important;
+ font-size: 15px !important;
+ transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1) !important;
+ border: none !important;
+ background: transparent !important;
+ color: rgba(255, 255, 255, 0.8) !important;
+ position: relative !important;
+ overflow: hidden !important;
+ }
+
+ .gradio-container .tab-nav button::before {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: linear-gradient(135deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.05));
+ opacity: 0;
+ transition: opacity 0.3s ease;
+ }
+
+ .gradio-container .tab-nav button:hover::before {
+ opacity: 1;
+ }
+
+ .gradio-container .tab-nav button.selected {
+ background: rgba(255, 255, 255, 0.2) !important;
+ color: white !important;
+ backdrop-filter: blur(20px) !important;
+ box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1) !important;
+ }
+
+ .gradio-container .tab-nav button:hover {
+ color: white !important;
+ transform: translateY(-2px) !important;
+ }
+
+ /* Enhanced Chat Interface */
+ .gradio-container .chatbot {
+ border-radius: 24px !important;
+ border: 2px solid #e2e8f0 !important;
+ background: #ffffff !important;
+ box-shadow: 0 15px 35px rgba(0, 0, 0, 0.1) !important;
+ backdrop-filter: blur(20px) !important;
+ overflow: hidden !important;
+ }
+
+ .gradio-container .chatbot .message {
+ border-radius: 20px !important;
+ margin: 16px 0 !important;
+ padding: 20px 24px !important;
+ background: #ffffff !important;
+ box-shadow: 0 8px 25px rgba(0, 0, 0, 0.08) !important;
+ transition: all 0.3s ease !important;
+ }
+
+ .gradio-container .chatbot .message:hover {
+ transform: translateX(4px) !important;
+ box-shadow: 0 12px 30px rgba(0, 0, 0, 0.12) !important;
+ }
+
+ /* Modern Progress System */
+ .progress-container {
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+ border-radius: 24px;
+ padding: 40px;
+ margin: 32px 0;
+ color: white;
+ text-align: center;
+ box-shadow: 0 25px 50px rgba(102, 126, 234, 0.3);
+ backdrop-filter: blur(20px);
+ position: relative;
+ overflow: hidden;
+ }
+
+ .progress-container::before {
+ content: '';
+ position: absolute;
+ top: -50%;
+ left: -50%;
+ width: 200%;
+ height: 200%;
+ background: radial-gradient(circle, rgba(255, 255, 255, 0.1) 0%, transparent 70%);
+ animation: rotate 20s linear infinite;
+ }
+
+ @keyframes rotate {
+ 0% { transform: rotate(0deg); }
+ 100% { transform: rotate(360deg); }
+ }
+
+ .progress-bar {
+ width: 100%;
+ height: 16px;
+ background: rgba(255, 255, 255, 0.2);
+ border-radius: 8px;
+ overflow: hidden;
+ margin: 24px 0;
+ position: relative;
+ }
+
+ .progress-fill {
+ height: 100%;
+ background: linear-gradient(90deg, #4facfe 0%, #00f2fe 100%);
+ border-radius: 8px;
+ animation: progress-animation 2s ease-in-out;
+ position: relative;
+ }
+
+ .progress-fill::after {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
+ animation: shimmer 2s infinite;
+ }
+
+ @keyframes shimmer {
+ 0% { transform: translateX(-100%); }
+ 100% { transform: translateX(100%); }
+ }
+
+ @keyframes progress-animation {
+ 0% { width: 0%; }
+ 100% { width: 100%; }
+ }
+
+ .status-text {
+ font-size: 20px;
+ font-weight: 700;
+ margin: 20px 0;
+ text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
+ }
+
+ .step-text {
+ font-size: 18px;
+ opacity: 0.9;
+ margin: 12px 0;
+ font-weight: 500;
+ }
+
+ /* Modern Header Design */
+ .modern-header {
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+ border-radius: 24px;
+ padding: 50px;
+ margin: 32px 0;
+ text-align: center;
+ color: white;
+ box-shadow: 0 25px 50px rgba(102, 126, 234, 0.3);
+ position: relative;
+ overflow: hidden;
+ }
+
+ .modern-header::before {
+ content: '';
+ position: absolute;
+ top: -50%;
+ left: -50%;
+ width: 200%;
+ height: 200%;
+ background: radial-gradient(circle, rgba(255, 255, 255, 0.1) 0%, transparent 70%);
+ animation: float 6s ease-in-out infinite;
+ }
+
+ @keyframes float {
+ 0%, 100% { transform: translateY(0px) rotate(0deg); }
+ 50% { transform: translateY(-20px) rotate(180deg); }
+ }
+
+ .modern-header h1 {
+ font-size: 3rem;
+ font-weight: 800;
+ margin: 0 0 16px 0;
+ text-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
+ position: relative;
+ z-index: 1;
+ }
+
+ .modern-header p {
+ font-size: 1.4rem;
+ opacity: 0.9;
+ margin: 0;
+ position: relative;
+ z-index: 1;
+ font-weight: 500;
+ }
+
+ /* Animation Classes */
+ .fade-in {
+ animation: fadeIn 0.8s cubic-bezier(0.4, 0, 0.2, 1);
+ }
+
+ @keyframes fadeIn {
+ from { opacity: 0; transform: translateY(30px); }
+ to { opacity: 1; transform: translateY(0); }
+ }
+
+ .slide-in-left {
+ animation: slideInLeft 1s cubic-bezier(0.4, 0, 0.2, 1);
+ }
+
+ @keyframes slideInLeft {
+ from { transform: translateX(-100%); opacity: 0; }
+ to { transform: translateX(0); opacity: 1; }
+ }
+
+ .slide-in-right {
+ animation: slideInRight 1s cubic-bezier(0.4, 0, 0.2, 1);
+ }
+
+ @keyframes slideInRight {
+ from { transform: translateX(100%); opacity: 0; }
+ to { transform: translateX(0); opacity: 1; }
+ }
+
+ .bounce-in {
+ animation: bounceIn 1.2s cubic-bezier(0.68, -0.55, 0.265, 1.55);
+ }
+
+ @keyframes bounceIn {
+ 0% { transform: scale(0.3); opacity: 0; }
+ 50% { transform: scale(1.05); }
+ 70% { transform: scale(0.9); }
+ 100% { transform: scale(1); opacity: 1; }
+ }
+
+ /* Legacy Progress Container */
+ .progress-container {
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+ border-radius: 15px;
+ padding: 20px;
+ margin: 20px 0;
+ box-shadow: 0 8px 32px rgba(0,0,0,0.1);
+ }
+ .progress-bar {
+ width: 100%;
+ height: 8px;
+ background: rgba(255,255,255,0.2);
+ border-radius: 4px;
+ overflow: hidden;
+ margin: 10px 0;
+ }
+ .progress-fill {
+ height: 100%;
+ background: linear-gradient(90deg, #4facfe 0%, #00f2fe 100%);
+ border-radius: 4px;
+ animation: progress-animation 2s ease-in-out infinite;
+ }
+ @keyframes progress-animation {
+ 0% { width: 0%; }
+ 50% { width: 70%; }
+ 100% { width: 100%; }
+ }
+ .typewriter-container {
+ background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
+ border-radius: 15px;
+ padding: 25px;
+ margin: 20px 0;
+ box-shadow: 0 10px 40px rgba(0,0,0,0.1);
+ border-left: 5px solid #667eea;
+ }
+ .typewriter-header {
+ display: flex;
+ align-items: center;
+ margin-bottom: 15px;
+ }
+ .book-icon {
+ font-size: 24px;
+ margin-right: 10px;
+ color: #8b4513;
+ animation: book-flip 2s ease-in-out infinite;
+ }
+ @keyframes book-flip {
+ 0%, 100% { transform: rotateY(0deg); }
+ 50% { transform: rotateY(10deg); }
+ }
+ .typewriter-text {
+ font-family: 'Courier New', monospace;
+ font-size: 16px;
+ line-height: 1.6;
+ color: #2c3e50;
+ white-space: pre-wrap;
+ min-height: 200px;
+ }
+ .cursor {
+ display: inline-block;
+ width: 2px;
+ height: 20px;
+ background: #667eea;
+ animation: blink 1s infinite;
+ }
+ @keyframes blink {
+ 0%, 50% { opacity: 1; }
+ 51%, 100% { opacity: 0; }
+ }
+ .generation-status {
+ text-align: center;
+ color: #667eea;
+ font-weight: 600;
+ margin: 10px 0;
+ }
+ .professional-header {
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+ color: white;
+ padding: 30px;
+ border-radius: 15px;
+ text-align: center;
+ margin-bottom: 30px;
+ box-shadow: 0 10px 40px rgba(0,0,0,0.1);
+ }
+ .professional-header h1 {
+ margin: 0;
+ font-size: 2.5em;
+ font-weight: 700;
+ }
+ .professional-header p {
+ margin: 10px 0 0 0;
+ font-size: 1.2em;
+ opacity: 0.9;
+ }
+
+ /* Albert Chat Avatar Styling */
+ .chatbot .message {
+ margin: 15px 0;
+ padding: 10px;
+ border-radius: 10px;
+ background: rgba(255,255,255,0.1);
+ }
+
+ .chatbot .message .avatar {
+ width: 300px !important;
+ height: 300px !important;
+ border-radius: 50% !important;
+ margin-right: 20px !important;
+ border: 6px solid #667eea !important;
+ box-shadow: 0 8px 16px rgba(0,0,0,0.3) !important;
+ transition: all 0.3s ease !important;
+ }
+
+ .chatbot .message .avatar:hover {
+ transform: scale(1.1) !important;
+ box-shadow: 0 8px 16px rgba(102, 126, 234, 0.4) !important;
+ }
+
+ .chatbot .message .message-content {
+ font-size: 16px;
+ line-height: 1.6;
+ }
+
+ .chatbot .message .message-content strong {
+ color: #667eea;
+ font-size: 18px;
+ }
+
+ /* Voice button styling */
+ .voice-controls {
+ background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
+ border-radius: 10px;
+ padding: 15px;
+ margin: 10px 0;
+ border-left: 4px solid #4CAF50;
+ }
+
+ .voice-controls button {
+ background: linear-gradient(135deg, #4CAF50 0%, #45a049 100%) !important;
+ color: white !important;
+ border: none !important;
+ padding: 6px 12px !important;
+ border-radius: 6px !important;
+ cursor: pointer !important;
+ font-weight: 500 !important;
+ font-size: 11px !important;
+ box-shadow: 0 2px 6px rgba(76, 175, 80, 0.3) !important;
+ transition: all 0.3s ease !important;
+ }
+
+ .voice-controls button:hover {
+ transform: translateY(-2px) !important;
+ box-shadow: 0 6px 16px rgba(76, 175, 80, 0.4) !important;
+ }
+
+ /* Auto-scroll for chat */
+ #albert_chat .chatbot {
+ scroll-behavior: smooth !important;
+ }
+
+ #albert_chat .overflow-y-auto {
+ scroll-behavior: smooth !important;
+ }
+
+
+ """
+) as demo:
+
+ # Modern Header
+ with gr.Row():
+ gr.HTML("""
+
+ """)
+
+ with gr.Tabs():
+ with gr.TabItem("🧠 Ask Albert"):
+ with gr.Row():
+ with gr.Column(scale=1):
+ gr.HTML("""
+
+
🧠 Meet Albert!
+
Your friendly learning buddy! 😊
+
+
✨ Tell Albert your name & age → Ask any question → Get fun explanations!
+
+
+ """)
+
+ # Modern Form Section
+ gr.HTML("""
+
+
👤 User Setup
+ """)
+
+ user_name = gr.Textbox(
+ label="👋 What's your name?",
+ placeholder="Enter your name here...",
+ value=""
+ )
+
+ user_age_group = gr.Dropdown(
+ choices=["K-2", "3-5", "6-8", "9-12", "Adult"],
+ label="🎂 What's your age group?",
+ value="6-8"
+ )
+
+ gr.HTML("")
+
+ # Modern Chat Interface
+ gr.HTML("""
+
+
💬 Chat Interface
+ """)
+
+ chat_input = gr.Textbox(
+ label="Ask Albert anything!",
+ placeholder="Type your question here...",
+ lines=2
+ )
+
+ with gr.Row():
+ send_btn = gr.Button("🚀 Send Message", variant="primary")
+ clear_btn = gr.Button("🗑️ Clear Chat", variant="secondary")
+
+ gr.HTML("")
+
+
+ with gr.Column(scale=2):
+ # Modern Albert Section
+ gr.HTML("""
+
+
+
👨🏫
+
Albert is ready to help!
+
+
+ """)
+
+ # Modern Chat Display
+ gr.HTML("""
+
+
💬 Albert's Chat
+ """)
+
+ chat_display = gr.Chatbot(
+ label="",
+ height=400,
+ show_label=False,
+ container=True,
+ bubble_full_width=False,
+ avatar_images=[
+ "https://img.icons8.com/color/48/000000/user-male-circle.png", # User avatar
+ "https://img.icons8.com/color/48/000000/teacher.png" # Albert avatar (professional teacher)
+ ],
+ elem_id="albert_chat"
+ )
+
+ gr.HTML("")
+
+ # Typing indicator
+ typing_indicator = gr.HTML(
+ value="",
+ visible=False
+ )
+
+ # Context display
+ context_display = gr.HTML(
+ value=""
+ )
+
+ # Event handlers for Albert chat
+ def send_message_with_typing(message, name, age_group, history):
+ """Send message with typing effect and context memory"""
+ if not message.strip():
+ return history, "", "", ""
+
+ # Add user message to history
+ if history is None:
+ history = []
+
+ # Add user message with name
+ history.append([f"{name}: {message}", None])
+
+ # Show typing indicator with Albert thinking animation
+ typing_html = """
+
+
+ 🧠
+
+
+
Albert is thinking
+
+ ...
+
+
+
+
+ """
+
+ # Generate Albert's response with full context
+ albert_response = generate_albert_response(message, name, age_group, history)
+
+ # Add Albert's response with fast typing effect
+ import time
+ typed_response = ""
+ for i, char in enumerate(albert_response):
+ typed_response += char
+ history[-1][1] = f"{typed_response}|"
+ time.sleep(0.015) # Even faster typing speed
+
+ # Final response without cursor
+ history[-1][1] = f"{albert_response}"
+
+ # No context memory display
+ context_html = ""
+
+ # Add auto-scroll trigger
+ scroll_script = """
+
+ """
+
+ return history, "", context_html, scroll_script
+
+ def clear_chat():
+ return [], "", "", ""
+
+ def initialize_chat(name, age_group):
+ if not name.strip():
+ return [], "", ""
+
+ welcome_message = f"Hi {name}! 🧠✨ I'm Albert, your learning buddy! I'm so excited to help you learn! I'll remember our conversation so you can ask follow-up questions anytime. What would you like to know about today? 😊🚀"
+ return [[None, f"{welcome_message}"]], "", ""
+
+ # Connect event handlers
+ send_btn.click(
+ fn=send_message_with_typing,
+ inputs=[chat_input, user_name, user_age_group, chat_display],
+ outputs=[chat_display, chat_input, context_display, typing_indicator]
+ )
+
+ clear_btn.click(
+ fn=clear_chat,
+ outputs=[chat_display, context_display, context_display, typing_indicator]
+ )
+
+ # Initialize chat when name is entered
+ user_name.change(
+ fn=initialize_chat,
+ inputs=[user_name, user_age_group],
+ outputs=[chat_display, context_display, context_display]
+ )
+
+ with gr.TabItem("📚 Lesson Plan Generator"):
+ with gr.Row():
+ with gr.Column():
+ # Modern Form Section
+ gr.HTML("""
+
+
📚 Lesson Plan Generator
+
Create comprehensive lesson plans with AI assistance
+ """)
+
+ topic = gr.Textbox(label="📝 Topic", placeholder="e.g., Photosynthesis, World War II, Algebra")
+ subject = gr.Dropdown(
+ choices=["Science", "Mathematics", "History", "English Language Arts", "Geography", "Art"],
+ label="📚 Subject",
+ value="Science",
+ interactive=True
+ )
+ grade_level = gr.Dropdown(
+ choices=["K-2", "3-5", "6-8", "9-12"],
+ label="🎓 Grade Level",
+ value="6-8",
+ interactive=True
+ )
+ duration = gr.Slider(
+ minimum=30,
+ maximum=180,
+ step=15,
+ value=60,
+ label="⏱️ Duration (minutes)"
+ )
+ difficulty = gr.Dropdown(
+ choices=["Beginner", "Intermediate", "Advanced"],
+ label="🎯 Difficulty",
+ value="Intermediate",
+ interactive=True
+ )
+
+ generate_lesson_btn = gr.Button("🚀 Generate Lesson Plan", variant="primary")
+
+ gr.HTML("
")
+
+ with gr.Column():
+ # Modern Output Section
+ gr.HTML("""
+
+
📋 Generated Lesson Plan
+ """)
+
+ progress_display = gr.HTML("", visible=False)
+ lesson_plan_output = gr.Markdown(label="")
+
+ gr.HTML("")
+
+ # Modern Examples Section
+ gr.HTML("""
+
+
💡 Example Topics
+
Click on any example to get started quickly!
+ """)
+
+ gr.Dataset(
+ components=[topic, subject, grade_level, duration, difficulty],
+ samples=[
+ ["Photosynthesis", "Science", "6-8", 60, "Intermediate"],
+ ["World War II", "History", "9-12", 90, "Advanced"],
+ ["Basic Algebra", "Mathematics", "3-5", 45, "Beginner"]
+ ],
+ )
+
+ gr.HTML("
")
+
+ # Event handler for lesson plan generation
+ generate_lesson_btn.click(
+ fn=generate_lesson_plan_with_progress,
+ inputs=[topic, subject, grade_level, duration, difficulty],
+ outputs=[progress_display, lesson_plan_output],
+ show_progress=True
+ )
+
+
+ with gr.TabItem("📝 Content Generator"):
+ with gr.Row():
+ with gr.Column(scale=1):
+ # Modern Form Section
+ gr.HTML("""
+
+
📝 Content Generation
+
Generate educational materials tailored to your specific needs
+
+ """)
+
+ with gr.Group():
+ content_topic = gr.Textbox(label="📝 Topic", placeholder="e.g., Photosynthesis, World War II, Algebra")
+ content_subject = gr.Dropdown(
+ choices=["Science", "Mathematics", "History", "English Language Arts", "Geography", "Art"],
+ label="📚 Subject",
+ value="Science",
+ interactive=True
+ )
+ content_grade_level = gr.Dropdown(
+ choices=["K-2", "3-5", "6-8", "9-12"],
+ label="🎓 Grade Level",
+ value="6-8",
+ interactive=True
+ )
+ content_difficulty = gr.Dropdown(
+ choices=["Beginner", "Intermediate", "Advanced"],
+ label="🎯 Difficulty",
+ value="Intermediate",
+ interactive=True
+ )
+ content_type = gr.Dropdown(
+ choices=["Worksheets", "Handouts", "Study Guides", "Activities", "Presentations", "Lesson Materials"],
+ label="📄 Content Type",
+ value="Worksheets",
+ interactive=True
+ )
+ content_length = gr.Dropdown(
+ choices=["Short (1-2 pages)", "Medium (3-5 pages)", "Long (6+ pages)"],
+ label="📏 Length",
+ value="Medium (3-5 pages)",
+ interactive=True
+ )
+
+ generate_content_btn = gr.Button("🚀 Generate Content", variant="primary", size="lg")
+ clear_content_btn = gr.Button("🗑️ Clear", variant="secondary")
+
+ with gr.Column(scale=2):
+ # Modern Output Section
+ gr.HTML("""
+
+
📄 Generated Content
+
Your educational materials will appear here
+
+ """)
+
+ content_progress_display = gr.HTML("", visible=False)
+ content_output = gr.HTML(value="Your educational content will appear here...
")
+
+ # Content examples
+ content_examples = gr.Dataset(
+ components=[content_topic, content_subject, content_grade_level, content_difficulty, content_type, content_length],
+ samples=[
+ ["Photosynthesis", "Science", "6-8", "Intermediate", "Worksheets", "Medium (3-5 pages)"],
+ ["World War II", "History", "9-12", "Advanced", "Study Guides", "Long (6+ pages)"],
+ ["Basic Algebra", "Mathematics", "3-5", "Beginner", "Activities", "Short (1-2 pages)"]
+ ],
+ label="💡 Content Examples"
+ )
+
+ # Event handlers for content generation
+ generate_content_btn.click(
+ fn=generate_content_with_progress,
+ inputs=[content_topic, content_subject, content_grade_level, content_difficulty, content_type, content_length],
+ outputs=[content_progress_display, content_output],
+ show_progress=True
+ )
+
+ clear_content_btn.click(
+ fn=lambda: ("", "Your educational content will appear here..."),
+ inputs=[],
+ outputs=[content_progress_display, content_output]
+ )
+
+ with gr.TabItem("🎯 Quiz Generator"):
+ with gr.Row():
+ with gr.Column():
+ # Modern Form Section
+ gr.HTML("""
+
+
🎯 Quiz Generator
+
Create engaging quizzes with multiple question types
+ """)
+
+ quiz_topic = gr.Textbox(label="📝 Quiz Topic", placeholder="e.g., Photosynthesis, World War II, Algebra")
+ quiz_subject = gr.Dropdown(
+ choices=["Science", "Mathematics", "History", "English Language Arts", "Geography", "Art"],
+ label="📚 Subject",
+ value="Science",
+ interactive=True
+ )
+ quiz_grade_level = gr.Dropdown(
+ choices=["K-2", "3-5", "6-8", "9-12"],
+ label="🎓 Grade Level",
+ value="6-8",
+ interactive=True
+ )
+ question_count = gr.Slider(
+ minimum=3,
+ maximum=20,
+ step=1,
+ value=5,
+ label="❓ Number of Questions"
+ )
+ question_types = gr.CheckboxGroup(
+ choices=["Multiple Choice", "True/False", "Short Answer", "Fill in the Blank"],
+ label="📋 Question Types",
+ value=["Multiple Choice", "True/False"]
+ )
+
+ generate_quiz_btn = gr.Button("🚀 Generate Quiz", variant="primary")
+
+ gr.HTML("
")
+
+ with gr.Column():
+ # Modern Output Section
+ gr.HTML("""
+
+
📋 Generated Quiz
+ """)
+
+ quiz_progress_display = gr.HTML(visible=False)
+ quiz_output = gr.Markdown(label="")
+
+ gr.HTML("")
+
+ # Event handlers
+ generate_quiz_btn.click(
+ fn=generate_quiz_with_progress,
+ inputs=[quiz_topic, quiz_subject, quiz_grade_level, question_count, question_types],
+ outputs=[quiz_progress_display, quiz_output],
+ show_progress=True
+ )
+
+ # Examples
+ gr.Examples(
+ examples=[
+ ["Photosynthesis", "Science", "6-8", 5, ["Multiple Choice", "True/False"]],
+ ["World War II", "History", "9-12", 8, ["Multiple Choice", "Short Answer"]],
+ ["Basic Algebra", "Mathematics", "3-5", 4, ["Multiple Choice", "Fill in the Blank"]]
+ ],
+ inputs=[quiz_topic, quiz_subject, quiz_grade_level, question_count, question_types]
+ )
+
+
+ with gr.TabItem("🔧 Admin Dashboard", visible=False): # Hidden by default
+ with gr.Row():
+ with gr.Column():
+ gr.Markdown("""
+ ## 🔧 Admin Dashboard
+
+ **Access Level**: Administrator Only
+ **Database**: SQLite (feedback.db)
+ **Last Updated**: Real-time
+ """)
+
+ refresh_btn = gr.Button("🔄 Refresh Data", variant="secondary")
+ view_feedback_btn = gr.Button("📊 View All Feedback", variant="primary")
+
+ with gr.Column():
+ admin_output = gr.Markdown(label="Admin Data")
+
+ # Event handlers for admin
+ def format_stats():
+ stats = get_feedback_stats()
+ result = f"""
+# 📊 Feedback Statistics
+
+**Total Feedback Entries:** {stats['total_feedback']}
+**Average Rating:** {stats['avg_rating']}/5 ⭐
+**Database Status:** ✅ Active
+
+## Recent Feedback (Last 5)
+"""
+ for entry in stats['recent_feedback']:
+ timestamp, feedback_type, rating, comments, user_email = entry
+ result += f"""
+### Entry from {timestamp}
+- **Type:** {feedback_type}
+- **Rating:** {rating}/5 ⭐
+- **Comments:** {comments[:100]}{'...' if len(comments) > 100 else ''}
+- **Email:** {user_email if user_email else 'Not provided'}
+---
+"""
+ return result
+
+ refresh_btn.click(
+ fn=format_stats,
+ outputs=admin_output
+ )
+
+ view_feedback_btn.click(
+ fn=view_feedback_admin,
+ outputs=admin_output
+ )
+
+if __name__ == "__main__":
+ demo.launch()