ror HF Staff commited on
Commit
9aa1b3d
·
1 Parent(s): 66b7161
Files changed (4) hide show
  1. app.py +23 -82
  2. requirements.txt +2 -1
  3. styles.css +35 -581
  4. utils.py +0 -51
app.py CHANGED
@@ -1,108 +1,49 @@
1
- import matplotlib.pyplot as plt
2
- import matplotlib
3
  import pandas as pd
4
  import gradio as gr
5
  import random
6
 
7
- from utils import logger
8
-
9
-
10
- # Configure matplotlib to prevent memory warnings and set dark background
11
- matplotlib.rcParams['figure.facecolor'] = '#000000'
12
- matplotlib.rcParams['axes.facecolor'] = '#000000'
13
- matplotlib.rcParams['savefig.facecolor'] = '#000000'
14
- plt.ioff() # Turn off interactive mode to prevent figure accumulation
15
-
16
-
17
- # Function to generate random data for the plot
18
  def generate_random_data():
19
- """Generate random data points for the scatter plot."""
20
- n_points = random.randint(20, 50) # Random number of points
21
- x_data = [random.uniform(-100, 100) for _ in range(n_points)]
22
- y_data = [random.uniform(-100, 100) for _ in range(n_points)]
23
- return pd.DataFrame({"x": x_data, "y": y_data})
24
-
25
 
26
- # Function to get current description text
27
- def get_description_text():
28
- """Get description text."""
29
- msg = [
30
- "Random Data Dashboard",
31
- "-",
32
- "Click summary to refresh data",
33
- "Demo visualization",
34
- ]
35
- msg = ["**" + x + "**" for x in msg] + [""]
36
- msg.append("*Random scatter plot data*<br>*Updated on each click*")
37
- return "<br>".join(msg)
38
-
39
- # Load CSS from external file
40
  def load_css():
 
41
  try:
42
  with open("styles.css", "r") as f:
43
- css_content = f.read()
44
-
45
- return css_content
46
  except FileNotFoundError:
47
- logger.warning("styles.css not found, using minimal default styles")
48
  return "body { background: #000; color: #fff; }"
49
 
 
 
 
50
 
51
- # Create the Gradio interface with sidebar and dark theme
52
- with gr.Blocks(title="Model Test Results Dashboard", css=load_css(), fill_height=True, fill_width=True) as demo:
53
-
54
-
55
  with gr.Row():
56
- # Sidebar for model selection
57
  with gr.Column(scale=1, elem_classes=["sidebar"]):
58
  gr.Markdown("# 🤖 TCID", elem_classes=["sidebar-title"])
 
 
59
 
60
- # Description with integrated last update time
61
- description_text = get_description_text()
62
- description_display = gr.Markdown(description_text, elem_classes=["sidebar-description"])
63
-
64
- # Summary button
65
- summary_button = gr.Button(
66
- "summary\n📊",
67
- variant="primary",
68
- size="lg",
69
- elem_classes=["summary-button"]
70
- )
71
-
72
-
73
- # Main content area
74
  with gr.Column(elem_classes=["main-content"]):
75
- # Summary display (default view)
76
- summary_display = gr.ScatterPlot(
77
  generate_random_data(),
78
- x = "x",
79
- y = "y",
80
  height="100vh",
81
  container=False,
82
  show_fullscreen_button=True,
83
- elem_classes=["plot-container"],
84
  )
85
 
 
 
86
 
87
-
88
- # Summary button click handler
89
- def refresh_plot_data():
90
- """Generate new random data for the plot."""
91
- new_data = generate_random_data()
92
- return new_data, get_description_text()
93
-
94
- summary_button.click(
95
- fn=refresh_plot_data,
96
- outputs=[summary_display, description_display]
97
- )
98
-
99
- # Auto-update description when the interface loads
100
- demo.load(
101
- fn=get_description_text,
102
- outputs=[description_display]
103
- )
104
-
105
-
106
- # Gradio entrypoint
107
  if __name__ == "__main__":
108
- demo.launch()
 
 
 
1
  import pandas as pd
2
  import gradio as gr
3
  import random
4
 
 
 
 
 
 
 
 
 
 
 
 
5
  def generate_random_data():
6
+ """Generate random scatter plot data."""
7
+ n_points = random.randint(20, 50)
8
+ return pd.DataFrame({
9
+ "x": [random.uniform(-100, 100) for _ in range(n_points)],
10
+ "y": [random.uniform(-100, 100) for _ in range(n_points)]
11
+ })
12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  def load_css():
14
+ """Load CSS styling."""
15
  try:
16
  with open("styles.css", "r") as f:
17
+ return f.read()
 
 
18
  except FileNotFoundError:
 
19
  return "body { background: #000; color: #fff; }"
20
 
21
+ def refresh_plot():
22
+ """Generate new random data and update description."""
23
+ return generate_random_data(), "**Transformer CI Dashboard**<br>-<br>**AMD runs on MI325**<br>**NVIDIA runs on A10**<br><br>*This dashboard only tracks important models*<br>*(Data refreshed)*"
24
 
25
+ # Create Gradio interface
26
+ with gr.Blocks(title="Random Data Dashboard", css=load_css(), fill_height=True, fill_width=True) as demo:
 
 
27
  with gr.Row():
28
+ # Sidebar
29
  with gr.Column(scale=1, elem_classes=["sidebar"]):
30
  gr.Markdown("# 🤖 TCID", elem_classes=["sidebar-title"])
31
+ description = gr.Markdown("**Transformer CI Dashboard**<br>-<br>**AMD runs on MI325**<br>**NVIDIA runs on A10**<br><br>*This dashboard only tracks important models*", elem_classes=["sidebar-description"])
32
+ summary_btn = gr.Button("summary\n📊", variant="primary", size="lg", elem_classes=["summary-button"])
33
 
34
+ # Main plot area
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  with gr.Column(elem_classes=["main-content"]):
36
+ plot = gr.ScatterPlot(
 
37
  generate_random_data(),
38
+ x="x", y="y",
 
39
  height="100vh",
40
  container=False,
41
  show_fullscreen_button=True,
42
+ elem_classes=["plot-container"]
43
  )
44
 
45
+ # Button click handler
46
+ summary_btn.click(fn=refresh_plot, outputs=[plot, description])
47
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  if __name__ == "__main__":
49
+ demo.launch()
requirements.txt CHANGED
@@ -1 +1,2 @@
1
- matplotlib>=3.8
 
 
1
+ gradio
2
+ pandas
styles.css CHANGED
@@ -1,396 +1,100 @@
1
- /* Global dark theme with configurable margins */
2
  :root {
3
- --main-content-bottom-margin: 10px; /* Configurable bottom margin for main content */
4
- --plot-padding: 10%; /* Configurable padding for plot centering in percent */
5
  }
6
 
 
7
  .gradio-container {
8
  background-color: #000000 !important;
9
  color: white !important;
10
  height: 100vh !important;
11
- max-height: 100vh !important;
12
  overflow: hidden !important;
13
  }
14
 
15
- /* Remove borders from all components */
16
- .gr-box, .gr-form, .gr-panel {
17
- border: none !important;
18
- background-color: #000000 !important;
19
- }
20
-
21
- /* Simplified sidebar styling */
22
  .sidebar {
23
  background: linear-gradient(145deg, #111111, #1a1a1a) !important;
24
- border: none !important;
25
  padding: 15px !important;
26
- margin: 0 !important;
27
  height: 100vh !important;
28
  position: fixed !important;
29
  left: 0 !important;
30
  top: 0 !important;
31
  width: 300px !important;
32
- box-sizing: border-box !important;
33
  overflow-y: auto !important;
34
- overflow-x: hidden !important;
35
  }
36
 
37
- /* Target the actual Gradio column containing sidebar */
38
- div[data-testid="column"]:has(.sidebar) {
39
- height: 100vh !important;
40
- overflow-y: auto !important;
41
- overflow-x: hidden !important;
42
- }
43
-
44
- /* Individual sidebar elements */
45
  .sidebar-title {
46
- margin-bottom: 10px !important;
47
- }
48
-
49
- .sidebar-description {
50
- margin-bottom: 15px !important;
51
- }
52
-
53
- /* Summary button styling - distinct from model buttons */
54
- .summary-button {
55
- background: linear-gradient(135deg, #4a4a4a, #3e3e3e) !important;
56
- color: white !important;
57
- border: 2px solid #555555 !important;
58
- margin: 0 0 15px 0 !important;
59
- border-radius: 5px !important;
60
- padding: 12px 10px !important;
61
- transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1) !important;
62
- position: relative !important;
63
- overflow: hidden !important;
64
- box-shadow:
65
- 0 4px 15px rgba(0, 0, 0, 0.3),
66
- inset 0 1px 0 rgba(255, 255, 255, 0.2) !important;
67
- font-weight: 600 !important;
68
- font-size: 14px !important;
69
- text-transform: uppercase !important;
70
- letter-spacing: 0.3px !important;
71
- font-family: monospace !important;
72
- height: 60px !important;
73
- display: flex !important;
74
- flex-direction: column !important;
75
- justify-content: center !important;
76
- align-items: center !important;
77
- line-height: 1.2 !important;
78
- width: 100% !important;
79
- max-width: 100% !important;
80
- min-width: 0 !important;
81
- box-sizing: border-box !important;
82
- }
83
-
84
- .model-header {
85
- margin-bottom: 10px !important;
86
- background: linear-gradient(135deg, #2a2a2a, #1e1e1e) !important;
87
- color: white !important;
88
- border: 1px solid #333 !important;
89
- border-radius: 5px !important;
90
- font-weight: 600 !important;
91
- font-size: 14px !important;
92
  font-family: monospace !important;
93
- text-align: left !important;
94
- width: 100% !important;
95
- }
96
-
97
- .model-header:hover {
98
- background: linear-gradient(135deg, #3a3a3a, #2e2e2e) !important;
99
- }
100
-
101
- .sidebar-links {
102
- margin-top: 15px !important;
103
- }
104
-
105
- /* Hide scrollbar for model container */
106
- .model-container::-webkit-scrollbar {
107
- display: none !important;
108
- }
109
-
110
- /* Ensure all sidebar content fits within width */
111
- .sidebar * {
112
- max-width: 100% !important;
113
- word-wrap: break-word !important;
114
- overflow-wrap: break-word !important;
115
- }
116
-
117
- /* Specific control for markdown content */
118
- .sidebar .markdown,
119
- .sidebar h1,
120
- .sidebar h2,
121
- .sidebar h3,
122
- .sidebar p {
123
- max-width: 100% !important;
124
- word-wrap: break-word !important;
125
- overflow: hidden !important;
126
- }
127
-
128
- /* Sidebar scrollbar styling */
129
- .sidebar::-webkit-scrollbar {
130
- width: 8px !important;
131
- background: #111111 !important;
132
- }
133
-
134
- .sidebar::-webkit-scrollbar-track {
135
- background: #111111 !important;
136
- }
137
-
138
- .sidebar::-webkit-scrollbar-thumb {
139
- background-color: #333333 !important;
140
- border-radius: 4px !important;
141
- }
142
-
143
- .sidebar::-webkit-scrollbar-thumb:hover {
144
- background-color: #555555 !important;
145
- }
146
-
147
- /* Force button containers to single column in model list */
148
- .model-list .gr-button,
149
- .model-list button {
150
- display: block !important;
151
- width: 100% !important;
152
- max-width: 100% !important;
153
- margin: 4px 0 !important;
154
- flex: none !important;
155
- }
156
-
157
- /* Simple unfolding menu with invisible scrollbar */
158
- .model-list-visible {
159
- max-height: 200px !important;
160
- overflow-y: auto !important;
161
- transition: max-height 0.3s ease !important;
162
- scrollbar-width: none !important;
163
- -ms-overflow-style: none !important;
164
  }
165
 
166
- .model-list-visible::-webkit-scrollbar {
167
- width: 0px !important;
168
- background: transparent !important;
169
- }
170
-
171
- .model-list-hidden {
172
- max-height: 0 !important;
173
- overflow: hidden !important;
174
- transition: max-height 0.3s ease !important;
175
- }
176
-
177
-
178
- /* Model button styling */
179
- .model-button {
180
- background: linear-gradient(135deg, #2a2a2a, #1e1e1e) !important;
181
- color: white !important;
182
- margin: 3px 0 !important;
183
- padding: 8px 12px !important;
184
- font-weight: 600 !important;
185
  font-size: 14px !important;
186
- text-transform: uppercase !important;
187
- letter-spacing: 0.3px !important;
188
  font-family: monospace !important;
189
- width: 100% !important;
190
- max-width: 100% !important;
191
- white-space: nowrap !important;
192
- text-overflow: ellipsis !important;
193
- display: block !important;
194
- cursor: pointer !important;
195
- transition: all 0.3s ease !important;
196
- border: 1px solid #333 !important;
197
- border-radius: 5px !important;
198
- }
199
-
200
- .model-button:hover {
201
- background: linear-gradient(135deg, #3a3a3a, #2e2e2e) !important;
202
- border-color: #74b9ff !important;
203
- color: #74b9ff !important;
204
- transform: translateY(-1px) !important;
205
- box-shadow: 0 2px 8px rgba(116, 185, 255, 0.2) !important;
206
- }
207
-
208
- /* Model buttons with failures - fuzzy red border with inner glow */
209
- .model-button-failed {
210
- border: 1px solid #712626 !important;
211
- box-shadow: inset 0 0 8px rgba(204, 68, 68, 0.4) !important;
212
- }
213
-
214
- .model-button-failed:hover {
215
- border-color: #712626 !important;
216
- box-shadow: 0 0 12px rgba(255, 107, 107, 0.5) !important;
217
- }
218
-
219
- /*
220
- .model-button:active {
221
- background: linear-gradient(135deg, #2a2a2a, #1e1e1e) !important;
222
- color: #5a9bd4 !important;
223
- }
224
- */
225
-
226
- /* Model stats badge */
227
- .model-stats {
228
- display: flex !important;
229
- justify-content: space-between !important;
230
- align-items: center !important;
231
- margin-top: 8px !important;
232
- font-size: 12px !important;
233
- opacity: 0.8 !important;
234
  }
235
 
236
- .stats-badge {
237
- background: rgba(116, 185, 255, 0.2) !important;
238
- padding: 4px 8px !important;
239
- border-radius: 10px !important;
240
- font-weight: 500 !important;
241
- font-size: 11px !important;
242
  color: #74b9ff !important;
 
243
  }
244
 
245
- .success-indicator {
246
- width: 8px !important;
247
- height: 8px !important;
248
- border-radius: 50% !important;
249
- display: inline-block !important;
250
- margin-right: 6px !important;
251
- }
252
-
253
- .success-high { background-color: #4CAF50 !important; }
254
- .success-medium { background-color: #FF9800 !important; }
255
- .success-low { background-color: #F44336 !important; }
256
-
257
- /* Refresh button styling */
258
- .refresh-button {
259
- background: linear-gradient(135deg, #2d5aa0, #1e3f73) !important;
260
- color: white !important;
261
- border: 1px solid #3a6bc7 !important;
262
- margin: 0 0 10px 0 !important;
263
- border-radius: 5px !important;
264
- padding: 6px 8px !important;
265
- transition: all 0.3s ease !important;
266
- font-weight: 500 !important;
267
- font-size: 11px !important;
268
- text-transform: lowercase !important;
269
- letter-spacing: 0.1px !important;
270
- font-family: monospace !important;
271
- width: 100% !important;
272
- max-width: 100% !important;
273
- min-width: 0 !important;
274
- box-sizing: border-box !important;
275
- white-space: nowrap !important;
276
- overflow: hidden !important;
277
- text-overflow: ellipsis !important;
278
- }
279
-
280
- .refresh-button:hover {
281
- background: linear-gradient(135deg, #3a6bc7, #2d5aa0) !important;
282
- border-color: #4a7bd9 !important;
283
  }
284
 
285
- /* Summary button styling - distinct from model buttons */
286
  .summary-button {
287
  background: linear-gradient(135deg, #4a4a4a, #3e3e3e) !important;
288
  color: white !important;
289
  border: 2px solid #555555 !important;
290
- margin: 0 0 15px 0 !important;
291
  border-radius: 5px !important;
292
  padding: 12px 10px !important;
293
- transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1) !important;
294
- position: relative !important;
295
- overflow: hidden !important;
296
- box-shadow:
297
- 0 4px 15px rgba(0, 0, 0, 0.3),
298
- inset 0 1px 0 rgba(255, 255, 255, 0.2) !important;
299
  font-weight: 600 !important;
300
  font-size: 14px !important;
301
  text-transform: uppercase !important;
302
- letter-spacing: 0.3px !important;
303
  font-family: monospace !important;
304
  height: 60px !important;
305
- display: flex !important;
306
- flex-direction: column !important;
307
- justify-content: center !important;
308
- align-items: center !important;
309
- line-height: 1.2 !important;
310
- width: 100% !important;
311
- max-width: 100% !important;
312
- min-width: 0 !important;
313
- box-sizing: border-box !important;
314
- }
315
-
316
- /* Simplified Gradio layout control */
317
- .sidebar .gr-column,
318
- .sidebar .gradio-column {
319
- width: 100% !important;
320
- }
321
-
322
- /* Simplified Gradio targeting */
323
- div[data-testid="column"]:has(.sidebar) {
324
- width: 300px !important;
325
- min-width: 300px !important;
326
- }
327
-
328
- /* Button container with fixed height - DISABLED */
329
- /*
330
- .button-container {
331
- height: 50vh !important;
332
- max-height: 50vh !important;
333
- overflow-y: auto !important;
334
- overflow-x: hidden !important;
335
- scrollbar-width: thin !important;
336
- scrollbar-color: #333333 #111111 !important;
337
  width: 100% !important;
338
- max-width: 100% !important;
339
- box-sizing: border-box !important;
340
- padding: 5px 0 !important;
341
- margin-top: 10px !important;
342
  }
343
- */
344
-
345
- /* Removed simple scroll CSS - was hiding buttons */
346
 
347
  .summary-button:hover {
348
  background: linear-gradient(135deg, #5a5a5a, #4e4e4e) !important;
349
  color: #74b9ff !important;
350
- border-color: #666666 !important;
351
  }
352
 
353
- .summary-button:active {
354
- background: linear-gradient(135deg, #4a4a4a, #3e3e3e) !important;
355
- color: #5a9bd4 !important;
356
- }
357
-
358
- /* Regular button styling for non-model buttons */
359
- .gr-button:not(.model-button):not(.summary-button) {
360
- background-color: #222222 !important;
361
- color: white !important;
362
- border: 1px solid #444444 !important;
363
- margin: 5px 0 !important;
364
- border-radius: 8px !important;
365
- transition: all 0.3s ease !important;
366
- }
367
-
368
- .gr-button:not(.model-button):not(.summary-button):hover {
369
- background-color: #333333 !important;
370
- border-color: #666666 !important;
371
  }
372
 
373
- /* Plot container with smooth transitions and no scrolling */
374
  .plot-container {
375
  background-color: #000000 !important;
376
- border: none !important;
377
- transition: opacity 0.6s ease-in-out !important;
378
  flex: 1 1 auto !important;
379
- min-height: 0 !important;
380
  overflow: hidden !important;
381
  padding: var(--plot-padding) !important;
382
- box-sizing: border-box !important;
383
  display: flex !important;
384
  justify-content: center !important;
385
  align-items: center !important;
386
  }
387
 
388
- /* Plot container scrollbar removed - using overflow: hidden */
389
-
390
- /* Gradio plot component styling */
391
  .gr-plot {
392
  background-color: #000000 !important;
393
- transition: opacity 0.6s ease-in-out !important;
394
  width: 100% !important;
395
  height: 100% !important;
396
  display: flex !important;
@@ -398,269 +102,19 @@ div[data-testid="column"]:has(.sidebar) {
398
  align-items: center !important;
399
  }
400
 
401
- .gr-plot .gradio-plot {
402
- background-color: #000000 !important;
403
- transition: opacity 0.6s ease-in-out !important;
404
- width: 100% !important;
405
- height: 100% !important;
406
- }
407
-
408
  .gr-plot img {
409
- transition: opacity 0.6s ease-in-out !important;
410
  max-width: 100% !important;
411
  max-height: 100% !important;
412
  object-fit: contain !important;
413
  }
414
 
415
- /* Target the plot wrapper */
416
- div[data-testid="plot"] {
417
- background-color: #000000 !important;
418
- }
419
-
420
- /* Target all possible plot containers */
421
- .plot-container img,
422
- .gr-plot img,
423
- .gradio-plot img {
424
- background-color: #000000 !important;
425
- }
426
-
427
- /* Ensure plot area background */
428
- .gr-plot > div,
429
- .plot-container > div {
430
- background-color: #000000 !important;
431
- }
432
-
433
- /* Prevent white flash during plot updates */
434
- .plot-container::before {
435
- content: "";
436
- position: absolute;
437
- top: 0;
438
- left: 0;
439
- right: 0;
440
- bottom: 0;
441
- background-color: #000000;
442
- z-index: -1;
443
- }
444
-
445
- /* Force all plot elements to have black background */
446
- .plot-container *,
447
- .gr-plot *,
448
- div[data-testid="plot"] * {
449
- background-color: #000000 !important;
450
- }
451
-
452
- /* Override any white backgrounds in matplotlib */
453
- .plot-container canvas,
454
- .gr-plot canvas {
455
- background-color: #000000 !important;
456
- }
457
-
458
- /* Text elements */
459
- h1, h2, h3, p, .markdown {
460
- color: white !important;
461
- }
462
-
463
- /* Sidebar header enhancement */
464
- .sidebar h1 {
465
- background: linear-gradient(45deg, #74b9ff, #a29bfe) !important;
466
- -webkit-background-clip: text !important;
467
- -webkit-text-fill-color: transparent !important;
468
- background-clip: text !important;
469
- text-align: center !important;
470
- margin-bottom: 15px !important;
471
- font-size: 28px !important;
472
- font-weight: 700 !important;
473
- font-family: monospace !important;
474
- }
475
-
476
- /* Sidebar description text */
477
- .sidebar p {
478
- text-align: center !important;
479
- margin-bottom: 20px !important;
480
- line-height: 1.5 !important;
481
- font-size: 14px !important;
482
- font-family: monospace !important;
483
- }
484
-
485
- /* CI Links styling */
486
- .sidebar a {
487
- color: #74b9ff !important;
488
- text-decoration: none !important;
489
- font-weight: 500 !important;
490
- font-family: monospace !important;
491
- transition: color 0.3s ease !important;
492
- }
493
-
494
- .sidebar a:hover {
495
- color: #a29bfe !important;
496
- text-decoration: underline !important;
497
- }
498
-
499
- .sidebar strong {
500
- color: #74b9ff !important;
501
- font-weight: 600 !important;
502
- font-family: monospace !important;
503
- }
504
-
505
- .sidebar em {
506
- color: #a29bfe !important;
507
- font-style: normal !important;
508
- opacity: 0.9 !important;
509
- font-family: monospace !important;
510
- }
511
-
512
- /* Remove all borders globally */
513
  * {
514
  border-color: transparent !important;
515
  }
516
 
517
- /* Main content area */
518
- .main-content {
519
- background-color: #000000 !important;
520
- padding: 0px 20px var(--main-content-bottom-margin, 10px) 20px !important;
521
- margin-left: 300px !important;
522
- height: 100vh !important;
523
- overflow-y: auto !important;
524
- box-sizing: border-box !important;
525
- display: flex !important;
526
- flex-direction: column !important;
527
- }
528
-
529
- /* Custom scrollbar for main content */
530
- .main-content {
531
- scrollbar-width: thin !important;
532
- scrollbar-color: #333333 #000000 !important;
533
- }
534
-
535
- .main-content::-webkit-scrollbar {
536
- width: 8px !important;
537
- background: #000000 !important;
538
- }
539
-
540
- .main-content::-webkit-scrollbar-track {
541
- background: #000000 !important;
542
- }
543
-
544
- .main-content::-webkit-scrollbar-thumb {
545
- background-color: #333333 !important;
546
- border-radius: 4px !important;
547
- }
548
-
549
- .main-content::-webkit-scrollbar-thumb:hover {
550
- background-color: #555555 !important;
551
- }
552
-
553
- /* Failed tests display - seamless appearance with constrained height */
554
- .failed-tests textarea {
555
- background-color: #000000 !important;
556
- color: #FFFFFF !important;
557
- font-family: monospace !important;
558
- font-size: 14px !important;
559
- border: none !important;
560
- padding: 10px !important;
561
- outline: none !important;
562
- line-height: 1.4 !important;
563
- height: 180px !important;
564
- max-height: 180px !important;
565
- min-height: 180px !important;
566
- overflow-y: auto !important;
567
- resize: none !important;
568
- scrollbar-width: thin !important;
569
- scrollbar-color: #333333 #000000 !important;
570
- scroll-behavior: auto !important;
571
- transition: opacity 0.5s ease-in-out !important;
572
- scroll-padding-top: 0 !important;
573
- }
574
-
575
- /* WebKit scrollbar styling for failed tests */
576
- .failed-tests textarea::-webkit-scrollbar {
577
- width: 8px !important;
578
- }
579
-
580
- .failed-tests textarea::-webkit-scrollbar-track {
581
- background: #000000 !important;
582
- }
583
-
584
- .failed-tests textarea::-webkit-scrollbar-thumb {
585
- background-color: #333333 !important;
586
- border-radius: 4px !important;
587
- }
588
-
589
- .failed-tests textarea::-webkit-scrollbar-thumb:hover {
590
- background-color: #555555 !important;
591
- }
592
-
593
- /* Prevent white flash in text boxes during updates */
594
- .failed-tests::before {
595
- content: "";
596
- position: absolute;
597
- top: 0;
598
- left: 0;
599
- right: 0;
600
- bottom: 0;
601
- background-color: #000000;
602
- z-index: -1;
603
- }
604
-
605
- .failed-tests {
606
- background-color: #000000 !important;
607
- height: 200px !important;
608
- max-height: 200px !important;
609
- min-height: 200px !important;
610
- position: relative;
611
- transition: opacity 0.5s ease-in-out !important;
612
- flex-shrink: 0 !important;
613
- }
614
-
615
- .failed-tests .gr-textbox {
616
- background-color: #000000 !important;
617
- border: none !important;
618
- height: 180px !important;
619
- max-height: 180px !important;
620
- min-height: 180px !important;
621
- transition: opacity 0.5s ease-in-out !important;
622
- }
623
-
624
- /* Force all textbox elements to have black background */
625
- .failed-tests *,
626
- .failed-tests .gr-textbox *,
627
- .failed-tests textarea * {
628
- background-color: #000000 !important;
629
- }
630
-
631
- /* Summary display styling */
632
- .summary-display textarea {
633
- background-color: #000000 !important;
634
- color: #FFFFFF !important;
635
- font-family: monospace !important;
636
- font-size: 24px !important;
637
- border: none !important;
638
- padding: 20px !important;
639
- outline: none !important;
640
- line-height: 2 !important;
641
- text-align: right !important;
642
- resize: none !important;
643
- }
644
-
645
- .summary-display {
646
  background-color: #000000 !important;
647
- }
648
-
649
- /* Detail view layout */
650
- .detail-view {
651
- display: flex !important;
652
- flex-direction: column !important;
653
- height: 100% !important;
654
- min-height: 0 !important;
655
- }
656
-
657
- /* JavaScript to reset scroll position */
658
- .scroll-reset {
659
- animation: resetScroll 0.1s ease;
660
- }
661
-
662
- @keyframes resetScroll {
663
- 0% { scroll-behavior: auto; }
664
- 100% { scroll-behavior: auto; }
665
- }
666
-
 
1
+ /* CSS Variables */
2
  :root {
3
+ --plot-padding: 10%;
 
4
  }
5
 
6
+ /* Global styles */
7
  .gradio-container {
8
  background-color: #000000 !important;
9
  color: white !important;
10
  height: 100vh !important;
 
11
  overflow: hidden !important;
12
  }
13
 
14
+ /* Sidebar */
 
 
 
 
 
 
15
  .sidebar {
16
  background: linear-gradient(145deg, #111111, #1a1a1a) !important;
 
17
  padding: 15px !important;
 
18
  height: 100vh !important;
19
  position: fixed !important;
20
  left: 0 !important;
21
  top: 0 !important;
22
  width: 300px !important;
 
23
  overflow-y: auto !important;
 
24
  }
25
 
 
 
 
 
 
 
 
 
26
  .sidebar-title {
27
+ background: linear-gradient(45deg, #74b9ff, #a29bfe) !important;
28
+ -webkit-background-clip: text !important;
29
+ -webkit-text-fill-color: transparent !important;
30
+ text-align: center !important;
31
+ font-size: 28px !important;
32
+ font-weight: 700 !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  font-family: monospace !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  }
35
 
36
+ .sidebar-description {
37
+ text-align: center !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  font-size: 14px !important;
 
 
39
  font-family: monospace !important;
40
+ margin-bottom: 15px !important;
41
+ line-height: 1.5 !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  }
43
 
44
+ .sidebar-description strong {
 
 
 
 
 
45
  color: #74b9ff !important;
46
+ font-weight: 600 !important;
47
  }
48
 
49
+ .sidebar-description em {
50
+ color: #a29bfe !important;
51
+ font-style: normal !important;
52
+ opacity: 0.9 !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  }
54
 
55
+ /* Summary button */
56
  .summary-button {
57
  background: linear-gradient(135deg, #4a4a4a, #3e3e3e) !important;
58
  color: white !important;
59
  border: 2px solid #555555 !important;
 
60
  border-radius: 5px !important;
61
  padding: 12px 10px !important;
 
 
 
 
 
 
62
  font-weight: 600 !important;
63
  font-size: 14px !important;
64
  text-transform: uppercase !important;
 
65
  font-family: monospace !important;
66
  height: 60px !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  width: 100% !important;
 
 
 
 
68
  }
 
 
 
69
 
70
  .summary-button:hover {
71
  background: linear-gradient(135deg, #5a5a5a, #4e4e4e) !important;
72
  color: #74b9ff !important;
 
73
  }
74
 
75
+ /* Main content */
76
+ .main-content {
77
+ background-color: #000000 !important;
78
+ margin-left: 300px !important;
79
+ height: 100vh !important;
80
+ display: flex !important;
81
+ flex-direction: column !important;
 
 
 
 
 
 
 
 
 
 
 
82
  }
83
 
84
+ /* Plot container */
85
  .plot-container {
86
  background-color: #000000 !important;
 
 
87
  flex: 1 1 auto !important;
 
88
  overflow: hidden !important;
89
  padding: var(--plot-padding) !important;
 
90
  display: flex !important;
91
  justify-content: center !important;
92
  align-items: center !important;
93
  }
94
 
95
+ /* Plot elements */
 
 
96
  .gr-plot {
97
  background-color: #000000 !important;
 
98
  width: 100% !important;
99
  height: 100% !important;
100
  display: flex !important;
 
102
  align-items: center !important;
103
  }
104
 
 
 
 
 
 
 
 
105
  .gr-plot img {
 
106
  max-width: 100% !important;
107
  max-height: 100% !important;
108
  object-fit: contain !important;
109
  }
110
 
111
+ /* Remove borders globally */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
  * {
113
  border-color: transparent !important;
114
  }
115
 
116
+ /* Force black backgrounds */
117
+ .plot-container *,
118
+ .gr-plot * {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
  background-color: #000000 !important;
120
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
utils.py DELETED
@@ -1,51 +0,0 @@
1
- import logging
2
- import sys
3
- from datetime import datetime
4
-
5
-
6
- class TimestampFormatter(logging.Formatter):
7
- """Custom formatter that matches the existing timestamp format used in print statements."""
8
-
9
- def format(self, record):
10
- # Create timestamp in the same format as existing print statements
11
- timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
12
-
13
- # Format the message with timestamp prefix
14
- if record.levelno == logging.WARNING:
15
- return f"WARNING: {record.getMessage()}"
16
- elif record.levelno == logging.ERROR:
17
- return f"Error {record.getMessage()}"
18
- else:
19
- return f"[{timestamp}] {record.getMessage()}"
20
-
21
-
22
- def setup_logger(name="tcid", level=logging.INFO):
23
- """Set up logger with custom timestamp formatting to match existing print format."""
24
- logger = logging.getLogger(name)
25
-
26
- # Avoid adding multiple handlers if logger already exists
27
- if logger.handlers:
28
- return logger
29
-
30
- logger.setLevel(level)
31
-
32
- # Create console handler
33
- handler = logging.StreamHandler(sys.stdout)
34
- handler.setLevel(level)
35
-
36
- # Set custom formatter
37
- formatter = TimestampFormatter()
38
- handler.setFormatter(formatter)
39
-
40
- logger.addHandler(handler)
41
-
42
- return logger
43
-
44
-
45
- # Create default logger instance
46
- logger = setup_logger()
47
-
48
-
49
-
50
- def generate_underlined_line(text: str) -> str:
51
- return text + "\n" + "─" * len(text)