Spaces:
Running
Upload from GitHub Actions: Refresh dashboard UI: design tokens, indigo accent, research footer
Browse filesIntroduce a CSS design-token layer (palette, type, spacing, shadows) in index.css and apply it across the app:
- Hero: system-sans headline and flat indigo primary + outline secondary buttons, replacing the gradient/emoji buttons; quiet GitHub link
- Cool off-white background with a single restrained indigo accent on links, primary button, active filter states and the active carousel dot
- Harmonized table header tints and softened card/chart-panel chrome; data tables, score bars, medals and world-map encodings unchanged
- Refreshed About/Contribute dialogs and added a footer with the paper citation (arXiv:2507.08538) and BMZ/GIZ/DFKI credits
- Fix chart carousel overflow so the indicator dots no longer overlap the footer
- Drop the external web-font dependency (system fonts only)
- frontend/public/index.html +1 -1
- frontend/src/App.js +18 -96
- frontend/src/components/AutoComplete.js +20 -20
- frontend/src/components/DatasetTable.js +1 -1
- frontend/src/components/Footer.js +147 -0
- frontend/src/components/LanguageTable.js +1 -1
- frontend/src/components/ModelTable.js +3 -3
- frontend/src/index.css +294 -58
- frontend/src/index.js +1 -0
|
@@ -4,7 +4,7 @@
|
|
| 4 |
<meta charset="utf-8" />
|
| 5 |
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%221em%22 font-size=%2280%22>🌍</text></svg>">
|
| 6 |
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
| 7 |
-
<meta name="theme-color" content="#
|
| 8 |
<meta
|
| 9 |
name="description"
|
| 10 |
content="AI Language Benchmarks – model evaluations for every language in the world"
|
|
|
|
| 4 |
<meta charset="utf-8" />
|
| 5 |
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%221em%22 font-size=%2280%22>🌍</text></svg>">
|
| 6 |
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
| 7 |
+
<meta name="theme-color" content="#fbfbfd" />
|
| 8 |
<meta
|
| 9 |
name="description"
|
| 10 |
content="AI Language Benchmarks – model evaluations for every language in the world"
|
|
@@ -1,6 +1,5 @@
|
|
| 1 |
import { useState, useEffect } from 'react'
|
| 2 |
import { PrimeReactProvider } from 'primereact/api'
|
| 3 |
-
import 'primereact/resources/themes/lara-light-cyan/theme.css'
|
| 4 |
import ModelTable from './components/ModelTable'
|
| 5 |
import LanguageTable from './components/LanguageTable'
|
| 6 |
import DatasetTable from './components/DatasetTable'
|
|
@@ -12,6 +11,7 @@ import HistoryPlot from './components/HistoryPlot'
|
|
| 12 |
import LanguageTierHistoryPlot from './components/LanguageTierHistoryPlot'
|
| 13 |
import LicenseHistoryPlot from './components/LicenseHistoryPlot'
|
| 14 |
import CostPlot from './components/CostPlot'
|
|
|
|
| 15 |
import { Carousel } from 'primereact/carousel'
|
| 16 |
import { Dialog } from 'primereact/dialog'
|
| 17 |
import { Button } from 'primereact/button'
|
|
@@ -153,7 +153,7 @@ function App () {
|
|
| 153 |
minHeight: '100vh',
|
| 154 |
display: 'flex',
|
| 155 |
flexDirection: 'column',
|
| 156 |
-
width: '
|
| 157 |
}}
|
| 158 |
>
|
| 159 |
{/* <div
|
|
@@ -184,24 +184,7 @@ function App () {
|
|
| 184 |
href='https://github.com/datenlabor-bmz/evals-for-every-language'
|
| 185 |
target='_blank'
|
| 186 |
rel='noopener noreferrer'
|
| 187 |
-
|
| 188 |
-
textDecoration: 'none',
|
| 189 |
-
color: '#6c757d',
|
| 190 |
-
fontSize: '1rem',
|
| 191 |
-
fontWeight: '500',
|
| 192 |
-
padding: '0.5rem 1rem',
|
| 193 |
-
borderRadius: '0.375rem',
|
| 194 |
-
backgroundColor: '#f8f9fa',
|
| 195 |
-
border: '1px solid #e9ecef',
|
| 196 |
-
display: 'flex',
|
| 197 |
-
alignItems: 'center',
|
| 198 |
-
gap: '0.5rem',
|
| 199 |
-
transition: 'all 0.2s ease',
|
| 200 |
-
':hover': {
|
| 201 |
-
backgroundColor: '#e9ecef',
|
| 202 |
-
color: '#495057'
|
| 203 |
-
}
|
| 204 |
-
}}
|
| 205 |
>
|
| 206 |
<i className='pi pi-github' title='View on GitHub' />
|
| 207 |
GitHub
|
|
@@ -228,21 +211,11 @@ function App () {
|
|
| 228 |
🌍
|
| 229 |
</span>
|
| 230 |
</div>
|
| 231 |
-
<h1
|
| 232 |
-
style={{
|
| 233 |
-
fontSize: '2.5rem',
|
| 234 |
-
fontWeight: '600',
|
| 235 |
-
margin: '1rem 0 0.5rem 0',
|
| 236 |
-
color: '#333',
|
| 237 |
-
letterSpacing: '-0.01em'
|
| 238 |
-
}}
|
| 239 |
-
>
|
| 240 |
-
AI Language Benchmarks
|
| 241 |
-
</h1>
|
| 242 |
<p
|
| 243 |
style={{
|
| 244 |
-
fontSize: '1.
|
| 245 |
-
color: '
|
| 246 |
margin: '0 0 2.5rem 0',
|
| 247 |
fontWeight: '400',
|
| 248 |
maxWidth: '700px',
|
|
@@ -263,68 +236,16 @@ function App () {
|
|
| 263 |
>
|
| 264 |
<button
|
| 265 |
onClick={() => setAboutVisible(true)}
|
| 266 |
-
|
| 267 |
-
background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
|
| 268 |
-
color: 'white',
|
| 269 |
-
border: 'none',
|
| 270 |
-
padding: '0.75rem 1.5rem',
|
| 271 |
-
borderRadius: '12px',
|
| 272 |
-
fontSize: '0.95rem',
|
| 273 |
-
fontWeight: '500',
|
| 274 |
-
cursor: 'pointer',
|
| 275 |
-
display: 'flex',
|
| 276 |
-
alignItems: 'center',
|
| 277 |
-
gap: '0.5rem',
|
| 278 |
-
boxShadow: '0 4px 15px rgba(102, 126, 234, 0.25)',
|
| 279 |
-
transition: 'all 0.3s ease',
|
| 280 |
-
':hover': {
|
| 281 |
-
transform: 'translateY(-2px)',
|
| 282 |
-
boxShadow: '0 8px 25px rgba(102, 126, 234, 0.35)'
|
| 283 |
-
}
|
| 284 |
-
}}
|
| 285 |
-
onMouseEnter={(e) => {
|
| 286 |
-
e.target.style.transform = 'translateY(-2px)';
|
| 287 |
-
e.target.style.boxShadow = '0 8px 25px rgba(102, 126, 234, 0.35)';
|
| 288 |
-
}}
|
| 289 |
-
onMouseLeave={(e) => {
|
| 290 |
-
e.target.style.transform = 'translateY(0)';
|
| 291 |
-
e.target.style.boxShadow = '0 4px 15px rgba(102, 126, 234, 0.25)';
|
| 292 |
-
}}
|
| 293 |
>
|
| 294 |
-
<span style={{ fontSize: '1.1rem' }}>📚</span>
|
| 295 |
About this tool
|
| 296 |
</button>
|
| 297 |
|
| 298 |
<button
|
| 299 |
onClick={() => setContributeVisible(true)}
|
| 300 |
title='This feature is on our roadmap and will be available soon.'
|
| 301 |
-
|
| 302 |
-
background: 'linear-gradient(135deg, #ff9a9e 0%, #fecfef 50%, #fecfef 100%)',
|
| 303 |
-
color: '#6b46c1',
|
| 304 |
-
border: 'none',
|
| 305 |
-
padding: '0.75rem 1.5rem',
|
| 306 |
-
borderRadius: '12px',
|
| 307 |
-
fontSize: '0.95rem',
|
| 308 |
-
fontWeight: '500',
|
| 309 |
-
cursor: 'pointer',
|
| 310 |
-
display: 'flex',
|
| 311 |
-
alignItems: 'center',
|
| 312 |
-
gap: '0.5rem',
|
| 313 |
-
boxShadow: '0 4px 15px rgba(255, 154, 158, 0.25)',
|
| 314 |
-
transition: 'all 0.3s ease',
|
| 315 |
-
position: 'relative',
|
| 316 |
-
overflow: 'hidden'
|
| 317 |
-
}}
|
| 318 |
-
onMouseEnter={(e) => {
|
| 319 |
-
e.target.style.transform = 'translateY(-2px)';
|
| 320 |
-
e.target.style.boxShadow = '0 8px 25px rgba(255, 154, 158, 0.35)';
|
| 321 |
-
}}
|
| 322 |
-
onMouseLeave={(e) => {
|
| 323 |
-
e.target.style.transform = 'translateY(0)';
|
| 324 |
-
e.target.style.boxShadow = '0 4px 15px rgba(255, 154, 158, 0.25)';
|
| 325 |
-
}}
|
| 326 |
>
|
| 327 |
-
<span style={{ fontSize: '1.1rem' }}>🚀</span>
|
| 328 |
Add your model/benchmark
|
| 329 |
</button>
|
| 330 |
</div>
|
|
@@ -428,6 +349,7 @@ function App () {
|
|
| 428 |
</>
|
| 429 |
)}
|
| 430 |
</main>
|
|
|
|
| 431 |
|
| 432 |
{/* About Dialog */}
|
| 433 |
<Dialog
|
|
@@ -441,7 +363,7 @@ function App () {
|
|
| 441 |
<p>
|
| 442 |
<i>languagebench</i> provides AI model evaluations for every language in the world.
|
| 443 |
</p>
|
| 444 |
-
<h4>
|
| 445 |
<ul>
|
| 446 |
<li>
|
| 447 |
<b>Practitioners</b> can pick the best model for a given
|
|
@@ -455,7 +377,7 @@ function App () {
|
|
| 455 |
<b>Model developers</b> can compete on our benchmarks.
|
| 456 |
</li>
|
| 457 |
</ul>
|
| 458 |
-
<h4>
|
| 459 |
<p>
|
| 460 |
Benchmark results automatically refresh every night and include
|
| 461 |
the most popular models from{' '}
|
|
@@ -468,11 +390,11 @@ function App () {
|
|
| 468 |
</a>
|
| 469 |
, plus community-submitted models.
|
| 470 |
</p>
|
| 471 |
-
<h4>
|
| 472 |
<p>
|
| 473 |
Results are currently based on a sample of 10 sentences per language and task to keep computation affordable. For this reason, we report confidence intervals and recommend treating small differences between models with caution. In future iterations, we plan to add more benchmark datasets and richer visualisations, with large-scale evaluations across many more prompts and tasks as a longer-term goal.
|
| 474 |
</p>
|
| 475 |
-
<h4>
|
| 476 |
<p>
|
| 477 |
languagebench is a collaboration between
|
| 478 |
BMZ's{' '}
|
|
@@ -513,7 +435,7 @@ function App () {
|
|
| 513 |
</a>{' '}
|
| 514 |
of DFKI's Multilinguality and Language Technology Lab.
|
| 515 |
</p>
|
| 516 |
-
<h4>
|
| 517 |
<p>
|
| 518 |
<a
|
| 519 |
href='https://github.com/datenlabor-bmz/evals-for-every-language'
|
|
@@ -543,7 +465,7 @@ function App () {
|
|
| 543 |
header='Contribute your Model/Benchmark'
|
| 544 |
>
|
| 545 |
<div>
|
| 546 |
-
<h4>
|
| 547 |
<p>
|
| 548 |
Have a custom fine-tuned model you'd like to see on the
|
| 549 |
leaderboard or a new benchmark you think should be added?
|
|
@@ -553,13 +475,13 @@ function App () {
|
|
| 553 |
href='https://forms.gle/ckvY9pS7XLcHYnaV8'
|
| 554 |
target='_blank'
|
| 555 |
rel='noopener noreferrer'
|
| 556 |
-
style={{ color: '
|
| 557 |
>
|
| 558 |
→ Submit your model here
|
| 559 |
</a>
|
| 560 |
</p>
|
| 561 |
|
| 562 |
-
<h4>
|
| 563 |
<p>
|
| 564 |
Help us expand language coverage and add new evaluation tasks:
|
| 565 |
</p>
|
|
@@ -568,7 +490,7 @@ function App () {
|
|
| 568 |
href='https://github.com/datenlabor-bmz/evals-for-every-language/blob/main/CONTRIBUTING.md'
|
| 569 |
target='_blank'
|
| 570 |
rel='noopener noreferrer'
|
| 571 |
-
style={{ color: '
|
| 572 |
>
|
| 573 |
→ Contribution guidelines
|
| 574 |
</a>
|
|
|
|
| 1 |
import { useState, useEffect } from 'react'
|
| 2 |
import { PrimeReactProvider } from 'primereact/api'
|
|
|
|
| 3 |
import ModelTable from './components/ModelTable'
|
| 4 |
import LanguageTable from './components/LanguageTable'
|
| 5 |
import DatasetTable from './components/DatasetTable'
|
|
|
|
| 11 |
import LanguageTierHistoryPlot from './components/LanguageTierHistoryPlot'
|
| 12 |
import LicenseHistoryPlot from './components/LicenseHistoryPlot'
|
| 13 |
import CostPlot from './components/CostPlot'
|
| 14 |
+
import Footer from './components/Footer'
|
| 15 |
import { Carousel } from 'primereact/carousel'
|
| 16 |
import { Dialog } from 'primereact/dialog'
|
| 17 |
import { Button } from 'primereact/button'
|
|
|
|
| 153 |
minHeight: '100vh',
|
| 154 |
display: 'flex',
|
| 155 |
flexDirection: 'column',
|
| 156 |
+
width: '100%'
|
| 157 |
}}
|
| 158 |
>
|
| 159 |
{/* <div
|
|
|
|
| 184 |
href='https://github.com/datenlabor-bmz/evals-for-every-language'
|
| 185 |
target='_blank'
|
| 186 |
rel='noopener noreferrer'
|
| 187 |
+
className='ghost-link'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 188 |
>
|
| 189 |
<i className='pi pi-github' title='View on GitHub' />
|
| 190 |
GitHub
|
|
|
|
| 211 |
🌍
|
| 212 |
</span>
|
| 213 |
</div>
|
| 214 |
+
<h1 className='hero-title'>AI Language Benchmarks</h1>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 215 |
<p
|
| 216 |
style={{
|
| 217 |
+
fontSize: '1.15rem',
|
| 218 |
+
color: 'var(--ink-muted)',
|
| 219 |
margin: '0 0 2.5rem 0',
|
| 220 |
fontWeight: '400',
|
| 221 |
maxWidth: '700px',
|
|
|
|
| 236 |
>
|
| 237 |
<button
|
| 238 |
onClick={() => setAboutVisible(true)}
|
| 239 |
+
className='btn btn-primary'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 240 |
>
|
|
|
|
| 241 |
About this tool
|
| 242 |
</button>
|
| 243 |
|
| 244 |
<button
|
| 245 |
onClick={() => setContributeVisible(true)}
|
| 246 |
title='This feature is on our roadmap and will be available soon.'
|
| 247 |
+
className='btn btn-secondary'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 248 |
>
|
|
|
|
| 249 |
Add your model/benchmark
|
| 250 |
</button>
|
| 251 |
</div>
|
|
|
|
| 349 |
</>
|
| 350 |
)}
|
| 351 |
</main>
|
| 352 |
+
<Footer />
|
| 353 |
|
| 354 |
{/* About Dialog */}
|
| 355 |
<Dialog
|
|
|
|
| 363 |
<p>
|
| 364 |
<i>languagebench</i> provides AI model evaluations for every language in the world.
|
| 365 |
</p>
|
| 366 |
+
<h4>Who is this for?</h4>
|
| 367 |
<ul>
|
| 368 |
<li>
|
| 369 |
<b>Practitioners</b> can pick the best model for a given
|
|
|
|
| 377 |
<b>Model developers</b> can compete on our benchmarks.
|
| 378 |
</li>
|
| 379 |
</ul>
|
| 380 |
+
<h4>Live Updates</h4>
|
| 381 |
<p>
|
| 382 |
Benchmark results automatically refresh every night and include
|
| 383 |
the most popular models from{' '}
|
|
|
|
| 390 |
</a>
|
| 391 |
, plus community-submitted models.
|
| 392 |
</p>
|
| 393 |
+
<h4>Note on interpretation</h4>
|
| 394 |
<p>
|
| 395 |
Results are currently based on a sample of 10 sentences per language and task to keep computation affordable. For this reason, we report confidence intervals and recommend treating small differences between models with caution. In future iterations, we plan to add more benchmark datasets and richer visualisations, with large-scale evaluations across many more prompts and tasks as a longer-term goal.
|
| 396 |
</p>
|
| 397 |
+
<h4>Authors</h4>
|
| 398 |
<p>
|
| 399 |
languagebench is a collaboration between
|
| 400 |
BMZ's{' '}
|
|
|
|
| 435 |
</a>{' '}
|
| 436 |
of DFKI's Multilinguality and Language Technology Lab.
|
| 437 |
</p>
|
| 438 |
+
<h4>Links</h4>
|
| 439 |
<p>
|
| 440 |
<a
|
| 441 |
href='https://github.com/datenlabor-bmz/evals-for-every-language'
|
|
|
|
| 465 |
header='Contribute your Model/Benchmark'
|
| 466 |
>
|
| 467 |
<div>
|
| 468 |
+
<h4>Submit Your Model</h4>
|
| 469 |
<p>
|
| 470 |
Have a custom fine-tuned model you'd like to see on the
|
| 471 |
leaderboard or a new benchmark you think should be added?
|
|
|
|
| 475 |
href='https://forms.gle/ckvY9pS7XLcHYnaV8'
|
| 476 |
target='_blank'
|
| 477 |
rel='noopener noreferrer'
|
| 478 |
+
style={{ color: 'var(--accent)', fontWeight: 'bold' }}
|
| 479 |
>
|
| 480 |
→ Submit your model here
|
| 481 |
</a>
|
| 482 |
</p>
|
| 483 |
|
| 484 |
+
<h4>Contribute to Development</h4>
|
| 485 |
<p>
|
| 486 |
Help us expand language coverage and add new evaluation tasks:
|
| 487 |
</p>
|
|
|
|
| 490 |
href='https://github.com/datenlabor-bmz/evals-for-every-language/blob/main/CONTRIBUTING.md'
|
| 491 |
target='_blank'
|
| 492 |
rel='noopener noreferrer'
|
| 493 |
+
style={{ color: 'var(--accent)', fontWeight: 'bold' }}
|
| 494 |
>
|
| 495 |
→ Contribution guidelines
|
| 496 |
</a>
|
|
@@ -114,12 +114,12 @@ const AutoComplete = ({ languages, onComplete }) => {
|
|
| 114 |
}
|
| 115 |
|
| 116 |
const buttonStyle = {
|
| 117 |
-
color: selectedLanguage ? '
|
| 118 |
-
border: '1px solid
|
| 119 |
padding: '0.75rem 1rem',
|
| 120 |
-
borderRadius: '
|
| 121 |
fontSize: '0.95rem',
|
| 122 |
-
backgroundColor: '
|
| 123 |
cursor: 'pointer',
|
| 124 |
display: 'flex',
|
| 125 |
alignItems: 'center',
|
|
@@ -135,7 +135,7 @@ const AutoComplete = ({ languages, onComplete }) => {
|
|
| 135 |
fontSize: '0.95rem',
|
| 136 |
width: '100%',
|
| 137 |
backgroundColor: 'transparent',
|
| 138 |
-
color: '
|
| 139 |
}
|
| 140 |
|
| 141 |
const dropdownStyle = {
|
|
@@ -143,20 +143,20 @@ const AutoComplete = ({ languages, onComplete }) => {
|
|
| 143 |
top: '100%',
|
| 144 |
left: 0,
|
| 145 |
right: 0,
|
| 146 |
-
backgroundColor: '
|
| 147 |
-
border: '1px solid
|
| 148 |
borderTop: 'none',
|
| 149 |
-
borderRadius: '0 0
|
| 150 |
maxHeight: '300px',
|
| 151 |
overflowY: 'auto',
|
| 152 |
zIndex: 1000,
|
| 153 |
-
boxShadow: '
|
| 154 |
}
|
| 155 |
|
| 156 |
const itemStyle = {
|
| 157 |
padding: '0.75rem 1rem',
|
| 158 |
cursor: 'pointer',
|
| 159 |
-
borderBottom: '1px solid
|
| 160 |
display: 'flex',
|
| 161 |
justifyContent: 'space-between',
|
| 162 |
alignItems: 'center',
|
|
@@ -166,7 +166,7 @@ const AutoComplete = ({ languages, onComplete }) => {
|
|
| 166 |
const clearButtonStyle = {
|
| 167 |
background: 'none',
|
| 168 |
border: 'none',
|
| 169 |
-
color: '
|
| 170 |
cursor: 'pointer',
|
| 171 |
padding: '0.25rem',
|
| 172 |
borderRadius: '50%',
|
|
@@ -186,11 +186,11 @@ const AutoComplete = ({ languages, onComplete }) => {
|
|
| 186 |
onClick={handleContainerClick}
|
| 187 |
onMouseEnter={e => {
|
| 188 |
if (!selectedLanguage) {
|
| 189 |
-
e.target.style.borderColor = '
|
| 190 |
}
|
| 191 |
}}
|
| 192 |
onMouseLeave={e => {
|
| 193 |
-
e.target.style.borderColor = '
|
| 194 |
}}
|
| 195 |
>
|
| 196 |
{selectedLanguage && !isOpen ? (
|
|
@@ -202,7 +202,7 @@ const AutoComplete = ({ languages, onComplete }) => {
|
|
| 202 |
style={clearButtonStyle}
|
| 203 |
onClick={handleClear}
|
| 204 |
onMouseEnter={e => {
|
| 205 |
-
e.target.style.backgroundColor = '
|
| 206 |
}}
|
| 207 |
onMouseLeave={e => {
|
| 208 |
e.target.style.backgroundColor = 'transparent'
|
|
@@ -229,7 +229,7 @@ const AutoComplete = ({ languages, onComplete }) => {
|
|
| 229 |
<span>Go to leaderboard for specific language...</span>
|
| 230 |
)}
|
| 231 |
{(!selectedLanguage || isOpen) && (
|
| 232 |
-
<span style={{ color: '
|
| 233 |
{isOpen ? '▲' : '▼'}
|
| 234 |
</span>
|
| 235 |
)}
|
|
@@ -238,7 +238,7 @@ const AutoComplete = ({ languages, onComplete }) => {
|
|
| 238 |
{isOpen && (
|
| 239 |
<div style={dropdownStyle}>
|
| 240 |
{filteredLanguages.length === 0 ? (
|
| 241 |
-
<div style={{ ...itemStyle, color: '
|
| 242 |
No languages found
|
| 243 |
</div>
|
| 244 |
) : (
|
|
@@ -248,7 +248,7 @@ const AutoComplete = ({ languages, onComplete }) => {
|
|
| 248 |
style={itemStyle}
|
| 249 |
onClick={() => handleSelect(language)}
|
| 250 |
onMouseEnter={e => {
|
| 251 |
-
e.target.style.backgroundColor = '
|
| 252 |
}}
|
| 253 |
onMouseLeave={e => {
|
| 254 |
e.target.style.backgroundColor = 'transparent'
|
|
@@ -258,11 +258,11 @@ const AutoComplete = ({ languages, onComplete }) => {
|
|
| 258 |
<div style={{ fontWeight: '500', marginBottom: '2px' }}>
|
| 259 |
{language.language_name} Leaderboard
|
| 260 |
</div>
|
| 261 |
-
<div style={{ fontSize: '0.85rem', color: '
|
| 262 |
{language.autonym}
|
| 263 |
</div>
|
| 264 |
</div>
|
| 265 |
-
<div style={{ color: '
|
| 266 |
{language.bcp_47}
|
| 267 |
</div>
|
| 268 |
</div>
|
|
@@ -272,7 +272,7 @@ const AutoComplete = ({ languages, onComplete }) => {
|
|
| 272 |
<div
|
| 273 |
style={{
|
| 274 |
...itemStyle,
|
| 275 |
-
color: '
|
| 276 |
cursor: 'default',
|
| 277 |
fontStyle: 'italic'
|
| 278 |
}}
|
|
|
|
| 114 |
}
|
| 115 |
|
| 116 |
const buttonStyle = {
|
| 117 |
+
color: selectedLanguage ? 'var(--ink)' : 'var(--ink-muted)',
|
| 118 |
+
border: '1px solid var(--border)',
|
| 119 |
padding: '0.75rem 1rem',
|
| 120 |
+
borderRadius: 'var(--radius-sm)',
|
| 121 |
fontSize: '0.95rem',
|
| 122 |
+
backgroundColor: 'var(--surface)',
|
| 123 |
cursor: 'pointer',
|
| 124 |
display: 'flex',
|
| 125 |
alignItems: 'center',
|
|
|
|
| 135 |
fontSize: '0.95rem',
|
| 136 |
width: '100%',
|
| 137 |
backgroundColor: 'transparent',
|
| 138 |
+
color: 'var(--ink)'
|
| 139 |
}
|
| 140 |
|
| 141 |
const dropdownStyle = {
|
|
|
|
| 143 |
top: '100%',
|
| 144 |
left: 0,
|
| 145 |
right: 0,
|
| 146 |
+
backgroundColor: 'var(--surface)',
|
| 147 |
+
border: '1px solid var(--border)',
|
| 148 |
borderTop: 'none',
|
| 149 |
+
borderRadius: '0 0 var(--radius-sm) var(--radius-sm)',
|
| 150 |
maxHeight: '300px',
|
| 151 |
overflowY: 'auto',
|
| 152 |
zIndex: 1000,
|
| 153 |
+
boxShadow: 'var(--shadow-md)'
|
| 154 |
}
|
| 155 |
|
| 156 |
const itemStyle = {
|
| 157 |
padding: '0.75rem 1rem',
|
| 158 |
cursor: 'pointer',
|
| 159 |
+
borderBottom: '1px solid var(--hairline)',
|
| 160 |
display: 'flex',
|
| 161 |
justifyContent: 'space-between',
|
| 162 |
alignItems: 'center',
|
|
|
|
| 166 |
const clearButtonStyle = {
|
| 167 |
background: 'none',
|
| 168 |
border: 'none',
|
| 169 |
+
color: 'var(--ink-subtle)',
|
| 170 |
cursor: 'pointer',
|
| 171 |
padding: '0.25rem',
|
| 172 |
borderRadius: '50%',
|
|
|
|
| 186 |
onClick={handleContainerClick}
|
| 187 |
onMouseEnter={e => {
|
| 188 |
if (!selectedLanguage) {
|
| 189 |
+
e.target.style.borderColor = 'var(--accent)'
|
| 190 |
}
|
| 191 |
}}
|
| 192 |
onMouseLeave={e => {
|
| 193 |
+
e.target.style.borderColor = 'var(--border)'
|
| 194 |
}}
|
| 195 |
>
|
| 196 |
{selectedLanguage && !isOpen ? (
|
|
|
|
| 202 |
style={clearButtonStyle}
|
| 203 |
onClick={handleClear}
|
| 204 |
onMouseEnter={e => {
|
| 205 |
+
e.target.style.backgroundColor = 'var(--accent-wash)'
|
| 206 |
}}
|
| 207 |
onMouseLeave={e => {
|
| 208 |
e.target.style.backgroundColor = 'transparent'
|
|
|
|
| 229 |
<span>Go to leaderboard for specific language...</span>
|
| 230 |
)}
|
| 231 |
{(!selectedLanguage || isOpen) && (
|
| 232 |
+
<span style={{ color: 'var(--ink-subtle)', fontSize: '12px' }}>
|
| 233 |
{isOpen ? '▲' : '▼'}
|
| 234 |
</span>
|
| 235 |
)}
|
|
|
|
| 238 |
{isOpen && (
|
| 239 |
<div style={dropdownStyle}>
|
| 240 |
{filteredLanguages.length === 0 ? (
|
| 241 |
+
<div style={{ ...itemStyle, color: 'var(--ink-subtle)', cursor: 'default' }}>
|
| 242 |
No languages found
|
| 243 |
</div>
|
| 244 |
) : (
|
|
|
|
| 248 |
style={itemStyle}
|
| 249 |
onClick={() => handleSelect(language)}
|
| 250 |
onMouseEnter={e => {
|
| 251 |
+
e.target.style.backgroundColor = 'var(--accent-wash)'
|
| 252 |
}}
|
| 253 |
onMouseLeave={e => {
|
| 254 |
e.target.style.backgroundColor = 'transparent'
|
|
|
|
| 258 |
<div style={{ fontWeight: '500', marginBottom: '2px' }}>
|
| 259 |
{language.language_name} Leaderboard
|
| 260 |
</div>
|
| 261 |
+
<div style={{ fontSize: '0.85rem', color: 'var(--ink-muted)' }}>
|
| 262 |
{language.autonym}
|
| 263 |
</div>
|
| 264 |
</div>
|
| 265 |
+
<div style={{ color: 'var(--ink-subtle)', fontSize: '0.8rem' }}>
|
| 266 |
{language.bcp_47}
|
| 267 |
</div>
|
| 268 |
</div>
|
|
|
|
| 272 |
<div
|
| 273 |
style={{
|
| 274 |
...itemStyle,
|
| 275 |
+
color: 'var(--ink-subtle)',
|
| 276 |
cursor: 'default',
|
| 277 |
fontStyle: 'italic'
|
| 278 |
}}
|
|
@@ -106,7 +106,7 @@ const DatasetTable = ({ data }) => {
|
|
| 106 |
groupRowsBy='group'
|
| 107 |
header={
|
| 108 |
<span>
|
| 109 |
-
<span style={{ fontWeight:
|
| 110 |
<span style={{ fontSize: '0.85em', marginLeft: '0.5rem' }}>
|
| 111 |
Multilingual datasets used for this evaluation, and beyond
|
| 112 |
</span>
|
|
|
|
| 106 |
groupRowsBy='group'
|
| 107 |
header={
|
| 108 |
<span>
|
| 109 |
+
<span style={{ fontWeight: 600, fontSize: '1.15em', color: 'var(--ink)' }}>Datasets</span>
|
| 110 |
<span style={{ fontSize: '0.85em', marginLeft: '0.5rem' }}>
|
| 111 |
Multilingual datasets used for this evaluation, and beyond
|
| 112 |
</span>
|
|
@@ -0,0 +1,147 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
const linkStyle = {
|
| 2 |
+
color: 'var(--accent)',
|
| 3 |
+
textDecoration: 'none',
|
| 4 |
+
fontWeight: 500
|
| 5 |
+
}
|
| 6 |
+
|
| 7 |
+
const Footer = () => {
|
| 8 |
+
return (
|
| 9 |
+
<footer
|
| 10 |
+
style={{
|
| 11 |
+
borderTop: '1px solid var(--border)',
|
| 12 |
+
background: 'var(--surface-warm)',
|
| 13 |
+
padding: '3rem 15vw'
|
| 14 |
+
}}
|
| 15 |
+
>
|
| 16 |
+
<div
|
| 17 |
+
style={{
|
| 18 |
+
maxWidth: '900px',
|
| 19 |
+
margin: '0 auto',
|
| 20 |
+
display: 'flex',
|
| 21 |
+
flexDirection: 'column',
|
| 22 |
+
gap: '1.25rem'
|
| 23 |
+
}}
|
| 24 |
+
>
|
| 25 |
+
<div>
|
| 26 |
+
<div
|
| 27 |
+
style={{
|
| 28 |
+
fontWeight: 600,
|
| 29 |
+
fontSize: '1.2rem',
|
| 30 |
+
letterSpacing: '-0.01em',
|
| 31 |
+
color: 'var(--ink)'
|
| 32 |
+
}}
|
| 33 |
+
>
|
| 34 |
+
AI Language Benchmarks
|
| 35 |
+
</div>
|
| 36 |
+
<div
|
| 37 |
+
style={{
|
| 38 |
+
color: 'var(--ink-muted)',
|
| 39 |
+
fontSize: '0.95rem',
|
| 40 |
+
marginTop: '0.25rem'
|
| 41 |
+
}}
|
| 42 |
+
>
|
| 43 |
+
AI model evaluations for every language in the world.
|
| 44 |
+
</div>
|
| 45 |
+
</div>
|
| 46 |
+
|
| 47 |
+
<p
|
| 48 |
+
style={{
|
| 49 |
+
color: 'var(--ink-muted)',
|
| 50 |
+
fontSize: '0.9rem',
|
| 51 |
+
lineHeight: 1.6,
|
| 52 |
+
margin: 0
|
| 53 |
+
}}
|
| 54 |
+
>
|
| 55 |
+
Pomerenke, D., Nothnagel, J., & Ostermann, S. (2025).{' '}
|
| 56 |
+
<a
|
| 57 |
+
href='https://arxiv.org/abs/2507.08538'
|
| 58 |
+
target='_blank'
|
| 59 |
+
rel='noopener noreferrer'
|
| 60 |
+
style={{ ...linkStyle, fontStyle: 'italic' }}
|
| 61 |
+
>
|
| 62 |
+
The AI Language Proficiency Monitor – Tracking the Progress of LLMs
|
| 63 |
+
on Multilingual Benchmarks
|
| 64 |
+
</a>
|
| 65 |
+
. arXiv:2507.08538.
|
| 66 |
+
</p>
|
| 67 |
+
|
| 68 |
+
<p
|
| 69 |
+
style={{
|
| 70 |
+
color: 'var(--ink-muted)',
|
| 71 |
+
fontSize: '0.9rem',
|
| 72 |
+
lineHeight: 1.6,
|
| 73 |
+
margin: 0
|
| 74 |
+
}}
|
| 75 |
+
>
|
| 76 |
+
A collaboration of{' '}
|
| 77 |
+
<a
|
| 78 |
+
href='https://www.bmz-digital.global/en/overview-of-initiatives/the-bmz-data-lab/'
|
| 79 |
+
target='_blank'
|
| 80 |
+
rel='noopener noreferrer'
|
| 81 |
+
style={linkStyle}
|
| 82 |
+
>
|
| 83 |
+
BMZ Data Lab
|
| 84 |
+
</a>
|
| 85 |
+
,{' '}
|
| 86 |
+
<a
|
| 87 |
+
href='https://www.bmz-digital.global/en/overview-of-initiatives/fair-forward/'
|
| 88 |
+
target='_blank'
|
| 89 |
+
rel='noopener noreferrer'
|
| 90 |
+
style={linkStyle}
|
| 91 |
+
>
|
| 92 |
+
GIZ Fair Forward
|
| 93 |
+
</a>
|
| 94 |
+
, and the{' '}
|
| 95 |
+
<a
|
| 96 |
+
href='https://www.dfki.de/en/web/research/research-departments/multilinguality-and-language-technology/ee-team'
|
| 97 |
+
target='_blank'
|
| 98 |
+
rel='noopener noreferrer'
|
| 99 |
+
style={linkStyle}
|
| 100 |
+
>
|
| 101 |
+
DFKI
|
| 102 |
+
</a>{' '}
|
| 103 |
+
Multilinguality and Language Technology Lab.
|
| 104 |
+
</p>
|
| 105 |
+
|
| 106 |
+
<div
|
| 107 |
+
style={{
|
| 108 |
+
display: 'flex',
|
| 109 |
+
flexWrap: 'wrap',
|
| 110 |
+
gap: '1.75rem',
|
| 111 |
+
fontSize: '0.9rem',
|
| 112 |
+
paddingTop: '1rem',
|
| 113 |
+
borderTop: '1px solid var(--border)'
|
| 114 |
+
}}
|
| 115 |
+
>
|
| 116 |
+
<a
|
| 117 |
+
href='https://github.com/datenlabor-bmz/evals-for-every-language'
|
| 118 |
+
target='_blank'
|
| 119 |
+
rel='noopener noreferrer'
|
| 120 |
+
style={linkStyle}
|
| 121 |
+
>
|
| 122 |
+
<i className='pi pi-github' style={{ marginRight: '0.4rem' }} />
|
| 123 |
+
GitHub
|
| 124 |
+
</a>
|
| 125 |
+
<a
|
| 126 |
+
href='https://huggingface.co/spaces/fair-forward/languagebench'
|
| 127 |
+
target='_blank'
|
| 128 |
+
rel='noopener noreferrer'
|
| 129 |
+
style={linkStyle}
|
| 130 |
+
>
|
| 131 |
+
Hugging Face Space
|
| 132 |
+
</a>
|
| 133 |
+
<a
|
| 134 |
+
href='https://arxiv.org/abs/2507.08538'
|
| 135 |
+
target='_blank'
|
| 136 |
+
rel='noopener noreferrer'
|
| 137 |
+
style={linkStyle}
|
| 138 |
+
>
|
| 139 |
+
Read the paper
|
| 140 |
+
</a>
|
| 141 |
+
</div>
|
| 142 |
+
</div>
|
| 143 |
+
</footer>
|
| 144 |
+
)
|
| 145 |
+
}
|
| 146 |
+
|
| 147 |
+
export default Footer
|
|
@@ -125,7 +125,7 @@ const LanguageTable = ({ data, selectedLanguages, setSelectedLanguages, totalMod
|
|
| 125 |
dataKey='bcp_47'
|
| 126 |
header={
|
| 127 |
<span>
|
| 128 |
-
<span style={{ fontWeight:
|
| 129 |
<span style={{ fontSize: '0.85em', marginLeft: '0.5rem' }}>
|
| 130 |
Average performance of {totalModels} evaluated AI models
|
| 131 |
</span>
|
|
|
|
| 125 |
dataKey='bcp_47'
|
| 126 |
header={
|
| 127 |
<span>
|
| 128 |
+
<span style={{ fontWeight: 600, fontSize: '1.15em', color: 'var(--ink)' }}>Languages</span>
|
| 129 |
<span style={{ fontSize: '0.85em', marginLeft: '0.5rem' }}>
|
| 130 |
Average performance of {totalModels} evaluated AI models
|
| 131 |
</span>
|
|
@@ -194,7 +194,7 @@ const ModelTable = ({ data, selectedLanguages = [], allLanguages = [], machineTr
|
|
| 194 |
if (selectedLanguages.length === 0) {
|
| 195 |
return (
|
| 196 |
<span>
|
| 197 |
-
<span style={{ fontWeight:
|
| 198 |
<span style={{ fontSize: '0.85em', marginLeft: '0.5rem' }}>
|
| 199 |
Performance across {evaluatedLanguagesCount} evaluated languages
|
| 200 |
</span>
|
|
@@ -203,7 +203,7 @@ const ModelTable = ({ data, selectedLanguages = [], allLanguages = [], machineTr
|
|
| 203 |
} else if (selectedLanguages.length === 1) {
|
| 204 |
return (
|
| 205 |
<span>
|
| 206 |
-
<span style={{ fontWeight:
|
| 207 |
<span style={{ fontSize: '0.85em', marginLeft: '0.5rem' }}>
|
| 208 |
{selectedLanguages[0].language_name} performance
|
| 209 |
</span>
|
|
@@ -213,7 +213,7 @@ const ModelTable = ({ data, selectedLanguages = [], allLanguages = [], machineTr
|
|
| 213 |
const languageNames = selectedLanguages.map(lang => lang.language_name).join(', ')
|
| 214 |
return (
|
| 215 |
<span>
|
| 216 |
-
<span style={{ fontWeight:
|
| 217 |
<span style={{ fontSize: '0.85em', marginLeft: '0.5rem' }}>
|
| 218 |
Performance for {languageNames}
|
| 219 |
</span>
|
|
|
|
| 194 |
if (selectedLanguages.length === 0) {
|
| 195 |
return (
|
| 196 |
<span>
|
| 197 |
+
<span style={{ fontWeight: 600, fontSize: '1.15em', color: 'var(--ink)' }}>AI Models</span>
|
| 198 |
<span style={{ fontSize: '0.85em', marginLeft: '0.5rem' }}>
|
| 199 |
Performance across {evaluatedLanguagesCount} evaluated languages
|
| 200 |
</span>
|
|
|
|
| 203 |
} else if (selectedLanguages.length === 1) {
|
| 204 |
return (
|
| 205 |
<span>
|
| 206 |
+
<span style={{ fontWeight: 600, fontSize: '1.15em', color: 'var(--ink)' }}>AI Models</span>
|
| 207 |
<span style={{ fontSize: '0.85em', marginLeft: '0.5rem' }}>
|
| 208 |
{selectedLanguages[0].language_name} performance
|
| 209 |
</span>
|
|
|
|
| 213 |
const languageNames = selectedLanguages.map(lang => lang.language_name).join(', ')
|
| 214 |
return (
|
| 215 |
<span>
|
| 216 |
+
<span style={{ fontWeight: 600, fontSize: '1.15em', color: 'var(--ink)' }}>AI Models</span>
|
| 217 |
<span style={{ fontSize: '0.85em', marginLeft: '0.5rem' }}>
|
| 218 |
Performance for {languageNames}
|
| 219 |
</span>
|
|
@@ -1,21 +1,162 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
body {
|
| 2 |
margin: 0;
|
| 3 |
-
font-family: -
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-webkit-font-smoothing: antialiased;
|
| 7 |
-moz-osx-font-smoothing: grayscale;
|
| 8 |
}
|
| 9 |
|
| 10 |
code {
|
| 11 |
-
font-family:
|
| 12 |
-
monospace;
|
| 13 |
}
|
| 14 |
|
| 15 |
html, body, #root {
|
| 16 |
height: 100%;
|
| 17 |
}
|
| 18 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
.p-component, .pi {
|
| 20 |
font-size: 0.8rem;
|
| 21 |
}
|
|
@@ -26,7 +167,7 @@ html, body, #root {
|
|
| 26 |
}
|
| 27 |
|
| 28 |
.p-datatable-wrapper {
|
| 29 |
-
scrollbar-color:
|
| 30 |
border-radius: 0 0 6px 6px;
|
| 31 |
}
|
| 32 |
|
|
@@ -35,92 +176,187 @@ html, body, #root {
|
|
| 35 |
}
|
| 36 |
|
| 37 |
.p-datatable .p-datatable-tbody > tr:hover {
|
| 38 |
-
background-color:
|
| 39 |
}
|
| 40 |
|
| 41 |
.p-datatable .p-datatable-thead > tr > th {
|
| 42 |
-
border-bottom: 1px solid
|
| 43 |
-
background-color:
|
| 44 |
font-weight: 500;
|
| 45 |
-
color:
|
| 46 |
padding: 0.75rem 1rem;
|
| 47 |
}
|
| 48 |
|
| 49 |
.p-datatable .p-datatable-tbody > tr > td {
|
| 50 |
padding: 0.75rem 1rem;
|
| 51 |
-
border-bottom: 1px solid
|
| 52 |
}
|
| 53 |
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
|
|
|
|
|
|
|
|
|
| 58 |
}
|
| 59 |
|
| 60 |
-
#model-table
|
| 61 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 62 |
border-radius: 6px 6px 0 0;
|
| 63 |
-
|
| 64 |
-
color: #333;
|
| 65 |
-
border-bottom: 2px solid #d1d5ff;
|
| 66 |
padding: 1rem 1.25rem;
|
| 67 |
font-weight: 500;
|
| 68 |
}
|
| 69 |
|
| 70 |
-
#
|
| 71 |
-
|
| 72 |
-
border-
|
| 73 |
-
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
|
| 74 |
}
|
| 75 |
|
| 76 |
#language-table .p-datatable-header {
|
| 77 |
-
|
| 78 |
-
border-
|
| 79 |
-
background: #f0fff0;
|
| 80 |
-
color: #333;
|
| 81 |
-
border-bottom: 2px solid #c8f2c8;
|
| 82 |
-
padding: 1rem 1.25rem;
|
| 83 |
-
font-weight: 500;
|
| 84 |
-
}
|
| 85 |
-
|
| 86 |
-
#dataset-table {
|
| 87 |
-
border: 2px solid #ffe4cc;
|
| 88 |
-
border-radius: 8px;
|
| 89 |
-
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
|
| 90 |
}
|
| 91 |
|
| 92 |
#dataset-table .p-datatable-header {
|
| 93 |
-
|
| 94 |
-
border-
|
| 95 |
-
background: #fff8f0;
|
| 96 |
-
color: #333;
|
| 97 |
-
border-bottom: 2px solid #ffe4cc;
|
| 98 |
-
padding: 1rem 1.25rem;
|
| 99 |
-
font-weight: 500;
|
| 100 |
}
|
| 101 |
|
|
|
|
| 102 |
#figure {
|
| 103 |
width: 100%;
|
| 104 |
min-width: 600px;
|
| 105 |
-
height:
|
| 106 |
-
|
| 107 |
-
border
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
|
|
|
|
|
|
| 111 |
}
|
| 112 |
|
|
|
|
| 113 |
.p-autocomplete-input {
|
| 114 |
width: max(100%, 40vw);
|
| 115 |
margin-top: 2vh;
|
| 116 |
-
border-radius:
|
| 117 |
-
border: 1px solid
|
| 118 |
-
box-shadow:
|
| 119 |
}
|
| 120 |
|
|
|
|
| 121 |
.p-carousel-indicators button.p-link {
|
| 122 |
-
border-radius:
|
| 123 |
-
width:
|
| 124 |
-
height:
|
| 125 |
-
background-color:
|
| 126 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* ============================================================
|
| 2 |
+
Design tokens
|
| 3 |
+
============================================================ */
|
| 4 |
+
:root {
|
| 5 |
+
/* Surfaces */
|
| 6 |
+
--bg: #fbfbfd; /* soft cool off-white page background */
|
| 7 |
+
--surface: #ffffff; /* cards, tables */
|
| 8 |
+
--surface-warm: #f7f8fc; /* chart panel, subtle fills, row hover */
|
| 9 |
+
|
| 10 |
+
/* Ink */
|
| 11 |
+
--ink: #1b1d24; /* headings + primary text (slate-ink) */
|
| 12 |
+
--ink-muted: #5e626e; /* subtitles, secondary */
|
| 13 |
+
--ink-subtle: #9296a1; /* tertiary labels */
|
| 14 |
+
|
| 15 |
+
/* Accent — indigo, used sparingly */
|
| 16 |
+
--accent: #4350c4;
|
| 17 |
+
--accent-hover: #343fa0;
|
| 18 |
+
--accent-wash: rgba(67, 80, 196, 0.08);
|
| 19 |
+
|
| 20 |
+
/* Lines */
|
| 21 |
+
--border: #e5e6ec; /* structural borders, card edges */
|
| 22 |
+
--border-strong: #d4d6de;
|
| 23 |
+
--hairline: #eff0f4; /* faint inner row separators */
|
| 24 |
+
|
| 25 |
+
/* Warmed, ivory-friendly table accents (replace blue/green/orange) */
|
| 26 |
+
--tbl-model-border: #d7daec; --tbl-model-head: #eef0f8; /* soft periwinkle */
|
| 27 |
+
--tbl-lang-border: #cde3cd; --tbl-lang-head: #eff6ee; /* soft sage */
|
| 28 |
+
--tbl-data-border: #ecd9c5; --tbl-data-head: #faf2e9; /* soft sand */
|
| 29 |
+
|
| 30 |
+
/* Soft, warm-tinted shadows */
|
| 31 |
+
--shadow-sm: 0 1px 2px rgba(40, 33, 28, 0.05);
|
| 32 |
+
--shadow-md: 0 6px 20px rgba(40, 33, 28, 0.07);
|
| 33 |
+
|
| 34 |
+
/* Radius */
|
| 35 |
+
--radius: 12px;
|
| 36 |
+
--radius-sm: 8px;
|
| 37 |
+
|
| 38 |
+
/* Type */
|
| 39 |
+
--font-serif: ui-serif, Georgia, Cambria, 'Times New Roman', Times, serif; /* clean system serif, headings */
|
| 40 |
+
--font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
| 41 |
+
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
|
| 42 |
+
--font-mono: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace;
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
/* ============================================================
|
| 46 |
+
Base
|
| 47 |
+
============================================================ */
|
| 48 |
body {
|
| 49 |
margin: 0;
|
| 50 |
+
font-family: var(--font-sans);
|
| 51 |
+
background: var(--bg);
|
| 52 |
+
color: var(--ink);
|
| 53 |
-webkit-font-smoothing: antialiased;
|
| 54 |
-moz-osx-font-smoothing: grayscale;
|
| 55 |
}
|
| 56 |
|
| 57 |
code {
|
| 58 |
+
font-family: var(--font-mono);
|
|
|
|
| 59 |
}
|
| 60 |
|
| 61 |
html, body, #root {
|
| 62 |
height: 100%;
|
| 63 |
}
|
| 64 |
|
| 65 |
+
a {
|
| 66 |
+
color: var(--accent);
|
| 67 |
+
text-decoration: none;
|
| 68 |
+
transition: color 0.15s ease;
|
| 69 |
+
}
|
| 70 |
+
|
| 71 |
+
a:hover {
|
| 72 |
+
color: var(--accent-hover);
|
| 73 |
+
text-decoration: underline;
|
| 74 |
+
}
|
| 75 |
+
|
| 76 |
+
:focus-visible {
|
| 77 |
+
outline: 2px solid var(--accent);
|
| 78 |
+
outline-offset: 2px;
|
| 79 |
+
}
|
| 80 |
+
|
| 81 |
+
/* Serif display headline (hero) */
|
| 82 |
+
.hero-title {
|
| 83 |
+
font-family: var(--font-sans);
|
| 84 |
+
font-weight: 600;
|
| 85 |
+
font-size: clamp(2.25rem, 4vw, 2.75rem);
|
| 86 |
+
line-height: 1.12;
|
| 87 |
+
letter-spacing: -0.02em;
|
| 88 |
+
color: var(--ink);
|
| 89 |
+
margin: 1.25rem 0 0.75rem 0;
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
/* ============================================================
|
| 93 |
+
Buttons (replace inline gradients + JS hover handlers)
|
| 94 |
+
============================================================ */
|
| 95 |
+
.btn {
|
| 96 |
+
display: inline-flex;
|
| 97 |
+
align-items: center;
|
| 98 |
+
gap: 0.5rem;
|
| 99 |
+
padding: 0.7rem 1.4rem;
|
| 100 |
+
border-radius: 10px;
|
| 101 |
+
font-family: var(--font-sans);
|
| 102 |
+
font-size: 0.95rem;
|
| 103 |
+
font-weight: 500;
|
| 104 |
+
line-height: 1;
|
| 105 |
+
cursor: pointer;
|
| 106 |
+
border: 1px solid transparent;
|
| 107 |
+
transition: background-color 0.15s ease, border-color 0.15s ease,
|
| 108 |
+
color 0.15s ease;
|
| 109 |
+
}
|
| 110 |
+
|
| 111 |
+
.btn-primary {
|
| 112 |
+
background: var(--accent);
|
| 113 |
+
color: #fff;
|
| 114 |
+
box-shadow: var(--shadow-sm);
|
| 115 |
+
}
|
| 116 |
+
|
| 117 |
+
.btn-primary:hover {
|
| 118 |
+
background: var(--accent-hover);
|
| 119 |
+
color: #fff;
|
| 120 |
+
}
|
| 121 |
+
|
| 122 |
+
.btn-secondary {
|
| 123 |
+
background: transparent;
|
| 124 |
+
color: var(--ink);
|
| 125 |
+
border-color: var(--border-strong);
|
| 126 |
+
}
|
| 127 |
+
|
| 128 |
+
.btn-secondary:hover {
|
| 129 |
+
background: var(--accent-wash);
|
| 130 |
+
border-color: var(--accent);
|
| 131 |
+
color: var(--accent-hover);
|
| 132 |
+
}
|
| 133 |
+
|
| 134 |
+
/* Quiet ghost link (top-right GitHub) */
|
| 135 |
+
.ghost-link {
|
| 136 |
+
display: inline-flex;
|
| 137 |
+
align-items: center;
|
| 138 |
+
gap: 0.5rem;
|
| 139 |
+
padding: 0.5rem 0.9rem;
|
| 140 |
+
border-radius: var(--radius-sm);
|
| 141 |
+
font-size: 0.9rem;
|
| 142 |
+
font-weight: 500;
|
| 143 |
+
color: var(--ink-muted);
|
| 144 |
+
background: var(--surface);
|
| 145 |
+
border: 1px solid var(--border);
|
| 146 |
+
transition: background-color 0.15s ease, color 0.15s ease,
|
| 147 |
+
border-color 0.15s ease;
|
| 148 |
+
}
|
| 149 |
+
|
| 150 |
+
.ghost-link:hover {
|
| 151 |
+
background: var(--accent-wash);
|
| 152 |
+
border-color: var(--accent);
|
| 153 |
+
color: var(--accent-hover);
|
| 154 |
+
text-decoration: none;
|
| 155 |
+
}
|
| 156 |
+
|
| 157 |
+
/* ============================================================
|
| 158 |
+
PrimeReact base tweaks
|
| 159 |
+
============================================================ */
|
| 160 |
.p-component, .pi {
|
| 161 |
font-size: 0.8rem;
|
| 162 |
}
|
|
|
|
| 167 |
}
|
| 168 |
|
| 169 |
.p-datatable-wrapper {
|
| 170 |
+
scrollbar-color: var(--border) transparent;
|
| 171 |
border-radius: 0 0 6px 6px;
|
| 172 |
}
|
| 173 |
|
|
|
|
| 176 |
}
|
| 177 |
|
| 178 |
.p-datatable .p-datatable-tbody > tr:hover {
|
| 179 |
+
background-color: var(--surface-warm) !important;
|
| 180 |
}
|
| 181 |
|
| 182 |
.p-datatable .p-datatable-thead > tr > th {
|
| 183 |
+
border-bottom: 1px solid var(--border);
|
| 184 |
+
background-color: var(--surface-warm);
|
| 185 |
font-weight: 500;
|
| 186 |
+
color: var(--ink-muted);
|
| 187 |
padding: 0.75rem 1rem;
|
| 188 |
}
|
| 189 |
|
| 190 |
.p-datatable .p-datatable-tbody > tr > td {
|
| 191 |
padding: 0.75rem 1rem;
|
| 192 |
+
border-bottom: 1px solid var(--hairline);
|
| 193 |
}
|
| 194 |
|
| 195 |
+
/* ============================================================
|
| 196 |
+
Table cards — IDs keep specificity over the PrimeReact theme
|
| 197 |
+
============================================================ */
|
| 198 |
+
#model-table, #language-table, #dataset-table {
|
| 199 |
+
border-radius: var(--radius-sm);
|
| 200 |
+
box-shadow: var(--shadow-sm);
|
| 201 |
+
background: var(--surface);
|
| 202 |
}
|
| 203 |
|
| 204 |
+
#model-table { border: 1px solid var(--tbl-model-border); }
|
| 205 |
+
#language-table { border: 1px solid var(--tbl-lang-border); }
|
| 206 |
+
#dataset-table { border: 1px solid var(--tbl-data-border); }
|
| 207 |
+
|
| 208 |
+
#model-table .p-datatable-header,
|
| 209 |
+
#language-table .p-datatable-header,
|
| 210 |
+
#dataset-table .p-datatable-header {
|
| 211 |
+
border-top-width: 0;
|
| 212 |
border-radius: 6px 6px 0 0;
|
| 213 |
+
color: var(--ink);
|
|
|
|
|
|
|
| 214 |
padding: 1rem 1.25rem;
|
| 215 |
font-weight: 500;
|
| 216 |
}
|
| 217 |
|
| 218 |
+
#model-table .p-datatable-header {
|
| 219 |
+
background: var(--tbl-model-head);
|
| 220 |
+
border-bottom: 1px solid var(--tbl-model-border);
|
|
|
|
| 221 |
}
|
| 222 |
|
| 223 |
#language-table .p-datatable-header {
|
| 224 |
+
background: var(--tbl-lang-head);
|
| 225 |
+
border-bottom: 1px solid var(--tbl-lang-border);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 226 |
}
|
| 227 |
|
| 228 |
#dataset-table .p-datatable-header {
|
| 229 |
+
background: var(--tbl-data-head);
|
| 230 |
+
border-bottom: 1px solid var(--tbl-data-border);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 231 |
}
|
| 232 |
|
| 233 |
+
/* Chart panel */
|
| 234 |
#figure {
|
| 235 |
width: 100%;
|
| 236 |
min-width: 600px;
|
| 237 |
+
height: auto;
|
| 238 |
+
min-height: 700px;
|
| 239 |
+
border: 1px solid var(--border);
|
| 240 |
+
border-radius: var(--radius);
|
| 241 |
+
padding: 1rem 1rem 1.5rem;
|
| 242 |
+
background: var(--surface-warm);
|
| 243 |
+
box-shadow: var(--shadow-md);
|
| 244 |
+
font-family: var(--font-sans);
|
| 245 |
}
|
| 246 |
|
| 247 |
+
/* Legacy PrimeReact autocomplete input — soften the dated hard shadow */
|
| 248 |
.p-autocomplete-input {
|
| 249 |
width: max(100%, 40vw);
|
| 250 |
margin-top: 2vh;
|
| 251 |
+
border-radius: var(--radius-sm);
|
| 252 |
+
border: 1px solid var(--border);
|
| 253 |
+
box-shadow: var(--shadow-sm);
|
| 254 |
}
|
| 255 |
|
| 256 |
+
/* Carousel indicators */
|
| 257 |
.p-carousel-indicators button.p-link {
|
| 258 |
+
border-radius: 999px;
|
| 259 |
+
width: 8px;
|
| 260 |
+
height: 8px;
|
| 261 |
+
background-color: var(--border-strong);
|
| 262 |
+
}
|
| 263 |
+
|
| 264 |
+
.p-carousel-indicators .p-carousel-indicator.p-highlight button.p-link {
|
| 265 |
+
background-color: var(--accent);
|
| 266 |
+
}
|
| 267 |
+
|
| 268 |
+
/* ============================================================
|
| 269 |
+
PrimeReact accent harmonization (cyan -> clay).
|
| 270 |
+
index.css is imported AFTER theme.css (see index.js), so these
|
| 271 |
+
equal-specificity rules win without !important.
|
| 272 |
+
============================================================ */
|
| 273 |
+
.p-checkbox .p-checkbox-box.p-highlight {
|
| 274 |
+
background: var(--accent);
|
| 275 |
+
border-color: var(--accent);
|
| 276 |
+
}
|
| 277 |
+
|
| 278 |
+
.p-checkbox .p-checkbox-box.p-highlight:hover {
|
| 279 |
+
background: var(--accent-hover);
|
| 280 |
+
border-color: var(--accent-hover);
|
| 281 |
+
}
|
| 282 |
+
|
| 283 |
+
.p-radiobutton .p-radiobutton-box.p-highlight {
|
| 284 |
+
background: var(--accent);
|
| 285 |
+
border-color: var(--accent);
|
| 286 |
+
}
|
| 287 |
+
|
| 288 |
+
.p-slider .p-slider-range {
|
| 289 |
+
background: var(--accent);
|
| 290 |
+
}
|
| 291 |
+
|
| 292 |
+
.p-slider .p-slider-handle {
|
| 293 |
+
border-color: var(--accent);
|
| 294 |
+
}
|
| 295 |
+
|
| 296 |
+
.p-slider .p-slider-handle:hover {
|
| 297 |
+
background: var(--accent);
|
| 298 |
+
}
|
| 299 |
+
|
| 300 |
+
.p-multiselect-panel .p-multiselect-items .p-multiselect-item.p-highlight,
|
| 301 |
+
.p-dropdown-panel .p-dropdown-items .p-dropdown-item.p-highlight {
|
| 302 |
+
background: var(--accent-wash);
|
| 303 |
+
color: var(--accent-hover);
|
| 304 |
+
}
|
| 305 |
+
|
| 306 |
+
.p-multiselect .p-multiselect-token {
|
| 307 |
+
background: var(--accent-wash);
|
| 308 |
+
color: var(--accent-hover);
|
| 309 |
+
}
|
| 310 |
+
|
| 311 |
+
.p-datatable .p-datatable-tbody > tr.p-highlight {
|
| 312 |
+
background: var(--accent-wash);
|
| 313 |
+
color: var(--ink);
|
| 314 |
+
}
|
| 315 |
+
|
| 316 |
+
.p-inputtext:enabled:focus {
|
| 317 |
+
border-color: var(--accent);
|
| 318 |
+
box-shadow: 0 0 0 2px var(--accent-wash);
|
| 319 |
+
}
|
| 320 |
+
|
| 321 |
+
/* ============================================================
|
| 322 |
+
Dialogs — cohesive with the hero (serif headings, clean chrome)
|
| 323 |
+
============================================================ */
|
| 324 |
+
.p-dialog {
|
| 325 |
+
border-radius: var(--radius);
|
| 326 |
+
border: 1px solid var(--border);
|
| 327 |
+
box-shadow: var(--shadow-md);
|
| 328 |
+
overflow: hidden;
|
| 329 |
+
}
|
| 330 |
+
|
| 331 |
+
.p-dialog .p-dialog-header {
|
| 332 |
+
background: var(--surface);
|
| 333 |
+
border-bottom: 1px solid var(--border);
|
| 334 |
+
padding: 1.25rem 1.5rem;
|
| 335 |
+
}
|
| 336 |
+
|
| 337 |
+
.p-dialog .p-dialog-header .p-dialog-title {
|
| 338 |
+
font-family: var(--font-sans);
|
| 339 |
+
font-weight: 600;
|
| 340 |
+
font-size: 1.3rem;
|
| 341 |
+
letter-spacing: -0.01em;
|
| 342 |
+
color: var(--ink);
|
| 343 |
+
}
|
| 344 |
+
|
| 345 |
+
.p-dialog .p-dialog-content {
|
| 346 |
+
padding: 0 1.5rem 1.5rem;
|
| 347 |
+
color: var(--ink);
|
| 348 |
+
}
|
| 349 |
+
|
| 350 |
+
.p-dialog .p-dialog-content h4 {
|
| 351 |
+
font-family: var(--font-sans);
|
| 352 |
+
font-weight: 600;
|
| 353 |
+
font-size: 1.05rem;
|
| 354 |
+
color: var(--ink);
|
| 355 |
+
margin: 1.6rem 0 0.5rem;
|
| 356 |
+
}
|
| 357 |
+
|
| 358 |
+
.p-dialog .p-dialog-content p,
|
| 359 |
+
.p-dialog .p-dialog-content li {
|
| 360 |
+
color: var(--ink-muted);
|
| 361 |
+
line-height: 1.6;
|
| 362 |
+
}
|
|
@@ -1,5 +1,6 @@
|
|
| 1 |
import React from 'react';
|
| 2 |
import ReactDOM from 'react-dom/client';
|
|
|
|
| 3 |
import './index.css';
|
| 4 |
import App from './App';
|
| 5 |
import reportWebVitals from './reportWebVitals';
|
|
|
|
| 1 |
import React from 'react';
|
| 2 |
import ReactDOM from 'react-dom/client';
|
| 3 |
+
import 'primereact/resources/themes/lara-light-cyan/theme.css';
|
| 4 |
import './index.css';
|
| 5 |
import App from './App';
|
| 6 |
import reportWebVitals from './reportWebVitals';
|