README.md CHANGED
@@ -1,5 +1,5 @@
1
  ---
2
- title: InferBench
3
  emoji: 🥇
4
  colorFrom: green
5
  colorTo: indigo
@@ -12,73 +12,34 @@ tags:
12
  - leaderboard
13
  ---
14
 
15
- # InferBench
16
 
17
- Evaluate the quality and efficiency of image gen api's.
 
18
 
19
- ## Installation
20
 
21
- ### Install dependencies
22
 
23
- Install dependencies with conda like that:
24
- ```
25
- conda env create -f environment.yml
26
- ```
27
-
28
- ### Install uv
29
-
30
- Install uv with pip like that:
31
-
32
- ```
33
- uv venv --python 3.12
34
- ```
35
-
36
- Then activate the environment:
37
 
38
  ```
 
39
  source .venv/bin/activate
 
 
40
  ```
41
 
42
- Then install the dependencies with uv:
43
 
44
- ```
45
- uv sync --all-groups
46
- ```
47
 
48
- ## Usage
49
 
50
- Create .env file with all the credentials you will need.
 
51
 
52
- This is how you can generate the images.
53
- ```
54
- python sample.py replicate draw_bench genai_bench geneval hps parti
55
- ```
56
-
57
- This is how you would evaluate the benchmarks once you have all images:
58
- ```
59
- python evaluate.py replicate draw_bench genai_bench geneval hps parti
60
  ```
61
-
62
- ## Leaderboard
63
-
64
- The leaderboard is [hosted on Hugging Face](https://huggingface.co/spaces/PrunaAI/InferBench/tree/main) with gradio.
65
-
66
- To run the dashboard locally, you can use the following command:
67
-
68
- ```
69
- python dashboard/app.py
70
- ```
71
-
72
- To deploy the dashboard to Hugging Face, you can use the following commands:
73
-
74
- First, add the remote:
75
-
76
- ```
77
- git remote add hf https://huggingface.co/spaces/PrunaAI/InferBench
78
- ```
79
-
80
- Then push the changes of your branch to the remote:
81
-
82
  ```
83
- git push hf $(git rev-parse --abbrev-ref HEAD):main --force
84
- ```
 
1
  ---
2
+ title: P-Bench
3
  emoji: 🥇
4
  colorFrom: green
5
  colorTo: indigo
 
12
  - leaderboard
13
  ---
14
 
15
+ # P-Bench
16
 
17
+ Compare text-to-image models on quality, speed, and price. This repo is the
18
+ Gradio dashboard: leaderboards, Pareto plots, and side-by-side samples.
19
 
20
+ The live Space is [PrunaAI/P-Bench](https://huggingface.co/spaces/PrunaAI/P-Bench).
21
 
22
+ ## Run locally
23
 
24
+ From the repo root:
 
 
 
 
 
 
 
 
 
 
 
 
 
25
 
26
  ```
27
+ python -m venv .venv
28
  source .venv/bin/activate
29
+ pip install "gradio==5.19.0" pandas -r requirements.txt
30
+ python app.py
31
  ```
32
 
33
+ The app is served at `http://127.0.0.1:7860`.
34
 
35
+ `requirements.txt` lists Plotly. Gradio and pandas are required locally;
36
+ Hugging Face Spaces installs Gradio from the YAML `sdk_version` above.
 
37
 
38
+ ## Deploy
39
 
40
+ `origin` is the Space (`https://huggingface.co/spaces/PrunaAI/P-Bench`).
41
+ Publish the current branch to the live app with:
42
 
 
 
 
 
 
 
 
 
43
  ```
44
+ git push origin HEAD:main
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  ```
 
 
app.py CHANGED
@@ -1,429 +1,1555 @@
 
1
  import json
2
  from collections import defaultdict
3
  from pathlib import Path
4
 
 
 
 
 
 
 
 
5
  import gradio as gr
6
  import pandas as pd
7
 
8
  from ui import (
9
- render_about,
10
- render_benchmarks,
11
  render_footer,
12
  render_header,
13
- render_home,
14
  )
15
 
 
16
  custom_css = """
17
- .logo {
18
- width: 300px;
19
- height: auto;
20
- max-width: 100%;
21
- margin: 0 auto;
22
- object-fit: contain;
23
- padding-bottom: 0;
24
- }
25
- .text {
26
- font-size: 16px !important;
27
- }
28
- .tabs button,
29
- .tab-nav button,
30
- .subtabs button {
31
- font-size: 20px;
32
- color: #581c87 !important;
33
- }
34
- .tabs button.selected,
35
- .tabs button[aria-selected="true"],
36
- .tab-nav button.selected,
37
- .tab-nav button[aria-selected="true"],
38
- .subtabs button.selected,
39
- .subtabs button[aria-selected="true"] {
40
- color: #ffffff !important;
41
- background: #7c3aed !important;
42
- border-color: #6d28d9 !important;
43
- }
44
- .dark .tabs button,
45
- .dark .tab-nav button,
46
- .dark .subtabs button {
47
- color: #e9d5ff !important;
48
- }
49
- .dark .tabs button.selected,
50
- .dark .tabs button[aria-selected="true"],
51
- .dark .tab-nav button.selected,
52
- .dark .tab-nav button[aria-selected="true"],
53
- .dark .subtabs button.selected,
54
- .dark .subtabs button[aria-selected="true"] {
55
- color: #ffffff !important;
56
- background: #6d28d9 !important;
57
- }
58
- .benchmark-catalogue-row {
59
- width: 100%;
60
- gap: 16px;
61
- }
62
- .benchmark-card {
63
- width: 100%;
64
- max-width: none;
65
- min-height: 220px;
66
- border: 1px solid rgba(124, 58, 237, 0.45);
67
- border-left: 4px solid #7c3aed;
68
- border-radius: 12px;
69
- background: rgba(139, 92, 246, 0.14);
70
- padding: 16px 18px;
71
- box-shadow: 0 4px 12px rgba(76, 29, 149, 0.12);
72
- }
73
- .benchmark-card:hover {
74
- border-color: #5b21b6;
75
- box-shadow: 0 6px 18px rgba(76, 29, 149, 0.22);
76
- }
77
- .community-footer {
78
- margin-top: 24px;
79
- padding: 18px 20px;
80
- border: 1px solid #c4b5fd;
81
- border-radius: 12px;
82
- background: rgba(139, 92, 246, 0.16);
83
- }
84
- .community-footer h3 {
85
- margin: 0 0 10px;
86
- color: #581c87;
87
- font-size: 1.05rem;
88
- }
89
- .community-footer-links {
90
- display: flex;
91
- flex-wrap: wrap;
92
- gap: 10px 14px;
93
- align-items: center;
94
- }
95
- .dark .community-footer {
96
- border-color: #6d28d9;
97
- background: rgba(76, 29, 149, 0.35);
98
- }
99
- .dark .community-footer h3 {
100
- color: #f5f3ff;
101
- }
102
- .home-callouts {
103
- display: grid;
104
- grid-template-columns: repeat(3, minmax(0, 1fr));
105
- gap: 12px;
106
- margin: 8px 0 20px;
107
  }
108
- .home-callouts > div {
109
- padding: 14px 16px;
110
- border: 1px solid #a78bfa;
111
- border-radius: 10px;
112
- background: #f5f3ff;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
  }
114
- .home-callouts span {
115
- color: #5b21b6;
116
- font-size: 11px;
117
- font-weight: 700;
118
- letter-spacing: 0.05em;
 
 
 
 
 
 
 
 
 
 
 
 
119
  }
120
- .home-callouts strong {
121
- display: block;
122
- margin-top: 6px;
123
- color: #1e1b4b;
124
- font-size: 18px;
125
- word-break: break-word;
126
  }
127
- .home-callouts em {
128
- display: block;
129
- margin-top: 4px;
130
- color: #4c1d95;
131
- font-style: normal;
132
- font-size: 13px;
133
  }
134
- .home-benchmark-card {
135
- height: 100%;
136
- padding: 18px 18px 16px;
137
- border: 1px solid #a78bfa;
138
- border-left: 4px solid #7c3aed;
139
- border-radius: 12px;
140
- background: #f5f3ff;
141
- box-shadow: 0 4px 12px rgba(76, 29, 149, 0.12);
142
  }
143
- .home-benchmark-title {
144
- color: #1e1b4b;
145
- font-size: 1.35rem;
146
- font-weight: 700;
 
 
 
 
 
 
 
147
  }
148
- .home-benchmark-blurb {
149
- margin: 8px 0 14px;
150
- color: #312e81;
151
- font-size: 0.95rem;
152
- line-height: 1.45;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
153
  }
154
- .home-top-label {
155
- color: #5b21b6;
156
- font-size: 11px;
157
- font-weight: 700;
158
- letter-spacing: 0.05em;
159
- text-transform: uppercase;
 
 
 
 
 
 
 
 
 
 
 
160
  }
161
- .home-top-list {
162
- list-style: none;
 
 
 
 
163
  margin: 8px 0 0;
164
- padding: 0;
 
165
  }
166
- .home-top-list li {
167
  display: grid;
168
- grid-template-columns: 28px 1fr auto;
169
- gap: 10px;
170
  align-items: center;
171
- padding: 8px 0;
172
- border-bottom: 1px solid #ddd6fe;
173
- color: #1e1b4b;
174
- }
175
- .home-rank {
176
- width: 28px;
177
- height: 28px;
178
- border-radius: 999px;
179
- background: #ede9fe;
180
- color: #5b21b6;
181
- font-weight: 700;
182
- font-size: 13px;
183
- display: inline-flex;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
184
  align-items: center;
185
  justify-content: center;
 
 
 
 
 
 
186
  }
187
- .home-model {
188
- font-weight: 600;
189
- word-break: break-word;
190
- color: #1e1b4b;
191
- }
192
- .home-score {
193
- font-variant-numeric: tabular-nums;
194
- color: #4c1d95;
195
- font-weight: 600;
196
- }
197
- .home-empty {
198
- color: #4c1d95;
199
  }
200
- .dark .home-callouts > div,
201
- .dark .home-benchmark-card {
202
- border-color: #7c3aed;
203
- background: #1e1b4b;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
204
  }
205
- .dark .home-callouts span,
206
- .dark .home-top-label,
207
- .dark .home-rank {
208
- color: #c4b5fd;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
209
  }
210
- .dark .home-rank {
211
- background: #312e81;
 
 
 
 
 
 
 
 
212
  }
213
- .dark .home-callouts strong,
214
- .dark .home-benchmark-title,
215
- .dark .home-model,
216
- .dark .home-top-list li {
217
- color: #faf5ff;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
218
  }
219
- .dark .home-callouts em,
220
- .dark .home-benchmark-blurb,
221
- .dark .home-score,
222
- .dark .home-empty {
223
- color: #ddd6fe;
 
224
  }
225
- .dark .home-top-list li {
226
- border-bottom-color: #4c1d95;
 
227
  }
 
228
  @media (max-width: 700px) {
229
- .home-callouts {
230
- grid-template-columns: 1fr;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
231
  }
232
  }
233
- .pareto-plot {
234
- width: 100%;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
235
  }
236
- .pareto-plot .plotly {
 
 
 
 
 
237
  width: 100% !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
238
  }
239
- .pareto-plot .js-plotly-plot,
240
- .pareto-plot .plot-container {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
241
  width: 100% !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
242
  }
243
- /* Hide the Plotly toolbar so it doesn't cover points in the top-right. */
244
- .pareto-plot .modebar {
245
- display: none !important;
 
 
246
  }
247
- .leaderboard-summary {
248
- display: grid;
249
- grid-template-columns: repeat(4, minmax(0, 1fr));
250
- gap: 12px;
251
- margin: 8px 0 16px;
252
  }
253
- .leaderboard-summary > div {
254
- padding: 14px 16px;
255
- border: 1px solid #c4b5fd;
256
- border-radius: 10px;
257
- background: rgba(139, 92, 246, 0.14);
258
  }
259
- .leaderboard-summary span,
260
- .results-heading {
261
- color: #7e22ce;
262
- font-size: 11px;
263
- font-weight: 700;
264
- letter-spacing: 0.05em;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
265
  }
266
- .leaderboard-summary strong {
267
- display: block;
268
- margin-top: 4px;
269
- color: #581c87;
270
- font-size: 22px;
 
 
 
 
 
 
 
271
  }
 
 
272
  .leaderboard-controls {
273
- align-items: end;
274
- margin-bottom: 8px;
275
- }
276
- .ranking-table-host {
277
- width: 100%;
278
- }
279
- .ranking-table {
280
- margin-top: 4px;
281
- width: 100%;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
282
  }
283
- .results-heading {
284
- display: flex;
285
- justify-content: space-between;
286
- margin: 16px 0 8px;
287
- text-transform: uppercase;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
288
  }
289
  .ranking-table-scroll {
 
 
 
 
 
 
 
 
290
  overflow-x: auto;
291
- border: 1px solid #c4b5fd;
292
- border-radius: 10px;
293
- background: rgba(139, 92, 246, 0.12);
294
  }
295
- .ranking-table table {
 
296
  width: 100%;
297
- min-width: 800px;
298
- border-collapse: collapse;
299
- color: #581c87;
300
- font-size: 14px;
301
- }
302
- .ranking-table th {
303
- padding: 11px 14px;
304
- border-bottom: 1px solid #c4b5fd;
305
- color: #7e22ce;
306
- font-size: 11px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
307
  letter-spacing: 0.04em;
308
  text-align: left;
309
  text-transform: uppercase;
310
- }
311
- .ranking-table th.sortable-col {
312
- cursor: pointer;
313
- user-select: none;
314
  white-space: nowrap;
 
315
  }
316
- .ranking-table th.sortable-col:hover {
317
- color: #4c1d95;
318
- }
319
  .ranking-table th.sortable-col.sorted-asc::after,
320
  .ranking-table th.sortable-col.sorted-desc::after {
321
  margin-left: 0.35em;
322
  font-size: 0.85em;
323
  opacity: 0.85;
324
  }
325
- .ranking-table th.sortable-col.sorted-asc::after {
326
- content: "";
327
- }
328
- .ranking-table th.sortable-col.sorted-desc::after {
329
- content: "▼";
330
- }
331
- .ranking-table td {
332
- padding: 13px 14px;
333
- border-bottom: 1px solid #e9d5ff;
334
- }
335
- .ranking-table tbody tr:last-child td {
336
- border-bottom: 0;
337
- }
338
- .ranking-table tbody tr:hover {
339
- background: #6d28d9;
340
  }
341
  .ranking-table tbody tr:hover td,
342
  .ranking-table tbody tr:hover .rank,
343
  .ranking-table tbody tr:hover .metric-score,
 
344
  .ranking-table tbody tr:hover .model-cell strong,
345
- .ranking-table tbody tr:hover .model-cell span {
346
- color: #ffffff;
 
 
 
 
 
 
 
 
 
 
 
347
  }
348
- .ranking-table .rank {
349
- color: #7c3aed;
350
- font-weight: 700;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
351
  }
352
  .ranking-table .model-cell strong,
353
- .ranking-table .model-cell span {
354
- display: block;
 
 
 
 
 
355
  }
356
  .ranking-table .model-cell span {
357
  margin-top: 3px;
358
- color: #9333ea;
359
  font-size: 12px;
360
  }
361
- .ranking-table .metric-score {
362
- color: #4c1d95;
 
 
 
 
 
 
 
363
  font-variant-numeric: tabular-nums;
364
- font-weight: 700;
 
 
365
  }
 
366
  .ranking-table .empty-state {
367
- color: #9333ea;
368
  padding: 32px;
369
  text-align: center;
370
  }
371
- @media (prefers-color-scheme: dark) {
372
- .leaderboard-summary > div,
373
- .ranking-table-scroll {
374
- border-color: rgba(221, 214, 254, 0.45);
375
- }
376
- .leaderboard-summary span,
377
- .results-heading,
378
- .ranking-table th,
379
- .ranking-table .model-cell span,
380
- .ranking-table .empty-state {
381
- color: #ddd6fe;
382
- }
383
- .leaderboard-summary strong,
384
- .ranking-table table,
385
- .ranking-table .rank,
386
- .ranking-table .metric-score {
387
- color: #f5f3ff;
388
- }
389
- .ranking-table td {
390
- border-bottom-color: rgba(221, 214, 254, 0.2);
391
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
392
  }
393
- .dark .leaderboard-summary > div,
394
- .dark .ranking-table-scroll {
395
- border-color: rgba(221, 214, 254, 0.45);
 
 
 
396
  }
397
- .dark .leaderboard-summary span,
398
- .dark .results-heading,
399
- .dark .ranking-table th,
400
- .dark .ranking-table .model-cell span,
401
- .dark .ranking-table .empty-state {
402
- color: #ddd6fe;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
403
  }
404
- .dark .leaderboard-summary strong,
405
- .dark .ranking-table table,
406
- .dark .ranking-table .rank,
407
- .dark .ranking-table .metric-score {
408
- color: #f5f3ff;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
409
  }
410
- .compare-samples-help {
411
- color: #6b21a8;
412
- margin-bottom: 8px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
413
  }
414
  .compare-prompt-block {
415
  margin: 0 0 22px;
416
  padding: 14px 16px;
417
- border: 1px solid #c4b5fd;
418
- border-radius: 12px;
419
- background: rgba(139, 92, 246, 0.10);
420
  }
421
  .compare-prompt-meta {
422
  display: flex;
423
  justify-content: space-between;
424
  gap: 12px;
425
  margin-bottom: 8px;
426
- color: #7e22ce;
427
  font-size: 12px;
428
  font-weight: 700;
429
  letter-spacing: 0.04em;
@@ -431,20 +1557,221 @@ custom_css = """
431
  }
432
  .compare-prompt-text {
433
  margin: 0 0 14px;
434
- color: #3b0764;
435
  font-size: 15px;
436
  line-height: 1.45;
437
  }
438
- .compare-row {
439
- display: grid;
440
- gap: 12px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
441
  }
442
- .compare-cell {
443
- min-width: 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
444
  }
 
445
  .compare-model-label {
446
  margin-bottom: 6px;
447
- color: #5b21b6;
448
  font-size: 13px;
449
  font-weight: 700;
450
  word-break: break-word;
@@ -454,57 +1781,341 @@ custom_css = """
454
  width: 100%;
455
  aspect-ratio: 1 / 1;
456
  object-fit: cover;
457
- border-radius: 10px;
458
- border: 1px solid #ddd6fe;
459
- background: #f5f3ff;
460
  }
461
- .compare-empty {
462
- padding: 18px;
463
- border: 1px dashed #c4b5fd;
 
 
 
464
  border-radius: 10px;
465
- color: #6b21a8;
466
- text-align: center;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
467
  }
468
- .dark .compare-samples-help,
469
- .dark .compare-prompt-meta,
470
- .dark .compare-model-label,
471
- .dark .compare-empty {
472
- color: #e9d5ff;
 
 
473
  }
474
- .dark .compare-prompt-block {
475
- border-color: #6d28d9;
476
- background: rgba(76, 29, 149, 0.35);
 
477
  }
478
- .dark .compare-prompt-text {
479
- color: #f5f3ff;
 
480
  }
481
- .dark .compare-cell img {
482
- border-color: #6d28d9;
483
- background: #2e1065;
 
 
484
  }
485
- .dark .ranking-table td {
486
- border-bottom-color: rgba(221, 214, 254, 0.2);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
487
  }
488
- @media (max-width: 700px) {
489
- .leaderboard-summary {
490
- grid-template-columns: repeat(2, minmax(0, 1fr));
491
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
492
  }
493
- h1, h2 {
494
- margin: 0;
495
- padding-top: 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
496
  }
497
  """
498
 
499
- theme = gr.Theme.from_hub("Werli/Purple-Crimson-Gradio-Theme").set(
500
- body_background_fill="#c4b5fd",
501
- body_background_fill_dark="#120B1B",
502
- body_text_color="#3b0764",
503
- body_text_color_dark="#ffffff",
504
- block_background_fill="#ede9fe",
505
- block_background_fill_dark="#2e1065",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
506
  )
507
 
 
508
  space_root = Path(__file__).resolve().parent
509
  data_dir = space_root / "data"
510
 
@@ -563,18 +2174,11 @@ def load_sample_comparison_data(folder):
563
  }
564
 
565
 
566
- def format_url_links(value):
567
- if pd.isna(value) or not value:
568
- return ""
569
-
570
- links = [url.strip() for url in str(value).split(",") if url.strip()]
571
- if not links:
572
- return ""
573
-
574
- return " ".join(
575
- f'<a target="_blank" href="{url}" style="color: var(--link-text-color); text-decoration: underline;text-decoration-style: dotted;">run {idx}</a>'
576
- for idx, url in enumerate(links, start=1)
577
- )
578
 
579
 
580
  def load_oneig_dataframe(path):
@@ -582,7 +2186,6 @@ def load_oneig_dataframe(path):
582
  df = df.rename(
583
  columns={
584
  "Owner": "Endpoint Owner",
585
- "Optimization": "Optimization Details",
586
  "Anime Alignment Score": "OneIG (Anime Alignment)",
587
  "Human Alignment Score": "OneIG (Human Alignment)",
588
  "Object Alignment Score": "OneIG (Object Alignment)",
@@ -591,67 +2194,86 @@ def load_oneig_dataframe(path):
591
  "OneIG (General Object) (Alignment Score)": "OneIG (Object Alignment)",
592
  }
593
  )
594
- if "URL" in df.columns:
595
- df["URL"] = df["URL"].apply(format_url_links)
 
 
 
 
 
596
  if "Optimized" in df.columns:
597
  df["Optimized"] = df["Optimized"].map(
598
  {True: "Yes", False: "No", "TRUE": "Yes", "FALSE": "No"}
599
  ).fillna(df["Optimized"])
600
 
601
- for column in [
602
- "Price / Image (USD)",
603
- "Median Generation Time (s)",
604
- "Min Generation Time (s)",
605
- "OneIG (Anime Alignment)",
606
- "OneIG (Human Alignment)",
607
- "OneIG (Object Alignment)",
608
- "OneIG Anime Elo",
609
- "OneIG Human Elo",
610
- "OneIG Object Elo",
611
- "P-Judge Overall",
612
- "Rapidata Elo",
613
- ]:
614
- if column in df.columns:
615
- df[column] = pd.to_numeric(df[column], errors="coerce")
 
616
 
617
- preferred_columns = [
618
- "Platform",
619
- "Endpoint Owner",
620
- "Device",
621
- "Model",
622
- "Optimized",
623
- "Optimization Details",
624
- "OneIG (Anime Alignment)",
625
- "OneIG (Human Alignment)",
626
- "OneIG (Object Alignment)",
627
- "OneIG Anime Elo",
628
- "OneIG Human Elo",
629
- "OneIG Object Elo",
630
- "Median Inference Time",
631
- "Median Inference Time (s)",
632
- "Median Generation Time (s)",
633
- "Min Generation Time (s)",
634
- "Median Total Duration (s)",
635
- "Price per Image",
636
- "Price / Image (USD)",
637
- "Evaluation Date (UTC)",
638
- "URL",
639
- ]
640
- present_preferred_columns = [col for col in preferred_columns if col in df.columns]
641
- df = df[
642
- present_preferred_columns
643
- + [col for col in df.columns.tolist() if col not in present_preferred_columns]
644
- ]
645
 
646
- if "OneIG (Human Alignment)" in df.columns:
647
- df = df.sort_values(
648
- by="OneIG (Human Alignment)", ascending=False, na_position="last"
649
- )
 
 
 
 
 
 
 
 
 
 
 
650
 
651
- numeric_cols = df.select_dtypes(include=[float, int]).columns.tolist()
652
- for col in numeric_cols:
653
- df[col] = df[col].apply(lambda x: round(x, 4) if pd.notna(x) else x)
654
- return df
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
655
 
656
 
657
  def load_qwen_combined_dataframe(path):
@@ -664,36 +2286,17 @@ def load_qwen_combined_dataframe(path):
664
  df = df[~df["Model"].astype(str).str.startswith("#")].copy()
665
  df["Model"] = df["Model"].astype(str).str.strip()
666
 
667
- for column in [
668
- "Price / Image (USD)",
669
- "Median Generation Time (s)",
670
- "Min Generation Time (s)",
671
- "P-Judge Overall",
672
- "Rapidata Elo",
673
- "Datapoint Elo",
674
- ]:
675
- if column in df.columns:
676
- df[column] = pd.to_numeric(df[column], errors="coerce")
677
-
678
- sort_column = next(
679
- (
680
- col
681
- for col in [
682
- "Datapoint Elo",
683
- "P-Judge Overall",
684
- "Rapidata Elo",
685
- ]
686
- if col in df.columns
687
- ),
688
- None,
689
- )
690
- if sort_column:
691
- df = df.sort_values(by=sort_column, ascending=False, na_position="last")
692
-
693
- numeric_cols = df.select_dtypes(include=[float, int]).columns.tolist()
694
- for col in numeric_cols:
695
- df[col] = df[col].apply(lambda x: round(x, 4) if pd.notna(x) else x)
696
- return df.reset_index(drop=True)
697
 
698
 
699
  df = load_oneig_dataframe(oneig_path)
@@ -712,9 +2315,6 @@ if oneig_metric_columns:
712
  oneig_df["OneIG Overall Score"] = oneig_df[oneig_metric_columns].mean(
713
  axis=1, skipna=True
714
  )
715
- oneig_df = oneig_df.sort_values(
716
- by="OneIG Overall Score", ascending=False, na_position="last"
717
- )
718
 
719
  oneig_display_columns = [
720
  col
@@ -723,6 +2323,7 @@ oneig_display_columns = [
723
  "Endpoint Owner",
724
  "Model",
725
  "Optimized",
 
726
  *oneig_metric_columns,
727
  "OneIG Anime Elo",
728
  "OneIG Human Elo",
@@ -733,12 +2334,9 @@ oneig_display_columns = [
733
  "Median Generation Time (s)",
734
  "Min Generation Time (s)",
735
  "Price / Image (USD)",
736
- "URL",
737
  ]
738
  if col in oneig_df.columns
739
  ]
740
- # Top-level Leaderboard tab uses the same OneIG table.
741
- display_columns = oneig_display_columns
742
 
743
  oneig_combined_dir = _resolve_data_path(
744
  data_dir / "oneig_combined",
@@ -752,97 +2350,332 @@ qwen_path = _resolve_data_path(
752
  data_dir / "qwen_image_bench_model_price_and_median_generation_time.csv",
753
  space_root.parent / "qwen_image_bench_model_price_and_median_generation_time.csv",
754
  )
 
 
 
 
 
 
 
 
755
 
756
  qwen_df = load_qwen_combined_dataframe(qwen_path)
757
- qwen_score_columns = [
 
 
758
  col
759
  for col in [
760
- "P-Judge Overall",
761
  "Datapoint Elo",
762
  "Rapidata Elo",
 
 
 
 
 
763
  ]
764
  if col in qwen_df.columns
765
  ]
766
- qwen_display_columns = [
767
  col
768
  for col in [
769
  "Model",
770
- *qwen_score_columns,
771
- "Raw Win Rate",
772
- "Median Generation Time (s)",
773
- "Min Generation Time (s)",
774
  "Price / Image (USD)",
775
  ]
776
- if col in qwen_df.columns
 
 
 
 
 
 
 
 
 
777
  ]
778
- qwen_overall_column = (
779
- "Datapoint Elo"
780
- if "Datapoint Elo" in qwen_df.columns
781
- else (qwen_score_columns[0] if qwen_score_columns else None)
782
- )
783
 
784
  oneig_samples = load_sample_comparison_data(oneig_combined_dir)
785
  qwen_samples = load_sample_comparison_data(qwen_combined_dir)
786
 
787
- # Dataset-first catalogue: each card is a prompt suite; metrics are leaderboard columns.
788
- benchmarks = [
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
789
  {
790
  "id": "oneig",
791
- "title": "OneIG Alignment",
792
- "emoji": "🎯",
793
- "card_description": (
794
- "Anime/stylization, portrait, and general-object alignment prompts — "
795
- "alignment scores and Datapoint Elo (not the full OneIG suite), plus "
796
- "side-by-side generations."
797
- ),
798
- "intro": (
799
- "OneIG Alignment covers the alignment slice of OneIG (not every OneIG "
800
- "dimension). The leaderboard shows category alignment scores and Datapoint "
801
- "Elo columns; Compare samples uses the combined alignment generations."
802
- ),
803
  "data": oneig_df,
804
  "columns": oneig_display_columns,
805
- "score_columns": oneig_metric_columns,
806
- "overall_column": "OneIG Overall Score",
807
- "best_score_label": "BEST ONEIG ALIGNMENT",
808
- "metrics_same_scale": True,
809
  "note": (
810
- "> Rankings are ordered by the mean of the available alignment category "
811
- "scores. Missing category scores are not included in that model's mean."
812
  ),
813
  "samples": oneig_samples,
814
  },
815
  {
816
- "id": "qwen_image_bench",
817
- "title": "Qwen Image Bench",
818
- "emoji": "🖼️",
819
- "card_description": (
820
- "Qwen image-bench prompts with P-Judge, Datapoint Elo, and Rapidata Elo "
821
- "as metric columns, plus combined generations for comparison."
822
- ),
823
- "intro": (
824
- "Qwen Image Bench is a shared prompt suite. The leaderboard joins every "
825
- "available metric for this benchmark; Compare samples uses the combined "
826
- "Qwen generations."
827
- ),
828
- "data": qwen_df,
829
- "columns": qwen_display_columns,
830
- "score_columns": qwen_score_columns,
831
- "overall_column": qwen_overall_column,
832
- "best_score_label": "BEST DATAPOINT ELO",
833
- "metrics_same_scale": False,
834
- "note": (
835
- "> Models are ordered by Datapoint Elo when available. Other metric "
836
- "columns come from the P-Judge and Rapidata evaluations on the same "
837
- "prompt suite."
838
- ),
839
- "samples": qwen_samples,
840
  },
841
  ]
 
 
 
 
 
 
 
842
 
843
 
844
  custom_head = """
845
  <script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
846
  (() => {
847
  if (window.__inferbenchLeaderboardSortBound) return;
848
  window.__inferbenchLeaderboardSortBound = true;
@@ -897,25 +2730,40 @@ custom_head = """
897
  });
898
  })();
899
  </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
900
  """
901
 
902
  with gr.Blocks(
903
- theme=theme, fill_width=True, css=custom_css, head=custom_head
 
 
 
 
904
  ) as demo:
905
  render_header()
906
- with gr.Tabs():
907
- with gr.TabItem("Home"):
908
- render_home(benchmarks)
909
- with gr.TabItem("Benchmarks") as benchmarks_tab:
910
- reset_benchmarks, reset_benchmark_outputs = render_benchmarks(benchmarks)
911
- benchmarks_tab.select(
912
- reset_benchmarks,
913
- outputs=reset_benchmark_outputs,
914
- )
915
- with gr.TabItem("About"):
916
- render_about()
917
  render_footer()
918
 
919
 
920
  if __name__ == "__main__":
921
- demo.launch(ssr_mode=False)
 
 
 
 
1
+ import asyncio
2
  import json
3
  from collections import defaultdict
4
  from pathlib import Path
5
 
6
+ # Gradio 5.19's safe_get_lock() returns None on Python 3.12+/3.14 when no
7
+ # event loop exists yet, which breaks /queue/join (pending_message_lock).
8
+ try:
9
+ asyncio.get_running_loop()
10
+ except RuntimeError:
11
+ asyncio.set_event_loop(asyncio.new_event_loop())
12
+
13
  import gradio as gr
14
  import pandas as pd
15
 
16
  from ui import (
 
 
17
  render_footer,
18
  render_header,
19
+ render_image_workspace,
20
  )
21
 
22
+ # Visual tokens from https://www.pruna.ai/ and https://playground.pruna.ai/
23
  custom_css = """
24
+ :root, :host, .dark, :host(.dark) {
25
+ --pruna-bg-primary: #120b1b;
26
+ --pruna-bg-card: #171021;
27
+ --pruna-bg-elevated: #1d1429;
28
+ --pruna-bg-header: #17101f;
29
+ --pruna-border: rgba(74, 57, 98, 0.75);
30
+ --pruna-hairline: rgba(255, 255, 255, 0.08);
31
+ --pruna-text-primary: #fafafa;
32
+ --pruna-text-body: #d4d4d4;
33
+ --pruna-text-muted: #a3a3a3;
34
+ --pruna-accent: #9334e9;
35
+ --pruna-accent-bright: #8f35ff;
36
+ --pruna-lavender: #d8b4fe;
37
+ --pruna-link: #bf8bff;
38
+ --pruna-font: "Inter", ui-sans-serif, system-ui, -apple-system, sans-serif;
39
+ --pruna-glow: radial-gradient(ellipse 60% 35% at 50% -5%, rgba(147, 52, 233, 0.18), transparent 55%);
40
+ --pruna-card-bg: color-mix(in oklab, #1d1429 92%, black 8%);
41
+ --pruna-card-shadow: 0 24px 55px rgba(0, 0, 0, 0.42), inset 0 1px rgba(255, 255, 255, 0.04);
42
+ --pruna-callout-bg: color-mix(in oklab, #171021 82%, black 18%);
43
+ --pruna-menu-border: rgba(255, 255, 255, 0.08);
44
+ --pruna-menu-bg: rgba(255, 255, 255, 0.03);
45
+ --pruna-menu-hover-bg: rgba(255, 255, 255, 0.05);
46
+ --pruna-menu-hover-color: #e4e4e7;
47
+ --pruna-menu-selected-bg: rgba(143, 53, 255, 0.22);
48
+ --pruna-menu-selected-color: #ffffff;
49
+ --pruna-tab-hover: #e4e4e7;
50
+ --pruna-tab-selected: #ffffff;
51
+ --pruna-input-bg: rgba(255, 255, 255, 0.03);
52
+ --pruna-input-border: rgba(255, 255, 255, 0.08);
53
+ --pruna-focus-border: rgba(143, 53, 255, 0.45);
54
+ --pruna-focus-ring: 0 0 0 3px rgba(143, 53, 255, 0.16);
55
+ --pruna-table-hover: rgba(143, 53, 255, 0.16);
56
+ --pruna-table-hover-text: #ffffff;
57
+ --pruna-table-sticky: #17101f;
58
+ --pruna-table-sticky-hover: #2a1844;
59
+ --pruna-rank-bg: rgba(143, 53, 255, 0.22);
60
+ --pruna-rank-ring: 0 0 0 1px rgba(143, 53, 255, 0.45);
61
+ --pruna-score: #ddd6fe;
62
+ --pruna-accordion-bg: rgba(255, 255, 255, 0.02);
63
+ --pruna-accordion-border: rgba(216, 180, 254, 0.15);
64
+ --pruna-dropdown-hover: #2a1844;
65
+ --pruna-toggle-track: var(--pruna-bg-header);
66
+ --pruna-toggle-thumb: var(--pruna-bg-elevated);
67
+ --pruna-toggle-thumb-shadow: 0 1px 2px rgba(0, 0, 0, 0.45), inset 0 1px rgba(255, 255, 255, 0.06);
68
+ color-scheme: dark;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
  }
70
+
71
+ .light, :host(.light) {
72
+ --pruna-bg-primary: #f6f3fa;
73
+ --pruna-bg-card: #ffffff;
74
+ --pruna-bg-elevated: #ffffff;
75
+ --pruna-bg-header: #f3eef8;
76
+ --pruna-border: rgba(126, 34, 206, 0.16);
77
+ --pruna-hairline: rgba(24, 24, 27, 0.08);
78
+ --pruna-text-primary: #18181b;
79
+ --pruna-text-body: #3f3f46;
80
+ --pruna-text-muted: #71717a;
81
+ --pruna-accent: #9334e9;
82
+ --pruna-accent-bright: #7c22ce;
83
+ --pruna-lavender: #7e22ce;
84
+ --pruna-link: #6d28d9;
85
+ --pruna-glow: radial-gradient(ellipse 60% 35% at 50% -5%, rgba(147, 52, 233, 0.10), transparent 55%);
86
+ --pruna-card-bg: #ffffff;
87
+ --pruna-card-shadow: 0 10px 28px rgba(88, 28, 135, 0.08);
88
+ --pruna-callout-bg: #ffffff;
89
+ --pruna-menu-border: var(--pruna-border);
90
+ --pruna-menu-bg: var(--pruna-bg-card);
91
+ --pruna-menu-hover-bg: rgba(147, 52, 233, 0.06);
92
+ --pruna-menu-hover-color: var(--pruna-text-primary);
93
+ --pruna-menu-selected-bg: rgba(147, 52, 233, 0.12);
94
+ --pruna-menu-selected-color: var(--pruna-accent-bright);
95
+ --pruna-tab-hover: var(--pruna-text-primary);
96
+ --pruna-tab-selected: var(--pruna-text-primary);
97
+ --pruna-input-bg: var(--pruna-bg-card);
98
+ --pruna-input-border: var(--pruna-border);
99
+ --pruna-focus-border: rgba(124, 34, 206, 0.45);
100
+ --pruna-focus-ring: 0 0 0 3px rgba(143, 53, 255, 0.16);
101
+ --pruna-table-hover: rgba(147, 52, 233, 0.08);
102
+ --pruna-table-hover-text: var(--pruna-text-primary);
103
+ --pruna-table-sticky: var(--pruna-bg-card);
104
+ --pruna-table-sticky-hover: #f3e8ff;
105
+ --pruna-rank-bg: rgba(147, 52, 233, 0.12);
106
+ --pruna-rank-ring: 0 0 0 1px rgba(147, 52, 233, 0.28);
107
+ --pruna-score: var(--pruna-accent-bright);
108
+ --pruna-accordion-bg: var(--pruna-bg-card);
109
+ --pruna-accordion-border: var(--pruna-border);
110
+ --pruna-dropdown-hover: #f3e8ff;
111
+ --pruna-toggle-track: var(--pruna-bg-header);
112
+ --pruna-toggle-thumb: var(--pruna-bg-card);
113
+ --pruna-toggle-thumb-shadow: 0 1px 2px rgba(88, 28, 135, 0.12);
114
+ color-scheme: light;
115
  }
116
+
117
+ html {
118
+ width: 100% !important;
119
+ max-width: 100% !important;
120
+ min-width: 0 !important;
121
+ overflow-x: hidden;
122
+ overflow-y: auto;
123
+ -webkit-text-size-adjust: 100%;
124
+ text-size-adjust: 100%;
125
+ -webkit-tap-highlight-color: transparent;
126
+ }
127
+ body, gradio-app {
128
+ width: 100% !important;
129
+ max-width: 100% !important;
130
+ min-width: 0 !important;
131
+ overflow: visible;
132
+ -webkit-tap-highlight-color: transparent;
133
  }
134
+ html, body, .gradio-container, .main {
135
+ background: var(--pruna-bg-primary) !important;
136
+ color: var(--pruna-text-primary) !important;
137
+ font-family: var(--pruna-font) !important;
 
 
138
  }
139
+ button, a, label, input, select, textarea,
140
+ [role="button"], [role="tab"], [role="radio"],
141
+ .gradio-container * {
142
+ -webkit-tap-highlight-color: transparent !important;
 
 
143
  }
144
+
145
+ .gradio-container {
146
+ --input-radius: 10px;
147
+ --container-radius: 10px;
148
+ --block-radius: 10px;
 
 
 
149
  }
150
+
151
+ /* Subtle depth — not a marketing-site hero glow */
152
+ body, .gradio-container {
153
+ background-image: var(--pruna-glow) !important;
154
+ background-repeat: no-repeat !important;
155
+ background-attachment: scroll !important;
156
+ }
157
+ @media (min-width: 701px) and (hover: hover) and (pointer: fine) {
158
+ body, .gradio-container {
159
+ background-attachment: fixed !important;
160
+ }
161
  }
162
+
163
+ .gradio-container {
164
+ width: 100% !important;
165
+ max-width: 1200px !important;
166
+ min-width: 0 !important;
167
+ margin: 0 auto !important;
168
+ padding-top: 0 !important;
169
+ padding-left: 20px !important;
170
+ padding-right: 20px !important;
171
+ box-sizing: border-box !important;
172
+ overflow-x: hidden;
173
+ }
174
+ .gradio-container .main,
175
+ .gradio-container .wrap,
176
+ .gradio-container .contain,
177
+ .gradio-container .block,
178
+ .gradio-container .form,
179
+ .gradio-container .row,
180
+ .gradio-container .column,
181
+ .gradio-container .gap,
182
+ .gradio-container .html-container,
183
+ .gradio-container .prose,
184
+ .gradio-container .padded,
185
+ .main-tabs,
186
+ .main-tabs .tab-wrapper,
187
+ .main-tabs .tabitem,
188
+ .leaderboard-controls,
189
+ .workspace-shell,
190
+ .workspace-filters,
191
+ .view-filters {
192
+ max-width: 100% !important;
193
+ min-width: 0 !important;
194
  }
195
+
196
+ /* —— App header (P-Bench only) —— */
197
+ .app-header-host,
198
+ .app-header-host .html-container,
199
+ .app-header-host .prose,
200
+ .app-header-host.block,
201
+ .app-header-host .padded {
202
+ border: none !important;
203
+ background: transparent !important;
204
+ box-shadow: none !important;
205
+ padding: 0 !important;
206
+ margin: 0 auto !important;
207
+ width: 100% !important;
208
+ max-width: none !important;
209
+ display: block !important;
210
+ text-align: center !important;
211
+ overflow: visible !important;
212
  }
213
+ .app-header {
214
+ position: relative;
215
+ display: flex;
216
+ flex-direction: column;
217
+ align-items: stretch;
218
+ width: 100%;
219
  margin: 8px 0 0;
220
+ padding: 4px 0 10px;
221
+ text-align: center;
222
  }
223
+ .app-header-bar {
224
  display: grid;
225
+ grid-template-columns: minmax(36px, 1fr) auto minmax(36px, 1fr);
 
226
  align-items: center;
227
+ width: 100%;
228
+ column-gap: 8px;
229
+ }
230
+ .app-header .theme-toggle,
231
+ button.theme-toggle {
232
+ position: static !important;
233
+ top: auto;
234
+ right: auto;
235
+ grid-column: 3;
236
+ justify-self: end;
237
+ display: inline-flex !important;
238
+ align-items: center !important;
239
+ justify-content: center !important;
240
+ width: 36px !important;
241
+ height: 36px !important;
242
+ min-width: 36px !important;
243
+ min-height: 36px !important;
244
+ margin: 0 !important;
245
+ padding: 0 !important;
246
+ border: 1px solid var(--pruna-menu-border) !important;
247
+ border-radius: 10px !important;
248
+ background: var(--pruna-menu-bg) !important;
249
+ color: var(--pruna-text-muted) !important;
250
+ box-shadow: none !important;
251
+ appearance: none !important;
252
+ -webkit-appearance: none !important;
253
+ box-sizing: border-box !important;
254
+ font: inherit !important;
255
+ line-height: 0 !important;
256
+ cursor: pointer;
257
+ z-index: 6;
258
+ }
259
+ .app-header .theme-toggle:hover,
260
+ .app-header .theme-toggle:active,
261
+ button.theme-toggle:hover,
262
+ button.theme-toggle:active {
263
+ color: var(--pruna-menu-hover-color) !important;
264
+ background: var(--pruna-menu-hover-bg) !important;
265
+ border-color: var(--pruna-menu-border) !important;
266
+ box-shadow: none !important;
267
+ }
268
+ .app-header .theme-toggle:focus,
269
+ button.theme-toggle:focus {
270
+ outline: none !important;
271
+ }
272
+ .app-header .theme-toggle:focus-visible,
273
+ button.theme-toggle:focus-visible {
274
+ color: var(--pruna-menu-hover-color) !important;
275
+ background: var(--pruna-menu-hover-bg) !important;
276
+ border-color: var(--pruna-focus-border) !important;
277
+ box-shadow: var(--pruna-focus-ring) !important;
278
+ }
279
+ .app-header .theme-toggle svg,
280
+ button.theme-toggle svg {
281
+ width: 18px;
282
+ height: 18px;
283
+ flex-shrink: 0;
284
+ }
285
+ .app-header .theme-toggle .theme-icon-sun,
286
+ button.theme-toggle .theme-icon-sun { display: block !important; }
287
+ .app-header .theme-toggle .theme-icon-moon,
288
+ button.theme-toggle .theme-icon-moon { display: none !important; }
289
+ .app-header .theme-toggle[data-mode="light"] .theme-icon-sun,
290
+ button.theme-toggle[data-mode="light"] .theme-icon-sun { display: none !important; }
291
+ .app-header .theme-toggle[data-mode="light"] .theme-icon-moon,
292
+ button.theme-toggle[data-mode="light"] .theme-icon-moon { display: block !important; }
293
+ .app-header-brand {
294
+ display: inline-flex !important;
295
+ flex-direction: row;
296
  align-items: center;
297
  justify-content: center;
298
+ gap: 12px;
299
+ grid-column: 2;
300
+ justify-self: center;
301
+ width: auto !important;
302
+ max-width: 100%;
303
+ margin: 0;
304
  }
305
+ .app-header-logo {
306
+ display: block !important;
307
+ width: 44px !important;
308
+ height: 52px !important;
309
+ margin: 0 !important;
310
+ object-fit: contain;
311
+ flex: 0 0 auto;
 
 
 
 
 
312
  }
313
+
314
+ /* —— Page tabs: centered underline nav —— */
315
+ .workspace-shell,
316
+ .workspace-shell.block,
317
+ .workspace-shell.column,
318
+ .workspace-shell.gap {
319
+ display: flex !important;
320
+ flex-direction: column !important;
321
+ gap: 0 !important;
322
+ padding: 0 !important;
323
+ margin: 0 !important;
324
+ border: none !important;
325
+ background: transparent !important;
326
+ box-shadow: none !important;
327
+ }
328
+ /* Flatten tabs so the bar sits above shared filters. display:contents is
329
+ the fallback; Safari can drop or mis-order those children, so browsers
330
+ with subgrid use the grid layout below instead. */
331
+ .workspace-shell > .tabs,
332
+ .workspace-shell > .main-tabs,
333
+ .workspace-shell > .block:not(.workspace-filters),
334
+ .workspace-shell .tabs.main-tabs {
335
+ display: contents !important;
336
+ }
337
+ .workspace-filters {
338
+ order: 2 !important;
339
+ }
340
+ .main-tabs .tabitem {
341
+ order: 3 !important;
342
+ }
343
+ .tabs {
344
+ gap: 0 !important;
345
+ }
346
+ .main-tabs > .tab-wrapper {
347
+ order: 1 !important;
348
+ height: auto !important;
349
+ min-height: 0 !important;
350
+ padding: 0 !important;
351
+ margin: 0 0 16px !important;
352
+ justify-content: center !important;
353
+ width: 100% !important;
354
+ overflow: visible !important;
355
+ }
356
+ @supports (grid-template-rows: subgrid) {
357
+ .workspace-shell,
358
+ .workspace-shell.block,
359
+ .workspace-shell.column,
360
+ .workspace-shell.gap {
361
+ display: grid !important;
362
+ grid-template-columns: minmax(0, 1fr) !important;
363
+ grid-template-rows: auto auto auto !important;
364
+ align-content: start !important;
365
+ }
366
+ .workspace-shell > .tabs,
367
+ .workspace-shell > .main-tabs,
368
+ .workspace-shell .tabs.main-tabs {
369
+ display: grid !important;
370
+ grid-template-columns: minmax(0, 1fr) !important;
371
+ grid-template-rows: subgrid !important;
372
+ grid-column: 1 !important;
373
+ grid-row: 1 / 4 !important;
374
+ position: static !important;
375
+ }
376
+ .main-tabs > .tab-wrapper {
377
+ grid-row: 1 !important;
378
+ order: 0 !important;
379
+ }
380
+ .workspace-filters {
381
+ grid-column: 1 !important;
382
+ grid-row: 2 !important;
383
+ order: 0 !important;
384
+ }
385
+ .main-tabs .tabitem {
386
+ grid-row: 3 !important;
387
+ order: 0 !important;
388
+ min-width: 0 !important;
389
+ }
390
  }
391
+ .main-tabs .tab-container {
392
+ height: auto !important;
393
+ min-height: 0 !important;
394
+ justify-content: center !important;
395
+ flex-wrap: wrap !important;
396
+ overflow: visible !important;
397
+ max-width: 100% !important;
398
+ gap: 2px;
399
+ }
400
+ .main-tabs .tab-container::after {
401
+ background: var(--pruna-hairline) !important;
402
+ }
403
+ .main-tabs .tab-container > button {
404
+ font-family: var(--pruna-font) !important;
405
+ font-size: 0.95rem !important;
406
+ font-weight: 600 !important;
407
+ letter-spacing: -0.015em !important;
408
+ color: var(--pruna-text-muted) !important;
409
+ background: transparent !important;
410
+ border: none !important;
411
+ border-radius: 0 !important;
412
+ box-shadow: none !important;
413
+ padding: 12px 20px !important;
414
+ min-height: 44px !important;
415
+ height: auto !important;
416
+ }
417
+ .main-tabs .tab-container > button:hover:not(.selected),
418
+ .main-tabs .tab-container > button:active:not(.selected) {
419
+ color: var(--pruna-tab-hover) !important;
420
+ background: transparent !important;
421
+ }
422
+ .main-tabs .tab-container > button.selected,
423
+ .main-tabs .tab-container > button[aria-selected="true"] {
424
+ color: var(--pruna-tab-selected) !important;
425
+ background: transparent !important;
426
+ }
427
+ .main-tabs .tab-container > button:disabled,
428
+ .main-tabs .tab-container > button[disabled] {
429
+ opacity: 0.4 !important;
430
+ color: var(--pruna-text-muted) !important;
431
+ cursor: not-allowed !important;
432
+ }
433
+ .main-tabs .tab-container > button.selected::after,
434
+ .main-tabs .tab-container > button[aria-selected="true"]::after {
435
+ background: var(--pruna-accent-bright) !important;
436
+ height: 2px !important;
437
+ }
438
+ .main-tabs .tabitem {
439
+ padding: 8px 0 0 !important;
440
+ border-radius: 0 !important;
441
+ overflow: visible !important;
442
  }
443
+
444
+ /* —— About: two columns on desktop, stacked on phone —— */
445
+ .about-layout,
446
+ .about-layout.row,
447
+ .about-layout .form {
448
+ display: flex !important;
449
+ flex-wrap: wrap !important;
450
+ align-items: flex-start !important;
451
+ gap: 8px 40px !important;
452
+ width: 100% !important;
453
  }
454
+ .about-layout > .about-col,
455
+ .about-layout .form > .about-col {
456
+ flex: 1 1 340px !important;
457
+ min-width: 280px !important;
458
+ max-width: 100% !important;
459
+ }
460
+ .about-copy,
461
+ .about-copy.block,
462
+ .about-copy .prose,
463
+ .about-copy.prose,
464
+ .about-copy.padded {
465
+ border: none !important;
466
+ background: transparent !important;
467
+ box-shadow: none !important;
468
+ padding: 0 !important;
469
+ margin: 0 !important;
470
+ width: 100% !important;
471
+ max-width: 100% !important;
472
+ overflow-wrap: break-word !important;
473
+ word-break: break-word !important;
474
  }
475
+ .about-copy ol,
476
+ .about-copy ul,
477
+ .about-copy .prose ol,
478
+ .about-copy .prose ul {
479
+ padding-left: 1.25rem !important;
480
+ margin: 0 0 0.8rem !important;
481
  }
482
+ .about-copy li,
483
+ .about-copy .prose li {
484
+ overflow-wrap: break-word;
485
  }
486
+
487
  @media (max-width: 700px) {
488
+ .gradio-container {
489
+ padding-left: 12px !important;
490
+ padding-right: 12px !important;
491
+ }
492
+ .gradio-container .block,
493
+ .gradio-container .form,
494
+ .gradio-container .row,
495
+ .gradio-container .column,
496
+ .gradio-container .wrap,
497
+ .leaderboard-controls,
498
+ .view-filters {
499
+ min-width: 0 !important;
500
+ max-width: 100% !important;
501
+ }
502
+ .app-header {
503
+ padding: 4px 0 8px;
504
+ margin: 4px 0 0;
505
+ }
506
+ .app-header-logo {
507
+ width: 36px !important;
508
+ height: 42px !important;
509
+ }
510
+ .app-header-brand h1,
511
+ .gradio-container .app-header-brand h1 {
512
+ font-size: 1.55rem !important;
513
+ width: auto !important;
514
+ max-width: 100% !important;
515
+ }
516
+ .app-header-tagline {
517
+ font-size: 0.88rem !important;
518
+ padding: 0 8px !important;
519
+ }
520
+ .main-tabs > .tab-wrapper {
521
+ margin: 4px 0 14px !important;
522
+ }
523
+ .main-tabs .tab-container {
524
+ flex-wrap: wrap !important;
525
+ justify-content: center !important;
526
+ gap: 0 !important;
527
+ }
528
+ .main-tabs .tab-container > button {
529
+ padding: 10px 12px !important;
530
+ font-size: 0.88rem !important;
531
+ min-height: 40px !important;
532
+ }
533
+ .about-layout,
534
+ .about-layout.row,
535
+ .about-layout .form {
536
+ flex-direction: column !important;
537
+ flex-wrap: nowrap !important;
538
+ gap: 8px !important;
539
+ }
540
+ .about-layout > .about-col,
541
+ .about-layout > div {
542
+ flex: 1 1 auto !important;
543
+ width: 100% !important;
544
+ }
545
+ .about-copy h1,
546
+ .about-copy .prose h1 {
547
+ font-size: 1.3rem !important;
548
+ }
549
+ .about-copy h2,
550
+ .about-copy .prose h2 {
551
+ margin-top: 1.25rem !important;
552
+ font-size: 1.12rem !important;
553
+ }
554
+ .community-footer-links {
555
+ gap: 10px 14px;
556
+ }
557
+ .leaderboard-controls,
558
+ .leaderboard-controls.row,
559
+ .leaderboard-controls .form,
560
+ .view-filters,
561
+ .view-filters.row,
562
+ .view-filters .form {
563
+ flex-direction: column !important;
564
+ align-items: stretch !important;
565
+ }
566
+ .leaderboard-controls > div,
567
+ .leaderboard-controls .form > div,
568
+ .view-filters > div,
569
+ .view-filters .form > div {
570
+ flex: 1 1 auto !important;
571
+ width: 100% !important;
572
+ max-width: 100% !important;
573
+ }
574
+ .ranking-table-scroll {
575
+ max-height: min(75vh, 640px);
576
+ width: 100%;
577
+ }
578
+ .ranking-table th,
579
+ .ranking-table td,
580
+ .prose .ranking-table th,
581
+ .prose .ranking-table td {
582
+ padding: 8px 10px !important;
583
+ }
584
+ .ranking-table .rank,
585
+ .prose .ranking-table .rank,
586
+ .ranking-table th.rank {
587
+ position: sticky !important;
588
+ left: 0 !important;
589
+ width: 2.4rem;
590
+ min-width: 2.4rem;
591
+ box-shadow: 6px 0 8px -6px rgba(0, 0, 0, 0.45);
592
+ }
593
+ .ranking-table .model-cell,
594
+ .prose .ranking-table .model-cell {
595
+ position: static !important;
596
+ left: auto !important;
597
+ z-index: auto;
598
+ min-width: 140px;
599
+ max-width: none;
600
+ background: transparent !important;
601
+ }
602
+ .ranking-table th.model-cell,
603
+ .prose .ranking-table th.model-cell {
604
+ position: sticky !important;
605
+ top: 0 !important;
606
+ left: auto !important;
607
+ z-index: 3;
608
+ min-width: 140px;
609
+ max-width: none;
610
+ background: var(--pruna-bg-header) !important;
611
+ }
612
+ .ranking-table tbody tr:hover .model-cell {
613
+ background: var(--pruna-table-hover) !important;
614
+ }
615
+ .compare-controls,
616
+ .compare-controls.row,
617
+ .compare-controls .form {
618
+ flex-direction: column !important;
619
+ flex-wrap: nowrap !important;
620
+ flex: 0 0 auto !important;
621
+ align-items: stretch !important;
622
+ align-content: flex-start !important;
623
+ height: auto !important;
624
+ min-height: 0 !important;
625
+ gap: 10px !important;
626
+ margin-bottom: 12px !important;
627
+ }
628
+ .compare-controls .compare-models,
629
+ .compare-controls .compare-prompt-count,
630
+ .compare-controls .compare-shuffle,
631
+ .compare-controls .form > div {
632
+ flex: 0 0 auto !important;
633
+ width: 100% !important;
634
+ max-width: 100% !important;
635
+ min-width: 0 !important;
636
+ height: auto !important;
637
+ min-height: 0 !important;
638
+ align-self: stretch !important;
639
+ }
640
+ .compare-controls .compare-prompt-count {
641
+ max-width: 100% !important;
642
+ }
643
+ .compare-controls .compare-models .wrap,
644
+ .compare-controls .compare-models .wrap-inner {
645
+ height: auto !important;
646
+ min-height: 40px !important;
647
+ }
648
+ .compare-controls .compare-shuffle,
649
+ .compare-controls .compare-shuffle button {
650
+ width: 100% !important;
651
+ align-self: stretch !important;
652
+ margin-top: 0 !important;
653
+ }
654
+ .compare-row {
655
+ grid-template-columns: 1fr !important;
656
+ }
657
+ .compare-prompt-meta {
658
+ flex-wrap: wrap;
659
+ }
660
+ .pareto-layout,
661
+ .pareto-layout.row,
662
+ .pareto-layout .form {
663
+ flex-direction: column !important;
664
+ }
665
+ .pareto-layout > .pareto-col,
666
+ .pareto-layout > div,
667
+ .pareto-layout .form > div {
668
+ flex: 1 1 auto !important;
669
+ width: 100% !important;
670
  }
671
  }
672
+
673
+ /* —— Workspace filters (dataset / metric / models) —— */
674
+ .workspace-filters,
675
+ .workspace-filters.block,
676
+ .workspace-filters.column,
677
+ .workspace-filters.gap {
678
+ margin: 0 0 12px;
679
+ padding: 0 !important;
680
+ gap: 12px !important;
681
+ overflow: visible !important;
682
+ }
683
+ .view-filters {
684
+ display: flex !important;
685
+ flex-wrap: wrap !important;
686
+ align-items: flex-end !important;
687
+ gap: 12px !important;
688
+ margin: 0;
689
+ overflow: visible !important;
690
+ }
691
+ .view-filters > div,
692
+ .view-filters > .block,
693
+ .view-filters > .form {
694
+ flex: 1 1 0% !important;
695
+ min-width: 0 !important;
696
+ }
697
+ .view-filters > .block,
698
+ .view-filters .form,
699
+ .view-filters .block {
700
+ border: none !important;
701
+ background: transparent !important;
702
+ box-shadow: none !important;
703
+ padding: 0 !important;
704
+ overflow: visible !important;
705
+ --block-border-width: 0 !important;
706
+ }
707
+ .view-filters label {
708
+ display: block !important;
709
+ margin: 0 !important;
710
+ padding: 0 0 8px !important;
711
+ color: var(--pruna-text-muted) !important;
712
+ font-size: 0.8rem !important;
713
+ font-weight: 500 !important;
714
+ line-height: 1.2 !important;
715
+ }
716
+ .view-filters .wrap {
717
+ min-width: 0 !important;
718
+ border: none !important;
719
+ background: transparent !important;
720
+ box-shadow: none !important;
721
+ overflow: visible !important;
722
+ }
723
+ .view-filters .wrap-inner {
724
+ display: flex !important;
725
+ flex-wrap: nowrap !important;
726
+ align-items: center !important;
727
+ gap: 6px !important;
728
+ min-height: 40px !important;
729
+ height: 40px !important;
730
+ padding: 0 10px !important;
731
+ border: 1px solid var(--pruna-input-border) !important;
732
+ border-radius: 10px !important;
733
+ background: var(--pruna-input-bg) !important;
734
+ box-shadow: none !important;
735
+ overflow: hidden !important;
736
+ }
737
+ .view-filters .secondary-wrap {
738
+ display: flex !important;
739
+ flex-wrap: nowrap !important;
740
+ align-items: center !important;
741
+ flex: 1 1 auto !important;
742
+ min-width: 0 !important;
743
+ height: 40px !important;
744
+ margin: 0 !important;
745
+ padding: 0 !important;
746
+ border: none !important;
747
+ background: transparent !important;
748
+ box-shadow: none !important;
749
+ overflow: visible !important;
750
+ }
751
+ .view-filters .filter-chips .wrap-inner {
752
+ overflow-x: auto !important;
753
+ overflow-y: hidden !important;
754
+ overscroll-behavior-x: contain;
755
+ scrollbar-width: thin;
756
+ scrollbar-color: var(--pruna-border) transparent;
757
+ }
758
+ .view-filters .filter-chips .secondary-wrap {
759
+ min-width: 2.5rem !important;
760
+ }
761
+ .view-filters .filter-chips .wrap-inner::-webkit-scrollbar {
762
+ height: 6px;
763
+ }
764
+ .view-filters .filter-chips .wrap-inner::-webkit-scrollbar-thumb {
765
+ background: var(--pruna-border);
766
+ border-radius: 99px;
767
+ }
768
+ .view-filters .filter-chips .token {
769
+ flex: 0 0 auto !important;
770
+ white-space: nowrap !important;
771
+ word-break: keep-all !important;
772
+ }
773
+ .view-filters .filter-chips .token span {
774
+ white-space: nowrap !important;
775
+ overflow: hidden !important;
776
+ text-overflow: ellipsis !important;
777
+ max-width: 14rem;
778
+ }
779
+ .view-filters .token:empty {
780
+ display: none !important;
781
  }
782
+ .view-filters input {
783
+ border: none !important;
784
+ background: transparent !important;
785
+ box-shadow: none !important;
786
+ min-height: 28px !important;
787
+ height: 28px !important;
788
  width: 100% !important;
789
+ min-width: 0 !important;
790
+ padding: 0 4px !important;
791
+ line-height: 28px !important;
792
+ }
793
+ .view-filters .dropdown-arrow,
794
+ .view-filters .icon-wrap {
795
+ flex: 0 0 auto !important;
796
+ align-self: center !important;
797
+ margin-left: auto !important;
798
+ }
799
+ .view-title,
800
+ .view-title.block,
801
+ .view-title .padded {
802
+ border: none !important;
803
+ background: transparent !important;
804
+ box-shadow: none !important;
805
+ padding: 0 !important;
806
+ margin: 0 0 8px !important;
807
+ }
808
+ .view-title h1,
809
+ .view-title .prose h1,
810
+ .gradio-container .view-title h1 {
811
+ margin: 0.35rem 0 0.4rem !important;
812
+ font-size: 1.45rem !important;
813
+ }
814
+ .filter-help-host,
815
+ .filter-help-host.block,
816
+ .filter-help-host .padded,
817
+ .filter-help-host .html-container,
818
+ .filter-help-host .prose {
819
+ border: none !important;
820
+ background: transparent !important;
821
+ box-shadow: none !important;
822
+ padding: 0 !important;
823
+ margin: 0 !important;
824
+ }
825
+ .view-help-host,
826
+ .view-help-host.block,
827
+ .view-help-host .padded,
828
+ .view-help-host .html-container,
829
+ .view-help-host .prose {
830
+ border: none !important;
831
+ background: transparent !important;
832
+ box-shadow: none !important;
833
+ padding: 0 !important;
834
+ margin: 0 0 10px !important;
835
+ }
836
+ .filter-help,
837
+ .prose .filter-help,
838
+ .view-help,
839
+ .prose .view-help {
840
+ margin: 0 !important;
841
+ color: var(--pruna-text-muted) !important;
842
+ font-size: 0.95rem !important;
843
+ line-height: 1.45 !important;
844
+ font-weight: 400 !important;
845
+ }
846
+ .view-help + .view-help,
847
+ .prose .view-help + .view-help {
848
+ margin-top: 0.45rem !important;
849
+ }
850
+ .view-filters span[data-testid="block-info"],
851
+ .view-filters .info,
852
+ .view-filters .block-info {
853
+ color: var(--pruna-text-muted) !important;
854
+ font-size: 0.75rem !important;
855
+ line-height: 1.35 !important;
856
+ margin-top: 4px !important;
857
  }
858
+ .compare-prompt-block {
859
+ border: 1px solid var(--pruna-border) !important;
860
+ border-radius: 16px !important;
861
+ background: var(--pruna-card-bg) !important;
862
+ box-shadow: var(--pruna-card-shadow) !important;
863
+ }
864
+
865
+ /* Page footer — flat community strip + quiet citation accordion */
866
+ .page-footer-host,
867
+ .page-footer-host .html-container,
868
+ .page-footer-host .prose,
869
+ .page-footer-host.block,
870
+ .page-footer-host .padded {
871
+ border: none !important;
872
+ background: transparent !important;
873
+ box-shadow: none !important;
874
+ padding: 0 !important;
875
+ margin: 0 !important;
876
  width: 100% !important;
877
+ max-width: none !important;
878
+ overflow: visible !important;
879
+ }
880
+ .page-footer {
881
+ margin: 32px 0 16px;
882
+ padding: 20px 0 0;
883
+ border-top: 1px solid var(--pruna-hairline);
884
+ }
885
+ .page-footer h3 {
886
+ margin: 0 0 10px !important;
887
+ font-size: 1.05rem !important;
888
+ font-weight: 600 !important;
889
+ letter-spacing: -0.015em !important;
890
+ text-transform: none !important;
891
+ color: var(--pruna-text-primary) !important;
892
  }
893
+ .community-footer-links {
894
+ display: flex;
895
+ flex-wrap: wrap;
896
+ gap: 8px 16px;
897
+ align-items: center;
898
  }
899
+ .community-footer-links a {
900
+ color: var(--pruna-text-muted) !important;
901
+ text-decoration: none !important;
902
+ font-size: 0.9rem !important;
903
+ font-weight: 500 !important;
904
  }
905
+ .community-footer-links a:hover {
906
+ color: var(--pruna-link) !important;
 
 
 
907
  }
908
+
909
+ /* Citation accordion — full-width control, not a section heading */
910
+ .citation-accordion {
911
+ margin: 0 0 28px !important;
912
+ }
913
+ .citation-accordion,
914
+ .citation-accordion.block {
915
+ border: 1px solid var(--pruna-accordion-border) !important;
916
+ border-radius: 10px !important;
917
+ background: var(--pruna-accordion-bg) !important;
918
+ box-shadow: none !important;
919
+ overflow: hidden !important;
920
+ }
921
+ .citation-accordion > .label-wrap,
922
+ .citation-accordion .label-wrap {
923
+ border: none !important;
924
+ background: transparent !important;
925
+ box-shadow: none !important;
926
+ padding: 11px 14px !important;
927
+ font-size: 0.92rem !important;
928
+ font-weight: 500 !important;
929
+ color: var(--pruna-text-primary) !important;
930
+ letter-spacing: -0.01em !important;
931
+ }
932
+ .citation-accordion > .label-wrap:hover,
933
+ .citation-accordion .label-wrap:hover {
934
+ background: var(--pruna-menu-hover-bg) !important;
935
+ }
936
+ .citation-accordion > .label-wrap span,
937
+ .citation-accordion .label-wrap span {
938
+ color: var(--pruna-text-primary) !important;
939
+ font-size: 0.92rem !important;
940
+ font-weight: 500 !important;
941
+ }
942
+ .citation-accordion .icon,
943
+ .citation-accordion .label-wrap .icon {
944
+ color: var(--pruna-text-muted) !important;
945
+ opacity: 0.9;
946
+ }
947
+ .citation-accordion .prose,
948
+ .citation-accordion .markdown,
949
+ .citation-accordion pre,
950
+ .citation-accordion code {
951
+ color: var(--pruna-text-muted) !important;
952
+ background: transparent !important;
953
+ border: none !important;
954
+ box-shadow: none !important;
955
+ }
956
+ .citation-accordion .wrap,
957
+ .citation-accordion > .wrap {
958
+ border-top: 1px solid var(--pruna-hairline) !important;
959
+ padding: 4px 14px 12px !important;
960
+ background: transparent !important;
961
+ }
962
+ .citation-accordion pre {
963
+ margin: 0 !important;
964
+ padding: 0 !important;
965
+ font-size: 0.8rem !important;
966
+ line-height: 1.55 !important;
967
+ overflow-x: auto;
968
  }
969
+
970
+ .pareto-plot,
971
+ .pareto-plot.block,
972
+ .pareto-plot .plotly,
973
+ .pareto-plot .js-plotly-plot,
974
+ .pareto-plot .plot-container,
975
+ .pareto-plot .svg-container,
976
+ .pareto-plot .main-svg {
977
+ width: 100% !important;
978
+ max-width: 100% !important;
979
+ background: transparent !important;
980
+ border-color: var(--pruna-border) !important;
981
  }
982
+ .pareto-plot .modebar { display: none !important; }
983
+
984
  .leaderboard-controls {
985
+ display: flex !important;
986
+ flex-wrap: wrap !important;
987
+ align-items: flex-end !important;
988
+ gap: 10px !important;
989
+ margin-bottom: 12px;
990
+ overflow: visible !important;
991
+ }
992
+ .leaderboard-controls > div {
993
+ min-width: 0 !important;
994
+ }
995
+ .leaderboard-controls > .block,
996
+ .leaderboard-controls .form,
997
+ .leaderboard-controls .block {
998
+ border: none !important;
999
+ background: transparent !important;
1000
+ box-shadow: none !important;
1001
+ padding: 0 !important;
1002
+ --block-border-width: 0 !important;
1003
+ }
1004
+ .leaderboard-controls label {
1005
+ color: var(--pruna-text-muted) !important;
1006
+ font-size: 0.8rem !important;
1007
+ font-weight: 500 !important;
1008
+ }
1009
+ .leaderboard-controls textarea {
1010
+ min-height: 40px !important;
1011
+ height: 40px !important;
1012
+ padding: 0 12px !important;
1013
+ border: 1px solid var(--pruna-input-border) !important;
1014
+ border-radius: 10px !important;
1015
+ background: var(--pruna-input-bg) !important;
1016
+ box-shadow: none !important;
1017
+ color: var(--pruna-text-primary) !important;
1018
+ font-family: var(--pruna-font) !important;
1019
+ font-size: 0.9rem !important;
1020
+ line-height: 40px !important;
1021
+ resize: none !important;
1022
+ }
1023
+ .leaderboard-controls textarea:focus {
1024
+ border-color: var(--pruna-focus-border) !important;
1025
+ outline: none !important;
1026
+ box-shadow: var(--pruna-focus-ring) !important;
1027
+ }
1028
+ .leaderboard-controls .wrap {
1029
+ min-height: 0 !important;
1030
+ border: none !important;
1031
+ background: transparent !important;
1032
+ box-shadow: none !important;
1033
+ overflow: visible !important;
1034
+ }
1035
+ .leaderboard-controls .wrap-inner {
1036
+ display: flex !important;
1037
+ flex-wrap: wrap !important;
1038
+ align-items: center !important;
1039
+ gap: 6px !important;
1040
+ min-height: 40px !important;
1041
+ height: auto !important;
1042
+ padding: 4px 10px !important;
1043
+ border: 1px solid var(--pruna-input-border) !important;
1044
+ border-radius: 10px !important;
1045
+ background: var(--pruna-input-bg) !important;
1046
+ box-shadow: none !important;
1047
+ overflow: visible !important;
1048
+ }
1049
+ .leaderboard-controls .secondary-wrap {
1050
+ display: flex !important;
1051
+ flex-wrap: wrap !important;
1052
+ align-items: center !important;
1053
+ gap: 6px !important;
1054
+ flex: 1 1 auto !important;
1055
+ min-width: 0 !important;
1056
+ min-height: 0 !important;
1057
+ height: auto !important;
1058
+ margin: 0 !important;
1059
+ padding: 0 !important;
1060
+ border: none !important;
1061
+ background: transparent !important;
1062
+ box-shadow: none !important;
1063
+ }
1064
+ .leaderboard-controls .token {
1065
+ display: inline-flex !important;
1066
+ align-items: center !important;
1067
+ max-width: 100% !important;
1068
+ margin: 0 !important;
1069
+ }
1070
+ .leaderboard-controls .token:empty {
1071
+ display: none !important;
1072
  }
1073
+ .leaderboard-controls .dropdown-arrow,
1074
+ .leaderboard-controls .icon-wrap {
1075
+ flex: 0 0 auto !important;
1076
+ align-self: center !important;
1077
+ margin-left: auto !important;
1078
+ }
1079
+ .ranking-table-host,
1080
+ .ranking-table-host .html-container,
1081
+ .ranking-table-host .prose,
1082
+ .ranking-table-host.block,
1083
+ .ranking-table-host .padded,
1084
+ .ranking-table-host.prose {
1085
+ display: grid !important;
1086
+ grid-template-columns: minmax(0, 1fr) !important;
1087
+ border: none !important;
1088
+ outline: none !important;
1089
+ background: transparent !important;
1090
+ box-shadow: none !important;
1091
+ padding: 0 !important;
1092
+ margin: 0 !important;
1093
+ width: 100% !important;
1094
+ max-width: 100% !important;
1095
+ min-width: 0 !important;
1096
+ overflow: hidden !important;
1097
+ --block-border-width: 0 !important;
1098
  }
1099
  .ranking-table-scroll {
1100
+ border: 1px solid var(--pruna-menu-border);
1101
+ border-radius: 12px;
1102
+ background: var(--pruna-menu-bg);
1103
+ box-shadow: none;
1104
+ width: 100%;
1105
+ max-width: 100%;
1106
+ min-width: 0;
1107
+ max-height: min(70vh, 720px);
1108
  overflow-x: auto;
1109
+ overflow-y: auto;
1110
+ -webkit-overflow-scrolling: touch;
1111
+ overscroll-behavior-x: contain;
1112
  }
1113
+ .ranking-table,
1114
+ .prose .ranking-table {
1115
  width: 100%;
1116
+ margin: 0 !important;
1117
+ overflow: visible;
1118
+ }
1119
+ .ranking-table table,
1120
+ .prose .ranking-table table {
1121
+ display: table !important;
1122
+ width: max-content !important;
1123
+ min-width: 100% !important;
1124
+ max-width: none !important;
1125
+ margin: 0 !important;
1126
+ border-collapse: separate !important;
1127
+ border-spacing: 0 !important;
1128
+ color: var(--pruna-text-body) !important;
1129
+ font-size: 13px !important;
1130
+ line-height: 1.35 !important;
1131
+ background: transparent !important;
1132
+ border: none !important;
1133
+ outline: none !important;
1134
+ }
1135
+ .ranking-table thead { display: table-header-group !important; }
1136
+ .ranking-table tbody { display: table-row-group !important; }
1137
+ .ranking-table tr { display: table-row !important; }
1138
+ .ranking-table th,
1139
+ .ranking-table td,
1140
+ .prose .ranking-table th,
1141
+ .prose .ranking-table td {
1142
+ display: table-cell !important;
1143
+ vertical-align: middle !important;
1144
+ padding: 11px 14px !important;
1145
+ border: 0 !important;
1146
+ border-bottom: 1px solid var(--pruna-hairline) !important;
1147
+ background: transparent !important;
1148
+ box-shadow: none !important;
1149
+ outline: none !important;
1150
+ }
1151
+ .ranking-table th,
1152
+ .prose .ranking-table th {
1153
+ position: sticky;
1154
+ top: 0;
1155
+ z-index: 3;
1156
+ background: var(--pruna-bg-header) !important;
1157
+ color: var(--pruna-text-muted) !important;
1158
+ font-size: 11px !important;
1159
+ font-weight: 600 !important;
1160
  letter-spacing: 0.04em;
1161
  text-align: left;
1162
  text-transform: uppercase;
 
 
 
 
1163
  white-space: nowrap;
1164
+ box-shadow: 0 1px 0 var(--pruna-hairline) !important;
1165
  }
1166
+ .ranking-table th.sortable-col { cursor: pointer; user-select: none; }
1167
+ .ranking-table th.sortable-col:hover { color: var(--pruna-lavender) !important; }
 
1168
  .ranking-table th.sortable-col.sorted-asc::after,
1169
  .ranking-table th.sortable-col.sorted-desc::after {
1170
  margin-left: 0.35em;
1171
  font-size: 0.85em;
1172
  opacity: 0.85;
1173
  }
1174
+ .ranking-table th.sortable-col.sorted-asc::after { content: "▲"; }
1175
+ .ranking-table th.sortable-col.sorted-desc::after { content: ""; }
1176
+ .ranking-table tbody tr:last-child td { border-bottom: 0 !important; }
1177
+ .ranking-table tbody tr:hover td {
1178
+ background: var(--pruna-table-hover) !important;
 
 
 
 
 
 
 
 
 
 
1179
  }
1180
  .ranking-table tbody tr:hover td,
1181
  .ranking-table tbody tr:hover .rank,
1182
  .ranking-table tbody tr:hover .metric-score,
1183
+ .ranking-table tbody tr:hover .text-cell,
1184
  .ranking-table tbody tr:hover .model-cell strong,
1185
+ .ranking-table tbody tr:hover .model-cell span { color: var(--pruna-table-hover-text) !important; }
1186
+ .ranking-table .rank,
1187
+ .prose .ranking-table .rank {
1188
+ position: sticky;
1189
+ left: 0;
1190
+ z-index: 1;
1191
+ box-sizing: border-box;
1192
+ width: 3.25rem;
1193
+ min-width: 3.25rem;
1194
+ color: var(--pruna-lavender) !important;
1195
+ font-weight: 700 !important;
1196
+ text-align: center;
1197
+ background: var(--pruna-table-sticky) !important;
1198
  }
1199
+ .ranking-table th.rank,
1200
+ .prose .ranking-table th.rank {
1201
+ top: 0;
1202
+ left: 0;
1203
+ z-index: 5;
1204
+ text-align: center;
1205
+ background: var(--pruna-bg-header) !important;
1206
+ }
1207
+ .ranking-table .model-cell,
1208
+ .prose .ranking-table .model-cell {
1209
+ position: sticky;
1210
+ left: 3.25rem;
1211
+ z-index: 1;
1212
+ min-width: 180px;
1213
+ max-width: 260px;
1214
+ background: var(--pruna-table-sticky) !important;
1215
+ }
1216
+ .ranking-table th.model-cell,
1217
+ .prose .ranking-table th.model-cell {
1218
+ top: 0;
1219
+ left: 3.25rem;
1220
+ z-index: 5;
1221
+ background: var(--pruna-bg-header) !important;
1222
+ }
1223
+ .ranking-table tbody tr:hover .rank,
1224
+ .ranking-table tbody tr:hover .model-cell {
1225
+ background: var(--pruna-table-sticky-hover) !important;
1226
  }
1227
  .ranking-table .model-cell strong,
1228
+ .ranking-table .model-cell span { display: block; }
1229
+ .ranking-table .model-cell strong {
1230
+ color: var(--pruna-text-primary) !important;
1231
+ font-weight: 600 !important;
1232
+ white-space: nowrap;
1233
+ overflow: hidden;
1234
+ text-overflow: ellipsis;
1235
  }
1236
  .ranking-table .model-cell span {
1237
  margin-top: 3px;
1238
+ color: var(--pruna-text-muted) !important;
1239
  font-size: 12px;
1240
  }
1241
+ .ranking-table .text-cell,
1242
+ .prose .ranking-table .text-cell {
1243
+ color: var(--pruna-text-muted) !important;
1244
+ font-weight: 500 !important;
1245
+ white-space: nowrap;
1246
+ }
1247
+ .ranking-table .metric-score,
1248
+ .prose .ranking-table .metric-score {
1249
+ color: var(--pruna-text-primary) !important;
1250
  font-variant-numeric: tabular-nums;
1251
+ font-weight: 600 !important;
1252
+ text-align: right;
1253
+ white-space: nowrap;
1254
  }
1255
+ .ranking-table th.metric-score { text-align: right; }
1256
  .ranking-table .empty-state {
1257
+ color: var(--pruna-text-muted);
1258
  padding: 32px;
1259
  text-align: center;
1260
  }
1261
+
1262
+ .compare-samples-help { color: var(--pruna-text-body); margin-bottom: 8px; }
1263
+ .compare-controls,
1264
+ .compare-controls.row,
1265
+ .compare-controls.column,
1266
+ .compare-controls .form {
1267
+ display: flex !important;
1268
+ flex-direction: column !important;
1269
+ flex-wrap: nowrap !important;
1270
+ align-items: stretch !important;
1271
+ align-content: flex-start !important;
1272
+ justify-content: flex-start !important;
1273
+ gap: 12px !important;
1274
+ width: 100% !important;
1275
+ max-width: 100% !important;
1276
+ flex-grow: 0 !important;
1277
+ height: auto !important;
1278
+ min-height: 0 !important;
1279
+ margin-bottom: 16px;
1280
+ }
1281
+ .compare-controls > .block,
1282
+ .compare-controls .form,
1283
+ .compare-controls .block,
1284
+ .compare-controls .compare-models,
1285
+ .compare-controls .compare-prompt-count {
1286
+ border: none !important;
1287
+ background: transparent !important;
1288
+ box-shadow: none !important;
1289
+ padding: 0 !important;
1290
+ --block-border-width: 0 !important;
1291
+ height: auto !important;
1292
+ min-height: 0 !important;
1293
+ }
1294
+ .compare-controls label,
1295
+ .compare-controls span[data-testid="block-info"] {
1296
+ display: block !important;
1297
+ margin: 0 0 6px !important;
1298
+ padding: 0 !important;
1299
+ color: var(--pruna-text-muted) !important;
1300
+ font-size: 0.8rem !important;
1301
+ font-weight: 500 !important;
1302
+ line-height: 1.2 !important;
1303
+ }
1304
+ .compare-controls .compare-models span[data-testid="block-info"] {
1305
+ min-height: 1.15rem;
1306
+ }
1307
+ .compare-controls .compare-models {
1308
+ flex: 0 0 auto !important;
1309
+ width: 100% !important;
1310
+ min-width: 0 !important;
1311
+ max-width: 100% !important;
1312
+ align-self: stretch !important;
1313
  }
1314
+ .compare-controls .compare-prompt-count {
1315
+ flex: 0 0 auto !important;
1316
+ width: 100% !important;
1317
+ min-width: 0 !important;
1318
+ max-width: 100% !important;
1319
+ align-self: stretch !important;
1320
  }
1321
+ .compare-controls .compare-shuffle {
1322
+ flex: 0 0 auto !important;
1323
+ width: 100% !important;
1324
+ max-width: 100% !important;
1325
+ align-self: stretch !important;
1326
+ }
1327
+ .compare-controls .compare-models .wrap,
1328
+ .compare-controls .compare-models .wrap-inner {
1329
+ min-height: 40px !important;
1330
+ height: auto !important;
1331
+ overflow: hidden !important;
1332
+ border: 1px solid var(--pruna-input-border) !important;
1333
+ border-radius: 10px !important;
1334
+ background: var(--pruna-input-bg) !important;
1335
+ box-shadow: none !important;
1336
+ }
1337
+ .compare-controls .compare-models .wrap-inner {
1338
+ display: flex !important;
1339
+ flex-direction: row !important;
1340
+ flex-wrap: wrap !important;
1341
+ align-items: center !important;
1342
+ gap: 6px !important;
1343
+ width: 100% !important;
1344
+ padding: 4px 8px !important;
1345
+ }
1346
+ .compare-controls .compare-models .secondary-wrap {
1347
+ display: flex !important;
1348
+ flex-direction: row !important;
1349
+ flex-wrap: wrap !important;
1350
+ align-items: center !important;
1351
+ gap: 6px !important;
1352
+ flex: 1 1 auto !important;
1353
+ width: auto !important;
1354
+ min-width: 0 !important;
1355
+ height: auto !important;
1356
+ margin: 0 !important;
1357
+ padding: 0 !important;
1358
+ border: none !important;
1359
+ background: transparent !important;
1360
+ box-shadow: none !important;
1361
+ }
1362
+ .compare-controls .compare-models .token {
1363
+ display: inline-flex !important;
1364
+ align-items: center !important;
1365
+ justify-content: center !important;
1366
+ width: auto !important;
1367
+ max-width: 100% !important;
1368
+ margin: 0 !important;
1369
+ white-space: nowrap !important;
1370
+ }
1371
+ .compare-controls .compare-models .token:empty {
1372
+ display: none !important;
1373
  }
1374
+ .compare-controls .compare-models input {
1375
+ width: auto !important;
1376
+ min-width: 2.5rem !important;
1377
+ flex: 1 1 5rem !important;
1378
+ height: 28px !important;
1379
+ min-height: 28px !important;
1380
+ }
1381
+ .compare-controls .compare-models .dropdown-arrow,
1382
+ .compare-controls .compare-models .icon-wrap {
1383
+ flex: 0 0 auto !important;
1384
+ align-self: center !important;
1385
+ margin-left: auto !important;
1386
+ }
1387
+ .compare-controls .compare-prompt-count .wrap {
1388
+ display: grid !important;
1389
+ grid-template-columns: minmax(0, 1fr) auto;
1390
+ grid-template-rows: auto 40px;
1391
+ gap: 6px 10px;
1392
+ align-items: center;
1393
+ width: 100%;
1394
+ min-height: 0 !important;
1395
+ height: auto !important;
1396
+ margin: 0 !important;
1397
+ padding: 0 !important;
1398
+ border: none !important;
1399
+ background: transparent !important;
1400
+ box-shadow: none !important;
1401
+ }
1402
+ .compare-controls .compare-prompt-count .head {
1403
+ display: block !important;
1404
+ grid-column: 1 / -1;
1405
+ grid-row: 1;
1406
+ margin: 0 !important;
1407
+ }
1408
+ .compare-controls .compare-prompt-count .head label {
1409
+ grid-column: 1 / -1;
1410
+ grid-row: 1;
1411
+ }
1412
+ .compare-controls .compare-prompt-count .tab-like-container {
1413
+ grid-column: 2;
1414
+ grid-row: 2;
1415
+ height: 40px !important;
1416
+ min-height: 40px !important;
1417
+ align-self: stretch;
1418
+ border: 1px solid var(--pruna-input-border) !important;
1419
+ border-radius: 10px !important;
1420
+ background: var(--pruna-input-bg) !important;
1421
+ overflow: hidden;
1422
+ }
1423
+ .compare-controls .compare-prompt-count .slider_input_container {
1424
+ grid-column: 1;
1425
+ grid-row: 2;
1426
+ height: 40px !important;
1427
+ min-height: 40px !important;
1428
+ margin: 0 !important;
1429
+ gap: 0 !important;
1430
+ }
1431
+ .compare-controls .compare-prompt-count .min_value,
1432
+ .compare-controls .compare-prompt-count .max_value {
1433
+ display: none !important;
1434
  }
1435
+ .compare-controls .compare-prompt-count input[type="range"] {
1436
+ height: 40px !important;
1437
+ min-width: 0 !important;
1438
+ margin: 0 !important;
1439
+ padding: 0 !important;
1440
+ background: transparent !important;
1441
+ border: none !important;
1442
+ box-shadow: none !important;
1443
+ }
1444
+ .compare-controls .compare-prompt-count input[type="number"] {
1445
+ height: 40px !important;
1446
+ min-height: 40px !important;
1447
+ min-width: 2.5rem !important;
1448
+ margin: 0 !important;
1449
+ padding: 0 8px !important;
1450
+ line-height: 40px !important;
1451
+ border: none !important;
1452
+ background: transparent !important;
1453
+ box-shadow: none !important;
1454
+ }
1455
+ .compare-controls .compare-shuffle.block:not(button) {
1456
+ width: 100% !important;
1457
+ max-width: 100% !important;
1458
+ align-self: stretch !important;
1459
+ background: transparent !important;
1460
+ border: none !important;
1461
+ box-shadow: none !important;
1462
+ padding: 0 !important;
1463
+ }
1464
+ .compare-controls button.compare-shuffle,
1465
+ .compare-controls .compare-shuffle button,
1466
+ .compare-controls .compare-shuffle button.primary,
1467
+ .compare-controls .compare-shuffle button.secondary {
1468
+ display: inline-flex !important;
1469
+ justify-content: center !important;
1470
+ align-items: center !important;
1471
+ width: 100% !important;
1472
+ min-width: 0 !important;
1473
+ height: 44px !important;
1474
+ min-height: 44px !important;
1475
+ margin: 0 !important;
1476
+ padding: 0 16px !important;
1477
+ border-radius: 10px !important;
1478
+ align-self: stretch !important;
1479
+ appearance: none !important;
1480
+ -webkit-appearance: none !important;
1481
+ -webkit-tap-highlight-color: transparent !important;
1482
+ background: var(--pruna-accent) !important;
1483
+ border: 1px solid color-mix(in oklab, var(--pruna-accent) 72%, transparent) !important;
1484
+ color: #fff !important;
1485
+ font-family: var(--pruna-font) !important;
1486
+ font-size: 0.95rem !important;
1487
+ font-weight: 600 !important;
1488
+ letter-spacing: -0.01em !important;
1489
+ box-shadow: inset 0 1px #fff3 !important;
1490
+ outline: none !important;
1491
+ }
1492
+ .compare-controls button.compare-shuffle:hover,
1493
+ .compare-controls button.compare-shuffle:active,
1494
+ .compare-controls button.compare-shuffle:focus,
1495
+ .compare-controls button.compare-shuffle:focus-visible,
1496
+ .compare-controls .compare-shuffle button:hover,
1497
+ .compare-controls .compare-shuffle button:active,
1498
+ .compare-controls .compare-shuffle button:focus,
1499
+ .compare-controls .compare-shuffle button:focus-visible {
1500
+ background: var(--pruna-accent) !important;
1501
+ border-color: color-mix(in oklab, var(--pruna-accent) 72%, transparent) !important;
1502
+ color: #fff !important;
1503
+ outline: none !important;
1504
+ box-shadow: inset 0 1px #fff3 !important;
1505
+ -webkit-tap-highlight-color: transparent !important;
1506
+ }
1507
+ @media (min-width: 701px) {
1508
+ .compare-controls,
1509
+ .compare-controls.row,
1510
+ .compare-controls.column,
1511
+ .compare-controls .form {
1512
+ flex-direction: row !important;
1513
+ flex-wrap: nowrap !important;
1514
+ align-items: flex-end !important;
1515
+ }
1516
+ .compare-controls .compare-models {
1517
+ flex: 4 1 0 !important;
1518
+ width: auto !important;
1519
+ max-width: none !important;
1520
+ align-self: flex-end !important;
1521
+ }
1522
+ .compare-controls .compare-prompt-count {
1523
+ flex: 1 1 200px !important;
1524
+ width: auto !important;
1525
+ min-width: 180px !important;
1526
+ max-width: 280px !important;
1527
+ align-self: flex-end !important;
1528
+ }
1529
+ .compare-controls .compare-shuffle,
1530
+ .compare-controls .compare-shuffle.block:not(button) {
1531
+ flex: 0 0 auto !important;
1532
+ width: auto !important;
1533
+ max-width: none !important;
1534
+ align-self: flex-end !important;
1535
+ }
1536
+ .compare-controls button.compare-shuffle,
1537
+ .compare-controls .compare-shuffle button {
1538
+ width: auto !important;
1539
+ min-width: 10.5rem !important;
1540
+ }
1541
  }
1542
  .compare-prompt-block {
1543
  margin: 0 0 22px;
1544
  padding: 14px 16px;
1545
+ background: var(--pruna-callout-bg) !important;
 
 
1546
  }
1547
  .compare-prompt-meta {
1548
  display: flex;
1549
  justify-content: space-between;
1550
  gap: 12px;
1551
  margin-bottom: 8px;
1552
+ color: var(--pruna-text-muted);
1553
  font-size: 12px;
1554
  font-weight: 700;
1555
  letter-spacing: 0.04em;
 
1557
  }
1558
  .compare-prompt-text {
1559
  margin: 0 0 14px;
1560
+ color: var(--pruna-text-body);
1561
  font-size: 15px;
1562
  line-height: 1.45;
1563
  }
1564
+ .compare-gallery,
1565
+ .compare-gallery.block,
1566
+ .compare-gallery .html-container,
1567
+ .compare-gallery .prose {
1568
+ width: 100% !important;
1569
+ max-width: 100% !important;
1570
+ min-width: 0 !important;
1571
+ overflow-x: hidden !important;
1572
+ border: none !important;
1573
+ background: transparent !important;
1574
+ box-shadow: none !important;
1575
+ padding: 0 !important;
1576
+ margin: 0 !important;
1577
+ }
1578
+ .compare-row { display: grid; gap: 12px; min-width: 0; width: 100%; }
1579
+ .compare-prompt-text { overflow-wrap: anywhere; word-break: break-word; }
1580
+ .pareto-heading-row,
1581
+ .pareto-heading-row.row,
1582
+ .pareto-heading-row .form {
1583
+ display: flex !important;
1584
+ flex-wrap: wrap !important;
1585
+ align-items: center !important;
1586
+ gap: 8px 12px !important;
1587
+ width: 100% !important;
1588
+ margin-bottom: 0.4rem !important;
1589
+ }
1590
+ .pareto-heading-row .pareto-subhead,
1591
+ .pareto-heading-row > div:first-child,
1592
+ .pareto-heading-row .form > div:first-child {
1593
+ flex: 1 1 240px !important;
1594
+ min-width: 0 !important;
1595
+ margin: 0 !important;
1596
+ }
1597
+ .pareto-heading-row .pareto-scale-control {
1598
+ display: flex !important;
1599
+ flex-direction: row !important;
1600
+ align-items: center !important;
1601
+ justify-content: flex-end !important;
1602
+ flex: 0 0 auto !important;
1603
+ gap: 0 !important;
1604
+ margin-left: auto !important;
1605
+ max-width: 168px !important;
1606
+ padding: 0 !important;
1607
+ }
1608
+ .pareto-scale-all-row,
1609
+ .pareto-scale-all-row.row,
1610
+ .pareto-scale-all-row .form {
1611
+ display: flex !important;
1612
+ flex-direction: row !important;
1613
+ flex-wrap: wrap !important;
1614
+ align-items: center !important;
1615
+ justify-content: flex-start !important;
1616
+ gap: 8px 12px !important;
1617
+ width: 100% !important;
1618
+ margin: 2px 0 14px !important;
1619
+ }
1620
+ .pareto-scale-all-row .html-container,
1621
+ .pareto-scale-all-row .block {
1622
+ border: none !important;
1623
+ background: transparent !important;
1624
+ box-shadow: none !important;
1625
+ padding: 0 !important;
1626
+ margin: 0 !important;
1627
+ width: auto !important;
1628
+ flex: 0 0 auto !important;
1629
+ }
1630
+ .pareto-scale-all-row .html-container {
1631
+ flex: 1 1 auto !important;
1632
+ min-width: 0 !important;
1633
+ }
1634
+ .pareto-scale-all-label {
1635
+ color: var(--pruna-text-muted);
1636
+ font-size: 0.8rem;
1637
+ font-weight: 500;
1638
+ white-space: nowrap;
1639
  }
1640
+ .pareto-scale-all-row .pareto-scale-toggle {
1641
+ margin-left: auto !important;
1642
+ }
1643
+ .pareto-scale-toggle,
1644
+ .pareto-scale-toggle.block {
1645
+ min-width: 0 !important;
1646
+ width: auto !important;
1647
+ border: none !important;
1648
+ background: transparent !important;
1649
+ box-shadow: none !important;
1650
+ padding: 0 !important;
1651
+ margin: 0 !important;
1652
+ }
1653
+ .pareto-scale-toggle .wrap,
1654
+ .pareto-scale-toggle .form {
1655
+ display: block !important;
1656
+ width: auto !important;
1657
+ margin: 0 !important;
1658
+ padding: 0 !important;
1659
+ border: none !important;
1660
+ background: transparent !important;
1661
+ box-shadow: none !important;
1662
+ }
1663
+ .pareto-scale-toggle legend {
1664
+ display: none !important;
1665
+ }
1666
+ .pareto-scale-toggle fieldset,
1667
+ .pareto-scale-toggle .wrap:has(> label),
1668
+ .pareto-scale-toggle .form:has(> label) {
1669
+ position: relative !important;
1670
+ display: grid !important;
1671
+ grid-template-columns: 1fr 1fr !important;
1672
+ align-items: stretch !important;
1673
+ isolation: isolate;
1674
+ box-sizing: border-box !important;
1675
+ width: max-content !important;
1676
+ min-width: 0 !important;
1677
+ padding: 4px !important;
1678
+ gap: 4px !important;
1679
+ border: 1px solid var(--pruna-input-border) !important;
1680
+ border-radius: 10px !important;
1681
+ background: var(--pruna-toggle-track) !important;
1682
+ box-shadow: none !important;
1683
+ }
1684
+ .pareto-scale-toggle fieldset::before,
1685
+ .pareto-scale-toggle .wrap:has(> label)::before,
1686
+ .pareto-scale-toggle .form:has(> label)::before {
1687
+ content: none !important;
1688
+ }
1689
+ .pareto-scale-toggle label {
1690
+ position: relative !important;
1691
+ z-index: 1 !important;
1692
+ display: flex !important;
1693
+ flex: 1 1 auto !important;
1694
+ align-items: center !important;
1695
+ justify-content: center !important;
1696
+ gap: 0 !important;
1697
+ box-sizing: border-box !important;
1698
+ min-width: 58px !important;
1699
+ min-height: 26px !important;
1700
+ margin: 0 !important;
1701
+ padding: 5px 12px !important;
1702
+ border: none !important;
1703
+ border-radius: 6px !important;
1704
+ background: transparent !important;
1705
+ box-shadow: none !important;
1706
+ color: var(--pruna-text-body) !important;
1707
+ font-size: 0.72rem !important;
1708
+ font-weight: 600 !important;
1709
+ line-height: 1.2 !important;
1710
+ letter-spacing: 0.01em;
1711
+ white-space: nowrap;
1712
+ cursor: pointer !important;
1713
+ }
1714
+ .pareto-scale-toggle-all label {
1715
+ min-width: 68px !important;
1716
+ min-height: 30px !important;
1717
+ padding: 6px 14px !important;
1718
+ font-size: 0.85rem !important;
1719
+ }
1720
+ .pareto-scale-toggle label span {
1721
+ margin: 0 !important;
1722
+ padding: 0 !important;
1723
+ color: inherit !important;
1724
+ opacity: 1 !important;
1725
+ }
1726
+ .pareto-scale-toggle label > * + * {
1727
+ margin-left: 0 !important;
1728
+ }
1729
+ .pareto-scale-toggle label + label::before,
1730
+ .pareto-scale-toggle label + label {
1731
+ content: none !important;
1732
+ border-left: none !important;
1733
+ }
1734
+ .pareto-scale-toggle input[type="radio"] {
1735
+ position: absolute !important;
1736
+ appearance: none !important;
1737
+ opacity: 0 !important;
1738
+ width: 0 !important;
1739
+ height: 0 !important;
1740
+ margin: 0 !important;
1741
+ pointer-events: none !important;
1742
+ }
1743
+ .pareto-scale-toggle label:hover {
1744
+ background: transparent !important;
1745
+ color: var(--pruna-text-primary) !important;
1746
+ }
1747
+ .pareto-scale-toggle label.selected,
1748
+ .pareto-scale-toggle label:has(input:checked) {
1749
+ background: var(--pruna-toggle-thumb) !important;
1750
+ color: var(--pruna-lavender) !important;
1751
+ font-weight: 700 !important;
1752
+ border-color: transparent !important;
1753
+ box-shadow: var(--pruna-toggle-thumb-shadow) !important;
1754
+ }
1755
+ .pareto-layout,
1756
+ .pareto-layout.row,
1757
+ .pareto-layout .form {
1758
+ display: flex !important;
1759
+ flex-wrap: wrap !important;
1760
+ align-items: stretch !important;
1761
+ gap: 16px !important;
1762
+ width: 100% !important;
1763
+ max-width: 100% !important;
1764
+ }
1765
+ .pareto-layout > .pareto-col,
1766
+ .pareto-layout .form > .pareto-col {
1767
+ flex: 1 1 360px !important;
1768
+ min-width: 0 !important;
1769
+ max-width: 100% !important;
1770
  }
1771
+ .compare-cell { min-width: 0; }
1772
  .compare-model-label {
1773
  margin-bottom: 6px;
1774
+ color: var(--pruna-lavender);
1775
  font-size: 13px;
1776
  font-weight: 700;
1777
  word-break: break-word;
 
1781
  width: 100%;
1782
  aspect-ratio: 1 / 1;
1783
  object-fit: cover;
1784
+ border-radius: 12px;
1785
+ border: 1px solid var(--pruna-border);
1786
+ background: var(--pruna-bg-elevated);
1787
  }
1788
+ .compare-empty,
1789
+ .pareto-note-copy {
1790
+ margin: 0;
1791
+ padding: 14px 16px;
1792
+ background: var(--pruna-callout-bg, var(--pruna-bg-card));
1793
+ border: 1px dashed color-mix(in oklab, var(--pruna-border) 70%, transparent);
1794
  border-radius: 10px;
1795
+ color: var(--pruna-text-muted);
1796
+ font-size: 0.95rem;
1797
+ line-height: 1.5;
1798
+ text-align: left;
1799
+ }
1800
+
1801
+ /*
1802
+ Type scale (playground-like):
1803
+ product title > page h1 > section h2/h3 > meta labels > body
1804
+ Uppercase lavender is reserved for meta labels only — not section titles.
1805
+ */
1806
+ .app-header-brand h1,
1807
+ .prose .app-header-brand h1,
1808
+ .gradio-container .app-header-brand h1,
1809
+ .app-header .app-header-brand h1 {
1810
+ display: block !important;
1811
+ width: max-content !important;
1812
+ max-width: 100% !important;
1813
+ flex: 0 0 auto !important;
1814
+ margin: 0 !important;
1815
+ padding: 0 !important;
1816
+ text-align: center !important;
1817
+ font-size: clamp(1.9rem, 3vw, 2.4rem) !important;
1818
+ font-weight: 700 !important;
1819
+ letter-spacing: -0.035em;
1820
+ line-height: 1 !important;
1821
+ color: var(--pruna-text-primary) !important;
1822
+ }
1823
+ .app-header-tagline,
1824
+ .prose .app-header-tagline,
1825
+ .gradio-container .app-header-tagline,
1826
+ .prose p.app-header-tagline {
1827
+ display: block !important;
1828
+ width: 100% !important;
1829
+ margin: 8px 0 0 !important;
1830
+ padding: 0 !important;
1831
+ text-align: center !important;
1832
+ color: var(--pruna-text-muted) !important;
1833
+ font-size: 0.95rem !important;
1834
+ line-height: 1.45 !important;
1835
+ font-weight: 400 !important;
1836
+ }
1837
+
1838
+ .gradio-container h1,
1839
+ .markdown h1, .md h1, .prose h1 {
1840
+ margin: 0 0 0.65rem !important;
1841
+ padding: 0 !important;
1842
+ color: var(--pruna-text-primary) !important;
1843
+ font-family: var(--pruna-font) !important;
1844
+ font-size: 1.5rem !important;
1845
+ font-weight: 700 !important;
1846
+ letter-spacing: -0.03em !important;
1847
+ line-height: 1.2 !important;
1848
+ text-transform: none !important;
1849
+ }
1850
+ .gradio-container h2,
1851
+ .markdown h2, .md h2, .prose h2 {
1852
+ margin: 1.75rem 0 0.75rem !important;
1853
+ padding: 0 !important;
1854
+ color: var(--pruna-text-primary) !important;
1855
+ font-family: var(--pruna-font) !important;
1856
+ font-size: 1.25rem !important;
1857
+ font-weight: 600 !important;
1858
+ letter-spacing: -0.02em !important;
1859
+ line-height: 1.3 !important;
1860
+ text-transform: none !important;
1861
+ }
1862
+ .gradio-container h3,
1863
+ .markdown h3, .md h3, .prose h3 {
1864
+ margin: 1.35rem 0 0.5rem !important;
1865
+ padding: 0 !important;
1866
+ color: var(--pruna-text-primary) !important;
1867
+ font-family: var(--pruna-font) !important;
1868
+ font-size: 1.05rem !important;
1869
+ font-weight: 600 !important;
1870
+ letter-spacing: -0.015em !important;
1871
+ line-height: 1.35 !important;
1872
+ text-transform: none !important;
1873
+ }
1874
+ .gradio-container h4,
1875
+ .markdown h4, .md h4, .prose h4 {
1876
+ margin: 1rem 0 0.4rem !important;
1877
+ padding: 0 !important;
1878
+ color: var(--pruna-text-body) !important;
1879
+ font-family: var(--pruna-font) !important;
1880
+ font-size: 0.95rem !important;
1881
+ font-weight: 600 !important;
1882
+ letter-spacing: -0.01em !important;
1883
+ line-height: 1.35 !important;
1884
+ text-transform: none !important;
1885
+ }
1886
+
1887
+ .markdown, .md, .prose,
1888
+ .gradio-container .markdown,
1889
+ .gradio-container .prose {
1890
+ overflow-wrap: break-word;
1891
+ max-width: 100%;
1892
  }
1893
+ .markdown p, .md p, .prose p,
1894
+ .gradio-container .markdown p {
1895
+ margin: 0 0 0.8rem !important;
1896
+ color: var(--pruna-text-body) !important;
1897
+ font-size: 0.95rem !important;
1898
+ font-weight: 400 !important;
1899
+ line-height: 1.55 !important;
1900
  }
1901
+ .markdown li, .md li, .prose li {
1902
+ color: var(--pruna-text-body) !important;
1903
+ font-size: 0.95rem;
1904
+ line-height: 1.5;
1905
  }
1906
+ .markdown strong, .md strong, .prose strong {
1907
+ color: var(--pruna-text-primary) !important;
1908
+ font-weight: 600 !important;
1909
  }
1910
+
1911
+ label, .block-label span {
1912
+ color: var(--pruna-text-muted) !important;
1913
+ font-size: 0.8rem !important;
1914
+ font-weight: 500 !important;
1915
  }
1916
+ a { color: var(--pruna-link); }
1917
+
1918
+ /* Gradio form chrome → playground */
1919
+ button.primary, .gr-button-primary, .primary-button,
1920
+ button.primary:hover, button.primary:active, button.primary:focus,
1921
+ .gr-button-primary:hover, .gr-button-primary:active {
1922
+ background: var(--pruna-accent) !important;
1923
+ border: 1px solid color-mix(in oklab, var(--pruna-accent) 72%, transparent) !important;
1924
+ color: #fff !important;
1925
+ border-radius: 8px !important;
1926
+ box-shadow: inset 0 1px #fff3 !important;
1927
+ font-weight: 600 !important;
1928
+ outline: none !important;
1929
+ -webkit-tap-highlight-color: transparent !important;
1930
+ }
1931
+ button.secondary:active, button.secondary:focus,
1932
+ .gr-button-secondary:active {
1933
+ outline: none !important;
1934
+ -webkit-tap-highlight-color: transparent !important;
1935
+ }
1936
+ .block, .gr-group, .form, .panel {
1937
+ border-color: var(--pruna-border) !important;
1938
+ background: transparent !important;
1939
+ }
1940
+ input, textarea, select {
1941
+ background: var(--pruna-bg-card) !important;
1942
+ border-color: var(--pruna-border) !important;
1943
+ color: var(--pruna-text-primary) !important;
1944
+ border-radius: 10px !important;
1945
+ }
1946
+ .view-filters input,
1947
+ .leaderboard-controls .wrap-inner input {
1948
+ background: transparent !important;
1949
+ border: none !important;
1950
+ box-shadow: none !important;
1951
+ min-height: 28px !important;
1952
+ height: 28px !important;
1953
+ padding: 0 4px !important;
1954
+ line-height: 28px !important;
1955
+ }
1956
+ .view-filters .wrap-inner:focus-within,
1957
+ .leaderboard-controls .wrap-inner:focus-within {
1958
+ border-color: var(--pruna-focus-border) !important;
1959
+ box-shadow: var(--pruna-focus-ring) !important;
1960
+ }
1961
+ footer, .footer { display: none !important; }
1962
+
1963
+ .pareto-note,
1964
+ .pareto-note.block,
1965
+ .pareto-note .html-container,
1966
+ .pareto-note .prose {
1967
+ border: none !important;
1968
+ background: transparent !important;
1969
+ box-shadow: none !important;
1970
+ padding: 0 !important;
1971
+ margin: 0 0 12px !important;
1972
+ }
1973
+ .pareto-metric-block {
1974
+ padding-bottom: 0.5rem;
1975
+ border-bottom: 1px solid var(--pruna-hairline);
1976
+ }
1977
+ .pareto-metric-block:last-child {
1978
+ border-bottom: none;
1979
+ }
1980
+ .pareto-metric-title {
1981
+ margin: 0 0 0.75rem;
1982
+ color: var(--pruna-text-primary);
1983
+ font-size: 1.05rem;
1984
+ font-weight: 600;
1985
  }
1986
+ .pareto-subhead,
1987
+ .pareto-subhead.block,
1988
+ .pareto-subhead .prose,
1989
+ .pareto-subhead .html-container {
1990
+ border: none !important;
1991
+ background: transparent !important;
1992
+ box-shadow: none !important;
1993
+ padding: 0 !important;
1994
+ margin: 0 0 0.4rem !important;
1995
+ color: var(--pruna-text-muted);
1996
+ }
1997
+ .pareto-subhead h4,
1998
+ .pareto-subhead .prose h4 {
1999
+ margin: 0 !important;
2000
+ color: var(--pruna-text-muted) !important;
2001
+ font-size: 0.95rem !important;
2002
+ font-weight: 600 !important;
2003
  }
2004
+
2005
+ .options,
2006
+ ul.options {
2007
+ position: absolute !important;
2008
+ top: calc(100% + 4px) !important;
2009
+ bottom: auto !important;
2010
+ left: 0 !important;
2011
+ right: auto !important;
2012
+ width: 100% !important;
2013
+ max-height: min(280px, 60vh) !important;
2014
+ background: var(--pruna-bg-card) !important;
2015
+ color: var(--pruna-text-primary) !important;
2016
+ border: 1px solid var(--pruna-border) !important;
2017
+ border-radius: 10px !important;
2018
+ overflow: auto !important;
2019
+ z-index: 50 !important;
2020
+ }
2021
+ .options .item:first-child,
2022
+ .options li:first-child {
2023
+ border-top-left-radius: 10px !important;
2024
+ border-top-right-radius: 10px !important;
2025
+ }
2026
+ .options .item:last-child,
2027
+ .options li:last-child {
2028
+ border-bottom-left-radius: 10px !important;
2029
+ border-bottom-right-radius: 10px !important;
2030
+ }
2031
+ .dropdown-arrow-inner {
2032
+ background: var(--pruna-bg-card) !important;
2033
+ color: var(--pruna-text-primary) !important;
2034
+ border-color: var(--pruna-border) !important;
2035
+ }
2036
+ .options .item,
2037
+ .options li {
2038
+ color: var(--pruna-text-primary) !important;
2039
+ }
2040
+ .options .item:hover,
2041
+ .options li:hover,
2042
+ .options .item.selected {
2043
+ background: var(--pruna-dropdown-hover) !important;
2044
+ color: var(--pruna-text-primary) !important;
2045
+ }
2046
+ input[type="range"] {
2047
+ accent-color: var(--pruna-accent);
2048
  }
2049
  """
2050
 
2051
+ theme = gr.themes.Base(
2052
+ primary_hue=gr.themes.Color(
2053
+ c50="#faf5ff",
2054
+ c100="#f3e8ff",
2055
+ c200="#e9d5ff",
2056
+ c300="#d8b4fe",
2057
+ c400="#c084fc",
2058
+ c500="#9334e9",
2059
+ c600="#9334e9",
2060
+ c700="#7e22ce",
2061
+ c800="#6b21a8",
2062
+ c900="#3b0764",
2063
+ c950="#120b1b",
2064
+ ),
2065
+ secondary_hue="zinc",
2066
+ neutral_hue="zinc",
2067
+ font=[gr.themes.GoogleFont("Inter"), "ui-sans-serif", "system-ui", "sans-serif"],
2068
+ font_mono=[gr.themes.GoogleFont("IBM Plex Mono"), "ui-monospace", "monospace"],
2069
+ ).set(
2070
+ body_background_fill="#f6f3fa",
2071
+ body_background_fill_dark="#120b1b",
2072
+ body_text_color="#18181b",
2073
+ body_text_color_dark="#fafafa",
2074
+ body_text_color_subdued="#71717a",
2075
+ body_text_color_subdued_dark="#a3a3a3",
2076
+ background_fill_primary="#f6f3fa",
2077
+ background_fill_primary_dark="#120b1b",
2078
+ background_fill_secondary="#ffffff",
2079
+ background_fill_secondary_dark="#171021",
2080
+ block_background_fill="#ffffff",
2081
+ block_background_fill_dark="#1d1429",
2082
+ block_border_color="#e4d7f2",
2083
+ block_border_color_dark="#4a3962bf",
2084
+ block_label_text_color="#71717a",
2085
+ block_label_text_color_dark="#a3a3a3",
2086
+ block_title_text_color="#18181b",
2087
+ block_title_text_color_dark="#fafafa",
2088
+ border_color_primary="#e4d7f2",
2089
+ border_color_primary_dark="#4a3962bf",
2090
+ button_primary_background_fill="#9334e9",
2091
+ button_primary_background_fill_dark="#9334e9",
2092
+ button_primary_background_fill_hover="#7c22ce",
2093
+ button_primary_background_fill_hover_dark="#8f35ff",
2094
+ button_primary_text_color="#ffffff",
2095
+ button_primary_text_color_dark="#ffffff",
2096
+ button_secondary_background_fill="#ffffff",
2097
+ button_secondary_background_fill_dark="#ffffff05",
2098
+ button_secondary_background_fill_hover="#f3e8ff",
2099
+ button_secondary_background_fill_hover_dark="rgba(147, 52, 233, 0.10)",
2100
+ button_secondary_text_color="#18181b",
2101
+ button_secondary_text_color_dark="#fafafa",
2102
+ button_secondary_border_color="#e4d7f2",
2103
+ button_secondary_border_color_dark="#d8b4fe26",
2104
+ input_background_fill="#ffffff",
2105
+ input_background_fill_dark="#171021",
2106
+ input_border_color="#e4d7f2",
2107
+ input_border_color_dark="#4a3962bf",
2108
+ input_placeholder_color="#71717a",
2109
+ input_placeholder_color_dark="#a3a3a3",
2110
+ link_text_color="#6d28d9",
2111
+ link_text_color_dark="#bf8bff",
2112
+ link_text_color_hover="#7c22ce",
2113
+ link_text_color_hover_dark="#d2a8ff",
2114
+ shadow_drop="none",
2115
+ shadow_drop_lg="none",
2116
  )
2117
 
2118
+
2119
  space_root = Path(__file__).resolve().parent
2120
  data_dir = space_root / "data"
2121
 
 
2174
  }
2175
 
2176
 
2177
+ def _as_numeric(df, columns):
2178
+ for column in columns:
2179
+ if column in df.columns:
2180
+ df[column] = pd.to_numeric(df[column], errors="coerce")
2181
+ return df
 
 
 
 
 
 
 
2182
 
2183
 
2184
  def load_oneig_dataframe(path):
 
2186
  df = df.rename(
2187
  columns={
2188
  "Owner": "Endpoint Owner",
 
2189
  "Anime Alignment Score": "OneIG (Anime Alignment)",
2190
  "Human Alignment Score": "OneIG (Human Alignment)",
2191
  "Object Alignment Score": "OneIG (Object Alignment)",
 
2194
  "OneIG (General Object) (Alignment Score)": "OneIG (Object Alignment)",
2195
  }
2196
  )
2197
+ df = df.drop(
2198
+ columns=[
2199
+ column
2200
+ for column in ("URL", "Device", "Optimization", "Optimization Details")
2201
+ if column in df.columns
2202
+ ]
2203
+ )
2204
  if "Optimized" in df.columns:
2205
  df["Optimized"] = df["Optimized"].map(
2206
  {True: "Yes", False: "No", "TRUE": "Yes", "FALSE": "No"}
2207
  ).fillna(df["Optimized"])
2208
 
2209
+ return _as_numeric(
2210
+ df,
2211
+ [
2212
+ "Price / Image (USD)",
2213
+ "Median Generation Time (s)",
2214
+ "Min Generation Time (s)",
2215
+ "OneIG (Anime Alignment)",
2216
+ "OneIG (Human Alignment)",
2217
+ "OneIG (Object Alignment)",
2218
+ "OneIG Anime Elo",
2219
+ "OneIG Human Elo",
2220
+ "OneIG Object Elo",
2221
+ "P-Judge Overall",
2222
+ "Rapidata Elo",
2223
+ ],
2224
+ )
2225
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2226
 
2227
+ def load_artificial_analysis_dataframe(path):
2228
+ """Load the Artificial Analysis text-to-image leaderboard."""
2229
+ df = pd.read_csv(path, na_values=["N/A", "n/a", ""])
2230
+ df = df.rename(
2231
+ columns={
2232
+ "model": "Model",
2233
+ "elo": "Artificial Analysis Elo",
2234
+ "price_per_image_usd": "Price / Image (USD)",
2235
+ }
2236
+ )
2237
+ df["Model"] = df["Model"].astype(str).str.strip()
2238
+ return _as_numeric(
2239
+ df, ["Artificial Analysis Elo", "Price / Image (USD)"]
2240
+ ).reset_index(drop=True)
2241
+
2242
 
2243
+ ARENA_CATEGORY_COLUMNS = {
2244
+ "product_branding_commercial_design_elo": "Arena Branding / Commercial Elo",
2245
+ "3d_imaging_and_modeling_elo": "Arena 3D Imaging Elo",
2246
+ "cartoon_anime_and_fantasy_elo": "Arena Cartoon / Anime Elo",
2247
+ "photorealistic_and_cinematic_imagery_elo": "Arena Photorealistic Elo",
2248
+ "art_elo": "Arena Art Elo",
2249
+ "portraits_elo": "Arena Portraits Elo",
2250
+ "text_rendering_elo": "Arena Text Rendering Elo",
2251
+ }
2252
+
2253
+
2254
+ def load_arena_ai_dataframe(path):
2255
+ """Load the Arena AI text-to-image leaderboard (overall + category Elos)."""
2256
+ df = pd.read_csv(path, na_values=["N/A", "n/a", ""])
2257
+ rename_map = {"model": "Model", "elo": "Arena Elo"}
2258
+ rename_map.update(
2259
+ {
2260
+ source: label
2261
+ for source, label in ARENA_CATEGORY_COLUMNS.items()
2262
+ if source in df.columns
2263
+ }
2264
+ )
2265
+ df = df.rename(columns=rename_map)
2266
+ df["Model"] = df["Model"].astype(str).str.strip()
2267
+ score_columns = [
2268
+ column
2269
+ for column in ["Arena Elo", *ARENA_CATEGORY_COLUMNS.values()]
2270
+ if column in df.columns
2271
+ ]
2272
+ df = _as_numeric(df, score_columns)
2273
+ ordered = ["Model", *score_columns]
2274
+ return df[[column for column in ordered if column in df.columns]].reset_index(
2275
+ drop=True
2276
+ )
2277
 
2278
 
2279
  def load_qwen_combined_dataframe(path):
 
2286
  df = df[~df["Model"].astype(str).str.startswith("#")].copy()
2287
  df["Model"] = df["Model"].astype(str).str.strip()
2288
 
2289
+ return _as_numeric(
2290
+ df,
2291
+ [
2292
+ "Price / Image (USD)",
2293
+ "Median Generation Time (s)",
2294
+ "Min Generation Time (s)",
2295
+ "P-Judge Overall",
2296
+ "Rapidata Elo",
2297
+ "Datapoint Elo",
2298
+ ],
2299
+ ).reset_index(drop=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2300
 
2301
 
2302
  df = load_oneig_dataframe(oneig_path)
 
2315
  oneig_df["OneIG Overall Score"] = oneig_df[oneig_metric_columns].mean(
2316
  axis=1, skipna=True
2317
  )
 
 
 
2318
 
2319
  oneig_display_columns = [
2320
  col
 
2323
  "Endpoint Owner",
2324
  "Model",
2325
  "Optimized",
2326
+ "OneIG Overall Score",
2327
  *oneig_metric_columns,
2328
  "OneIG Anime Elo",
2329
  "OneIG Human Elo",
 
2334
  "Median Generation Time (s)",
2335
  "Min Generation Time (s)",
2336
  "Price / Image (USD)",
 
2337
  ]
2338
  if col in oneig_df.columns
2339
  ]
 
 
2340
 
2341
  oneig_combined_dir = _resolve_data_path(
2342
  data_dir / "oneig_combined",
 
2350
  data_dir / "qwen_image_bench_model_price_and_median_generation_time.csv",
2351
  space_root.parent / "qwen_image_bench_model_price_and_median_generation_time.csv",
2352
  )
2353
+ aa_path = _resolve_data_path(
2354
+ data_dir / "artificial_analysis_text_to_image_leaderboard.csv",
2355
+ space_root.parent / "artificial_analysis_text_to_image_leaderboard.csv",
2356
+ )
2357
+ arena_path = _resolve_data_path(
2358
+ data_dir / "arena_ai_text_to_image_leaderboard.csv",
2359
+ space_root.parent / "arena_ai_text_to_image_leaderboard.csv",
2360
+ )
2361
 
2362
  qwen_df = load_qwen_combined_dataframe(qwen_path)
2363
+ aa_df = load_artificial_analysis_dataframe(aa_path)
2364
+ arena_df = load_arena_ai_dataframe(arena_path)
2365
+ qwen_display_columns = [
2366
  col
2367
  for col in [
2368
+ "Model",
2369
  "Datapoint Elo",
2370
  "Rapidata Elo",
2371
+ "P-Judge Overall",
2372
+ "Raw Win Rate",
2373
+ "Median Generation Time (s)",
2374
+ "Min Generation Time (s)",
2375
+ "Price / Image (USD)",
2376
  ]
2377
  if col in qwen_df.columns
2378
  ]
2379
+ aa_display_columns = [
2380
  col
2381
  for col in [
2382
  "Model",
2383
+ "Artificial Analysis Elo",
 
 
 
2384
  "Price / Image (USD)",
2385
  ]
2386
+ if col in aa_df.columns
2387
+ ]
2388
+ arena_display_columns = [
2389
+ col
2390
+ for col in [
2391
+ "Model",
2392
+ "Arena Elo",
2393
+ *ARENA_CATEGORY_COLUMNS.values(),
2394
+ ]
2395
+ if col in arena_df.columns
2396
  ]
 
 
 
 
 
2397
 
2398
  oneig_samples = load_sample_comparison_data(oneig_combined_dir)
2399
  qwen_samples = load_sample_comparison_data(qwen_combined_dir)
2400
 
2401
+ metrics = [
2402
+ {"id": "datapoint_elo", "column": "Datapoint Elo"},
2403
+ {"id": "rapidata_elo", "column": "Rapidata Elo"},
2404
+ {"id": "pjudger", "column": "P-Judge Overall"},
2405
+ {"id": "alignment_overall", "column": "OneIG Overall Score"},
2406
+ {"id": "datapoint_elo_anime", "column": "OneIG Anime Elo"},
2407
+ {"id": "datapoint_elo_human", "column": "OneIG Human Elo"},
2408
+ {"id": "datapoint_elo_object", "column": "OneIG Object Elo"},
2409
+ {"id": "aa_elo", "column": "Artificial Analysis Elo"},
2410
+ {"id": "arena_elo", "column": "Arena Elo"},
2411
+ {"id": "arena_branding", "column": "Arena Branding / Commercial Elo"},
2412
+ {"id": "arena_3d", "column": "Arena 3D Imaging Elo"},
2413
+ {"id": "arena_cartoon", "column": "Arena Cartoon / Anime Elo"},
2414
+ {"id": "arena_photo", "column": "Arena Photorealistic Elo"},
2415
+ {"id": "arena_art", "column": "Arena Art Elo"},
2416
+ {"id": "arena_portraits", "column": "Arena Portraits Elo"},
2417
+ {"id": "arena_text", "column": "Arena Text Rendering Elo"},
2418
+ ]
2419
+
2420
+
2421
+ def _metric_ids_for(data, metric_ids):
2422
+ columns = getattr(data, "columns", [])
2423
+ return [
2424
+ metric_id
2425
+ for metric_id in metric_ids
2426
+ if any(metric["id"] == metric_id and metric["column"] in columns for metric in metrics)
2427
+ ]
2428
+
2429
+
2430
+ qwen_metric_ids = _metric_ids_for(
2431
+ qwen_df, ["datapoint_elo", "rapidata_elo", "pjudger"]
2432
+ )
2433
+ oneig_metric_ids = _metric_ids_for(
2434
+ oneig_df,
2435
+ [
2436
+ "alignment_overall",
2437
+ "rapidata_elo",
2438
+ "pjudger",
2439
+ "datapoint_elo_anime",
2440
+ "datapoint_elo_human",
2441
+ "datapoint_elo_object",
2442
+ ],
2443
+ )
2444
+ aa_metric_ids = _metric_ids_for(aa_df, ["aa_elo"])
2445
+ arena_metric_ids = _metric_ids_for(
2446
+ arena_df,
2447
+ [
2448
+ "arena_elo",
2449
+ "arena_branding",
2450
+ "arena_3d",
2451
+ "arena_cartoon",
2452
+ "arena_photo",
2453
+ "arena_art",
2454
+ "arena_portraits",
2455
+ "arena_text",
2456
+ ],
2457
+ )
2458
+
2459
+ datasets = [
2460
+ {
2461
+ "id": "qwen",
2462
+ "name": "Qwen Image Dataset",
2463
+ "data": qwen_df,
2464
+ "columns": qwen_display_columns,
2465
+ "metric_ids": qwen_metric_ids,
2466
+ "note": "Rapidata Elo is a metric on this dataset, not a dataset of its own.",
2467
+ "samples": qwen_samples,
2468
+ },
2469
  {
2470
  "id": "oneig",
2471
+ "name": "OneIG Alignment Dataset",
 
 
 
 
 
 
 
 
 
 
 
2472
  "data": oneig_df,
2473
  "columns": oneig_display_columns,
2474
+ "metric_ids": oneig_metric_ids,
 
 
 
2475
  "note": (
2476
+ "Alignment Overall is the mean of the available category scores. "
2477
+ "Missing categories are skipped for that model."
2478
  ),
2479
  "samples": oneig_samples,
2480
  },
2481
  {
2482
+ "id": "artificial_analysis",
2483
+ "name": "Artificial Analysis Dataset",
2484
+ "data": aa_df,
2485
+ "columns": aa_display_columns,
2486
+ "metric_ids": aa_metric_ids,
2487
+ "note": "",
2488
+ "samples": None,
2489
+ },
2490
+ {
2491
+ "id": "arena_ai",
2492
+ "name": "Arena AI Dataset",
2493
+ "data": arena_df,
2494
+ "columns": arena_display_columns,
2495
+ "metric_ids": arena_metric_ids,
2496
+ "note": "",
2497
+ "samples": None,
 
 
 
 
 
 
 
 
2498
  },
2499
  ]
2500
+ datasets = [dataset for dataset in datasets if dataset["metric_ids"]]
2501
+
2502
+ DEFAULT_DATASET_ID = next(
2503
+ (dataset["id"] for dataset in datasets if dataset["id"] == "qwen"),
2504
+ datasets[0]["id"] if datasets else None,
2505
+ )
2506
+ DEFAULT_METRIC_ID = None
2507
 
2508
 
2509
  custom_head = """
2510
  <script>
2511
+ (function () {
2512
+ var mode = "dark";
2513
+ try {
2514
+ var stored = localStorage.getItem("inferbench-theme");
2515
+ if (stored === "light" || stored === "dark") mode = stored;
2516
+ else {
2517
+ var param = new URLSearchParams(location.search).get("__theme");
2518
+ if (param === "light" || param === "dark") mode = param;
2519
+ }
2520
+ } catch (e) {}
2521
+ document.documentElement.classList.toggle("dark", mode === "dark");
2522
+ document.documentElement.dataset.theme = mode;
2523
+ })();
2524
+ </script>
2525
+ <link rel="preconnect" href="https://fonts.googleapis.com" />
2526
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
2527
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet" />
2528
+ <script>
2529
+ (() => {
2530
+ const STORAGE_KEY = "inferbench-theme";
2531
+ const PLOT_LAYOUT = {
2532
+ dark: {
2533
+ paper_bgcolor: "#171021",
2534
+ plot_bgcolor: "#1d1429",
2535
+ "font.color": "#d4d4d4",
2536
+ "legend.font.color": "#d4d4d4",
2537
+ "xaxis.gridcolor": "rgba(74, 57, 98, 0.55)",
2538
+ "xaxis.color": "#d4d4d4",
2539
+ "xaxis.title.font.color": "#fafafa",
2540
+ "xaxis.tickfont.color": "#a3a3a3",
2541
+ "yaxis.gridcolor": "rgba(74, 57, 98, 0.55)",
2542
+ "yaxis.color": "#d4d4d4",
2543
+ "yaxis.title.font.color": "#fafafa",
2544
+ "yaxis.tickfont.color": "#a3a3a3",
2545
+ },
2546
+ light: {
2547
+ paper_bgcolor: "#f6f3fa",
2548
+ plot_bgcolor: "#ffffff",
2549
+ "font.color": "#3f3f46",
2550
+ "legend.font.color": "#3f3f46",
2551
+ "xaxis.gridcolor": "rgba(126, 34, 206, 0.12)",
2552
+ "xaxis.color": "#3f3f46",
2553
+ "xaxis.title.font.color": "#18181b",
2554
+ "xaxis.tickfont.color": "#71717a",
2555
+ "yaxis.gridcolor": "rgba(126, 34, 206, 0.12)",
2556
+ "yaxis.color": "#3f3f46",
2557
+ "yaxis.title.font.color": "#18181b",
2558
+ "yaxis.tickfont.color": "#71717a",
2559
+ },
2560
+ };
2561
+
2562
+ const currentMode = () => {
2563
+ try {
2564
+ const stored = localStorage.getItem(STORAGE_KEY);
2565
+ if (stored === "light" || stored === "dark") return stored;
2566
+ } catch (e) {}
2567
+ const param = new URLSearchParams(location.search).get("__theme");
2568
+ if (param === "light" || param === "dark") return param;
2569
+ return "dark";
2570
+ };
2571
+
2572
+ const queryAll = (selector) => {
2573
+ const found = [...document.querySelectorAll(selector)];
2574
+ document.querySelectorAll("gradio-app").forEach((app) => {
2575
+ if (app.shadowRoot) found.push(...app.shadowRoot.querySelectorAll(selector));
2576
+ });
2577
+ return found;
2578
+ };
2579
+
2580
+ const applyPlotTheme = (gd, mode) => {
2581
+ const layout = PLOT_LAYOUT[mode];
2582
+ if (!layout || typeof Plotly === "undefined" || !gd) return;
2583
+ if (gd.layout && gd.layout.paper_bgcolor === layout.paper_bgcolor) return;
2584
+ try { Plotly.relayout(gd, layout); } catch (e) {}
2585
+ };
2586
+
2587
+ const watchPlotTheme = (gd) => {
2588
+ if (!gd || gd.__inferbenchThemeBound) return;
2589
+ gd.__inferbenchThemeBound = true;
2590
+ gd.addEventListener("plotly_afterplot", () => applyPlotTheme(gd, currentMode()));
2591
+ };
2592
+
2593
+ const restylePlots = (mode) => {
2594
+ queryAll(".js-plotly-plot").forEach((gd) => {
2595
+ watchPlotTheme(gd);
2596
+ applyPlotTheme(gd, mode);
2597
+ });
2598
+ };
2599
+
2600
+ const applyMode = (mode, persist) => {
2601
+ const dark = mode === "dark";
2602
+ const targets = [
2603
+ document.documentElement,
2604
+ document.body,
2605
+ ...queryAll(".gradio-container"),
2606
+ ...document.querySelectorAll("gradio-app"),
2607
+ ].filter(Boolean);
2608
+ targets.forEach((el) => {
2609
+ el.classList.toggle("dark", dark);
2610
+ el.classList.toggle("light", !dark);
2611
+ });
2612
+ document.documentElement.dataset.theme = mode;
2613
+ const label = dark ? "Switch to light mode" : "Switch to dark mode";
2614
+ queryAll(".theme-toggle").forEach((btn) => {
2615
+ btn.setAttribute("data-mode", mode);
2616
+ btn.setAttribute("aria-label", label);
2617
+ btn.setAttribute("title", label);
2618
+ });
2619
+ if (persist) {
2620
+ try { localStorage.setItem(STORAGE_KEY, mode); } catch (e) {}
2621
+ try {
2622
+ const url = new URL(location.href);
2623
+ url.searchParams.set("__theme", mode);
2624
+ history.replaceState(null, "", url);
2625
+ } catch (e) {}
2626
+ }
2627
+ restylePlots(mode);
2628
+ };
2629
+
2630
+ applyMode(currentMode(), false);
2631
+
2632
+ document.addEventListener("click", (event) => {
2633
+ const path = typeof event.composedPath === "function" ? event.composedPath() : [event.target];
2634
+ const btn = path.find((el) => el.classList && el.classList.contains("theme-toggle"));
2635
+ if (!btn) return;
2636
+ event.preventDefault();
2637
+ const next = currentMode() === "dark" ? "light" : "dark";
2638
+ applyMode(next, true);
2639
+ });
2640
+
2641
+ const sync = () => applyMode(currentMode(), false);
2642
+ document.addEventListener("DOMContentLoaded", sync);
2643
+ window.addEventListener("load", () => {
2644
+ sync();
2645
+ setTimeout(sync, 80);
2646
+ setTimeout(sync, 400);
2647
+ });
2648
+
2649
+ const startObserver = () => {
2650
+ if (!document.body || window.__inferbenchThemeObserver) return;
2651
+ window.__inferbenchThemeObserver = true;
2652
+ const onMutations = (mutations) => {
2653
+ const mode = currentMode();
2654
+ const isDark = document.documentElement.classList.contains("dark");
2655
+ const added = mutations.flatMap((mutation) => [...mutation.addedNodes]).filter((node) => node.nodeType === 1);
2656
+ const hasContainer = added.some((node) => (
2657
+ node.classList?.contains("gradio-container") ||
2658
+ node.querySelector?.(".gradio-container, .theme-toggle")
2659
+ ));
2660
+ if ((mode === "dark") !== isDark || hasContainer) applyMode(mode, false);
2661
+ const hasPlot = added.some((node) => (
2662
+ node.classList?.contains("js-plotly-plot") ||
2663
+ node.querySelector?.(".js-plotly-plot")
2664
+ ));
2665
+ if (hasPlot) restylePlots(mode);
2666
+ };
2667
+ new MutationObserver(onMutations).observe(document.body, { childList: true, subtree: true });
2668
+ document.querySelectorAll("gradio-app").forEach((app) => {
2669
+ if (app.shadowRoot) {
2670
+ new MutationObserver(onMutations).observe(app.shadowRoot, { childList: true, subtree: true });
2671
+ }
2672
+ });
2673
+ };
2674
+ if (document.body) startObserver();
2675
+ else document.addEventListener("DOMContentLoaded", startObserver);
2676
+ })();
2677
+ </script>
2678
+ <script>
2679
  (() => {
2680
  if (window.__inferbenchLeaderboardSortBound) return;
2681
  window.__inferbenchLeaderboardSortBound = true;
 
2730
  });
2731
  })();
2732
  </script>
2733
+ <script>
2734
+ (() => {
2735
+ if (window.__inferbenchChipScrollBound) return;
2736
+ window.__inferbenchChipScrollBound = true;
2737
+ document.addEventListener("wheel", (event) => {
2738
+ const row = event.target.closest?.(".view-filters .filter-chips .wrap-inner");
2739
+ if (!row || row.scrollWidth <= row.clientWidth + 1) return;
2740
+ if (Math.abs(event.deltaY) < Math.abs(event.deltaX)) return;
2741
+ row.scrollLeft += event.deltaY;
2742
+ event.preventDefault();
2743
+ }, { capture: true, passive: false });
2744
+ })();
2745
+ </script>
2746
  """
2747
 
2748
  with gr.Blocks(
2749
+ title="P-Bench",
2750
+ theme=theme,
2751
+ fill_width=True,
2752
+ css=custom_css,
2753
+ head=custom_head,
2754
  ) as demo:
2755
  render_header()
2756
+ render_image_workspace(
2757
+ datasets,
2758
+ metrics,
2759
+ DEFAULT_DATASET_ID,
2760
+ DEFAULT_METRIC_ID,
2761
+ )
 
 
 
 
 
2762
  render_footer()
2763
 
2764
 
2765
  if __name__ == "__main__":
2766
+ demo.launch(
2767
+ ssr_mode=False,
2768
+ allowed_paths=[str(space_root)],
2769
+ )
data/arena_ai_text_to_image_leaderboard.csv ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ model,elo,product_branding_commercial_design_elo,3d_imaging_and_modeling_elo,cartoon_anime_and_fantasy_elo,photorealistic_and_cinematic_imagery_elo,art_elo,portraits_elo,text_rendering_elo
2
+ gpt-image-2 (medium),1381,1391,1361,1397,1380,1370,1429,1425
3
+ mai-image-2.6-preview,1336,1344,1362,1355,1325,1345,1365,1374
4
+ grok-imagine-image-2.0 (low),1316,1309,1268,1321,1327,1306,1371,1353
5
+ reve-2.1,1302,1314,1274,1310,1302,1289,1317,1341
6
+ muse-image,1282,1269,1255,1289,1293,1275,1313,1304
7
+ reve-2.0,1270,1279,1220,1275,1280,1259,1283,1297
8
+ gemini-3.1-flash-image (nano-banana-2) [web-search],1264,1271,1260,1268,1270,1251,1266,1295
9
+ seedream-5.0-pro,1258,1234,1246,1273,1280,1269,1291,1255
10
+ qwen-image-3.0-pro,1257,1258,1240,1271,1257,1257,1273,1289
11
+ mai-image-2.5,1256,1261,1248,1270,1252,1278,1259,1284
12
+ gemini-3.1-flash-lite-image (nano-banana-2-lite),1251,1250,1225,1258,1260,1257,1248,1275
13
+ gemini-3-pro-image-2k (nano-banana-pro),1246,1246,1231,1242,1260,1225,1258,1270
14
+ gpt-image-1.5-high-fidelity,1239,1241,1216,1243,1249,1224,1261,1254
15
+ gemini-3-pro-image-preview (nano-banana-pro),1232,1237,1209,1238,1243,1216,1236,1254
16
+ ideogram-4.0-quality,1204,1224,1180,1195,1203,1199,1201,1238
17
+ qwen-image-2.0-pro-2026-06-22,1191,1187,1198,1191,1205,1177,1216,1201
18
+ uni-1.1-max,1188,1197,1172,1194,1188,1195,1158,1217
19
+ mai-image-2,1183,1175,1179,1180,1203,1177,1207,1175
20
+ uni-1.1,1181,1181,1167,1189,1180,1188,1176,1202
21
+ Cosmos3-Super-Text2Image (Agentic),1175,1162,1170,1191,1189,1195,1212,1151
22
+ grok-imagine-image,1171,1175,1176,1177,1179,1179,1187,1185
23
+ recraft-v4.1-utility-pro,1169,1167,1147,1177,1180,1178,1169,1162
24
+ flux-2-max,1162,1165,1161,1169,1161,1170,1157,1167
25
+ grok-imagine-image-pro,1161,1168,1165,1163,1169,1165,1172,1182
26
+ flux-2-flex,1157,1173,1172,1162,1147,1156,1145,1172
27
+ flux-2-pro,1155,1157,1150,1161,1152,1163,1146,1157
28
+ Cosmos3-Super-Text2Image,1155,1129,1166,1177,1155,1173,1176,1122
29
+ reve-v1.5,1154,1182,1143,1141,1147,1144,1149,1185
30
+ hunyuan-image-3.0,1151,1153,1168,1163,1152,1153,1146,1150
31
+ gemini-2.5-flash-image-preview (nano-banana),1150,1152,1142,1145,1157,1145,1168,1154
32
+ imagen-ultra-4.0-generate-001,1148,1151,1141,1141,1156,1128,1168,1148
33
+ seedream-4.5,1147,1140,1147,1149,1166,1154,1166,1141
34
+ flux-2-dev,1145,1155,1149,1144,1143,1150,1133,1159
35
+ seedream-4-2k,1140,1134,1150,1149,1151,1164,1142,1143
36
+ seedream-5.0-lite,1137,1129,1138,1140,1154,1137,1150,1134
37
+ wan2.6-t2i,1136,1148,1146,1146,1128,1156,1123,1149
38
+ recraft-v4.1-pro,1130,1138,1111,1122,1143,1154,1144,1156
39
+ imagen-4.0-generate-001,1129,1129,1123,1120,1136,1110,1145,1123
40
+ qwen-image-2512,1125,1128,1135,1125,1135,1133,1143,1122
41
+ krea-2-medium,1122,1119,1132,1140,1127,1152,1148,1124
42
+ wan2.5-t2i-preview,1117,1138,1135,1120,1102,1120,1094,1142
43
+ hidream-o1-image,1117,1128,1121,1121,1111,1122,1106,1135
44
+ seedream-4-fal,1116,1128,1138,1109,1121,1119,1116,1124
45
+ gpt-image-1,1115,1115,1114,1115,1115,1115,1115,1115
46
+ recraft-v4,1114,1126,1076,1111,1119,1123,1119,1139
47
+ seedream-4-high-res-fal,1113,1113,1121,1109,1129,1112,1133,1110
48
+ krea-2-turbo,1111,1109,1133,1122,1123,1139,1138,1097
49
+ gpt-image-1-mini,1109,1109,1108,1108,1114,1113,1112,1104
50
+ krea-2-large,1107,1104,1113,1112,1121,1116,1117,1111
51
+ wan2.7-image-pro,1103,1114,1080,1080,1123,1079,1127,1118
52
+ wan2.7-image,1100,1110,1082,1075,1117,1075,1125,1114
53
+ mai-image-1,1093,1086,1096,1100,1103,1104,1095,1070
54
+ seedream-3,1082,1070,1094,1081,1102,1092,1102,1052
55
+ z-image-turbo,1082,1060,1066,1067,1115,1074,1140,1058
56
+ flux-1-kontext-max,1074,1082,1079,1079,1083,1081,1085,1071
57
+ flux-2-klein-9b,1070,1070,1078,1064,1090,1079,1092,1057
58
+ qwen-image-prompt-extend,1061,1087,1082,1062,1047,1055,1051,1082
59
+ flux-1-kontext-pro,1059,1068,1062,1058,1066,1067,1065,1053
60
+ imagen-3.0-generate-002,1058,1057,1046,1048,1075,1059,1077,1045
61
+ qwen-image,1057,1068,1064,1052,1062,1055,1076,1047
62
+ ideogram-v3-quality,1049,1082,1029,1027,1051,1039,1052,1070
63
+ photon,1035,1052,1033,1026,1035,1046,1023,1041
64
+ p-image,1034,1031,1031,1014,1074,1041,1100,1021
65
+ flux-2-klein-4b,1030,1026,1030,1023,1047,1028,1054,1015
66
+ runway-gen4,1025,1027,1013,1008,1041,1019,1022,1019
67
+ recraft-v3,1021,1027,1011,978,1054,991,1040,1005
68
+ flux-1.1-pro,1016,1012,1051,1016,1044,1044,1043,995
69
+ lucid-origin,1013,1020,1015,1007,1035,1031,1043,1005
70
+ ideogram-v2,1013,1054,990,995,1019,1017,1019,1046
71
+ glm-image,1010,1036,1018,1003,1000,1013,1000,1033
72
+ gemini-2.0-flash-preview-image-generation,975,1019,976,954,963,965,961,1007
73
+ flux-1-dev-fp8,969,991,978,957,990,978,999,963
74
+ dall-e-3,968,987,987,988,940,1010,924,969
75
+ flux-1-kontext-dev,940,966,943,924,935,927,944,953
76
+ stable-diffusion-v35-large,938,937,964,946,928,998,941,921
77
+ bagel,898,887,866,885,923,911,926,875
data/artificial_analysis_text_to_image_leaderboard.csv ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ model,elo,price_per_image_usd
2
+ GPT Image 2 (high),1370,0.211
3
+ Reve 2.1,1324,0.2
4
+ Nano Banana 2 (Gemini 3.1 Flash Image Preview),1322,0.067
5
+ GPT Image 1.5 (high),1312,0.133
6
+ MAI-Image-2.5,1306,0.0481
7
+ Nano Banana Pro (Gemini 3 Pro Image),1298,0.134
8
+ Nano Banana 2 Lite (Gemini 3.1 Flash Lite Image),1292,0.0336
9
+ Seedream 5.0 Pro,1281,0.09
10
+ grok-imagine-image-quality,1236,0.05
11
+ Qwen Image 2.0 Pro (2026-04-22),1235,0.075
12
+ FLUX.2 [max],1231,0.07
13
+ MAI-Image-2.5-Flash,1230,0.02
14
+ HiDream-O1-Image-1.5,1227,0.08
15
+ Seedream 4.0,1224,0.03
16
+ Luma UNI 1 Max,1223,0.1
17
+ FLUX.2 [flex],1222,0.06
18
+ Krea 2 Medium Turbo,1222,0.015
19
+ Krea 2 Large,1220,0.06
20
+ grok-imagine-image,1218,0.02
21
+ Recraft V4.1 Utility,1217,0.035
22
+ Ideogram 4.0,1217,0.06
23
+ Recraft V4.1 Utility Pro,1217,0.21
24
+ Ideogram 4.0 (Quality),1214,0.1
25
+ Wan2.6 Text to Image,1213,0.03
26
+ Krea 2 Medium,1212,0.03
27
+ MAI-Image-2,1210,0.035
28
+ FLUX.2 [pro],1208,0.03
29
+ Wan 2.6 Image,1206,0.03
30
+ Seedream 4.5,1205,0.04
31
+ GPT Image 1 (high),1205,0.167
32
+ Luma UNI 1,1205,0.0404
33
+ FLUX.2 [dev] Turbo,1199,0.008
34
+ FLUX.2 [dev],1199,0.012
35
+ Seedream 5.0 Lite,1199,0.035
36
+ Ideogram 4.0 Fast (Quality),1199,0.0175
37
+ P-Image-Ideogram (High),1198,0.015
38
+ Recraft V4 Pro,1195,0.25
39
+ Recraft V4.1,1191,0.035
40
+ Nano Banana (Gemini 2.5 Flash Image),1189,0.039
41
+ Recraft V4.1 Pro,1189,0.21
42
+ Imagen 4 Ultra,1189,0.06
43
+ Ideogram 4.0 Instant,1187,0.0075
44
+ Wan 2.7 Pro,1184,0.064
45
+ Recraft V4,1182,0.04
46
+ MAI-Image-2-Efficient,1182,0.022
47
+ P-Image-Ideogram (Medium),1181,0.01
48
+ FLUX.2 [dev] Flash,1179,0.005
49
+ HiDream-O1-Image,1176,
50
+ Ideogram 4.0 Fast,1176,0.0105
51
+ ImagineArt 2.0,1173,0.03
52
+ Qwen Image Max 2512,1173,0.02
53
+ Wan 2.7,1170,0.026
54
+ ImagineArt 1.5 Preview,1165,0.03
55
+ P-Image-Ideogram (Low),1165,0.0075
56
+ Seedream 3.0,1160,0.03
57
+ Vivago 2.1,1152,0.035
58
+ HunyuanImage 3.0 Instruct (Fal),1151,0.09
59
+ Wan 2.5 Preview,1150,0.021
60
+ FLUX.2 [klein] 9B,1146,0.015
61
+ FLUX.1 Kontext [max],1142,0.08
62
+ Kolors 2.1,1142,0.014
63
+ image-1,1141,0.04
64
+ HunyuanImage 3.0 (Fal),1140,0.1
65
+ Qwen Image 2.0 (2026-03-03),1135,0.035
66
+ Z-Image Turbo,1130,0.005
67
+ Vivago 2.0,1125,
68
+ Imagen 3 (v002),1124,0.04
69
+ Lucid Origin Ultra,1122,0.0867
70
+ Eigen Image,1122,0.025
71
+ Imagen 4 Standard,1120,0.04
72
+ Reve Image (Halfmoon),1116,
73
+ Kling Image 3.0 Omni,1115,0.028
74
+ Vidu Q2,1112,0.03
75
+ P-Image-Ideogram (Very Low),1111,0.003
76
+ Qwen Image Plus 2601,1110,0.03
77
+ GPT Image 1 Mini (medium),1110,0.011
78
+ Lucid Origin Fast,1110,0.0179
79
+ FLUX.1 Kontext [pro],1109,0.04
80
+ Dreamina 3.1,1108,0.03
81
+ FLUX1.1 [pro] Ultra,1104,0.06
82
+ Ideogram 3.0,1101,0.06
83
+ FLUX.2 [klein] Base 9B,1099,0.011
84
+ Imagen 4 Fast,1098,0.02
85
+ P-Image,1093,0.005
86
+ FLUX1.1 [pro],1092,0.04
87
+ Midjourney v7 Alpha,1092,
88
+ Ideogram v2,1084,0.08
89
+ FLUX.1 [pro],1083,0.05
90
+ Qwen Image,1082,0.02
91
+ SRPO,1080,0.026
92
+ HunyuanImage 2.1,1078,0.1
93
+ Midjourney v6,1076,
94
+ Ideogram v2 Turbo,1075,0.05
95
+ FIBO,1075,0.04
96
+ Recraft V3,1075,0.04
97
+ Luma Photon,1074,0.019
98
+ HiDream-O1-Image-Dev,1071,0.005
99
+ Image-01,1070,0.01
100
+ HiDream-I1-Dev,1070,0.024
101
+ GLM-Image,1068,0.05
102
+ Z-Image Base,1064,0.01
103
+ MAI Image 1,1064,
104
+ HiDream-I1-Fast,1063,0.012
105
+ FLUX.2 [klein] 4B,1057,0.014
106
+ Midjourney v6.1,1057,
107
+ Infinity 8B,1056,0.0017
108
+ LongCat Image,1053,0.13
109
+ Stable Diffusion 3 Large,1042,
110
+ FLUX.1 [dev],1041,0.025
111
+ Phoenix 1.0 Ultra,1041,0.0762
112
+ FLUX.1 Krea [dev],1036,0.025
113
+ Stable Diffusion 3.5 Large Turbo,1034,0.04
114
+ Stable Diffusion 3.5 Large,1034,0.065
115
+ Phoenix 0.9 Ultra,1028,0.0762
116
+ Ideogram v2a Turbo,1028,0.025
117
+ Ideogram v2a,1027,0.04
118
+ Playground v3 (beta),1015,0.0105
119
+ Krea 1,1013,
120
+ Phoenix 1.0 Fast,1007,0.0194
121
+ Luma Photon Flash,1004,0.005
122
+ FLUX.1 [schnell],1000,0.003
123
+ Step Image Edit 2,1000,0.003
124
+ Runway Gen-4 Image,992,0.08
125
+ Recraft 20B,984,0.022
126
+ Lumina Image v2,978,0.075
127
+ Playground v2.5,972,0.08
128
+ FLUX.2 [klein] Base 4B,972,0.009
129
+ DALLE 3,968,0.04
130
+ DALLE 3 HD,967,0.08
131
+ Stable Diffusion 3.5 Medium,963,0.02
132
+ Sana Sprint 1.6B,939,0.0015
133
+ Amazon Titan G1 v2 (Standard),923,0.01
134
+ Stable Diffusion 3 Medium,922,0.035
135
+ Stable Diffusion 3 Large Turbo,917,
136
+ Amazon Titan G1 (Standard),914,0.01
137
+ Stable Diffusion 1.6,914,0.009
138
+ OmniGen V2,911,0.15
139
+ SDXL Lightning,909,0.0019
140
+ Bagel,908,0.1
141
+ Bria 3.2,906,0.04
142
+ Stable Diffusion XL 1.0,884,0.009
143
+ Stable Diffusion 2.1,754,0.0039
144
+ DALLE 2,745,0.02
145
+ Janus Pro,720,0.0
146
+ Stable Diffusion 1.5,665,0.044
data/text_to_image.jsonl DELETED
@@ -1,31 +0,0 @@
1
- {"Platform": "Replicate", "Owner": "Pruna AI", "Device": "1xH100", "Model": "FLUX Schnell", "Optimization": "speed_mode_juiced", "URL": "https://replicate.com/prunaai/flux-schnell", "PartiPromts (ARNIQA)": 0.5665, "PartiPromts (ClipScore)": 27.4594, "PartiPromts (ClipIQA)": 0.8594, "PartiPromts (Sharpness - Laplacian Variance)": 4385.7579, "Long Text Bench (edit_distance)": 178.5125, "Long Text Bench (text_word_accuracy)": null, "HPS (v2.1)": 0.2106, "DrawBench (ClipScore)": 27.9985, "DrawBench (Image Reward)": 1.0057, "GenAI-Bench (VQA)": 0.79, "OneIG (Anime and Stylization) (Alignment Score)": null, "Median Inference Time": 0.9082, "Price per Image": 0.055}
2
- {"Platform": "fal.ai", "Owner": "fal.ai", "Device": "Undisclosed", "Model": "FLUX 1.1 Pro", "Optimization": "Undisclosed", "URL": "https://fal.ai/models/fal-ai/flux-pro/v1.1", "GenAI-Bench (VQA)": 0.7745, "HPS (v2.1)": 0.2093, "PartiPromts (ARNIQA)": 0.5998, "PartiPromts (ClipScore)": 26.7942, "PartiPromts (ClipIQA)": 0.9282, "PartiPromts (Sharpness - Laplacian Variance)": 14290.615, "Long Text Bench (edit_distance)": 163.5862, "Long Text Bench (text_word_accuracy)": null, "OneIG (Anime and Stylization) (Alignment Score)": null, "DrawBench (ClipScore)": 27.2099, "DrawBench (Image Reward)": 0.8609, "Median Inference Time": 4.031, "Price per Image": 0.04}
3
- {"Platform": "fal.ai", "Owner": "fal.ai", "Device": "Undisclosed", "Model": "FLUX Dev", "Optimization": "dev", "URL": "https://fal.ai/models/fal-ai/flux/dev", "Long Text Bench (edit_distance)": 177.7438, "Long Text Bench (text_word_accuracy)": null, "OneIG (Anime and Stylization) (Alignment Score)": null, "GenAI-Bench (VQA)": 0.7443, "DrawBench (ClipScore)": 27.0164, "DrawBench (Image Reward)": 0.8933, "PartiPromts (ARNIQA)": 0.6305, "PartiPromts (ClipScore)": 27.2592, "PartiPromts (ClipIQA)": 0.8593, "PartiPromts (Sharpness - Laplacian Variance)": 5212.9337, "HPS (v2.1)": 0.1932, "Median Inference Time": 1.9838, "Price per Image": 0.025}
4
- {"Platform": "Prodia", "Owner": "Prodia", "Device": "Undisclosed", "Model": "FLUX Dev", "Optimization": "fast", "URL": "https://app.prodia.com/models", "PartiPromts (ARNIQA)": 0.6224, "PartiPromts (ClipScore)": 26.8405, "PartiPromts (ClipIQA)": 0.9159, "PartiPromts (Sharpness - Laplacian Variance)": 5774.8605, "DrawBench (ClipScore)": 26.6909, "DrawBench (Image Reward)": 0.9675, "GenAI-Bench (VQA)": 0.7363, "OneIG (Anime and Stylization) (Alignment Score)": null, "Long Text Bench (edit_distance)": 178.3375, "Long Text Bench (text_word_accuracy)": null, "HPS (v2.1)": 0.1995, "Median Inference Time": 1.9977, "Price per Image": 0.02}
5
- {"Platform": "Prodia", "Owner": "Prodia", "Device": "Undisclosed", "Model": "FLUX 1.1 Pro", "Optimization": "Undisclosed", "URL": "https://app.prodia.com/models", "HPS (v2.1)": 0.2075, "Long Text Bench (edit_distance)": 178.5125, "Long Text Bench (text_word_accuracy)": null, "DrawBench (ClipScore)": 27.6498, "DrawBench (Image Reward)": 0.9484, "GenAI-Bench (VQA)": 0.7739, "OneIG (Anime and Stylization) (Alignment Score)": null, "PartiPromts (ARNIQA)": 0.6181, "PartiPromts (ClipScore)": 27.3402, "PartiPromts (ClipIQA)": 0.895, "PartiPromts (Sharpness - Laplacian Variance)": 6932.3266, "Median Inference Time": 3.285, "Price per Image": 0.04}
6
- {"Platform": "fal.ai", "Owner": "fal.ai", "Device": "Undisclosed", "Model": "FLUX Schnell", "Optimization": "schnell", "URL": "https://fal.ai/models/fal-ai/flux/schnell", "HPS (v2.1)": 0.206, "Long Text Bench (edit_distance)": 178.3125, "Long Text Bench (text_word_accuracy)": 0.0003, "PartiPromts (ARNIQA)": 0.6637, "PartiPromts (ClipScore)": 27.755, "PartiPromts (ClipIQA)": 0.8991, "PartiPromts (Sharpness - Laplacian Variance)": 6420.4761, "OneIG (Anime and Stylization) (Alignment Score)": null, "GenAI-Bench (VQA)": 0.7919, "DrawBench (ClipScore)": 28.0585, "DrawBench (Image Reward)": 0.9376, "Median Inference Time": 0.7981, "Price per Image": 0.003}
7
- {"Platform": "Together AI", "Owner": "Black Forest Labs", "Device": "Undisclosed", "Model": "FLUX Dev", "Optimization": "dev", "URL": "https://www.together.ai/models/flux-1-dev", "Long Text Bench (edit_distance)": 178.0437, "Long Text Bench (text_word_accuracy)": null, "GenAI-Bench (VQA)": 0.7592, "OneIG (Anime and Stylization) (Alignment Score)": null, "PartiPromts (ARNIQA)": 0.5982, "PartiPromts (ClipScore)": 27.5003, "PartiPromts (ClipIQA)": 0.8799, "PartiPromts (Sharpness - Laplacian Variance)": 5101.113, "HPS (v2.1)": 0.1973, "DrawBench (ClipScore)": 27.3007, "DrawBench (Image Reward)": 0.9612, "Median Inference Time": 3.862, "Price per Image": 0.025}
8
- {"Platform": "Replicate", "Owner": "Black Forest Labs", "Device": "1xH100", "Model": "FLUX 1.1 Pro", "Optimization": "Undisclosed", "URL": "https://replicate.com/black-forest-labs/flux-1.1-pro", "PartiPromts (ARNIQA)": 0.5879, "PartiPromts (ClipScore)": 27.8015, "PartiPromts (ClipIQA)": 0.8273, "PartiPromts (Sharpness - Laplacian Variance)": 6773.8274, "HPS (v2.1)": 0.2048, "OneIG (Anime and Stylization) (Alignment Score)": 0.87, "OneIG (General Object) (Alignment Score)": 0.83, "OneIG (Portrait) (Alignment Score)": 0.78, "DrawBench (ClipScore)": 27.7958, "DrawBench (Image Reward)": 0.9258, "Long Text Bench (edit_distance)": 163.28, "Long Text Bench (text_word_accuracy)": null, "GenAI-Bench (VQA)": 0.7813, "Median Inference Time": 2.8571, "Price per Image": 0.04}
9
- {"Platform": "Black Forest Labs", "Owner": "Black Forest Labs", "Device": "1xH100", "Model": "FLUX 2 pro", "Optimization": "Undisclosed", "URL": "https://bfl.ai/models", "PartiPromts (ARNIQA)": 0.6488, "PartiPromts (ClipScore)": 28.0808, "PartiPromts (ClipIQA)": 0.9172, "PartiPromts (Sharpness - Laplacian Variance)": 9335.3041, "GenAI-Bench (VQA)": 0.9633, "OneIG (Anime and Stylization) (Alignment Score)": null, "DrawBench (ClipScore)": 28.22, "DrawBench (Image Reward)": 1.0339, "Long Text Bench (edit_distance)": 159.2424, "Long Text Bench (text_word_accuracy)": null, "HPS (v2.1)": 0.1894, "Median Inference Time": 9.1787, "Price per Image": 0.1}
10
- {"Platform": "fal.ai", "Owner": "fal.ai", "Device": "Undisclosed", "Model": "FLUX Krea", "Optimization": "Undisclosed", "URL": "https://fal.ai/models/fal-ai/flux/krea", "DrawBench (ClipScore)": 28.1482, "DrawBench (Image Reward)": 0.9853, "OneIG (Anime and Stylization) (Alignment Score)": null, "Long Text Bench (edit_distance)": 178.5125, "Long Text Bench (text_word_accuracy)": null, "GenAI-Bench (VQA)": 0.7949, "PartiPromts (ARNIQA)": 0.615, "PartiPromts (ClipScore)": 27.7512, "PartiPromts (ClipIQA)": 0.848, "PartiPromts (Sharpness - Laplacian Variance)": 4043.6115, "HPS (v2.1)": 0.1902, "Median Inference Time": 2.0193, "Price per Image": 0.025}
11
- {"Platform": "Runware", "Owner": "Runware", "Device": "Undisclosed", "Model": "FLUX Dev", "Optimization": "Undisclosed", "URL": "https://runware.ai/models#", "PartiPromts (ARNIQA)": 0.638, "PartiPromts (ClipScore)": 27.3993, "PartiPromts (ClipIQA)": 0.8887, "PartiPromts (Sharpness - Laplacian Variance)": 6238.0671, "DrawBench (ClipScore)": 27.2074, "DrawBench (Image Reward)": 0.9923, "GenAI-Bench (VQA)": 0.7761, "Long Text Bench (edit_distance)": 178.3625, "Long Text Bench (text_word_accuracy)": null, "HPS (v2.1)": 0.194, "OneIG (Anime and Stylization) (Alignment Score)": null, "Median Inference Time": 4.2133, "Price per Image": 0.0038}
12
- {"Platform": "Black Forest Labs", "Owner": "Black Forest Labs", "Device": "1xH100", "Model": "FLUX 2 beta", "Optimization": "Undisclosed", "URL": "https://bfl.ai/models", "DrawBench (ClipScore)": 28.2489, "DrawBench (Image Reward)": 1.0498, "PartiPromts (ARNIQA)": 0.5988, "PartiPromts (ClipScore)": 28.2471, "PartiPromts (ClipIQA)": 0.8992, "PartiPromts (Sharpness - Laplacian Variance)": 7910.49, "Long Text Bench (edit_distance)": 155.9429, "Long Text Bench (text_word_accuracy)": null, "OneIG (Anime and Stylization) (Alignment Score)": null, "HPS (v2.1)": 0.2121, "GenAI-Bench (VQA)": 0.9673, "Median Inference Time": 15.5713, "Price per Image": 0.025}
13
- {"Platform": "Replicate", "Owner": "Black Forest Labs", "Device": "1xH100", "Model": "FLUX Schnell", "Optimization": "go_fast", "URL": "https://replicate.com/black-forest-labs/flux-schnell", "DrawBench (ClipScore)": 28.0363, "DrawBench (Image Reward)": 0.9009, "GenAI-Bench (VQA)": 0.7765, "OneIG (Anime and Stylization) (Alignment Score)": 0.88, "OneIG (Portrait) (Alignment Score)": 0.79, "OneIG (General Object) (Alignment Score)": 0.83, "PartiPromts (ARNIQA)": 0.5714, "PartiPromts (ClipScore)": 27.9771, "PartiPromts (ClipIQA)": 0.7947, "PartiPromts (Sharpness - Laplacian Variance)": 5685.5457, "HPS (v2.1)": 0.2086, "Long Text Bench (edit_distance)": 178.5125, "Long Text Bench (text_word_accuracy)": null, "Median Inference Time": 0.979, "Price per Image": 0.003}
14
- {"Platform": "Replicate", "Owner": "Black Forest Labs", "Device": "1xH100", "Model": "FLUX Krea", "Optimization": "go_fast", "URL": "https://replicate.com/black-forest-labs/flux-krea-dev", "DrawBench (ClipScore)": 28.3217, "DrawBench (Image Reward)": 0.9533, "PartiPromts (ARNIQA)": 0.6336, "PartiPromts (ClipScore)": 27.88, "PartiPromts (ClipIQA)": 0.8167, "PartiPromts (Sharpness - Laplacian Variance)": 4121.4541, "HPS (v2.1)": 0.1967, "OneIG (Anime and Stylization) (Alignment Score)": 0.88, "OneIG (Portrait) (Alignment Score)": 0.81, "OneIG (General Object) (Alignment Score)": 0.84, "GenAI-Bench (VQA)": 0.8218, "Long Text Bench (edit_distance)": 178.5125, "Long Text Bench (text_word_accuracy)": null, "Median Inference Time": 1.8774, "Price per Image": 0.025}
15
- {"Platform": "Prodia", "Owner": "Prodia", "Device": "Undisclosed", "Model": "FLUX Schnell", "Optimization": "fast", "URL": "https://app.prodia.com/models", "PartiPromts (ARNIQA)": 0.5726, "PartiPromts (ClipScore)": 27.388, "PartiPromts (ClipIQA)": 0.8827, "PartiPromts (Sharpness - Laplacian Variance)": 5464.0814, "OneIG (Anime and Stylization) (Alignment Score)": null, "Long Text Bench (edit_distance)": 178.5125, "Long Text Bench (text_word_accuracy)": null, "DrawBench (ClipScore)": 27.7805, "DrawBench (Image Reward)": 0.9845, "GenAI-Bench (VQA)": 0.7878, "HPS (v2.1)": 0.2128, "Median Inference Time": 0.7472, "Price per Image": 0.0015}
16
- {"Platform": "Replicate", "Owner": "Black Forest Labs", "Device": "1xH100", "Model": "FLUX Dev", "Optimization": "go_fast", "URL": "https://replicate.com/black-forest-labs/flux-dev", "PartiPromts (ARNIQA)": 0.5764, "PartiPromts (ClipScore)": 27.8144, "PartiPromts (ClipIQA)": 0.7859, "PartiPromts (Sharpness - Laplacian Variance)": 5164.9466, "Long Text Bench (edit_distance)": 177.8931, "Long Text Bench (text_word_accuracy)": null, "DrawBench (ClipScore)": 27.7887, "DrawBench (Image Reward)": 1.0318, "OneIG (Anime and Stylization) (Alignment Score)": 0.85, "OneIG (Portrait) (Alignment Score)": 0.78, "OneIG (General Object) (Alignment Score)": 0.8, "HPS (v2.1)": 0.1982, "GenAI-Bench (VQA)": 0.7686, "Median Inference Time": 1.8018, "Price per Image": 0.025}
17
- {"Platform": "Together AI", "Owner": "Black Forest Labs", "Device": "Undisclosed", "Model": "FLUX Schnell", "Optimization": "schnell", "URL": "https://www.together.ai/models/flux-1-schnell", "PartiPromts (ARNIQA)": 0.6082, "PartiPromts (ClipScore)": 27.6475, "PartiPromts (ClipIQA)": 0.898, "PartiPromts (Sharpness - Laplacian Variance)": 6446.8138, "DrawBench (ClipScore)": 27.6897, "DrawBench (Image Reward)": 0.9301, "GenAI-Bench (VQA)": 0.7706, "OneIG (Anime and Stylization) (Alignment Score)": null, "HPS (v2.1)": 0.2058, "Long Text Bench (edit_distance)": 178.5125, "Long Text Bench (text_word_accuracy)": null, "Median Inference Time": 1.3602, "Price per Image": 0.003}
18
- {"Platform": "Runware", "Owner": "Black Forest Labs", "Device": "Undisclosed", "Model": "FLUX 1.1 Pro", "Optimization": "Undisclosed", "URL": "https://runware.ai/models#", "PartiPromts (ARNIQA)": 0.659, "PartiPromts (ClipScore)": 27.4929, "PartiPromts (ClipIQA)": 0.9074, "PartiPromts (Sharpness - Laplacian Variance)": 6874.5826, "Long Text Bench (edit_distance)": 167.1325, "Long Text Bench (text_word_accuracy)": null, "DrawBench (ClipScore)": 27.7755, "DrawBench (Image Reward)": 0.9277, "HPS (v2.1)": 0.1971, "OneIG (Anime and Stylization) (Alignment Score)": null, "GenAI-Bench (VQA)": 0.7723, "Median Inference Time": 4.2135, "Price per Image": 0.04}
19
- {"Platform": "Runware", "Owner": "Runware", "Device": "Undisclosed", "Model": "FLUX Schnell", "Optimization": "Undisclosed", "URL": "https://runware.ai/models#", "HPS (v2.1)": 0.2026, "PartiPromts (ARNIQA)": 0.6344, "PartiPromts (ClipScore)": 27.7251, "PartiPromts (ClipIQA)": 0.8873, "PartiPromts (Sharpness - Laplacian Variance)": 7144.7132, "GenAI-Bench (VQA)": 0.769, "OneIG (Anime and Stylization) (Alignment Score)": null, "DrawBench (ClipScore)": 27.9708, "DrawBench (Image Reward)": 0.9571, "Long Text Bench (edit_distance)": 178.3812, "Long Text Bench (text_word_accuracy)": 0.0005, "Median Inference Time": 1.7584, "Price per Image": 0.0013}
20
- {"Platform": "Together AI", "Owner": "Black Forest Labs", "Device": "Undisclosed", "Model": "FLUX Krea", "Optimization": "dev", "URL": "https://www.together.ai/models/flux-1-krea-dev", "Long Text Bench (edit_distance)": 178.5125, "Long Text Bench (text_word_accuracy)": null, "DrawBench (ClipScore)": 28.2254, "DrawBench (Image Reward)": 1.101, "GenAI-Bench (VQA)": 0.797, "PartiPromts (ARNIQA)": 0.618, "PartiPromts (ClipScore)": 27.6353, "PartiPromts (ClipIQA)": 0.8776, "PartiPromts (Sharpness - Laplacian Variance)": 5297.8361, "OneIG (Anime and Stylization) (Alignment Score)": null, "HPS (v2.1)": 0.1981, "Median Inference Time": 4.3831, "Price per Image": 0.025}
21
- {"Platform": "Bria", "Owner": "Bria", "Device": "Undisclosed", "Model":"FIBO", Optimization: "Undisclosed", "URL": "https://bria.ai/models", "OneIG (Anime and Stylization) (Alignment Score)": 0.87, "Median Inference Time": 15.8328 , "Price per Image": 0.04}
22
- {"Platform": "Replicate", "Owner": "Black Forest Labs", "Device": "Undisclosed", "Model": "FLUX 1.1 Pro Ultra", "Optimization": "Undisclosed", "URL": "", "OneIG (Anime and Stylization) (Alignment Score)": 0.89, "OneIG (Portrait) (Alignment Score)": 0.8, "OneIG (General Object) (Alignment Score)": 0.85}
23
- {"Platform": "Replicate", "Owner": "Black Forest Labs", "Device": "Undisclosed", "Model": "FLUX 2 Pro", "Optimization": "", URL: "", "OneIG (Anime and Stylization) (Alignment Score)": 0.92, "OneIG (Portrait) (Alignment Score)": 0.84, "OneIG (General Object) (Alignment Score)": 0.88}
24
- {"Platform": "Replicate", "Owner": "Black Forest Labs", "Device": "Undisclosed", "Model": "FLUX 2 Flex", "Optimization": "", URL: "", "OneIG (Anime and Stylization) (Alignment Score)": 0.92, "OneIG (Portrait) (Alignment Score)": 0.84, "OneIG (General Object) (Alignment Score)": 0.90}
25
- {"Platform": "Replicate", "Owner": "Black Forest Labs", "Device": "Undisclosed", "Model": "Flux 2 Max", "Optimization": "", URL: "", "OneIG (Anime and Stylization) (Alignment Score)": 0.93, "OneIG (Portrait) (Alignment Score)": 0.85, "OneIG (General Object) (Alignment Score)": 0.89}
26
- {"Platform": "Replicate", "Owner": "Black Forest Labs", "Device": "Undisclosed", "Model": "Flux 2 Pro", "Optimization": "", URL: "", "OneIG (Anime and Stylization) (Alignment Score)": null, "OneIG (Portrait) (Alignment Score)": 0.84, "OneIG (General Object) (Alignment Score)": 0.90}
27
- {"Platform": "Replicate", "Owner": "Open AI", "Device": "Undisclosed", "Model": "GPT Image 1.5", "Optimization": "", URL: "", "OneIG (Anime and Stylization) (Alignment Score)": 0.92, "OneIG (Portrait) (Alignment Score)": 0.85, "OneIG (General Object) (Alignment Score)": null}
28
- {"Platform": "Replicate", "Owner": "Pruna AI", "Device": "Undisclosed", "Model": "Hidream I1 Dev", "Optimzation": "Extra Juiced", "URL":"", "OneIG (Anime and Stylization) (Alignment Score)": 0.87, "OneIG (Portrait) (Alignment Score)": 0.79, "OneIG (General Object) (Alignment Score)": 0.82}
29
- {"Platform": "Replicate", "Owner": "Pruna AI", "Device": "Undisclosed", "Model": "Hidream I1 Faast", "Optimzation": "Extra Juiced", "URL":"", "OneIG (Anime and Stylization) (Alignment Score)": 0.87, "OneIG (Portrait) (Alignment Score)": 0.79, "OneIG (General Object) (Alignment Score)": 0.82}
30
-
31
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
model_display.py ADDED
@@ -0,0 +1,214 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """UI-only model display names.
2
+
3
+ Raw CSV / sample IDs stay unchanged; this maps aliases to a shared label
4
+ shown in leaderboards, Pareto plots, dropdowns, and sample headers.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import re
10
+
11
+ # Explicit aliases (any leaderboard / sample id) -> shared display label.
12
+ MODEL_DISPLAY_NAMES = {
13
+ # FLUX
14
+ "flux_2_pro": "FLUX.2 [pro]",
15
+ "flux_2_max": "FLUX.2 [max]",
16
+ "flux_2_flex": "FLUX.2 [flex]",
17
+ "flux_2_dev": "FLUX.2 [dev]",
18
+ "flux_1_1_pro": "FLUX1.1 [pro]",
19
+ "flux_1_1_pro_ultra": "FLUX1.1 [pro] Ultra",
20
+ "flux_dev": "FLUX.1 [dev]",
21
+ "flux_schnell": "FLUX.1 [schnell]",
22
+ "flux_krea": "FLUX.1 Krea [dev]",
23
+ # GPT Image
24
+ "gpt_image_2": "GPT Image 2",
25
+ "GPT Image 2 (high)": "GPT Image 2",
26
+ "gpt_image_1_5": "GPT Image 1.5",
27
+ "GPT Image 1.5 (high)": "GPT Image 1.5",
28
+ "gpt_image_1": "GPT Image 1",
29
+ "GPT Image 1 (high)": "GPT Image 1",
30
+ "GPT Image 1 Mini (medium)": "GPT Image 1 Mini",
31
+ # Nano Banana / Gemini
32
+ "nano_banana_2_0": "Nano Banana 2",
33
+ "nano_banana_2": "Nano Banana 2",
34
+ "Nano Banana 2 (Gemini 3.1 Flash Image Preview)": "Nano Banana 2",
35
+ "Nano Banana 2 Lite (Gemini 3.1 Flash Lite Image)": "Nano Banana 2 Lite",
36
+ "nano_banana_pro": "Nano Banana Pro",
37
+ "Nano Banana Pro (Gemini 3 Pro Image)": "Nano Banana Pro",
38
+ "Nano Banana (Gemini 2.5 Flash Image)": "Nano Banana",
39
+ # Seedream
40
+ "seedream_5_0": "Seedream 5.0",
41
+ "seedream_4_5": "Seedream 4.5",
42
+ "seedream_4_0": "Seedream 4.0",
43
+ "seedream_3": "Seedream 3.0",
44
+ # Qwen
45
+ "qwen_image": "Qwen Image",
46
+ "qwen_image_2_0_pro": "Qwen Image 2.0 Pro",
47
+ "Qwen Image 2.0 Pro (2026-04-22)": "Qwen Image 2.0 Pro",
48
+ "Qwen Image 2.0 (2026-03-03)": "Qwen Image 2.0",
49
+ "qwen_image_2512": "Qwen Image 2512",
50
+ "Qwen Image Max 2512": "Qwen Image 2512",
51
+ "qwen_image_fast": "Qwen Image Fast",
52
+ # Ideogram
53
+ "ideogram_4_0_quality": "Ideogram 4.0 Quality",
54
+ "Ideogram 4.0 (Quality)": "Ideogram 4.0 Quality",
55
+ "Ideogram 4.0 Fast (Quality)": "Ideogram 4.0 Fast Quality",
56
+ # Imagen
57
+ "imagen_4_0": "Imagen 4",
58
+ "imagen_4": "Imagen 4",
59
+ "Imagen 4 Standard": "Imagen 4",
60
+ "imagen_4_0_ultra": "Imagen 4 Ultra",
61
+ "imagen_4_ultra": "Imagen 4 Ultra",
62
+ "imagen_4_fast": "Imagen 4 Fast",
63
+ "Imagen 3 (v002)": "Imagen 3",
64
+ # HiDream
65
+ "hidream_i1_dev": "HiDream-I1 Dev",
66
+ "HiDream-I1-Dev": "HiDream-I1 Dev",
67
+ "hidream_i1_fast": "HiDream-I1 Fast",
68
+ "HiDream-I1-Fast": "HiDream-I1 Fast",
69
+ "hidream_i1_full": "HiDream-I1 Full",
70
+ "HiDream-O1-Image": "HiDream-O1",
71
+ "HiDream-O1-Image-1.5": "HiDream-O1 1.5",
72
+ "HiDream-O1-Image-Dev": "HiDream-O1 Dev",
73
+ # Reve
74
+ "reve_2_1": "Reve 2.1",
75
+ "Reve Image (Halfmoon)": "Reve Image",
76
+ # P-Image
77
+ "p_image": "P-Image",
78
+ "p_image_2_ideogram_very_low_1k": "P-Image-Ideogram Very Low 1K",
79
+ "p_image_2_ideogram_very_low_2k": "P-Image-Ideogram Very Low 2K",
80
+ "P-Image-Ideogram (Very Low)": "P-Image-Ideogram Very Low",
81
+ "p_image_2_ideogram_low_1k": "P-Image-Ideogram Low 1K",
82
+ "p_image_2_ideogram_low_2k": "P-Image-Ideogram Low 2K",
83
+ "P-Image-Ideogram (Low)": "P-Image-Ideogram Low",
84
+ "p_image_2_ideogram_medium_1k": "P-Image-Ideogram Medium 1K",
85
+ "p_image_2_ideogram_medium_2k": "P-Image-Ideogram Medium 2K",
86
+ "P-Image-Ideogram (Medium)": "P-Image-Ideogram Medium",
87
+ "p_image_2_ideogram_high_1k": "P-Image-Ideogram High 1K",
88
+ "p_image_2_ideogram_high_2k": "P-Image-Ideogram High 2K",
89
+ "P-Image-Ideogram (High)": "P-Image-Ideogram High",
90
+ # Others overlapping P-Bench
91
+ "z_image": "Z-Image",
92
+ "glm_image": "GLM-Image",
93
+ "hunyuanimage_3_0": "HunyuanImage 3.0",
94
+ "hunyuan_image_3": "HunyuanImage 3.0",
95
+ "HunyuanImage 3.0 (Fal)": "HunyuanImage 3.0",
96
+ "HunyuanImage 3.0 Instruct (Fal)": "HunyuanImage 3.0 Instruct",
97
+ "wan_2_2_image": "Wan 2.2 Image",
98
+ "Wan2.6 Text to Image": "Wan 2.6 Text to Image",
99
+ "kling_v2_1": "Kling v2.1",
100
+ "juggernaut_base_flux": "Juggernaut Base FLUX",
101
+ "juggernaut_pro_flux": "Juggernaut Pro FLUX",
102
+ "juggernaut_lightning_flux": "Juggernaut Lightning FLUX",
103
+ "bria_4_fibo": "Bria FIBO",
104
+ "sdxl": "SDXL 1.0",
105
+ "Stable Diffusion XL 1.0": "SDXL 1.0",
106
+ "sdxl_lightning": "SDXL Lightning",
107
+ # Arena AI (kebab / arena.ai ids)
108
+ "gpt-image-2 (medium)": "GPT Image 2",
109
+ "gpt-image-1.5-high-fidelity": "GPT Image 1.5",
110
+ "gpt-image-1": "GPT Image 1",
111
+ "gpt-image-1-mini": "GPT Image 1 Mini",
112
+ "mai-image-2.6-preview": "MAI-Image-2.6 Preview",
113
+ "mai-image-2.5": "MAI-Image-2.5",
114
+ "mai-image-2": "MAI-Image-2",
115
+ "mai-image-1": "MAI Image 1",
116
+ "grok-imagine-image-2.0 (low)": "Grok Imagine Image 2.0",
117
+ "grok-imagine-image": "Grok Imagine Image",
118
+ "grok-imagine-image-pro": "Grok Imagine Image Pro",
119
+ "reve-2.1": "Reve 2.1",
120
+ "reve-2.0": "Reve 2.0",
121
+ "reve-v1.5": "Reve 1.5",
122
+ "muse-image": "Muse Image",
123
+ "gemini-3.1-flash-image (nano-banana-2) [web-search]": "Nano Banana 2",
124
+ "gemini-3.1-flash-lite-image (nano-banana-2-lite)": "Nano Banana 2 Lite",
125
+ "gemini-3-pro-image-2k (nano-banana-pro)": "Nano Banana Pro 2K",
126
+ "gemini-3-pro-image-preview (nano-banana-pro)": "Nano Banana Pro",
127
+ "gemini-2.5-flash-image-preview (nano-banana)": "Nano Banana",
128
+ "gemini-2.0-flash-preview-image-generation": "Gemini 2.0 Flash Image",
129
+ "seedream-5.0-pro": "Seedream 5.0 Pro",
130
+ "seedream-5.0-lite": "Seedream 5.0 Lite",
131
+ "seedream-4.5": "Seedream 4.5",
132
+ "seedream-4-2k": "Seedream 4.0 2K",
133
+ "seedream-4-fal": "Seedream 4.0",
134
+ "seedream-4-high-res-fal": "Seedream 4.0 High Res",
135
+ "seedream-3": "Seedream 3.0",
136
+ "qwen-image-3.0-pro": "Qwen Image 3.0 Pro",
137
+ "qwen-image-2.0-pro-2026-06-22": "Qwen Image 2.0 Pro",
138
+ "qwen-image-2512": "Qwen Image 2512",
139
+ "qwen-image-prompt-extend": "Qwen Image Prompt Extend",
140
+ "qwen-image": "Qwen Image",
141
+ "uni-1.1-max": "Luma UNI 1 Max",
142
+ "uni-1.1": "Luma UNI 1",
143
+ "Cosmos3-Super-Text2Image (Agentic)": "Cosmos3 Super Text2Image (Agentic)",
144
+ "Cosmos3-Super-Text2Image": "Cosmos3 Super Text2Image",
145
+ "recraft-v4.1-utility-pro": "Recraft V4.1 Utility Pro",
146
+ "recraft-v4.1-pro": "Recraft V4.1 Pro",
147
+ "recraft-v4": "Recraft V4",
148
+ "recraft-v3": "Recraft V3",
149
+ "flux-2-max": "FLUX.2 [max]",
150
+ "flux-2-flex": "FLUX.2 [flex]",
151
+ "flux-2-pro": "FLUX.2 [pro]",
152
+ "flux-2-dev": "FLUX.2 [dev]",
153
+ "flux-2-klein-9b": "FLUX.2 [klein] 9B",
154
+ "flux-2-klein-4b": "FLUX.2 [klein] 4B",
155
+ "flux-1-kontext-max": "FLUX.1 Kontext [max]",
156
+ "flux-1-kontext-pro": "FLUX.1 Kontext [pro]",
157
+ "flux-1-kontext-dev": "FLUX.1 Kontext [dev]",
158
+ "flux-1.1-pro": "FLUX1.1 [pro]",
159
+ "flux-1-dev-fp8": "FLUX.1 [dev]",
160
+ "hunyuan-image-3.0": "HunyuanImage 3.0",
161
+ "imagen-ultra-4.0-generate-001": "Imagen 4 Ultra",
162
+ "imagen-4.0-generate-001": "Imagen 4",
163
+ "imagen-3.0-generate-002": "Imagen 3",
164
+ "wan2.6-t2i": "Wan 2.6 Text to Image",
165
+ "wan2.5-t2i-preview": "Wan 2.5 Preview",
166
+ "wan2.7-image-pro": "Wan 2.7 Pro",
167
+ "wan2.7-image": "Wan 2.7",
168
+ "ideogram-4.0-quality": "Ideogram 4.0 Quality",
169
+ "ideogram-v3-quality": "Ideogram 3.0",
170
+ "ideogram-v2": "Ideogram v2",
171
+ "krea-2-medium": "Krea 2 Medium",
172
+ "krea-2-turbo": "Krea 2 Medium Turbo",
173
+ "krea-2-large": "Krea 2 Large",
174
+ "hidream-o1-image": "HiDream-O1",
175
+ "z-image-turbo": "Z-Image Turbo",
176
+ "photon": "Luma Photon",
177
+ "p-image": "P-Image",
178
+ "runway-gen4": "Runway Gen-4 Image",
179
+ "lucid-origin": "Lucid Origin",
180
+ "glm-image": "GLM-Image",
181
+ "dall-e-3": "DALLE 3",
182
+ "stable-diffusion-v35-large": "Stable Diffusion 3.5 Large",
183
+ "bagel": "Bagel",
184
+ }
185
+
186
+
187
+ def _prettify_snake_case(model_id: str) -> str:
188
+ parts = [part for part in str(model_id).split("_") if part]
189
+ pretty = []
190
+ for part in parts:
191
+ if part.isdigit():
192
+ pretty.append(part)
193
+ elif re.fullmatch(r"\d+k", part, flags=re.IGNORECASE):
194
+ pretty.append(part.upper())
195
+ elif part.lower() in {"flux", "gpt", "sdxl", "glm"}:
196
+ pretty.append(part.upper())
197
+ else:
198
+ pretty.append(part.capitalize())
199
+ return " ".join(pretty)
200
+
201
+
202
+ def display_model_name(model_id) -> str:
203
+ """Return the shared UI label for a raw model id / source name."""
204
+ if model_id is None:
205
+ return ""
206
+ raw = str(model_id).strip()
207
+ if not raw:
208
+ return ""
209
+ if raw in MODEL_DISPLAY_NAMES:
210
+ return MODEL_DISPLAY_NAMES[raw]
211
+ # Already a human label (spaces / punctuation) — keep as-is.
212
+ if re.search(r"[\s.\[\]()]", raw):
213
+ return raw
214
+ return _prettify_snake_case(raw)
pruna-logo.png ADDED
requirements.txt CHANGED
@@ -1,2 +1 @@
1
- gradio-leaderboard
2
- plotly
 
1
+ plotly
 
ui.py CHANGED
The diff for this file is too large to render. See raw diff