Dhruv Pawar commited on
Commit
74ac60c
·
1 Parent(s): 9d5bde0

working on ui

Browse files
Files changed (2) hide show
  1. src/ui/modern_interface.py +310 -0
  2. src/ui/styles.py +376 -144
src/ui/modern_interface.py ADDED
@@ -0,0 +1,310 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Modern UI with all features - Compact & High Quality
3
+ """
4
+ import gradio as gr
5
+ from src.core.reasoner import AdvancedReasoner
6
+ from src.config.constants import ReasoningMode, ModelConfig
7
+ from src.config.settings import AppConfig
8
+ from src.ui.handlers import EventHandlers
9
+ from src.ui.components import UIComponents
10
+
11
+ # Compact Modern CSS
12
+ MODERN_CSS = """
13
+ <style>
14
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
15
+ :root{--primary:#6366f1;--bg:#0f172a;--surface:rgba(255,255,255,0.05);--border:rgba(255,255,255,0.1);--text:#f1f5f9;--glow:0 0 20px rgba(99,102,241,0.3)}
16
+ *{font-family:'Inter',sans-serif}
17
+ body{background:linear-gradient(135deg,#0f172a 0%,#1e293b 100%);color:var(--text)}
18
+ .hero-header{background:linear-gradient(135deg,rgba(99,102,241,0.2),rgba(139,92,246,0.2));backdrop-filter:blur(20px);border:1px solid var(--border);border-radius:16px;padding:2rem;margin-bottom:1.5rem;box-shadow:var(--glow);animation:slideIn 0.5s ease}
19
+ .hero-header h1{font-size:2rem;font-weight:700;background:linear-gradient(135deg,#f1f5f9,#a5b4fc);-webkit-background-clip:text;-webkit-text-fill-color:transparent;margin:0 0 0.5rem}
20
+ .badges{display:flex;flex-wrap:wrap;gap:0.5rem;margin-top:1rem}
21
+ .badge{padding:0.4rem 0.8rem;background:var(--surface);border:1px solid var(--border);border-radius:8px;font-size:0.8rem;transition:all 0.3s}
22
+ .badge:hover{background:rgba(99,102,241,0.1);border-color:var(--primary);transform:translateY(-2px)}
23
+ .metrics-card{background:linear-gradient(135deg,rgba(16,185,129,0.1),rgba(6,182,212,0.1));backdrop-filter:blur(20px);border:1px solid rgba(16,185,129,0.2);border-radius:12px;padding:1.2rem;margin-top:1rem}
24
+ .metric-row{display:flex;justify-content:space-between;padding:0.5rem 0;border-bottom:1px solid var(--border)}
25
+ .metric-row:last-child{border-bottom:none}
26
+ .metric-label{color:#cbd5e1;font-size:0.85rem}
27
+ .metric-value{font-weight:700;font-family:monospace}
28
+ .status-active{color:#10b981}
29
+ .status-idle{color:#f59e0b}
30
+ @keyframes slideIn{from{opacity:0;transform:translateY(-20px)}to{opacity:1;transform:translateY(0)}}
31
+ .gradio-button{border-radius:8px;font-weight:600;transition:all 0.3s}
32
+ .gradio-button:hover{transform:translateY(-2px)}
33
+ </style>
34
+ """
35
+
36
+ # Compact Header
37
+ HEADER = f"""
38
+ <div class="hero-header">
39
+ <h1>🧠 AI Reasoning System Pro</h1>
40
+ <p style="color:#cbd5e1;margin:0">Advanced reasoning with Tree of Thoughts, Constitutional AI & Real-time Analytics</p>
41
+ <div class="badges">
42
+ <div class="badge">🌳 Tree of Thoughts</div>
43
+ <div class="badge">🛡️ Constitutional AI</div>
44
+ <div class="badge">🔬 {len(ReasoningMode)} Modes</div>
45
+ <div class="badge">⚡ Real-Time</div>
46
+ <div class="badge">💾 Smart Cache</div>
47
+ <div class="badge">📊 Analytics</div>
48
+ </div>
49
+ </div>
50
+ """
51
+
52
+ def create_metrics_html(reasoner):
53
+ """Compact metrics display"""
54
+ m = reasoner.metrics
55
+ cache = reasoner.cache.get_stats()
56
+ status = "status-active" if m.tokens_used > 0 else "status-idle"
57
+ return f"""
58
+ <div class="metrics-card">
59
+ <div class="metric-row"><span class="metric-label">⚡ Inference</span><span class="metric-value">{m.inference_time:.2f}s</span></div>
60
+ <div class="metric-row"><span class="metric-label">🚀 Speed</span><span class="metric-value">{m.tokens_per_second:.1f} tok/s</span></div>
61
+ <div class="metric-row"><span class="metric-label">🧠 Depth</span><span class="metric-value">{m.reasoning_depth} steps</span></div>
62
+ <div class="metric-row"><span class="metric-label">💬 Total</span><span class="metric-value">{m.total_conversations}</span></div>
63
+ <div class="metric-row"><span class="metric-label">📊 Tokens</span><span class="metric-value">{m.tokens_used:,}</span></div>
64
+ <div class="metric-row"><span class="metric-label">💾 Cache</span><span class="metric-value">{cache['hit_rate']}%</span></div>
65
+ <div class="metric-row"><span class="metric-label">📡 Status</span><span class="metric-value {status}">{"Active" if m.tokens_used > 0 else "Ready"}</span></div>
66
+ </div>
67
+ """
68
+
69
+ def create_modern_ui():
70
+ """Create modern UI with all features"""
71
+ reasoner = AdvancedReasoner()
72
+ components = UIComponents()
73
+ handlers = EventHandlers(reasoner)
74
+
75
+ with gr.Blocks(
76
+ theme=gr.themes.Soft(
77
+ primary_hue=AppConfig.THEME_PRIMARY,
78
+ secondary_hue=AppConfig.THEME_SECONDARY,
79
+ font=gr.themes.GoogleFont("Inter")
80
+ ),
81
+ css=MODERN_CSS,
82
+ title="🧠 AI Reasoning System Pro"
83
+ ) as demo:
84
+
85
+ gr.HTML(HEADER)
86
+
87
+ # Main Tabs
88
+ with gr.Tabs() as tabs:
89
+
90
+ # TAB 1: Reasoning Workspace
91
+ with gr.Tab("💬 Reasoning Workspace"):
92
+ with gr.Row():
93
+ with gr.Column(scale=4):
94
+ chatbot = gr.Chatbot(
95
+ label="💬 Reasoning Workspace",
96
+ height=600,
97
+ show_copy_button=True,
98
+ type="messages",
99
+ bubble_full_width=False,
100
+ avatar_images=(
101
+ "https://api.dicebear.com/7.x/avataaars/svg?seed=User&backgroundColor=6366f1",
102
+ "https://api.dicebear.com/7.x/bottts/svg?seed=AI&backgroundColor=8b5cf6"
103
+ )
104
+ )
105
+
106
+ msg = gr.Textbox(
107
+ placeholder="💭 Ask me anything... I'll use advanced reasoning to solve complex problems.",
108
+ label="Query Input",
109
+ lines=3,
110
+ max_lines=10,
111
+ show_label=False
112
+ )
113
+
114
+ with gr.Row():
115
+ submit_btn = gr.Button("🚀 Process", variant="primary", scale=2, size="lg")
116
+ clear_btn = gr.Button("🗑️ Clear", scale=1, size="lg")
117
+ pdf_btn = gr.Button("📄 PDF", scale=1, size="lg", variant="secondary")
118
+ toggle_sidebar_btn = gr.Button("⚙️ Settings", scale=1, size="lg", variant="secondary")
119
+
120
+ # Collapsible Sidebar
121
+ with gr.Column(scale=1, visible=True) as sidebar:
122
+ gr.Markdown("### ⚙️ Configuration")
123
+
124
+ reasoning_mode = gr.Radio(
125
+ choices=components.get_reasoning_mode_choices(),
126
+ value=ReasoningMode.TREE_OF_THOUGHTS.value,
127
+ label="🧠 Reasoning Method",
128
+ info="Select reasoning strategy"
129
+ )
130
+
131
+ prompt_template = gr.Dropdown(
132
+ choices=components.get_prompt_template_choices(),
133
+ value="Custom",
134
+ label="📝 Prompt Template",
135
+ info="Pre-built templates"
136
+ )
137
+
138
+ enable_critique = gr.Checkbox(
139
+ label="🔍 Enable Self-Critique",
140
+ value=True,
141
+ info="Auto validation"
142
+ )
143
+
144
+ use_cache = gr.Checkbox(
145
+ label="💾 Use Cache",
146
+ value=True,
147
+ info="Faster responses"
148
+ )
149
+
150
+ model = gr.Dropdown(
151
+ choices=components.get_model_choices(),
152
+ value=ModelConfig.LLAMA_70B.model_id,
153
+ label="🤖 AI Model"
154
+ )
155
+
156
+ with gr.Accordion("🎛️ Advanced", open=False):
157
+ temperature = gr.Slider(
158
+ AppConfig.MIN_TEMPERATURE,
159
+ AppConfig.MAX_TEMPERATURE,
160
+ value=AppConfig.DEFAULT_TEMPERATURE,
161
+ step=0.1,
162
+ label="🌡️ Temperature"
163
+ )
164
+
165
+ max_tokens = gr.Slider(
166
+ AppConfig.MIN_TOKENS,
167
+ 8000,
168
+ value=AppConfig.DEFAULT_MAX_TOKENS,
169
+ step=500,
170
+ label="📊 Max Tokens"
171
+ )
172
+
173
+ gr.Markdown("### 📊 Live Metrics")
174
+ metrics_display = gr.HTML(value=create_metrics_html(reasoner))
175
+
176
+ with gr.Accordion("ℹ️ System Info", open=False):
177
+ gr.HTML(components.get_system_info_html(reasoner))
178
+
179
+ pdf_file_output = gr.File(label="📥 Download PDF", visible=True, file_types=[".pdf"])
180
+ sidebar_visible_state = gr.State(value=True)
181
+
182
+ # TAB 2: Export & History
183
+ with gr.Tab("📤 Export & History"):
184
+ gr.Markdown("### 📤 Export Conversations")
185
+ gr.Markdown("Export your conversations in multiple formats with optional metadata.")
186
+
187
+ with gr.Row():
188
+ export_format = gr.Radio(
189
+ choices=["json", "markdown", "txt", "pdf"],
190
+ value="markdown",
191
+ label="Export Format"
192
+ )
193
+ include_meta = gr.Checkbox(
194
+ label="Include Metadata",
195
+ value=True,
196
+ info="Timestamps, models, metrics"
197
+ )
198
+
199
+ export_btn = gr.Button("📥 Export Now", variant="primary", size="lg")
200
+ export_output = gr.Code(label="Preview", language="markdown", lines=15)
201
+ download_file = gr.File(label="📥 Download File", file_types=[".json", ".md", ".txt", ".pdf"])
202
+
203
+ gr.Markdown("---")
204
+ gr.Markdown("### 🔍 Search Conversations")
205
+
206
+ with gr.Row():
207
+ search_input = gr.Textbox(
208
+ placeholder="Enter keyword to search...",
209
+ scale=3,
210
+ label="Search Query",
211
+ show_label=False
212
+ )
213
+ search_btn = gr.Button("🔍 Search", scale=1, size="lg")
214
+
215
+ search_results = gr.Markdown("💡 **Tip:** Enter a keyword and click Search.")
216
+
217
+ gr.Markdown("---")
218
+ gr.Markdown("### 📊 Conversation History")
219
+ history_stats = gr.Markdown("Loading statistics...")
220
+
221
+ # TAB 3: Analytics
222
+ with gr.Tab("📊 Analytics & Insights"):
223
+ gr.Markdown("### 📊 Performance Analytics Dashboard")
224
+ refresh_btn = gr.Button("🔄 Refresh Analytics", variant="primary", size="lg")
225
+
226
+ with gr.Row():
227
+ with gr.Column():
228
+ gr.Markdown("#### ⚡ Performance Metrics")
229
+ analytics_display = gr.HTML(components.get_empty_analytics_html())
230
+
231
+ with gr.Column():
232
+ gr.Markdown("#### 💾 Cache Statistics")
233
+ cache_display = gr.Markdown("No cache data yet. Start a conversation to see cache performance.")
234
+
235
+ gr.Markdown("---")
236
+ gr.Markdown("### 📈 Usage Distribution")
237
+
238
+ with gr.Row():
239
+ with gr.Column():
240
+ gr.Markdown("#### 🤖 Model Usage")
241
+ model_dist = gr.Markdown("No data yet. Models will be tracked as you use them.")
242
+
243
+ with gr.Column():
244
+ gr.Markdown("#### 🧠 Reasoning Mode Usage")
245
+ mode_dist = gr.Markdown("No data yet. Reasoning modes will be tracked as you use them.")
246
+
247
+ # TAB 4: Settings
248
+ with gr.Tab("⚙️ Settings"):
249
+ gr.Markdown("### ⚙️ Application Settings")
250
+ gr.Markdown("Current configuration and system controls.")
251
+ gr.HTML(components.get_settings_table_html())
252
+
253
+ gr.Markdown("---")
254
+ gr.Markdown("### 🔧 System Actions")
255
+
256
+ with gr.Row():
257
+ clear_cache_btn = gr.Button("🗑️ Clear Cache", variant="stop", size="lg")
258
+ reset_metrics_btn = gr.Button("🔄 Reset Metrics", variant="secondary", size="lg")
259
+
260
+ cache_status = gr.Markdown("")
261
+
262
+ # Event Handlers
263
+ def toggle_sidebar(visible):
264
+ return gr.update(visible=not visible), not visible
265
+
266
+ # Reasoning workspace handlers
267
+ submit_btn.click(
268
+ handlers.process_message,
269
+ [msg, chatbot, reasoning_mode, enable_critique, model, temperature, max_tokens, prompt_template, use_cache],
270
+ [chatbot, metrics_display]
271
+ ).then(lambda: "", None, msg)
272
+
273
+ msg.submit(
274
+ handlers.process_message,
275
+ [msg, chatbot, reasoning_mode, enable_critique, model, temperature, max_tokens, prompt_template, use_cache],
276
+ [chatbot, metrics_display]
277
+ ).then(lambda: "", None, msg)
278
+
279
+ clear_btn.click(handlers.reset_chat, None, [chatbot, metrics_display])
280
+ pdf_btn.click(handlers.download_chat_pdf, None, pdf_file_output)
281
+ toggle_sidebar_btn.click(toggle_sidebar, sidebar_visible_state, [sidebar, sidebar_visible_state])
282
+
283
+ # Export handlers (corrected method name)
284
+ export_btn.click(
285
+ handlers.export_conversation,
286
+ [export_format, include_meta],
287
+ [export_output, download_file]
288
+ )
289
+
290
+ search_btn.click(
291
+ handlers.search_conversations,
292
+ search_input,
293
+ search_results
294
+ )
295
+
296
+ # Analytics handlers
297
+ refresh_btn.click(
298
+ handlers.refresh_analytics,
299
+ None,
300
+ [analytics_display, cache_display, model_dist, mode_dist]
301
+ )
302
+
303
+ # Settings handlers
304
+ clear_cache_btn.click(handlers.clear_cache_action, None, cache_status)
305
+ reset_metrics_btn.click(handlers.reset_metrics_action, None, cache_status)
306
+
307
+ # Load initial data
308
+ demo.load(handlers.update_history_stats, None, history_stats)
309
+
310
+ return demo
src/ui/styles.py CHANGED
@@ -4,263 +4,495 @@ CSS styles for the Gradio interface
4
 
5
  CUSTOM_CSS = """
6
  @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600&display=swap');
7
-
8
  :root {
9
- --primary-gradient: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
10
- --success-gradient: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
11
- --shadow-lg: 0 10px 40px rgba(0,0,0,0.15);
12
- --border-radius: 16px;
13
- --transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  }
15
 
16
- /* ==================== HEADER ==================== */
17
 
18
  .research-header {
19
- background: var(--primary-gradient);
20
- padding: 3rem 2.5rem;
21
- border-radius: var(--border-radius);
22
- color: white;
23
- margin-bottom: 2rem;
24
- box-shadow: var(--shadow-lg);
25
- animation: slideDown 0.6s ease-out;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  }
27
 
28
- .research-header h1 {
29
- font-size: 2.5rem;
30
- font-weight: 800;
31
- margin-bottom: 1rem;
32
- text-shadow: 2px 2px 4px rgba(0,0,0,0.2);
33
  }
34
 
 
 
35
  .badge {
36
- background: rgba(255,255,255,0.25);
37
- backdrop-filter: blur(10px);
38
- color: white;
39
- padding: 0.5rem 1.2rem;
40
- border-radius: 25px;
41
- font-size: 0.9rem;
42
- margin: 0.3rem;
43
- display: inline-block;
44
- transition: var(--transition);
45
- border: 1px solid rgba(255,255,255,0.2);
46
  }
47
 
48
  .badge:hover {
49
- transform: translateY(-2px);
50
- background: rgba(255,255,255,0.35);
 
 
51
  }
52
 
53
- /* ==================== METRICS CARD ==================== */
54
 
55
  .metrics-card {
56
- background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%);
57
- border-left: 5px solid #667eea;
58
- padding: 1.8rem;
59
- border-radius: var(--border-radius);
60
- margin: 1rem 0;
61
- font-family: 'JetBrains Mono', monospace;
62
- transition: var(--transition);
63
- box-shadow: 0 2px 8px rgba(0,0,0,0.08);
64
- color: #2c3e50 !important;
 
 
 
 
 
 
65
  }
66
 
67
  .metrics-card * {
68
- color: #2c3e50 !important;
 
69
  }
70
 
71
  .metrics-card strong {
72
- color: #1a202c !important;
73
- font-weight: 700 !important;
74
  }
75
 
76
- .metrics-card:hover {
77
- transform: translateX(5px);
78
- box-shadow: 0 4px 12px rgba(0,0,0,0.12);
 
79
  }
80
 
81
  /* ==================== ANALYTICS PANEL ==================== */
82
 
83
  .analytics-panel {
84
- background: var(--success-gradient);
85
- color: white;
86
- padding: 2rem;
87
- border-radius: var(--border-radius);
88
- animation: fadeIn 0.5s ease-out;
89
- box-shadow: var(--shadow-lg);
 
90
  }
91
 
92
  .analytics-panel * {
93
- color: white !important;
94
  }
95
 
96
  .analytics-panel h3 {
97
- margin-bottom: 1rem;
98
- font-size: 1.5rem;
 
 
99
  }
100
 
101
  .analytics-panel p {
102
- line-height: 1.6;
 
 
103
  }
104
 
105
  .analytics-panel strong {
106
- font-weight: 600;
 
107
  }
108
 
109
  /* ==================== STATUS INDICATORS ==================== */
110
 
111
- .status-active {
112
- color: #10b981 !important;
113
- font-weight: bold;
114
- animation: pulse 2s infinite;
115
- text-shadow: 0 0 10px rgba(16, 185, 129, 0.5);
 
 
116
  }
117
 
118
- /* ==================== ANIMATIONS ==================== */
119
 
120
- @keyframes slideDown {
121
- from { opacity: 0; transform: translateY(-30px); }
122
- to { opacity: 1; transform: translateY(0); }
 
 
 
 
 
 
123
  }
124
 
125
- @keyframes fadeIn {
126
- from { opacity: 0; transform: scale(0.95); }
127
- to { opacity: 1; transform: scale(1); }
 
128
  }
129
 
130
- @keyframes pulse {
131
- 0%, 100% { opacity: 1; }
132
- 50% { opacity: 0.7; }
133
  }
134
 
135
- /* ==================== GLOBAL STYLES ==================== */
136
 
137
- .gradio-container {
138
- font-family: 'Inter', sans-serif !important;
139
- max-width: 1600px !important;
 
 
 
 
140
  }
141
 
142
- .gr-button {
143
- transition: var(--transition) !important;
 
 
144
  }
145
 
146
- .gr-button:hover {
147
- transform: translateY(-2px) !important;
148
- box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3) !important;
 
 
 
 
 
 
 
 
 
 
149
  }
150
 
151
- /* ==================== MARKDOWN TEXT FIX ==================== */
 
 
 
152
 
153
  .gr-markdown .metrics-card {
154
- color: #2c3e50 !important;
155
  }
156
 
157
  .gr-markdown .metrics-card p {
158
- color: #2c3e50 !important;
159
- margin: 0.25rem 0 !important;
160
  }
161
 
162
  .gr-markdown .metrics-card span {
163
- color: #2c3e50 !important;
164
  }
165
 
166
- /* ==================== SIDEBAR TOGGLE ==================== */
167
 
168
  .sidebar-hidden {
169
  display: none !important;
170
  }
171
 
172
  .toggle-btn {
173
- position: fixed;
174
- right: 20px;
175
- top: 50%;
176
- transform: translateY(-50%);
177
- z-index: 1000;
178
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
179
- color: white;
180
- border: none;
181
- border-radius: 50%;
182
- width: 50px;
183
- height: 50px;
184
- cursor: pointer;
185
- box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
186
- transition: all 0.3s ease;
187
- font-size: 20px;
188
- display: flex;
189
- align-items: center;
190
- justify-content: center;
191
  }
192
 
193
  .toggle-btn:hover {
194
- transform: translateY(-50%) scale(1.1);
195
- box-shadow: 0 6px 20px rgba(102, 126, 234, 0.6);
196
  }
197
 
198
  .settings-column {
199
- transition: all 0.3s ease-in-out;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
200
  }
201
 
202
- .fullscreen-chat .gradio-container {
203
- max-width: 98% !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
204
  }
205
 
206
  /* ==================== RESPONSIVE DESIGN ==================== */
207
 
208
  @media (max-width: 768px) {
 
 
 
 
 
 
 
 
209
  .research-header h1 {
210
- font-size: 1.8rem;
211
  }
212
 
213
  .badge {
214
- font-size: 0.75rem;
215
- padding: 0.4rem 0.8rem;
216
  }
217
 
218
- .toggle-btn {
219
- width: 40px;
220
- height: 40px;
221
- font-size: 16px;
222
- right: 10px;
 
 
 
 
 
 
 
 
 
 
 
223
  }
224
 
225
  .metrics-card {
226
- padding: 1.2rem;
227
- font-size: 0.9rem;
228
  }
229
  }
230
 
231
- /* ==================== DARK MODE SUPPORT ==================== */
232
 
233
- @media (prefers-color-scheme: dark) {
234
- .metrics-card {
235
- background: linear-gradient(135deg, #1e293b 0%, #334155 100%);
236
- color: #e2e8f0 !important;
237
  }
238
-
239
- .metrics-card * {
240
- color: #e2e8f0 !important;
 
 
 
 
 
 
 
 
241
  }
242
 
243
- .metrics-card strong {
244
- color: #f1f5f9 !important;
245
  }
246
  }
247
 
248
- /* ==================== LOADING SPINNER ==================== */
249
 
250
- .loading-spinner {
251
- border: 3px solid #f3f3f3;
252
- border-top: 3px solid #667eea;
253
- border-radius: 50%;
254
- width: 40px;
255
- height: 40px;
256
- animation: spin 1s linear infinite;
257
- margin: 20px auto;
258
  }
259
 
260
- @keyframes spin {
261
- 0% { transform: rotate(0deg); }
262
- 100% { transform: rotate(360deg); }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
263
  }
 
 
 
 
 
264
  """
265
 
266
- SIDEBAR_CSS = CUSTOM_CSS
 
4
 
5
  CUSTOM_CSS = """
6
  @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600&display=swap');
 
7
  :root {
8
+ --bg-primary: #0f0f0f;
9
+ --bg-secondary: #1a1a1a;
10
+ --bg-tertiary: #2d2d2d;
11
+ --bg-card: #1e1e1e;
12
+ --text-primary: #ffffff;
13
+ --text-secondary: #b0b0b0;
14
+ --text-tertiary: #888888;
15
+ --accent-primary: #3b82f6;
16
+ --accent-secondary: #60a5fa;
17
+ --accent-gradient: linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%);
18
+ --success: #10b981;
19
+ --warning: #f59e0b;
20
+ --error: #ef4444;
21
+ --border-color: #333333;
22
+ --border-light: #404040;
23
+ --shadow-dark: 0 4px 6px -1px rgba(0, 0, 0, 0.6);
24
+ --shadow-medium: 0 2px 4px rgba(0, 0, 0, 0.4);
25
+ --shadow-light: 0 1px 2px rgba(0, 0, 0, 0.3);
26
+ --border-radius: 12px;
27
+ --border-radius-lg: 16px;
28
+ --transition: all 0.3s ease;
29
+ }
30
+
31
+ /* ==================== GLOBAL STYLES ==================== */
32
+
33
+ .gradio-container {
34
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif !important;
35
+ background: var(--bg-primary) !important;
36
+ color: var(--text-primary) !important;
37
+ max-width: 1400px !important;
38
+ margin: 0 auto !important;
39
+ padding: 20px !important;
40
+ }
41
+
42
+ * {
43
+ color: var(--text-primary) !important;
44
  }
45
 
46
+ /* ==================== ENHANCED HEADER ==================== */
47
 
48
  .research-header {
49
+ background: var(--bg-card) !important;
50
+ border: 1px solid var(--border-color) !important;
51
+ padding: 2.5rem 2rem !important;
52
+ border-radius: var(--border-radius-lg) !important;
53
+ margin-bottom: 2rem !important;
54
+ box-shadow: var(--shadow-dark) !important;
55
+ position: relative;
56
+ overflow: hidden;
57
+ }
58
+
59
+ .research-header::before {
60
+ content: '';
61
+ position: absolute;
62
+ top: 0;
63
+ left: 0;
64
+ right: 0;
65
+ height: 3px;
66
+ background: var(--accent-gradient);
67
+ }
68
+
69
+ .research-header h1 {
70
+ font-size: 2.5rem !important;
71
+ font-weight: 700 !important;
72
+ margin-bottom: 1rem !important;
73
+ color: var(--text-primary) !important;
74
+ background: none !important;
75
+ -webkit-text-fill-color: var(--text-primary) !important;
76
  }
77
 
78
+ .research-header .subtitle {
79
+ font-size: 1.1rem !important;
80
+ color: var(--text-secondary) !important;
81
+ margin-bottom: 1.5rem !important;
82
+ line-height: 1.6 !important;
83
  }
84
 
85
+ /* ==================== CLEAN BADGES ==================== */
86
+
87
  .badge {
88
+ background: var(--bg-tertiary) !important;
89
+ color: var(--text-secondary) !important;
90
+ padding: 0.5rem 1rem !important;
91
+ border-radius: 20px !important;
92
+ font-size: 0.85rem !important;
93
+ font-weight: 500 !important;
94
+ margin: 0.3rem !important;
95
+ border: 1px solid var(--border-light) !important;
96
+ transition: var(--transition) !important;
97
+ backdrop-filter: none !important;
98
  }
99
 
100
  .badge:hover {
101
+ background: var(--accent-primary) !important;
102
+ color: white !important;
103
+ transform: translateY(-2px) !important;
104
+ box-shadow: var(--shadow-medium) !important;
105
  }
106
 
107
+ /* ==================== HIGH CONTRAST CARDS ==================== */
108
 
109
  .metrics-card {
110
+ background: var(--bg-card) !important;
111
+ border: 1px solid var(--border-color) !important;
112
+ padding: 1.5rem !important;
113
+ border-radius: var(--border-radius) !important;
114
+ margin: 1rem 0 !important;
115
+ font-family: 'JetBrains Mono', monospace !important;
116
+ transition: var(--transition) !important;
117
+ box-shadow: var(--shadow-medium) !important;
118
+ position: relative;
119
+ }
120
+
121
+ .metrics-card:hover {
122
+ border-color: var(--accent-primary) !important;
123
+ transform: translateY(-2px) !important;
124
+ box-shadow: var(--shadow-dark) !important;
125
  }
126
 
127
  .metrics-card * {
128
+ color: var(--text-primary) !important;
129
+ font-weight: 400 !important;
130
  }
131
 
132
  .metrics-card strong {
133
+ color: var(--accent-secondary) !important;
134
+ font-weight: 600 !important;
135
  }
136
 
137
+ .metrics-card p {
138
+ margin: 0.5rem 0 !important;
139
+ line-height: 1.5 !important;
140
+ color: var(--text-primary) !important;
141
  }
142
 
143
  /* ==================== ANALYTICS PANEL ==================== */
144
 
145
  .analytics-panel {
146
+ background: var(--bg-card) !important;
147
+ border: 1px solid var(--border-color) !important;
148
+ color: var(--text-primary) !important;
149
+ padding: 2rem !important;
150
+ border-radius: var(--border-radius) !important;
151
+ box-shadow: var(--shadow-dark) !important;
152
+ margin: 1rem 0 !important;
153
  }
154
 
155
  .analytics-panel * {
156
+ color: var(--text-primary) !important;
157
  }
158
 
159
  .analytics-panel h3 {
160
+ margin-bottom: 1.5rem !important;
161
+ font-size: 1.4rem !important;
162
+ font-weight: 600 !important;
163
+ color: var(--text-primary) !important;
164
  }
165
 
166
  .analytics-panel p {
167
+ line-height: 1.6 !important;
168
+ color: var(--text-secondary) !important;
169
+ margin-bottom: 1rem !important;
170
  }
171
 
172
  .analytics-panel strong {
173
+ color: var(--text-primary) !important;
174
+ font-weight: 600 !important;
175
  }
176
 
177
  /* ==================== STATUS INDICATORS ==================== */
178
 
179
+ .status-active {
180
+ color: var(--success) !important;
181
+ font-weight: 600 !important;
182
+ padding: 0.2rem 0.5rem !important;
183
+ background: rgba(16, 185, 129, 0.1) !important;
184
+ border-radius: 4px !important;
185
+ border: 1px solid rgba(16, 185, 129, 0.3) !important;
186
  }
187
 
188
+ /* ==================== BUTTON ENHANCEMENTS ==================== */
189
 
190
+ .gr-button {
191
+ background: var(--accent-primary) !important;
192
+ color: white !important;
193
+ border: none !important;
194
+ padding: 0.75rem 1.5rem !important;
195
+ border-radius: 8px !important;
196
+ font-weight: 500 !important;
197
+ transition: var(--transition) !important;
198
+ box-shadow: var(--shadow-medium) !important;
199
  }
200
 
201
+ .gr-button:hover {
202
+ background: var(--accent-secondary) !important;
203
+ transform: translateY(-2px) !important;
204
+ box-shadow: var(--shadow-dark) !important;
205
  }
206
 
207
+ .gr-button:active {
208
+ transform: translateY(0) !important;
 
209
  }
210
 
211
+ /* ==================== INPUT ENHANCEMENTS ==================== */
212
 
213
+ .gr-input, .gr-textbox, .gr-dropdown {
214
+ background: var(--bg-secondary) !important;
215
+ border: 1px solid var(--border-color) !important;
216
+ color: var(--text-primary) !important;
217
+ border-radius: 8px !important;
218
+ padding: 0.75rem 1rem !important;
219
+ transition: var(--transition) !important;
220
  }
221
 
222
+ .gr-input:focus, .gr-textbox:focus, .gr-dropdown:focus {
223
+ border-color: var(--accent-primary) !important;
224
+ box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.2) !important;
225
+ outline: none !important;
226
  }
227
 
228
+ .gr-input::placeholder, .gr-textbox::placeholder {
229
+ color: var(--text-tertiary) !important;
230
+ }
231
+
232
+ /* ==================== MARKDOWN TEXT FIXES ==================== */
233
+
234
+ .gr-markdown {
235
+ color: var(--text-primary) !important;
236
+ }
237
+
238
+ .gr-markdown p {
239
+ color: var(--text-primary) !important;
240
+ line-height: 1.6 !important;
241
  }
242
 
243
+ .gr-markdown strong {
244
+ color: var(--text-primary) !important;
245
+ font-weight: 600 !important;
246
+ }
247
 
248
  .gr-markdown .metrics-card {
249
+ color: var(--text-primary) !important;
250
  }
251
 
252
  .gr-markdown .metrics-card p {
253
+ color: var(--text-primary) !important;
 
254
  }
255
 
256
  .gr-markdown .metrics-card span {
257
+ color: var(--text-primary) !important;
258
  }
259
 
260
+ /* ==================== SIDEBAR & LAYOUT ==================== */
261
 
262
  .sidebar-hidden {
263
  display: none !important;
264
  }
265
 
266
  .toggle-btn {
267
+ background: var(--accent-primary) !important;
268
+ color: white !important;
269
+ border: none !important;
270
+ border-radius: 8px !important;
271
+ padding: 0.75rem !important;
272
+ cursor: pointer !important;
273
+ transition: var(--transition) !important;
274
+ box-shadow: var(--shadow-medium) !important;
 
 
 
 
 
 
 
 
 
 
275
  }
276
 
277
  .toggle-btn:hover {
278
+ background: var(--accent-secondary) !important;
279
+ transform: scale(1.05) !important;
280
  }
281
 
282
  .settings-column {
283
+ background: var(--bg-card) !important;
284
+ border: 1px solid var(--border-color) !important;
285
+ border-radius: var(--border-radius) !important;
286
+ padding: 1.5rem !important;
287
+ }
288
+
289
+ /* ==================== TABLE STYLES ==================== */
290
+
291
+ .gr-table {
292
+ background: var(--bg-card) !important;
293
+ border: 1px solid var(--border-color) !important;
294
+ border-radius: var(--border-radius) !important;
295
+ overflow: hidden !important;
296
+ }
297
+
298
+ .gr-table th {
299
+ background: var(--bg-tertiary) !important;
300
+ color: var(--text-primary) !important;
301
+ font-weight: 600 !important;
302
+ padding: 1rem !important;
303
+ border-bottom: 1px solid var(--border-color) !important;
304
+ }
305
+
306
+ .gr-table td {
307
+ padding: 1rem !important;
308
+ border-bottom: 1px solid var(--border-light) !important;
309
+ color: var(--text-primary) !important;
310
  }
311
 
312
+ .gr-table tr:hover {
313
+ background: var(--bg-tertiary) !important;
314
+ }
315
+
316
+ /* ==================== SCROLLBAR STYLING ==================== */
317
+
318
+ ::-webkit-scrollbar {
319
+ width: 8px;
320
+ height: 8px;
321
+ }
322
+
323
+ ::-webkit-scrollbar-track {
324
+ background: var(--bg-secondary);
325
+ border-radius: 4px;
326
+ }
327
+
328
+ ::-webkit-scrollbar-thumb {
329
+ background: var(--bg-tertiary);
330
+ border-radius: 4px;
331
+ }
332
+
333
+ ::-webkit-scrollbar-thumb:hover {
334
+ background: var(--accent-primary);
335
+ }
336
+
337
+ /* ==================== LOADING STATES ==================== */
338
+
339
+ .loading-spinner {
340
+ border: 3px solid var(--bg-tertiary);
341
+ border-top: 3px solid var(--accent-primary);
342
+ border-radius: 50%;
343
+ width: 40px;
344
+ height: 40px;
345
+ animation: spin 1s linear infinite;
346
+ margin: 20px auto;
347
+ }
348
+
349
+ @keyframes spin {
350
+ 0% { transform: rotate(0deg); }
351
+ 100% { transform: rotate(360deg); }
352
+ }
353
+
354
+ /* ==================== PROGRESS BARS ==================== */
355
+
356
+ .gr-progress {
357
+ background: var(--bg-tertiary) !important;
358
+ border-radius: 10px !important;
359
+ overflow: hidden !important;
360
+ }
361
+
362
+ .gr-progress .inner {
363
+ background: var(--accent-gradient) !important;
364
+ }
365
+
366
+ /* ==================== ALERT STYLES ==================== */
367
+
368
+ .gr-alert {
369
+ background: var(--bg-card) !important;
370
+ border: 1px solid var(--border-color) !important;
371
+ border-radius: var(--border-radius) !important;
372
+ padding: 1rem 1.5rem !important;
373
+ margin: 1rem 0 !important;
374
+ }
375
+
376
+ .gr-alert.success {
377
+ border-left: 4px solid var(--success) !important;
378
+ }
379
+
380
+ .gr-alert.warning {
381
+ border-left: 4px solid var(--warning) !important;
382
+ }
383
+
384
+ .gr-alert.error {
385
+ border-left: 4px solid var(--error) !important;
386
  }
387
 
388
  /* ==================== RESPONSIVE DESIGN ==================== */
389
 
390
  @media (max-width: 768px) {
391
+ .gradio-container {
392
+ padding: 1rem !important;
393
+ }
394
+
395
+ .research-header {
396
+ padding: 2rem 1.5rem !important;
397
+ }
398
+
399
  .research-header h1 {
400
+ font-size: 2rem !important;
401
  }
402
 
403
  .badge {
404
+ font-size: 0.8rem !important;
405
+ padding: 0.4rem 0.8rem !important;
406
  }
407
 
408
+ .metrics-card {
409
+ padding: 1.25rem !important;
410
+ }
411
+
412
+ .analytics-panel {
413
+ padding: 1.5rem !important;
414
+ }
415
+ }
416
+
417
+ @media (max-width: 480px) {
418
+ .research-header h1 {
419
+ font-size: 1.75rem !important;
420
+ }
421
+
422
+ .research-header .subtitle {
423
+ font-size: 1rem !important;
424
  }
425
 
426
  .metrics-card {
427
+ padding: 1rem !important;
428
+ font-size: 0.9rem !important;
429
  }
430
  }
431
 
432
+ /* ==================== ACCESSIBILITY ENHANCEMENTS ==================== */
433
 
434
+ @media (prefers-reduced-motion: reduce) {
435
+ * {
436
+ transition: none !important;
437
+ animation: none !important;
438
  }
439
+ }
440
+
441
+ /* High contrast mode support */
442
+ @media (prefers-contrast: high) {
443
+ :root {
444
+ --bg-primary: #000000;
445
+ --bg-secondary: #0a0a0a;
446
+ --bg-card: #111111;
447
+ --text-primary: #ffffff;
448
+ --text-secondary: #e0e0e0;
449
+ --border-color: #555555;
450
  }
451
 
452
+ .badge {
453
+ border: 2px solid var(--border-color) !important;
454
  }
455
  }
456
 
457
+ /* ==================== FOCUS INDICATORS ==================== */
458
 
459
+ button:focus-visible,
460
+ input:focus-visible,
461
+ select:focus-visible,
462
+ textarea:focus-visible {
463
+ outline: 2px solid var(--accent-primary) !important;
464
+ outline-offset: 2px !important;
 
 
465
  }
466
 
467
+ /* ==================== UTILITY CLASSES ==================== */
468
+
469
+ .text-primary { color: var(--text-primary) !important; }
470
+ .text-secondary { color: var(--text-secondary) !important; }
471
+ .text-accent { color: var(--accent-primary) !important; }
472
+ .bg-card { background: var(--bg-card) !important; }
473
+ .bg-secondary { background: var(--bg-secondary) !important; }
474
+
475
+ .border-light { border-color: var(--border-light) !important; }
476
+ .border-medium { border-color: var(--border-color) !important; }
477
+
478
+ .shadow-medium { box-shadow: var(--shadow-medium) !important; }
479
+ .shadow-dark { box-shadow: var(--shadow-dark) !important; }
480
+
481
+ /* ==================== CODE BLOCKS ==================== */
482
+
483
+ .gr-code {
484
+ background: var(--bg-secondary) !important;
485
+ border: 1px solid var(--border-color) !important;
486
+ border-radius: 8px !important;
487
+ padding: 1rem !important;
488
+ font-family: 'JetBrains Mono', monospace !important;
489
+ color: var(--text-primary) !important;
490
  }
491
+
492
+ .gr-code .token.keyword { color: var(--accent-secondary) !important; }
493
+ .gr-code .token.string { color: var(--success) !important; }
494
+ .gr-code .token.comment { color: var(--text-tertiary) !important; }
495
+ .gr-code .token.function { color: var(--accent-primary) !important; }
496
  """
497
 
498
+ SIDEBAR_CSS = CUSTOM_CSS