elmadany commited on
Commit
3786d08
·
verified ·
1 Parent(s): 709d464

Update public/index.html

Browse files
Files changed (1) hide show
  1. public/index.html +67 -61
public/index.html CHANGED
@@ -47,26 +47,47 @@
47
 
48
  /* --- HERO --- */
49
  .hero {
50
- max-width: 1000px; margin: 60px auto 100px; padding: 0 40px;
51
- position: relative; text-align: center;
 
 
 
 
 
 
 
 
 
52
  }
53
- .hero-content { z-index: 2; display: flex; flex-direction: column; align-items: center; }
54
  .conf-badge { background: white; color: black; display: inline-flex; align-items: center; gap: 10px; padding: 6px 16px; border-radius: 8px; margin-bottom: 30px; font-weight: 700; font-size: 14px; }
55
  .conf-badge i { color: #cc0000; font-size: 18px; }
56
  .hero h1 { font-family: 'Rubik', sans-serif; font-size: 64px; font-weight: 800; margin: 0; line-height: 1.1; }
57
  .hero h2 { font-family: 'Rubik', sans-serif; font-size: 32px; color: var(--text-yellow); margin: 15px 0 30px; font-weight: 700; }
58
  .hero p { color: #cbd5e1; font-size: 18px; line-height: 1.6; max-width: 700px; margin-bottom: 50px; }
 
59
  .hero-actions { display: flex; gap: 15px; flex-wrap: wrap; justify-content: center; }
60
- .action-btn { display: flex; align-items: center; gap: 8px; padding: 12px 24px; border-radius: 30px; color: white; font-weight: 600; font-size: 15px; transition: transform 0.2s; }
61
- .action-btn:hover { transform: translateY(-3px); color: white; }
62
- .bg-red { background: var(--grad-red); } .bg-purple { background: var(--grad-purple); }
63
 
64
- /* Wave Animation */
65
- .wave-bg { position: absolute; top: -50px; left: -50%; width: 200%; height: 100%; background: radial-gradient(circle, rgba(255,255,255,0.03) 0%, rgba(255,255,255,0) 70%); z-index: 0; pointer-events: none; }
66
- .audio-wave { height: 150px; display: flex; align-items: center; justify-content: center; gap: 6px; margin-top: 60px; mask-image: linear-gradient(to right, transparent, black 10%, black 90%, transparent); }
67
- .bar { width: 6px; background: #ffffff; border-radius: 99px; animation: bounce 1.2s ease-in-out infinite; }
68
- .bar:nth-child(odd) { animation-duration: 1.5s; } .bar:nth-child(2n) { animation-duration: 1.1s; }
69
- @keyframes bounce { 0%, 100% { height: 20px; } 50% { height: 120px; } }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
 
71
  /* --- CONTENT --- */
72
  .content-container { width: 80%; max-width: 1600px; margin: 0 auto; }
@@ -86,37 +107,17 @@
86
  .rank-info { font-size: 13px; color: #64748b; margin-top: 5px; font-style: italic; }
87
  .score-desc { font-size: 14px; color: #475569; background: #fff7ed; border-left: 4px solid #f97316; padding: 10px 15px; margin-bottom: 20px; border-radius: 4px; }
88
 
89
- /* --- NEW ASR BUTTON STYLES --- */
90
  .mode-btn {
91
- padding: 8px 20px;
92
- border-radius: 8px;
93
- font-weight: 600;
94
- font-size: 13px;
95
- cursor: pointer;
96
- transition: all 0.2s;
97
- border: 1px solid #e2e8f0;
98
- background: white;
99
- color: var(--simba-navy);
100
- }
101
- .mode-btn:hover {
102
- border-color: var(--text-yellow);
103
- color: var(--text-yellow);
104
- }
105
- .mode-btn.active {
106
- background-color: var(--simba-navy);
107
- color: white;
108
- border-color: var(--simba-navy);
109
- box-shadow: 0 4px 12px rgba(15, 23, 42, 0.15);
110
  }
 
 
111
 
112
- /* --- CHARTS --- */
113
- .chart-wrapper {
114
- width: 100%;
115
- /* Max height limits the chart size if small data */
116
- max-height: 400px;
117
- margin-bottom: 20px;
118
- display: none; /* Hidden by default */
119
- }
120
  canvas { max-width: 100%; }
121
 
122
  /* Summary Cards */
@@ -160,26 +161,30 @@
160
  <div class="nav-text"><span>Voice of a</span> Continent</div>
161
  </a>
162
  <div class="nav-links">
163
- <a href="https://aclanthology.org/2025.emnlp-main.559" target="_blank" class="nav-link">Paper</a>
164
  <a href="https://africa.dlnlp.ai/simba/" target="_blank" class="btn-submit">Submit New Results</a>
165
  </div>
166
  </nav>
167
 
168
  <div class="hero layout-width">
169
- <div class="wave-bg"></div>
170
  <div class="hero-content">
171
  <div class="conf-badge"><i class="fa-solid fa-location-dot"></i> EMNLP 2025 · Suzhou, China</div>
172
  <h1>SimbaBench Leaderboard</h1>
173
  <h2>Mapping Africa’s Speech Technology</h2>
174
  <p>SimbaBench bridges the digital divide with a unified suite for African AI: the largest open-source speech benchmark covering 61 languages.</p>
 
175
  <div class="hero-actions">
176
- <a href="https://aclanthology.org/2025.emnlp-main.559" target="_blank" class="action-btn bg-red"><i class="fa-regular fa-file-pdf"></i> Read Paper</a>
177
- <a href="https://africa.dlnlp.ai/simba" target="_blank" class="action-btn bg-purple"><i class="fa-solid fa-code-branch"></i> Official Website</a>
178
- </div>
179
- </div>
180
- <div class="hero-visual">
181
- <div class="audio-wave">
182
- <div class="bar"></div><div class="bar"></div><div class="bar"></div><div class="bar"></div><div class="bar"></div><div class="bar"></div><div class="bar"></div><div class="bar"></div><div class="bar"></div><div class="bar"></div><div class="bar"></div><div class="bar"></div><div class="bar"></div><div class="bar"></div><div class="bar"></div><div class="bar"></div>
 
 
 
 
 
183
  </div>
184
  </div>
185
  </div>
@@ -449,7 +454,7 @@
449
  function renderLanguageView() {
450
  const lang = document.getElementById('lang-select').value;
451
 
452
- // 1. ASR
453
  let asrRows = [];
454
  Object.keys(DATA.asr.by_model).forEach(modName => {
455
  const row = DATA.asr.by_model[modName].find(r => r.Language === lang);
@@ -457,14 +462,14 @@
457
  });
458
  asrRows.sort((a,b) => (a.wer - b.wer) || (a.cer - b.cer));
459
 
460
- // 2. TTS
461
  let ttsRows = [];
462
  Object.keys(DATA.tts).forEach(mod => {
463
  const row = DATA.tts[mod].find(r => r.language === lang);
464
  if(row) ttsRows.push({model: mod, ...row});
465
  });
466
 
467
- // 3. SLID
468
  let slidRows = [];
469
  const slidRow = DATA.slid.find(r => r.Language === lang) ||
470
  DATA.slid.find(r => r.Language.startsWith(lang + " (")) ||
@@ -472,13 +477,13 @@
472
  if(slidRow) {
473
  const models = Object.keys(slidRow).filter(k => k !== 'Language' && k !== 'ISO');
474
  models.forEach(m => slidRows.push({model: m, val: slidRow[m]}));
475
- slidRows.sort((a,b) => b.val - a.val);
476
  }
477
 
478
- // --- SUMMARY & CHARTS ---
479
  let summaryHTML = "";
480
 
481
- // ASR
482
  if(asrRows.length > 0) {
483
  summaryHTML += `<div class="stat-card"><div class="stat-title">Best ASR Model</div><div class="stat-model">${asrRows[0].model}</div><div class="stat-val">WER: ${fmt(asrRows[0].wer)}%</div></div>`;
484
  document.getElementById('wrp-chart-asr').style.display = 'block';
@@ -488,8 +493,9 @@
488
  document.getElementById('wrp-chart-asr').style.display = 'none';
489
  }
490
 
491
- // TTS
492
  if(ttsRows.length > 0) {
 
493
  const bestTTS = [...ttsRows].sort((a,b) => a.wer - b.wer)[0];
494
  summaryHTML += `<div class="stat-card"><div class="stat-title">Best TTS (Intelligibility)</div><div class="stat-model">${bestTTS.model}</div><div class="stat-val">WER: ${fmt(bestTTS.wer)}%</div></div>`;
495
  document.getElementById('wrp-chart-tts').style.display = 'block';
@@ -499,7 +505,7 @@
499
  document.getElementById('wrp-chart-tts').style.display = 'none';
500
  }
501
 
502
- // SLID
503
  if(slidRows.length > 0) {
504
  summaryHTML += `<div class="stat-card"><div class="stat-title">Best SLID Model</div><div class="stat-model">${slidRows[0].model}</div><div class="stat-val">F1: ${fmt(slidRows[0].val)}%</div></div>`;
505
  document.getElementById('wrp-chart-slid').style.display = 'block';
@@ -511,8 +517,8 @@
511
  document.getElementById('lang-summary').innerHTML = summaryHTML;
512
 
513
 
514
- // --- TABLES ---
515
- // ASR
516
  let h1 = `<table><thead><tr><th>Model</th><th>WER <i class="fa-solid fa-arrow-down arrow-down"></i></th><th>CER <i class="fa-solid fa-arrow-down arrow-down"></i></th></tr></thead><tbody>`;
517
  if(asrRows.length === 0) h1 += `<tr><td colspan="3" class="empty-msg">No ASR results available for ${lang}.</td></tr>`;
518
  else {
@@ -526,7 +532,7 @@
526
  h1 += `</tbody></table>`;
527
  document.getElementById('lang-asr-table').innerHTML = h1;
528
 
529
- // TTS
530
  let h2 = `<table><thead><tr><th>Model</th>
531
  <th>WER(↓)</th><th>MCD(↓)</th><th>LogF0RMSE(↓)</th><th>SpeechTokenDistance(↓)</th>
532
  <th>PESQ(↑)</th><th>UTMOS(↑)</th><th>SpeechBLEU(↑)</th><th>SpeechBERTScore(↑)</th>
@@ -546,7 +552,7 @@
546
  h2 += `</tbody></table>`;
547
  document.getElementById('lang-tts-table').innerHTML = h2;
548
 
549
- // SLID
550
  let h3 = `<table><thead><tr><th>Model</th><th>F1-Score <i class="fa-solid fa-arrow-up arrow-up"></i></th></tr></thead><tbody>`;
551
  if(slidRows.length === 0) h3 += `<tr><td colspan="2" class="empty-msg">No SLID results available for ${lang}.</td></tr>`;
552
  else {
 
47
 
48
  /* --- HERO --- */
49
  .hero {
50
+ max-width: 1000px;
51
+ margin: 60px auto 80px;
52
+ padding: 0 40px;
53
+ position: relative;
54
+ text-align: center;
55
+ }
56
+ .hero-content {
57
+ z-index: 2;
58
+ display: flex;
59
+ flex-direction: column;
60
+ align-items: center;
61
  }
 
62
  .conf-badge { background: white; color: black; display: inline-flex; align-items: center; gap: 10px; padding: 6px 16px; border-radius: 8px; margin-bottom: 30px; font-weight: 700; font-size: 14px; }
63
  .conf-badge i { color: #cc0000; font-size: 18px; }
64
  .hero h1 { font-family: 'Rubik', sans-serif; font-size: 64px; font-weight: 800; margin: 0; line-height: 1.1; }
65
  .hero h2 { font-family: 'Rubik', sans-serif; font-size: 32px; color: var(--text-yellow); margin: 15px 0 30px; font-weight: 700; }
66
  .hero p { color: #cbd5e1; font-size: 18px; line-height: 1.6; max-width: 700px; margin-bottom: 50px; }
67
+
68
  .hero-actions { display: flex; gap: 15px; flex-wrap: wrap; justify-content: center; }
 
 
 
69
 
70
+ /* Styled Buttons (Converted from React JSX) */
71
+ .action-btn {
72
+ display: flex; align-items: center; gap: 8px;
73
+ padding: 14px 26px; /* py-4 px-6 approx */
74
+ border-radius: 9999px; /* rounded-full */
75
+ color: white; font-weight: 700; font-size: 15px;
76
+ transition: all 0.3s ease;
77
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); /* shadow-xl */
78
+ white-space: nowrap;
79
+ }
80
+ .action-btn:hover { transform: scale(1.05); } /* hover:scale-105 */
81
+
82
+ .btn-red { background: #ef4444; box-shadow: 0 20px 25px -5px rgba(239, 68, 68, 0.2); }
83
+ .btn-indigo { background: #6366f1; box-shadow: 0 20px 25px -5px rgba(99, 102, 241, 0.2); }
84
+ .btn-orange { background: #f97316; box-shadow: 0 20px 25px -5px rgba(249, 115, 22, 0.2); }
85
+ .btn-blue { background: #3b82f6; box-shadow: 0 20px 25px -5px rgba(59, 130, 246, 0.2); }
86
+
87
+ .btn-red:hover { background: #dc2626; }
88
+ .btn-indigo:hover { background: #4f46e5; }
89
+ .btn-orange:hover { background: #ea580c; }
90
+ .btn-blue:hover { background: #2563eb; }
91
 
92
  /* --- CONTENT --- */
93
  .content-container { width: 80%; max-width: 1600px; margin: 0 auto; }
 
107
  .rank-info { font-size: 13px; color: #64748b; margin-top: 5px; font-style: italic; }
108
  .score-desc { font-size: 14px; color: #475569; background: #fff7ed; border-left: 4px solid #f97316; padding: 10px 15px; margin-bottom: 20px; border-radius: 4px; }
109
 
110
+ /* ASR Buttons */
111
  .mode-btn {
112
+ padding: 8px 20px; border-radius: 8px; font-weight: 600; font-size: 13px;
113
+ cursor: pointer; transition: all 0.2s; border: 1px solid #e2e8f0;
114
+ background: white; color: var(--simba-navy);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
  }
116
+ .mode-btn:hover { border-color: var(--text-yellow); color: var(--text-yellow); }
117
+ .mode-btn.active { background-color: var(--simba-navy); color: white; border-color: var(--simba-navy); box-shadow: 0 4px 12px rgba(15, 23, 42, 0.15); }
118
 
119
+ /* Charts */
120
+ .chart-wrapper { width: 100%; max-height: 400px; margin-bottom: 20px; display: none; }
 
 
 
 
 
 
121
  canvas { max-width: 100%; }
122
 
123
  /* Summary Cards */
 
161
  <div class="nav-text"><span>Voice of a</span> Continent</div>
162
  </a>
163
  <div class="nav-links">
 
164
  <a href="https://africa.dlnlp.ai/simba/" target="_blank" class="btn-submit">Submit New Results</a>
165
  </div>
166
  </nav>
167
 
168
  <div class="hero layout-width">
 
169
  <div class="hero-content">
170
  <div class="conf-badge"><i class="fa-solid fa-location-dot"></i> EMNLP 2025 · Suzhou, China</div>
171
  <h1>SimbaBench Leaderboard</h1>
172
  <h2>Mapping Africa’s Speech Technology</h2>
173
  <p>SimbaBench bridges the digital divide with a unified suite for African AI: the largest open-source speech benchmark covering 61 languages.</p>
174
+
175
  <div class="hero-actions">
176
+ <a href="https://aclanthology.org/2025.emnlp-main.559" target="_blank" class="action-btn btn-red">
177
+ <i class="fa-regular fa-file-pdf"></i> Read Paper
178
+ </a>
179
+ <a href="https://github.com/UBC-NLP/simba" target="_blank" class="action-btn btn-indigo">
180
+ <i class="fa-solid fa-code-branch"></i> Pipeline
181
+ </a>
182
+ <a href="https://huggingface.co/datasets/UBC-NLP/simba" target="_blank" class="action-btn btn-orange">
183
+ <i class="fa-solid fa-database"></i> Dataset
184
+ </a>
185
+ <a href="https://africa.dlnlp.ai/simba/#models" target="_blank" class="action-btn btn-blue">
186
+ <i class="fa-solid fa-bolt"></i> Models
187
+ </a>
188
  </div>
189
  </div>
190
  </div>
 
454
  function renderLanguageView() {
455
  const lang = document.getElementById('lang-select').value;
456
 
457
+ // 1. ASR Data Preparation
458
  let asrRows = [];
459
  Object.keys(DATA.asr.by_model).forEach(modName => {
460
  const row = DATA.asr.by_model[modName].find(r => r.Language === lang);
 
462
  });
463
  asrRows.sort((a,b) => (a.wer - b.wer) || (a.cer - b.cer));
464
 
465
+ // 2. TTS Data Preparation
466
  let ttsRows = [];
467
  Object.keys(DATA.tts).forEach(mod => {
468
  const row = DATA.tts[mod].find(r => r.language === lang);
469
  if(row) ttsRows.push({model: mod, ...row});
470
  });
471
 
472
+ // 3. SLID Data Preparation
473
  let slidRows = [];
474
  const slidRow = DATA.slid.find(r => r.Language === lang) ||
475
  DATA.slid.find(r => r.Language.startsWith(lang + " (")) ||
 
477
  if(slidRow) {
478
  const models = Object.keys(slidRow).filter(k => k !== 'Language' && k !== 'ISO');
479
  models.forEach(m => slidRows.push({model: m, val: slidRow[m]}));
480
+ slidRows.sort((a,b) => b.val - a.val); // Descending
481
  }
482
 
483
+ // --- RENDER SUMMARY CARDS ---
484
  let summaryHTML = "";
485
 
486
+ // ASR Winner
487
  if(asrRows.length > 0) {
488
  summaryHTML += `<div class="stat-card"><div class="stat-title">Best ASR Model</div><div class="stat-model">${asrRows[0].model}</div><div class="stat-val">WER: ${fmt(asrRows[0].wer)}%</div></div>`;
489
  document.getElementById('wrp-chart-asr').style.display = 'block';
 
493
  document.getElementById('wrp-chart-asr').style.display = 'none';
494
  }
495
 
496
+ // TTS Winner (Lowest WER for Intelligibility)
497
  if(ttsRows.length > 0) {
498
+ // Sort by WER ascending
499
  const bestTTS = [...ttsRows].sort((a,b) => a.wer - b.wer)[0];
500
  summaryHTML += `<div class="stat-card"><div class="stat-title">Best TTS (Intelligibility)</div><div class="stat-model">${bestTTS.model}</div><div class="stat-val">WER: ${fmt(bestTTS.wer)}%</div></div>`;
501
  document.getElementById('wrp-chart-tts').style.display = 'block';
 
505
  document.getElementById('wrp-chart-tts').style.display = 'none';
506
  }
507
 
508
+ // SLID Winner
509
  if(slidRows.length > 0) {
510
  summaryHTML += `<div class="stat-card"><div class="stat-title">Best SLID Model</div><div class="stat-model">${slidRows[0].model}</div><div class="stat-val">F1: ${fmt(slidRows[0].val)}%</div></div>`;
511
  document.getElementById('wrp-chart-slid').style.display = 'block';
 
517
  document.getElementById('lang-summary').innerHTML = summaryHTML;
518
 
519
 
520
+ // --- RENDER TABLES ---
521
+ // ASR Table
522
  let h1 = `<table><thead><tr><th>Model</th><th>WER <i class="fa-solid fa-arrow-down arrow-down"></i></th><th>CER <i class="fa-solid fa-arrow-down arrow-down"></i></th></tr></thead><tbody>`;
523
  if(asrRows.length === 0) h1 += `<tr><td colspan="3" class="empty-msg">No ASR results available for ${lang}.</td></tr>`;
524
  else {
 
532
  h1 += `</tbody></table>`;
533
  document.getElementById('lang-asr-table').innerHTML = h1;
534
 
535
+ // TTS Table
536
  let h2 = `<table><thead><tr><th>Model</th>
537
  <th>WER(↓)</th><th>MCD(↓)</th><th>LogF0RMSE(↓)</th><th>SpeechTokenDistance(↓)</th>
538
  <th>PESQ(↑)</th><th>UTMOS(↑)</th><th>SpeechBLEU(↑)</th><th>SpeechBERTScore(↑)</th>
 
552
  h2 += `</tbody></table>`;
553
  document.getElementById('lang-tts-table').innerHTML = h2;
554
 
555
+ // SLID Table
556
  let h3 = `<table><thead><tr><th>Model</th><th>F1-Score <i class="fa-solid fa-arrow-up arrow-up"></i></th></tr></thead><tbody>`;
557
  if(slidRows.length === 0) h3 += `<tr><td colspan="2" class="empty-msg">No SLID results available for ${lang}.</td></tr>`;
558
  else {