CompactAI commited on
Commit
46a4801
Β·
verified Β·
1 Parent(s): b4f3185

Upload index.html

Browse files
Files changed (1) hide show
  1. index.html +270 -321
index.html CHANGED
@@ -70,9 +70,9 @@ body {
70
  margin: 0 auto;
71
  padding: 1.25rem 1.75rem;
72
  }
73
- .welcome { padding: 1rem 0 1.5rem; }
74
  .welcome h1 {
75
- font-size: 1.8rem;
76
  font-weight: 700;
77
  letter-spacing: -0.02em;
78
  margin-bottom: 4px;
@@ -80,15 +80,15 @@ body {
80
  .welcome p { color: var(--text-secondary); font-size: 0.95rem; }
81
  .stat-row {
82
  display: grid;
83
- grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
84
- gap: 12px;
85
- margin-bottom: 1.5rem;
86
  }
87
  .stat-pill {
88
  background: var(--card);
89
  border: 1px solid var(--border);
90
  border-radius: var(--radius-sm);
91
- padding: 1rem 1.15rem;
92
  transition: box-shadow var(--transition), transform var(--transition);
93
  }
94
  .stat-pill:hover { box-shadow: var(--shadow-md); transform: translateY(-1px); }
@@ -96,11 +96,11 @@ body {
96
  font-size: 0.72rem; font-weight: 600; text-transform: uppercase;
97
  letter-spacing: 0.06em; color: var(--text-muted); margin-bottom: 3px;
98
  }
99
- .stat-pill .value { font-size: 1.4rem; font-weight: 700; letter-spacing: -0.02em; }
100
  .stat-pill .sub { font-size: 0.75rem; color: var(--text-secondary); margin-top: 1px; }
101
  .info-banner {
102
  background: var(--card); border: 1px solid var(--border); border-radius: var(--radius-sm);
103
- padding: 1rem 1.15rem; margin-bottom: 1.5rem; font-size: 0.88rem; line-height: 1.6;
104
  display: flex; align-items: flex-start; gap: 10px;
105
  }
106
  .info-banner svg { width: 18px; height: 18px; flex-shrink: 0; margin-top: 2px; color: var(--accent); }
@@ -130,6 +130,20 @@ body {
130
  }
131
  .banner-hint.rotated { transform: rotate(180deg); }
132
  .section { margin-bottom: 1.1rem; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
133
  .timeline-toolbar {
134
  display: flex; align-items: center; gap: 6px;
135
  margin-bottom: 10px;
@@ -259,6 +273,13 @@ body {
259
  background: var(--bg-warm); color: var(--text-secondary); border: 1px solid var(--border);
260
  }
261
  .section-head .head-right { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
 
 
 
 
 
 
 
262
  .sort-control {
263
  display: inline-flex; align-items: center; gap: 6px;
264
  background: var(--bg-warm); border: 1px solid var(--border);
@@ -278,29 +299,7 @@ body {
278
  .sort-control select:hover { background-color: var(--bg); }
279
  .sort-control select:focus { box-shadow: 0 0 0 2px rgba(88, 166, 255, 0.3); }
280
  .sort-control select option { background: var(--bg-warm); color: var(--text); }
281
- .eff-callout {
282
- display: flex; align-items: flex-start; gap: 12px;
283
- background: linear-gradient(135deg, rgba(88,166,255,0.14), rgba(63,185,80,0.08));
284
- border: 1px solid var(--accent);
285
- border-radius: var(--radius-sm);
286
- padding: 0.95rem 1.15rem;
287
- margin-bottom: 12px;
288
- font-size: 0.85rem;
289
- line-height: 1.6;
290
- color: var(--text);
291
- box-shadow: 0 0 0 1px rgba(88,166,255,0.08), var(--shadow-sm);
292
- }
293
- .eff-callout .eff-callout-icon {
294
- font-size: 1.4rem;
295
- line-height: 1;
296
- flex-shrink: 0;
297
- margin-top: 1px;
298
- }
299
- .eff-callout strong { color: var(--accent); }
300
- .eff-callout code {
301
- background: rgba(88,166,255,0.14); padding: 1px 6px; border-radius: 4px;
302
- font-family: 'SF Mono', 'Fira Code', monospace; font-size: 0.82rem; color: var(--accent);
303
- }
304
  .table-wrap {
305
  background: var(--card); border: 1px solid var(--border);
306
  border-radius: var(--radius); overflow: hidden;
@@ -373,8 +372,20 @@ tbody tr { transition: background var(--transition); }
373
  .chart-card.full { grid-column: 1 / -1; }
374
  .chart-card h3 { font-size: 0.85rem; font-weight: 600; margin-bottom: 3px; }
375
  .chart-card .chart-sub { font-size: 0.72rem; color: var(--text-muted); margin-bottom: 8px; }
376
- .chart-card canvas { max-height: 420px; }
377
- .legend-bar { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 12px; }
 
 
 
 
 
 
 
 
 
 
 
 
378
  .legend-bar .legend-item { display: flex; align-items: center; gap: 6px; font-size: 0.76rem; color: var(--text-secondary); }
379
  .legend-bar .ldot { width: 8px; height: 8px; border-radius: 50%; }
380
  .eff-note { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 6px; font-size: 0.7rem; color: var(--text-muted); }
@@ -390,16 +401,6 @@ tbody tr { transition: background var(--transition); }
390
  .timeline-custom-tooltip.visible { opacity: 1; }
391
  .timeline-custom-tooltip .tt-name { font-weight: 600; margin-bottom: 2px; }
392
  .timeline-custom-tooltip .tt-val { color: var(--text-secondary); }
393
- .wiki-bubble-wrap { position: relative; }
394
- .wiki-custom-tooltip {
395
- position: absolute; pointer-events: none; background: #1c2129;
396
- border: 1px solid var(--border); border-radius: 8px; padding: 8px 12px;
397
- font-size: 0.78rem; color: var(--text); box-shadow: var(--shadow-md);
398
- opacity: 0; transition: opacity 0.15s ease; z-index: 10; white-space: nowrap;
399
- }
400
- .wiki-custom-tooltip.visible { opacity: 1; }
401
- .wiki-custom-tooltip .tt-name { font-weight: 600; margin-bottom: 2px; }
402
- .wiki-custom-tooltip .tt-val { color: var(--text-secondary); }
403
  .cta-card {
404
  background: var(--card); border: 1px solid var(--border); border-radius: var(--radius);
405
  padding: 1.25rem; display: flex; align-items: center; justify-content: space-between;
@@ -461,35 +462,38 @@ footer a:hover { text-decoration: underline; }
461
  <p>Sub-150M parameter language models, same eval harness, transparent methodology.</p>
462
  </div>
463
  <div class="stat-row anim d1" id="stat-row"></div>
464
- <div class="info-banner anim d2">
465
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></svg>
466
- <div>
467
- <strong>Why this exists.</strong> The community deserves a single place to compare tiny LMs fairly.
468
- We include every model with verifiable benchmarks β€” ours, our competitors', yours.
469
- <a href="https://huggingface.co/spaces/Glint-Research/Tiny-ML-Leaderboard/discussions" target="_blank">Submit a model via PR.</a>
470
- </div>
471
- </div>
472
  <div class="info-banner anim d2 clickable" id="unknown-banner" onclick="toggleUnknownBanner()">
473
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M12 2L2 7l10 5 10-5-10-5z"/><path d="M2 17l10 5 10-5"/><path d="M2 12l10 5 10-5"/></svg>
474
  <div style="flex:1">
475
  <div style="display:flex;align-items:center;gap:4px;flex-wrap:wrap">
476
- <strong>Unknown org?</strong>
477
- <span>The "Unknown" tag is for model makers submitting their model ahead of official release.</span>
478
- <span>If that's you β€” DM <strong>glintresearch</strong> on Discord.</span>
479
  <span class="banner-hint" id="banner-hint">β–Ό</span>
480
  </div>
481
  <div class="banner-expand" id="banner-expand">
482
  <div class="banner-expand-inner">
483
- Model makers can submit their model's benchmarks before the official release so it appears on the leaderboard immediately when announced. The <strong>Unknown</strong> tag is temporary β€” once you DM <strong>glintresearch</strong> on Discord we can update it to your organization name and color.
 
 
 
484
  </div>
485
  </div>
486
  </div>
487
  </div>
488
 
489
- <div class="section anim d3" id="table-section">
 
 
 
 
 
 
 
490
  <div class="section-head">
491
  <h2>Detailed Results</h2>
492
  <div class="head-right">
 
493
  <span class="badge" id="model-count-badge"></span>
494
  <div class="sort-control">
495
  <span>Sort</span>
@@ -499,20 +503,13 @@ footer a:hover { text-decoration: underline; }
499
  <option value="wiki">WikiText-2 byte_ppl</option>
500
  <option value="blimp">BLiMP</option>
501
  <option value="arc">ARC-Easy</option>
 
502
  <option value="params">Parameters</option>
503
  <option value="date">Release Date</option>
504
  </select>
505
  </div>
506
  </div>
507
  </div>
508
- <div class="eff-callout">
509
- <span class="eff-callout-icon">⚑</span>
510
- <div>
511
- <strong>How Efficiency (⚑) is calculated:</strong> overall benchmark score (avg of BLiMP, ARC-Easy, and normalized WikiText-2) &times; a size bonus for smaller models.
512
- The size bonus is capped on a log scale &mdash; the smallest model on the board tops out at <code>1.5&times;</code>, the largest gets <code>1.0&times;</code> (no bonus) &mdash;
513
- so a tiny model can't out-rank a much larger, better-performing one purely from an inflated size multiplier.
514
- </div>
515
- </div>
516
  <div class="table-wrap">
517
  <div class="table-toolbar" id="org-filters"></div>
518
  <div class="table-scroll">
@@ -527,6 +524,7 @@ footer a:hover { text-decoration: underline; }
527
  <th class="cell-metric">WikiText-2 byte_ppl ↓</th>
528
  <th class="cell-metric">BLiMP ↑</th>
529
  <th class="cell-metric">ARC-Easy ↑</th>
 
530
  <th>Training Tokens</th>
531
  <th>Released</th>
532
  <th>Links</th>
@@ -537,39 +535,32 @@ footer a:hover { text-decoration: underline; }
537
  </div>
538
  </div>
539
  </div>
540
- <div class="section anim d4" id="timeline-section">
541
  <div class="section-head">
542
  <h2>Model Release Timeline</h2>
543
  <span class="badge">Most recent first</span>
544
  </div>
545
  <div class="timeline" id="timeline-list"></div>
546
  </div>
547
- <div class="section anim d5" id="charts-section">
548
- <div class="section-head"><h2>Benchmark Overview</h2></div>
549
- <div class="legend-bar" id="legend-bar"></div>
550
- <div class="chart-grid">
551
- <div class="chart-card">
552
- <h3>BLiMP ↑</h3>
553
- <p class="chart-sub">Higher is better</p>
554
- <canvas id="blimpChart"></canvas>
555
- </div>
556
- <div class="chart-card">
557
- <h3>ARC-Easy ↑</h3>
558
- <p class="chart-sub">Higher is better</p>
559
- <canvas id="arcChart"></canvas>
560
  </div>
561
- <div class="chart-card full wiki-bubble-wrap">
562
- <h3>WikiText-2 Byte-Level Perplexity ↓</h3>
563
- <p class="chart-sub">Lower is better Β· byte_ppl = exp(βˆ’loglik / total_bytes) Β· bubble size = perplexity (smaller bubble = better)</p>
564
- <canvas id="wikiChart"></canvas>
565
- <div class="wiki-custom-tooltip" id="wikiTooltip">
566
- <div class="tt-name"></div>
567
- <div class="tt-val"></div>
568
  </div>
 
569
  </div>
 
570
  </div>
571
  </div>
572
- <div class="section anim d6">
573
  <div class="section-head">
574
  <h2>Model Efficiency</h2>
575
  <span class="badge">Leaderboard Score vs Params</span>
@@ -578,11 +569,6 @@ footer a:hover { text-decoration: underline; }
578
  <div class="chart-card full">
579
  <h3>Parameters vs Leaderboard Score</h3>
580
  <p class="chart-sub">Scatter of each model's overall score vs its parameter count. Points above the dashed threshold line are &ge;1&sigma; above the trend. Top 3 marked.</p>
581
- <p class="chart-sub" style="margin-top:-4px">
582
- <strong>How Efficiency (⚑) is calculated:</strong> Efficiency score = overall benchmark score (avg of BLiMP, ARC-Easy, and normalized WikiText-2) &times; a size bonus.
583
- The size bonus rewards smaller models but is capped &mdash; using a log scale across the full parameter range on this board, the smallest model can score at most <strong>1.5&times;</strong> its raw benchmark score, and the largest gets no bonus (1.0&times;).
584
- This keeps small models competitive without letting a tiny parameter count alone produce an unrealistic (e.g. 100&times;) score gap over a larger, higher-performing model.
585
- </p>
586
  <canvas id="efficiencyChart" style="max-height:400px"></canvas>
587
  <div class="eff-note">
588
  <span><span class="line-sample" style="border-top:2px dashed rgba(255,200,0,0.4)"></span> Avg trend</span>
@@ -590,10 +576,6 @@ footer a:hover { text-decoration: underline; }
590
  <span><span class="line-sample" style="background:rgba(255,230,0,0.1);height:8px"></span> Outperforming zone</span>
591
  </div>
592
  </div>
593
- <div class="chart-card full">
594
- <h3>Models Released by Org</h3>
595
- <canvas id="orgCountChart" style="max-height:260px"></canvas>
596
- </div>
597
  </div>
598
  </div>
599
  <footer>
@@ -611,6 +593,7 @@ const models = [
611
  params: "1M",
612
  blimp: 73.96,
613
  arc: 36.80,
 
614
  wiki: 3.09,
615
  tokens: "~300B",
616
  releaseDate: "2026-07-19",
@@ -624,6 +607,7 @@ const models = [
624
  params: "1K",
625
  blimp: 58.61,
626
  arc: 26.39,
 
627
  wiki: 11.27,
628
  tokens: "β€”",
629
  releaseDate: "2026-05-13",
@@ -650,6 +634,7 @@ const models = [
650
  params: "168K",
651
  blimp: 53.5,
652
  arc: 26.8,
 
653
  wiki: 7.79,
654
  tokens: "β€”",
655
  releaseDate: "2026-05-12",
@@ -689,6 +674,7 @@ const models = [
689
  params: "1.51M",
690
  blimp: 60.7,
691
  arc: 24.58,
 
692
  wiki: 4.09,
693
  tokens: "~30M",
694
  releaseDate: "2026-05-19",
@@ -715,6 +701,7 @@ const models = [
715
  params: "1.71M",
716
  blimp: 60.51,
717
  arc: 26.68,
 
718
  wiki: 4.23,
719
  tokens: "~50M",
720
  releaseDate: "2026-05-19",
@@ -728,6 +715,7 @@ const models = [
728
  params: "587K",
729
  blimp: 59.01,
730
  arc: 27.06,
 
731
  wiki: 4.52,
732
  tokens: "~200M",
733
  releaseDate: "2026-05-27",
@@ -741,6 +729,7 @@ const models = [
741
  params: "1.71M",
742
  blimp: 54.2,
743
  arc: 27.4,
 
744
  wiki: 4.82,
745
  tokens: "~4.5B",
746
  releaseDate: "2026-05-22",
@@ -767,6 +756,7 @@ const models = [
767
  params: "468K",
768
  blimp: 55.3,
769
  arc: 27.3,
 
770
  wiki: 4.49,
771
  tokens: "β€”",
772
  releaseDate: "2026-05-14",
@@ -780,6 +770,7 @@ const models = [
780
  params: "79.7M",
781
  blimp: 50.47,
782
  arc: 27.82,
 
783
  wiki: 12.42,
784
  tokens: "~21M",
785
  releaseDate: "2026-05-30",
@@ -793,6 +784,7 @@ const models = [
793
  params: "87.60M",
794
  blimp: 57.61,
795
  arc: 25,
 
796
  wiki: 11.24,
797
  tokens: "~18M",
798
  releaseDate: "2026-05-31",
@@ -806,6 +798,7 @@ const models = [
806
  params: "2.62M",
807
  blimp: 60.7,
808
  arc: 31.5,
 
809
  wiki: 3.17,
810
  tokens: "β€”",
811
  releaseDate: "2026-05-14",
@@ -819,6 +812,7 @@ const models = [
819
  params: "4.23M",
820
  blimp: 62.87,
821
  arc: 27.36,
 
822
  wiki: 3.77,
823
  tokens: "~80M",
824
  releaseDate: "2026-05-05",
@@ -832,6 +826,7 @@ const models = [
832
  params: "5.03M",
833
  blimp: 54.3,
834
  arc: 26.3,
 
835
  wiki: 6.26,
836
  tokens: "~22M",
837
  releaseDate: "2026-06-02",
@@ -845,6 +840,7 @@ const models = [
845
  params: "9.96M",
846
  blimp: 47.8,
847
  arc: 31,
 
848
  wiki: 5.31,
849
  tokens: "~46.7M",
850
  releaseDate: "2026-06-04",
@@ -858,6 +854,7 @@ const models = [
858
  params: "9.96M",
859
  blimp: 69,
860
  arc: 28,
 
861
  wiki: 6.72,
862
  tokens: "~10M",
863
  releaseDate: "2026-06-03",
@@ -871,6 +868,7 @@ const models = [
871
  params: "12.6M",
872
  blimp: 61.47,
873
  arc: 28.45,
 
874
  wiki: 8.76,
875
  tokens: "β€”",
876
  releaseDate: "2026-05-15",
@@ -884,6 +882,7 @@ const models = [
884
  params: "7.87M",
885
  blimp: 63.5,
886
  arc: 34.4,
 
887
  wiki: 2.73,
888
  tokens: "β€”",
889
  releaseDate: "2026-05-16",
@@ -897,6 +896,7 @@ const models = [
897
  params: "9.96M",
898
  blimp: 56.95,
899
  arc: 26.8,
 
900
  wiki: 6.73,
901
  tokens: "462M",
902
  releaseDate: "2026-06-01",
@@ -911,6 +911,7 @@ const models = [
911
  params: "982K",
912
  blimp: 68.7,
913
  arc: 32.5,
 
914
  wiki: 3.08,
915
  tokens: "100B",
916
  releaseDate: "2026-05-13",
@@ -924,6 +925,7 @@ const models = [
924
  params: "1.41M",
925
  blimp: 61.86,
926
  arc: 30.26,
 
927
  wiki: 3,
928
  tokens: "β€”",
929
  releaseDate: "2026-05-30",
@@ -937,6 +939,7 @@ const models = [
937
  params: "5.16M",
938
  blimp: 72.27,
939
  arc: 35.69,
 
940
  wiki: 2.57,
941
  tokens: "25B",
942
  releaseDate: "2026-05-19",
@@ -950,6 +953,7 @@ const models = [
950
  params: "74M",
951
  blimp: 74.91,
952
  arc: 39.06,
 
953
  wiki: 2.2,
954
  tokens: "~1.2B",
955
  releaseDate: "2026-06-01",
@@ -963,6 +967,7 @@ const models = [
963
  params: "51.8M",
964
  blimp: 76.3,
965
  arc: 52.2,
 
966
  wiki: 2.56,
967
  tokens: "20B",
968
  releaseDate: "2026-05-21",
@@ -977,6 +982,7 @@ const models = [
977
  params: "55.7M",
978
  blimp: 74.08,
979
  arc: 37.33,
 
980
  wiki: 2.29,
981
  tokens: "1.3B",
982
  releaseDate: "2026-06-05",
@@ -990,6 +996,7 @@ const models = [
990
  params: "91.1M",
991
  blimp: 78.35,
992
  arc: 41.5,
 
993
  wiki: 2.07,
994
  tokens: "6.5B",
995
  releaseDate: "2026-06-28",
@@ -1003,6 +1010,7 @@ const models = [
1003
  params: "9.94M",
1004
  blimp: 72.52,
1005
  arc: 35.9,
 
1006
  wiki: 2.46,
1007
  tokens: "6.5B",
1008
  releaseDate: "2026-06-13",
@@ -1016,6 +1024,7 @@ const models = [
1016
  params: "5.96M",
1017
  blimp: 65.23,
1018
  arc: 33.38,
 
1019
  wiki: 3.25,
1020
  tokens: "1.1B",
1021
  releaseDate: "2026-06-10",
@@ -1029,6 +1038,7 @@ const models = [
1029
  params: "95M",
1030
  blimp: 80.20,
1031
  arc: 43.18,
 
1032
  wiki: 2.08,
1033
  tokens: "9B",
1034
  releaseDate: "2026-07-06",
@@ -1042,6 +1052,7 @@ const models = [
1042
  params: "28.4M",
1043
  blimp: 69.75,
1044
  arc: 38.59,
 
1045
  wiki: 2.3,
1046
  tokens: "2.6B",
1047
  releaseDate: "2026-06-09",
@@ -1055,6 +1066,7 @@ const models = [
1055
  params: "22.03M",
1056
  blimp: 61.4,
1057
  arc: 30.85,
 
1058
  wiki: 3.14,
1059
  tokens: "~1.57B",
1060
  releaseDate: "2026-06-05",
@@ -1068,6 +1080,7 @@ const models = [
1068
  params: "53.1M",
1069
  blimp: 72.81,
1070
  arc: 30.3,
 
1071
  wiki: 2.38,
1072
  tokens: "1.1B",
1073
  releaseDate: "2026-06-09",
@@ -1081,6 +1094,7 @@ const models = [
1081
  params: "117K",
1082
  blimp: 51.77,
1083
  arc: 26.39,
 
1084
  wiki: 25.17,
1085
  tokens: "500M",
1086
  releaseDate: "2026-05-18",
@@ -1094,6 +1108,7 @@ const models = [
1094
  params: "51.8M",
1095
  blimp: 76.3,
1096
  arc: 46.0,
 
1097
  wiki: 2.04,
1098
  tokens: "20B",
1099
  releaseDate: "2026-05-27",
@@ -1107,6 +1122,7 @@ const models = [
1107
  params: "51.8M",
1108
  blimp: 64.14,
1109
  arc: 45.16,
 
1110
  wiki: 2.6,
1111
  tokens: "20B",
1112
  releaseDate: "2026-06-04",
@@ -1121,6 +1137,7 @@ const models = [
1121
  params: "85.7M",
1122
  blimp: 71.44,
1123
  arc: 38.01,
 
1124
  wiki: 2.2228,
1125
  tokens: "~20B",
1126
  releaseDate: "2026-05-22",
@@ -1135,6 +1152,7 @@ const models = [
1135
  params: "75M",
1136
  blimp: 76.10,
1137
  arc: 35.65,
 
1138
  wiki: 2.08,
1139
  tokens: "~18B",
1140
  releaseDate: "2026-05-29",
@@ -1149,6 +1167,7 @@ const models = [
1149
  params: "75M",
1150
  blimp: 76.02,
1151
  arc: 39.10,
 
1152
  wiki: 2.17,
1153
  tokens: "~18B",
1154
  releaseDate: "2026-05-29",
@@ -1163,6 +1182,7 @@ const models = [
1163
  params: "11.9K",
1164
  blimp: 52.43,
1165
  arc: 25.46,
 
1166
  wiki: 14.73,
1167
  tokens: "500K",
1168
  releaseDate: "2026-06-16",
@@ -1176,6 +1196,7 @@ const models = [
1176
  params: "150M",
1177
  blimp: 72.67,
1178
  arc: 31.40,
 
1179
  wiki: 2.45,
1180
  tokens: "~1.47B",
1181
  releaseDate: "2026-05-05",
@@ -1189,6 +1210,7 @@ const models = [
1189
  params: "86M",
1190
  blimp: 73.56,
1191
  arc: 39.31,
 
1192
  wiki: 2.3753,
1193
  tokens: "β€”",
1194
  releaseDate: "2026-06-18",
@@ -1203,6 +1225,7 @@ const models = [
1203
  params: "86M",
1204
  blimp: 70.33,
1205
  arc: 34.68,
 
1206
  wiki: 2.6839,
1207
  tokens: "β€”",
1208
  releaseDate: "2026-06-18",
@@ -1244,6 +1267,7 @@ const models = [
1244
  params: "34.6M",
1245
  blimp: 64.05,
1246
  arc: 32.79,
 
1247
  wiki: 2.875,
1248
  tokens: "~115~165M",
1249
  releaseDate: "2026-06-25",
@@ -1257,6 +1281,7 @@ const models = [
1257
  params: "34.6M",
1258
  blimp: 64.87,
1259
  arc: 34.13,
 
1260
  wiki: 2.838,
1261
  tokens: "210M",
1262
  releaseDate: "2026-06-28",
@@ -1270,6 +1295,7 @@ const models = [
1270
  params: "125M",
1271
  blimp: 81.28,
1272
  arc: 57.07,
 
1273
  wiki: 1.86,
1274
  tokens: "75B",
1275
  releaseDate: "2026-04-22",
@@ -1293,6 +1319,7 @@ const models = [
1293
  params: "99.8M",
1294
  blimp: 61.13,
1295
  arc: 25.88,
 
1296
  wiki: 3.878,
1297
  tokens: "~625M",
1298
  releaseDate: "2026-06-15",
@@ -1306,6 +1333,7 @@ const models = [
1306
  params: "99.8M",
1307
  blimp: 66.01,
1308
  arc: 33.88,
 
1309
  wiki: 2.879,
1310
  tokens: "β€”",
1311
  releaseDate: "2026-07-05",
@@ -1332,6 +1360,7 @@ const models = [
1332
  params: "500k",
1333
  blimp: 60.61,
1334
  arc: 30.35,
 
1335
  wiki: 4.1228,
1336
  tokens: "300M",
1337
  releaseDate: "2026-07-16",
@@ -1345,6 +1374,7 @@ const models = [
1345
  params: "23.85M",
1346
  blimp: 75.09,
1347
  arc: 39.98,
 
1348
  wiki: 2.2250,
1349
  tokens: "~12.85B",
1350
  releaseDate: "2026-07-07",
@@ -1359,6 +1389,7 @@ const models = [
1359
  params: "51.8M",
1360
  blimp: 67.4,
1361
  arc: 45.9,
 
1362
  wiki: 2.7,
1363
  tokens: "23B",
1364
  releaseDate: "2026-06-12",
@@ -1373,6 +1404,7 @@ const models = [
1373
  params: "0.2M",
1374
  blimp: 51.84,
1375
  arc: 26.77,
 
1376
  wiki: 8.0696,
1377
  tokens: "1.5M",
1378
  releaseDate: "2026-05-15",
@@ -1571,13 +1603,16 @@ function renderStats() {
1571
  const orgs = new Set(models.map(m => m.org));
1572
  const blimps = models.filter(m => m.blimp).map(m => m.blimp);
1573
  const arcs = models.filter(m => m.arc).map(m => m.arc);
 
1574
  const bestB = Math.max(...blimps);
1575
  const bestA = Math.max(...arcs);
 
1576
  document.getElementById('stat-row').innerHTML = `
1577
  <div class="stat-pill"><div class="label">Models</div><div class="value">${models.length}</div><div class="sub">On leaderboard</div></div>
1578
  <div class="stat-pill"><div class="label">Organizations</div><div class="value">${orgs.size}</div><div class="sub">Contributing</div></div>
1579
  <div class="stat-pill"><div class="label">Best BLiMP</div><div class="value" style="color:var(--green)">${bestB}%</div><div class="sub">${models.find(m => m.blimp === bestB).name}</div></div>
1580
  <div class="stat-pill"><div class="label">Best ARC-E</div><div class="value" style="color:var(--green)">${bestA}%</div><div class="sub">${models.find(m => m.arc === bestA).name}</div></div>
 
1581
  `;
1582
  document.getElementById('model-count-badge').textContent = `${models.length} models`;
1583
  }
@@ -1604,6 +1639,11 @@ const sortComparators = {
1604
  if (b.arc == null) return -1;
1605
  return b.arc - a.arc;
1606
  },
 
 
 
 
 
1607
  efficiency: (a, b) => getEfficiencyScore(b) - getEfficiencyScore(a),
1608
  params: (a, b) => parseParams(a.params) - parseParams(b.params),
1609
  date: (a, b) => {
@@ -1620,6 +1660,14 @@ function sizeBucket(params) {
1620
  return 'large';
1621
  }
1622
 
 
 
 
 
 
 
 
 
1623
  function matchesFilter(m) {
1624
  if (activeFilter === 'all') return true;
1625
  if (activeFilter === 'small' || activeFilter === 'medium' || activeFilter === 'large') {
@@ -1629,7 +1677,16 @@ function matchesFilter(m) {
1629
  }
1630
 
1631
  function getFilteredModels() {
1632
- return models.filter(matchesFilter);
 
 
 
 
 
 
 
 
 
1633
  }
1634
 
1635
  function setupSortControl() {
@@ -1646,11 +1703,8 @@ function renderFilteredViews() {
1646
  renderTable();
1647
  buildLegend();
1648
  renderTimeline();
1649
- buildBarChart('blimpChart', 'blimp', false);
1650
- buildBarChart('arcChart', 'arc', false);
1651
- buildWikiChart();
1652
- buildEfficiencyChart();
1653
- buildOrgCountChart();
1654
  }
1655
 
1656
  function buildFilters() {
@@ -1706,9 +1760,10 @@ function renderTable() {
1706
  const tbody = document.getElementById('leaderboard-body');
1707
  const cmp = sortComparators[activeSort] || sortComparators.score;
1708
  const filtered = getFilteredModels().sort(cmp);
1709
- document.getElementById('model-count-badge').textContent = activeFilter === 'all'
1710
- ? `${models.length} models`
1711
- : `${filtered.length} of ${models.length} models`;
 
1712
  const blimps = models.filter(m => m.blimp).map(m => m.blimp);
1713
  const arcs = models.filter(m => m.arc).map(m => m.arc);
1714
  const wikis = models.filter(m => m.wiki).map(m => m.wiki);
@@ -1716,6 +1771,8 @@ function renderTable() {
1716
  const bMin = Math.min(...blimps), bMax = Math.max(...blimps);
1717
  const aMin = Math.min(...arcs), aMax = Math.max(...arcs);
1718
  const wMin = Math.min(...wikis), wMax = Math.max(...wikis);
 
 
1719
  const eMin = Math.min(...effs), eMax = Math.max(...effs);
1720
 
1721
  tbody.innerHTML = filtered.map((m, idx) => {
@@ -1753,6 +1810,11 @@ function renderTable() {
1753
  ? `<span class="metric-val${isBestArc ? ' best' : ''}">${m.arc}%</span>`
1754
  : '<span class="metric-na">TBD</span>'}
1755
  </td>
 
 
 
 
 
1756
  <td class="cell-tokens">${m.tokens}</td>
1757
  <td class="cell-date">${formatDate(m.releaseDate)}</td>
1758
  <td class="cell-links">
@@ -1761,7 +1823,7 @@ function renderTable() {
1761
  ${m.links.demo ? `<a href="${m.links.demo}" target="_blank">demo</a>` : ''}
1762
  </td>
1763
  </tr>`;
1764
- }).join('');
1765
  }
1766
 
1767
  /* ─── Legend ─── */
@@ -1852,54 +1914,113 @@ function renderTimeline() {
1852
 
1853
  /* ─── Bar charts ─── */
1854
 
1855
- function buildBarChart(canvasId, metric, reverse) {
1856
- const canvas = document.getElementById(canvasId);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1857
  const existing = Chart.getChart(canvas);
1858
  if (existing) existing.destroy();
1859
 
1860
- const fmt = v => v.toFixed(1) + '%';
 
 
 
1861
  const sorted = getFilteredModels()
1862
- .filter(d => d[metric] !== null && typeof d[metric] === 'number')
1863
- .sort((a, b) => reverse ? a[metric] - b[metric] : b[metric] - a[metric]);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1864
 
1865
  new Chart(canvas, {
1866
  type: 'bar',
1867
  data: {
1868
  labels: sorted.map(d => d.name),
1869
  datasets: [{
1870
- data: sorted.map(d => d[metric]),
1871
- backgroundColor: sorted.map(d => bgMap[d.org]),
 
 
 
 
 
1872
  borderColor: sorted.map(d => colorMap[d.org]),
1873
  borderWidth: 1,
1874
  borderRadius: 3,
1875
- borderSkipped: false
 
 
 
 
1876
  }]
1877
  },
1878
  options: {
1879
  indexAxis: 'y',
1880
  responsive: true,
1881
  maintainAspectRatio: false,
1882
- animation: { duration: 600, easing: 'easeOutQuart' },
1883
  plugins: {
1884
  tooltip: {
1885
- callbacks: { label: ctx => fmt(ctx.parsed.x) },
 
 
1886
  ...tooltipStyle
1887
  }
1888
  },
1889
  scales: {
1890
  x: {
1891
- beginAtZero: true,
1892
- grid: { drawBorder: false },
1893
- ticks: { callback: v => v + '%' }
 
 
 
1894
  },
1895
  y: {
 
1896
  grid: { display: false },
1897
  ticks: {
1898
- font: { size: 9 },
 
1899
  autoSkip: false,
1900
  callback: function(v) {
1901
  const l = this.getLabelForValue(v);
1902
- return l.length > 18 ? l.slice(0, 17) + '…' : l;
1903
  }
1904
  }
1905
  }
@@ -1908,163 +2029,6 @@ function buildBarChart(canvasId, metric, reverse) {
1908
  });
1909
  }
1910
 
1911
- /* ─── WikiText-2 Bubble ─── */
1912
-
1913
- function buildWikiChart() {
1914
- const canvas = document.getElementById('wikiChart');
1915
- const existing = Chart.getChart(canvas);
1916
- if (existing) existing.destroy();
1917
-
1918
- const data = getFilteredModels()
1919
- .filter(d => d.wiki !== null && typeof d.wiki === 'number')
1920
- .filter(d => d.name !== 'Glint-0.1' && d.name !== 'Glint-0.2')
1921
- .map(d => ({
1922
- name: d.name,
1923
- org: d.org,
1924
- wiki: d.wiki,
1925
- logWiki: Math.log10(Math.max(d.wiki, 0.1)),
1926
- params: d.params
1927
- }))
1928
- .sort((a, b) => a.wiki - b.wiki);
1929
-
1930
- const ySpread = [];
1931
- const used = [];
1932
- data.forEach(d => {
1933
- let y = 0.5;
1934
- const logX = d.logWiki;
1935
- for (let attempt = 0; attempt < 40; attempt++) {
1936
- const candidateY = 0.15 + (attempt % 8) * 0.1 + Math.floor(attempt / 8) * 0.02;
1937
- let overlap = false;
1938
- for (const u of used) {
1939
- const dx = Math.abs(logX - u.logX);
1940
- const dy = Math.abs(candidateY - u.y);
1941
- if (dx < 0.15 && dy < 0.08) { overlap = true; break; }
1942
- }
1943
- if (!overlap) { y = candidateY; break; }
1944
- }
1945
- used.push({ logX, y });
1946
- ySpread.push(y);
1947
- });
1948
-
1949
- const logVals = data.map(d => d.logWiki);
1950
- const logMin = Math.min(...logVals);
1951
- const logMax = Math.max(...logVals);
1952
-
1953
- function getRadius(logW) {
1954
- if (logMax === logMin) return 12;
1955
- const t = (logW - logMin) / (logMax - logMin);
1956
- return 6 + t * 26;
1957
- }
1958
-
1959
- const tooltip = document.getElementById('wikiTooltip');
1960
- tooltip.classList.remove('visible');
1961
-
1962
- new Chart(canvas, {
1963
- type: 'bubble',
1964
- data: {
1965
- datasets: [{
1966
- data: data.map((d, i) => ({
1967
- x: d.wiki,
1968
- y: ySpread[i],
1969
- r: getRadius(d.logWiki),
1970
- _name: d.name,
1971
- _org: d.org,
1972
- _wiki: d.wiki,
1973
- _params: d.params
1974
- })),
1975
- backgroundColor: data.map(d => orgTint(d.org, 0.5)),
1976
- borderColor: data.map(d => colorMap[d.org]),
1977
- borderWidth: 1.5,
1978
- hoverBorderWidth: 2.5,
1979
- hoverBackgroundColor: data.map(d => orgTint(d.org, 0.75))
1980
- }]
1981
- },
1982
- options: {
1983
- responsive: true,
1984
- maintainAspectRatio: true,
1985
- animation: { duration: 700, easing: 'easeOutQuart' },
1986
- layout: { padding: { top: 10, bottom: 10, left: 10, right: 10 } },
1987
- scales: {
1988
- x: {
1989
- type: 'logarithmic',
1990
- title: { display: true, text: 'byte_ppl (log scale)', color: '#8b949e', font: { size: 11 } },
1991
- grid: { drawBorder: false, color: 'rgba(255,255,255,0.04)' },
1992
- ticks: {
1993
- color: '#8b949e',
1994
- callback: function(v) {
1995
- if (v >= 1000) return (v / 1000).toFixed(v >= 10000 ? 0 : 1) + 'K';
1996
- if (v >= 1) return v.toFixed(v >= 100 ? 0 : v >= 10 ? 1 : 2);
1997
- return v.toString();
1998
- }
1999
- }
2000
- },
2001
- y: { display: false, min: 0, max: 1 }
2002
- },
2003
- plugins: {
2004
- legend: { display: false },
2005
- tooltip: { enabled: false }
2006
- }
2007
- },
2008
- plugins: [
2009
- {
2010
- id: 'customLabels',
2011
- afterDraw(chart) {
2012
- const ctx = chart.ctx;
2013
- const meta = chart.getDatasetMeta(0);
2014
- meta.data.forEach((point, i) => {
2015
- const d = chart.data.datasets[0].data[i];
2016
- if (d.r >= 12) {
2017
- ctx.save();
2018
- ctx.font = `500 ${Math.min(d.r * 0.55, 11)}px -apple-system,BlinkMacSystemFont,sans-serif`;
2019
- ctx.fillStyle = 'rgba(255,255,255,0.85)';
2020
- ctx.textAlign = 'center';
2021
- ctx.textBaseline = 'middle';
2022
- let label = d._name;
2023
- const maxW = d.r * 1.6;
2024
- if (ctx.measureText(label).width > maxW) {
2025
- label = label.slice(0, Math.floor(maxW / ctx.measureText('A').width)) + '…';
2026
- }
2027
- ctx.fillText(label, point.x, point.y);
2028
- ctx.restore();
2029
- }
2030
- });
2031
- }
2032
- },
2033
- {
2034
- id: 'customTooltip',
2035
- afterEvent(chart, args) {
2036
- const evt = args.event;
2037
- if (evt.type === 'mouseout') {
2038
- tooltip.classList.remove('visible');
2039
- return;
2040
- }
2041
- const elements = chart.getElementsAtEventForMode(evt, 'nearest', { intersect: true }, false);
2042
- if (elements.length > 0) {
2043
- const el = elements[0];
2044
- const d = chart.data.datasets[0].data[el.index];
2045
- const point = chart.getDatasetMeta(0).data[el.index];
2046
- tooltip.querySelector('.tt-name').textContent = d._name;
2047
- tooltip.querySelector('.tt-val').innerHTML =
2048
- `byte_ppl: <strong>${d._wiki.toLocaleString()}</strong> Β· ${d._params} params`;
2049
- let left = point.x + 14;
2050
- let top = point.y - 20;
2051
- const ttW = 250;
2052
- if (left + ttW > canvas.width) left = point.x - ttW - 10;
2053
- if (top < 0) top = 10;
2054
- tooltip.style.left = left + 'px';
2055
- tooltip.style.top = top + 'px';
2056
- tooltip.classList.add('visible');
2057
- } else {
2058
- tooltip.classList.remove('visible');
2059
- }
2060
- }
2061
- }
2062
- ]
2063
- });
2064
- }
2065
-
2066
- /* ─── Efficiency ── */
2067
-
2068
  function buildEfficiencyChart() {
2069
  const canvas = document.getElementById('efficiencyChart');
2070
  const existing = Chart.getChart(canvas);
@@ -2233,49 +2197,6 @@ function buildEfficiencyChart() {
2233
 
2234
  /* ─── Org Count ─── */
2235
 
2236
- function buildOrgCountChart() {
2237
- const canvas = document.getElementById('orgCountChart');
2238
- const existing = Chart.getChart(canvas);
2239
- if (existing) existing.destroy();
2240
-
2241
- const counts = {};
2242
- getFilteredModels().forEach(m => counts[m.org] = (counts[m.org] || 0) + 1);
2243
- const orgs = Object.keys(counts).sort((a, b) => counts[b] - counts[a]);
2244
-
2245
- new Chart(canvas, {
2246
- type: 'doughnut',
2247
- data: {
2248
- labels: orgs.map(o => orgNameMap[o]),
2249
- datasets: [{
2250
- data: orgs.map(o => counts[o]),
2251
- backgroundColor: orgs.map(o => colorMap[o]),
2252
- borderColor: '#161b22',
2253
- borderWidth: 2,
2254
- hoverOffset: 6
2255
- }]
2256
- },
2257
- options: {
2258
- responsive: true,
2259
- maintainAspectRatio: true,
2260
- cutout: '58%',
2261
- animation: { duration: 700, easing: 'easeOutQuart' },
2262
- plugins: {
2263
- legend: {
2264
- display: true,
2265
- position: 'bottom',
2266
- labels: {
2267
- color: '#c9d1d9',
2268
- padding: 14,
2269
- usePointStyle: true,
2270
- pointStyle: 'circle',
2271
- font: { size: 11 }
2272
- }
2273
- }
2274
- }
2275
- }
2276
- });
2277
- }
2278
-
2279
  /* ─── Toggle Banner ─── */
2280
 
2281
  function toggleUnknownBanner() {
@@ -2287,12 +2208,40 @@ function toggleUnknownBanner() {
2287
  if (hint) hint.classList.toggle('rotated');
2288
  }
2289
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2290
  /* ─── Init ─── */
2291
 
2292
  window.addEventListener('DOMContentLoaded', () => {
2293
  renderStats();
2294
  buildFilters();
2295
  setupSortControl();
 
 
 
2296
  renderFilteredViews();
2297
  });
2298
 
 
70
  margin: 0 auto;
71
  padding: 1.25rem 1.75rem;
72
  }
73
+ .welcome { padding: 0.5rem 0 1rem; }
74
  .welcome h1 {
75
+ font-size: 1.5rem;
76
  font-weight: 700;
77
  letter-spacing: -0.02em;
78
  margin-bottom: 4px;
 
80
  .welcome p { color: var(--text-secondary); font-size: 0.95rem; }
81
  .stat-row {
82
  display: grid;
83
+ grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
84
+ gap: 10px;
85
+ margin-bottom: 0.9rem;
86
  }
87
  .stat-pill {
88
  background: var(--card);
89
  border: 1px solid var(--border);
90
  border-radius: var(--radius-sm);
91
+ padding: 0.6rem 0.9rem;
92
  transition: box-shadow var(--transition), transform var(--transition);
93
  }
94
  .stat-pill:hover { box-shadow: var(--shadow-md); transform: translateY(-1px); }
 
96
  font-size: 0.72rem; font-weight: 600; text-transform: uppercase;
97
  letter-spacing: 0.06em; color: var(--text-muted); margin-bottom: 3px;
98
  }
99
+ .stat-pill .value { font-size: 1.15rem; font-weight: 700; letter-spacing: -0.02em; }
100
  .stat-pill .sub { font-size: 0.75rem; color: var(--text-secondary); margin-top: 1px; }
101
  .info-banner {
102
  background: var(--card); border: 1px solid var(--border); border-radius: var(--radius-sm);
103
+ padding: 0.7rem 1rem; margin-bottom: 0.9rem; font-size: 0.84rem; line-height: 1.55;
104
  display: flex; align-items: flex-start; gap: 10px;
105
  }
106
  .info-banner svg { width: 18px; height: 18px; flex-shrink: 0; margin-top: 2px; color: var(--accent); }
 
130
  }
131
  .banner-hint.rotated { transform: rotate(180deg); }
132
  .section { margin-bottom: 1.1rem; }
133
+ .tabbar {
134
+ display: flex; gap: 2px; padding: 3px; margin-bottom: 14px;
135
+ background: var(--bg-warm); border: 1px solid var(--border);
136
+ border-radius: 100px; width: fit-content; max-width: 100%; overflow-x: auto;
137
+ }
138
+ .tabbar .tab {
139
+ border: none; cursor: pointer; padding: 7px 18px; border-radius: 100px;
140
+ font-family: inherit; font-size: 0.82rem; font-weight: 600; letter-spacing: -0.01em;
141
+ color: var(--text-secondary); background: transparent; white-space: nowrap;
142
+ transition: all var(--transition);
143
+ }
144
+ .tabbar .tab:hover { color: var(--text); background: var(--card-hover); }
145
+ .tabbar .tab.active { background: var(--accent); color: #fff; }
146
+ [hidden] { display: none !important; }
147
  .timeline-toolbar {
148
  display: flex; align-items: center; gap: 6px;
149
  margin-bottom: 10px;
 
273
  background: var(--bg-warm); color: var(--text-secondary); border: 1px solid var(--border);
274
  }
275
  .section-head .head-right { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
276
+ .search {
277
+ background: var(--bg-warm); border: 1px solid var(--border); border-radius: 100px;
278
+ padding: 6px 14px; color: var(--text); font-family: inherit; font-size: 0.78rem;
279
+ width: 210px; outline: none; transition: border-color var(--transition);
280
+ }
281
+ .search::placeholder { color: var(--text-muted); }
282
+ .search:focus { border-color: var(--accent); }
283
  .sort-control {
284
  display: inline-flex; align-items: center; gap: 6px;
285
  background: var(--bg-warm); border: 1px solid var(--border);
 
299
  .sort-control select:hover { background-color: var(--bg); }
300
  .sort-control select:focus { box-shadow: 0 0 0 2px rgba(88, 166, 255, 0.3); }
301
  .sort-control select option { background: var(--bg-warm); color: var(--text); }
302
+ .banner-expand.open { max-height: 340px; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
303
  .table-wrap {
304
  background: var(--card); border: 1px solid var(--border);
305
  border-radius: var(--radius); overflow: hidden;
 
372
  .chart-card.full { grid-column: 1 / -1; }
373
  .chart-card h3 { font-size: 0.85rem; font-weight: 600; margin-bottom: 3px; }
374
  .chart-card .chart-sub { font-size: 0.72rem; color: var(--text-muted); margin-bottom: 8px; }
375
+
376
+ .metric-switch { display: inline-flex; gap: 2px; padding: 3px; background: var(--bg-warm);
377
+ border: 1px solid var(--border); border-radius: 100px; }
378
+ .metric-chip {
379
+ border: none; cursor: pointer; padding: 5px 14px; border-radius: 100px;
380
+ font-family: inherit; font-size: 0.76rem; font-weight: 600; letter-spacing: -0.01em;
381
+ color: var(--text-secondary); background: transparent; transition: all var(--transition);
382
+ }
383
+ .metric-chip:hover { color: var(--text); background: var(--card-hover); }
384
+ .metric-chip.active { background: var(--accent); color: #fff; }
385
+ .chart-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px;
386
+ flex-wrap: wrap; margin-bottom: 14px; }
387
+ .chart-scroll { position: relative; overflow-y: auto; max-height: 70vh; }
388
+ .legend-bar { display: flex; flex-wrap: wrap; gap: 10px 12px; justify-content: flex-end; max-width: 62%; }
389
  .legend-bar .legend-item { display: flex; align-items: center; gap: 6px; font-size: 0.76rem; color: var(--text-secondary); }
390
  .legend-bar .ldot { width: 8px; height: 8px; border-radius: 50%; }
391
  .eff-note { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 6px; font-size: 0.7rem; color: var(--text-muted); }
 
401
  .timeline-custom-tooltip.visible { opacity: 1; }
402
  .timeline-custom-tooltip .tt-name { font-weight: 600; margin-bottom: 2px; }
403
  .timeline-custom-tooltip .tt-val { color: var(--text-secondary); }
 
 
 
 
 
 
 
 
 
 
404
  .cta-card {
405
  background: var(--card); border: 1px solid var(--border); border-radius: var(--radius);
406
  padding: 1.25rem; display: flex; align-items: center; justify-content: space-between;
 
462
  <p>Sub-150M parameter language models, same eval harness, transparent methodology.</p>
463
  </div>
464
  <div class="stat-row anim d1" id="stat-row"></div>
 
 
 
 
 
 
 
 
465
  <div class="info-banner anim d2 clickable" id="unknown-banner" onclick="toggleUnknownBanner()">
466
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></svg>
467
  <div style="flex:1">
468
  <div style="display:flex;align-items:center;gap:4px;flex-wrap:wrap">
469
+ <strong>Every tiny LM with verifiable benchmarks</strong>
470
+ <span>&mdash; ours, our competitors', yours.</span>
471
+ <a href="https://huggingface.co/spaces/Glint-Research/Tiny-ML-Leaderboard/discussions" target="_blank" onclick="event.stopPropagation()">Submit a model via PR.</a>
472
  <span class="banner-hint" id="banner-hint">β–Ό</span>
473
  </div>
474
  <div class="banner-expand" id="banner-expand">
475
  <div class="banner-expand-inner">
476
+ <strong>Scoring.</strong> Efficiency (⚑) is the overall benchmark score (average of BLiMP, ARC-Easy and normalised WikiText-2)
477
+ times a size bonus, capped on a log scale: the smallest model on the board tops out at <code>1.5Γ—</code>, the largest gets <code>1.0Γ—</code>.
478
+ A tiny model can't out-rank a much larger, better-performing one on parameter count alone.<br>
479
+ <strong>Unknown org?</strong> That tag is for makers submitting benchmarks ahead of release &mdash; DM <strong>glintresearch</strong> on Discord to have it replaced with your org.
480
  </div>
481
  </div>
482
  </div>
483
  </div>
484
 
485
+ <nav class="tabbar anim d2" id="tabbar">
486
+ <button class="tab active" data-view="table">Leaderboard</button>
487
+ <button class="tab" data-view="charts">Charts</button>
488
+ <button class="tab" data-view="timeline">Timeline</button>
489
+ <button class="tab" data-view="efficiency">Efficiency</button>
490
+ </nav>
491
+
492
+ <div class="section anim d3 view" id="table-section">
493
  <div class="section-head">
494
  <h2>Detailed Results</h2>
495
  <div class="head-right">
496
+ <input class="search" id="model-search" type="search" placeholder="Search models or orgs…" autocomplete="off">
497
  <span class="badge" id="model-count-badge"></span>
498
  <div class="sort-control">
499
  <span>Sort</span>
 
503
  <option value="wiki">WikiText-2 byte_ppl</option>
504
  <option value="blimp">BLiMP</option>
505
  <option value="arc">ARC-Easy</option>
506
+ <option value="gci">GCI</option>
507
  <option value="params">Parameters</option>
508
  <option value="date">Release Date</option>
509
  </select>
510
  </div>
511
  </div>
512
  </div>
 
 
 
 
 
 
 
 
513
  <div class="table-wrap">
514
  <div class="table-toolbar" id="org-filters"></div>
515
  <div class="table-scroll">
 
524
  <th class="cell-metric">WikiText-2 byte_ppl ↓</th>
525
  <th class="cell-metric">BLiMP ↑</th>
526
  <th class="cell-metric">ARC-Easy ↑</th>
527
+ <th class="cell-metric">GCI ↑</th>
528
  <th>Training Tokens</th>
529
  <th>Released</th>
530
  <th>Links</th>
 
535
  </div>
536
  </div>
537
  </div>
538
+ <div class="section anim d4 view" id="timeline-section" hidden>
539
  <div class="section-head">
540
  <h2>Model Release Timeline</h2>
541
  <span class="badge">Most recent first</span>
542
  </div>
543
  <div class="timeline" id="timeline-list"></div>
544
  </div>
545
+ <div class="section anim d5 view" id="charts-section" hidden>
546
+ <div class="section-head">
547
+ <h2>Benchmark Overview</h2>
548
+ <div class="head-right">
549
+ <div class="metric-switch" id="metric-switch"></div>
 
 
 
 
 
 
 
 
550
  </div>
551
+ </div>
552
+ <div class="chart-card">
553
+ <div class="chart-head">
554
+ <div>
555
+ <h3 id="metric-title">BLiMP</h3>
556
+ <p class="chart-sub" id="metric-sub">Higher is better</p>
 
557
  </div>
558
+ <div class="legend-bar" id="legend-bar"></div>
559
  </div>
560
+ <div class="chart-scroll"><canvas id="metricChart"></canvas></div>
561
  </div>
562
  </div>
563
+ <div class="section anim d6 view" id="efficiency-section" hidden>
564
  <div class="section-head">
565
  <h2>Model Efficiency</h2>
566
  <span class="badge">Leaderboard Score vs Params</span>
 
569
  <div class="chart-card full">
570
  <h3>Parameters vs Leaderboard Score</h3>
571
  <p class="chart-sub">Scatter of each model's overall score vs its parameter count. Points above the dashed threshold line are &ge;1&sigma; above the trend. Top 3 marked.</p>
 
 
 
 
 
572
  <canvas id="efficiencyChart" style="max-height:400px"></canvas>
573
  <div class="eff-note">
574
  <span><span class="line-sample" style="border-top:2px dashed rgba(255,200,0,0.4)"></span> Avg trend</span>
 
576
  <span><span class="line-sample" style="background:rgba(255,230,0,0.1);height:8px"></span> Outperforming zone</span>
577
  </div>
578
  </div>
 
 
 
 
579
  </div>
580
  </div>
581
  <footer>
 
593
  params: "1M",
594
  blimp: 73.96,
595
  arc: 36.80,
596
+ gci: 48.02,
597
  wiki: 3.09,
598
  tokens: "~300B",
599
  releaseDate: "2026-07-19",
 
607
  params: "1K",
608
  blimp: 58.61,
609
  arc: 26.39,
610
+ gci: 0.57,
611
  wiki: 11.27,
612
  tokens: "β€”",
613
  releaseDate: "2026-05-13",
 
634
  params: "168K",
635
  blimp: 53.5,
636
  arc: 26.8,
637
+ gci: 48.95,
638
  wiki: 7.79,
639
  tokens: "β€”",
640
  releaseDate: "2026-05-12",
 
674
  params: "1.51M",
675
  blimp: 60.7,
676
  arc: 24.58,
677
+ gci: 51.57,
678
  wiki: 4.09,
679
  tokens: "~30M",
680
  releaseDate: "2026-05-19",
 
701
  params: "1.71M",
702
  blimp: 60.51,
703
  arc: 26.68,
704
+ gci: 51.28,
705
  wiki: 4.23,
706
  tokens: "~50M",
707
  releaseDate: "2026-05-19",
 
715
  params: "587K",
716
  blimp: 59.01,
717
  arc: 27.06,
718
+ gci: 51.40,
719
  wiki: 4.52,
720
  tokens: "~200M",
721
  releaseDate: "2026-05-27",
 
729
  params: "1.71M",
730
  blimp: 54.2,
731
  arc: 27.4,
732
+ gci: 49.54,
733
  wiki: 4.82,
734
  tokens: "~4.5B",
735
  releaseDate: "2026-05-22",
 
756
  params: "468K",
757
  blimp: 55.3,
758
  arc: 27.3,
759
+ gci: 48.96,
760
  wiki: 4.49,
761
  tokens: "β€”",
762
  releaseDate: "2026-05-14",
 
770
  params: "79.7M",
771
  blimp: 50.47,
772
  arc: 27.82,
773
+ gci: 49.77,
774
  wiki: 12.42,
775
  tokens: "~21M",
776
  releaseDate: "2026-05-30",
 
784
  params: "87.60M",
785
  blimp: 57.61,
786
  arc: 25,
787
+ gci: 49.50,
788
  wiki: 11.24,
789
  tokens: "~18M",
790
  releaseDate: "2026-05-31",
 
798
  params: "2.62M",
799
  blimp: 60.7,
800
  arc: 31.5,
801
+ gci: 50.42,
802
  wiki: 3.17,
803
  tokens: "β€”",
804
  releaseDate: "2026-05-14",
 
812
  params: "4.23M",
813
  blimp: 62.87,
814
  arc: 27.36,
815
+ gci: 50.99,
816
  wiki: 3.77,
817
  tokens: "~80M",
818
  releaseDate: "2026-05-05",
 
826
  params: "5.03M",
827
  blimp: 54.3,
828
  arc: 26.3,
829
+ gci: 48.40,
830
  wiki: 6.26,
831
  tokens: "~22M",
832
  releaseDate: "2026-06-02",
 
840
  params: "9.96M",
841
  blimp: 47.8,
842
  arc: 31,
843
+ gci: 49.54,
844
  wiki: 5.31,
845
  tokens: "~46.7M",
846
  releaseDate: "2026-06-04",
 
854
  params: "9.96M",
855
  blimp: 69,
856
  arc: 28,
857
+ gci: 50.21,
858
  wiki: 6.72,
859
  tokens: "~10M",
860
  releaseDate: "2026-06-03",
 
868
  params: "12.6M",
869
  blimp: 61.47,
870
  arc: 28.45,
871
+ gci: 49.86,
872
  wiki: 8.76,
873
  tokens: "β€”",
874
  releaseDate: "2026-05-15",
 
882
  params: "7.87M",
883
  blimp: 63.5,
884
  arc: 34.4,
885
+ gci: 52.56,
886
  wiki: 2.73,
887
  tokens: "β€”",
888
  releaseDate: "2026-05-16",
 
896
  params: "9.96M",
897
  blimp: 56.95,
898
  arc: 26.8,
899
+ gci: 50.71,
900
  wiki: 6.73,
901
  tokens: "462M",
902
  releaseDate: "2026-06-01",
 
911
  params: "982K",
912
  blimp: 68.7,
913
  arc: 32.5,
914
+ gci: 52.73,
915
  wiki: 3.08,
916
  tokens: "100B",
917
  releaseDate: "2026-05-13",
 
925
  params: "1.41M",
926
  blimp: 61.86,
927
  arc: 30.26,
928
+ gci: 51.04,
929
  wiki: 3,
930
  tokens: "β€”",
931
  releaseDate: "2026-05-30",
 
939
  params: "5.16M",
940
  blimp: 72.27,
941
  arc: 35.69,
942
+ gci: 53.07,
943
  wiki: 2.57,
944
  tokens: "25B",
945
  releaseDate: "2026-05-19",
 
953
  params: "74M",
954
  blimp: 74.91,
955
  arc: 39.06,
956
+ gci: 52.58,
957
  wiki: 2.2,
958
  tokens: "~1.2B",
959
  releaseDate: "2026-06-01",
 
967
  params: "51.8M",
968
  blimp: 76.3,
969
  arc: 52.2,
970
+ gci: 53.28,
971
  wiki: 2.56,
972
  tokens: "20B",
973
  releaseDate: "2026-05-21",
 
982
  params: "55.7M",
983
  blimp: 74.08,
984
  arc: 37.33,
985
+ gci: 52.90,
986
  wiki: 2.29,
987
  tokens: "1.3B",
988
  releaseDate: "2026-06-05",
 
996
  params: "91.1M",
997
  blimp: 78.35,
998
  arc: 41.5,
999
+ gci: 54.51,
1000
  wiki: 2.07,
1001
  tokens: "6.5B",
1002
  releaseDate: "2026-06-28",
 
1010
  params: "9.94M",
1011
  blimp: 72.52,
1012
  arc: 35.9,
1013
+ gci: 54.25,
1014
  wiki: 2.46,
1015
  tokens: "6.5B",
1016
  releaseDate: "2026-06-13",
 
1024
  params: "5.96M",
1025
  blimp: 65.23,
1026
  arc: 33.38,
1027
+ gci: 54.25,
1028
  wiki: 3.25,
1029
  tokens: "1.1B",
1030
  releaseDate: "2026-06-10",
 
1038
  params: "95M",
1039
  blimp: 80.20,
1040
  arc: 43.18,
1041
+ gci: 53.90,
1042
  wiki: 2.08,
1043
  tokens: "9B",
1044
  releaseDate: "2026-07-06",
 
1052
  params: "28.4M",
1053
  blimp: 69.75,
1054
  arc: 38.59,
1055
+ gci: 53.50,
1056
  wiki: 2.3,
1057
  tokens: "2.6B",
1058
  releaseDate: "2026-06-09",
 
1066
  params: "22.03M",
1067
  blimp: 61.4,
1068
  arc: 30.85,
1069
+ gci: 53.66,
1070
  wiki: 3.14,
1071
  tokens: "~1.57B",
1072
  releaseDate: "2026-06-05",
 
1080
  params: "53.1M",
1081
  blimp: 72.81,
1082
  arc: 30.3,
1083
+ gci: 52.77,
1084
  wiki: 2.38,
1085
  tokens: "1.1B",
1086
  releaseDate: "2026-06-09",
 
1094
  params: "117K",
1095
  blimp: 51.77,
1096
  arc: 26.39,
1097
+ gci: 52.23,
1098
  wiki: 25.17,
1099
  tokens: "500M",
1100
  releaseDate: "2026-05-18",
 
1108
  params: "51.8M",
1109
  blimp: 76.3,
1110
  arc: 46.0,
1111
+ gci: 53.53,
1112
  wiki: 2.04,
1113
  tokens: "20B",
1114
  releaseDate: "2026-05-27",
 
1122
  params: "51.8M",
1123
  blimp: 64.14,
1124
  arc: 45.16,
1125
+ gci: 53.16,
1126
  wiki: 2.6,
1127
  tokens: "20B",
1128
  releaseDate: "2026-06-04",
 
1137
  params: "85.7M",
1138
  blimp: 71.44,
1139
  arc: 38.01,
1140
+ gci: 52.51,
1141
  wiki: 2.2228,
1142
  tokens: "~20B",
1143
  releaseDate: "2026-05-22",
 
1152
  params: "75M",
1153
  blimp: 76.10,
1154
  arc: 35.65,
1155
+ gci: 52.27,
1156
  wiki: 2.08,
1157
  tokens: "~18B",
1158
  releaseDate: "2026-05-29",
 
1167
  params: "75M",
1168
  blimp: 76.02,
1169
  arc: 39.10,
1170
+ gci: 52.26,
1171
  wiki: 2.17,
1172
  tokens: "~18B",
1173
  releaseDate: "2026-05-29",
 
1182
  params: "11.9K",
1183
  blimp: 52.43,
1184
  arc: 25.46,
1185
+ gci: 50.00,
1186
  wiki: 14.73,
1187
  tokens: "500K",
1188
  releaseDate: "2026-06-16",
 
1196
  params: "150M",
1197
  blimp: 72.67,
1198
  arc: 31.40,
1199
+ gci: 50.83,
1200
  wiki: 2.45,
1201
  tokens: "~1.47B",
1202
  releaseDate: "2026-05-05",
 
1210
  params: "86M",
1211
  blimp: 73.56,
1212
  arc: 39.31,
1213
+ gci: 52.42,
1214
  wiki: 2.3753,
1215
  tokens: "β€”",
1216
  releaseDate: "2026-06-18",
 
1225
  params: "86M",
1226
  blimp: 70.33,
1227
  arc: 34.68,
1228
+ gci: 52.16,
1229
  wiki: 2.6839,
1230
  tokens: "β€”",
1231
  releaseDate: "2026-06-18",
 
1267
  params: "34.6M",
1268
  blimp: 64.05,
1269
  arc: 32.79,
1270
+ gci: 54.44,
1271
  wiki: 2.875,
1272
  tokens: "~115~165M",
1273
  releaseDate: "2026-06-25",
 
1281
  params: "34.6M",
1282
  blimp: 64.87,
1283
  arc: 34.13,
1284
+ gci: 54.16,
1285
  wiki: 2.838,
1286
  tokens: "210M",
1287
  releaseDate: "2026-06-28",
 
1295
  params: "125M",
1296
  blimp: 81.28,
1297
  arc: 57.07,
1298
+ gci: 54.53,
1299
  wiki: 1.86,
1300
  tokens: "75B",
1301
  releaseDate: "2026-04-22",
 
1319
  params: "99.8M",
1320
  blimp: 61.13,
1321
  arc: 25.88,
1322
+ gci: 50.66,
1323
  wiki: 3.878,
1324
  tokens: "~625M",
1325
  releaseDate: "2026-06-15",
 
1333
  params: "99.8M",
1334
  blimp: 66.01,
1335
  arc: 33.88,
1336
+ gci: 51.69,
1337
  wiki: 2.879,
1338
  tokens: "β€”",
1339
  releaseDate: "2026-07-05",
 
1360
  params: "500k",
1361
  blimp: 60.61,
1362
  arc: 30.35,
1363
+ gci: 49.58,
1364
  wiki: 4.1228,
1365
  tokens: "300M",
1366
  releaseDate: "2026-07-16",
 
1374
  params: "23.85M",
1375
  blimp: 75.09,
1376
  arc: 39.98,
1377
+ gci: 53.72,
1378
  wiki: 2.2250,
1379
  tokens: "~12.85B",
1380
  releaseDate: "2026-07-07",
 
1389
  params: "51.8M",
1390
  blimp: 67.4,
1391
  arc: 45.9,
1392
+ gci: 53.17,
1393
  wiki: 2.7,
1394
  tokens: "23B",
1395
  releaseDate: "2026-06-12",
 
1404
  params: "0.2M",
1405
  blimp: 51.84,
1406
  arc: 26.77,
1407
+ gci: 49.26,
1408
  wiki: 8.0696,
1409
  tokens: "1.5M",
1410
  releaseDate: "2026-05-15",
 
1603
  const orgs = new Set(models.map(m => m.org));
1604
  const blimps = models.filter(m => m.blimp).map(m => m.blimp);
1605
  const arcs = models.filter(m => m.arc).map(m => m.arc);
1606
+ const gcis = models.filter(m => typeof m.gci === 'number').map(m => m.gci);
1607
  const bestB = Math.max(...blimps);
1608
  const bestA = Math.max(...arcs);
1609
+ const bestG = gcis.length ? Math.max(...gcis) : null;
1610
  document.getElementById('stat-row').innerHTML = `
1611
  <div class="stat-pill"><div class="label">Models</div><div class="value">${models.length}</div><div class="sub">On leaderboard</div></div>
1612
  <div class="stat-pill"><div class="label">Organizations</div><div class="value">${orgs.size}</div><div class="sub">Contributing</div></div>
1613
  <div class="stat-pill"><div class="label">Best BLiMP</div><div class="value" style="color:var(--green)">${bestB}%</div><div class="sub">${models.find(m => m.blimp === bestB).name}</div></div>
1614
  <div class="stat-pill"><div class="label">Best ARC-E</div><div class="value" style="color:var(--green)">${bestA}%</div><div class="sub">${models.find(m => m.arc === bestA).name}</div></div>
1615
+ ${gcis.length ? `<div class="stat-pill"><div class="label">Best GCI</div><div class="value" style="color:var(--green)">${bestG.toFixed(2)}%</div><div class="sub">${models.find(m => m.gci === bestG).name}</div></div>` : ''}
1616
  `;
1617
  document.getElementById('model-count-badge').textContent = `${models.length} models`;
1618
  }
 
1639
  if (b.arc == null) return -1;
1640
  return b.arc - a.arc;
1641
  },
1642
+ gci: (a, b) => {
1643
+ if (typeof a.gci !== 'number') return 1;
1644
+ if (typeof b.gci !== 'number') return -1;
1645
+ return b.gci - a.gci;
1646
+ },
1647
  efficiency: (a, b) => getEfficiencyScore(b) - getEfficiencyScore(a),
1648
  params: (a, b) => parseParams(a.params) - parseParams(b.params),
1649
  date: (a, b) => {
 
1660
  return 'large';
1661
  }
1662
 
1663
+ let searchQuery = '';
1664
+
1665
+ function matchesSearch(m) {
1666
+ if (!searchQuery) return true;
1667
+ const q = searchQuery.toLowerCase();
1668
+ return m.name.toLowerCase().includes(q) || (orgNameMap[m.org] || '').toLowerCase().includes(q);
1669
+ }
1670
+
1671
  function matchesFilter(m) {
1672
  if (activeFilter === 'all') return true;
1673
  if (activeFilter === 'small' || activeFilter === 'medium' || activeFilter === 'large') {
 
1677
  }
1678
 
1679
  function getFilteredModels() {
1680
+ return models.filter(m => matchesFilter(m) && matchesSearch(m));
1681
+ }
1682
+
1683
+ function setupSearch() {
1684
+ const box = document.getElementById('model-search');
1685
+ if (!box) return;
1686
+ box.addEventListener('input', e => {
1687
+ searchQuery = e.target.value.trim();
1688
+ renderFilteredViews();
1689
+ });
1690
  }
1691
 
1692
  function setupSortControl() {
 
1703
  renderTable();
1704
  buildLegend();
1705
  renderTimeline();
1706
+ if (activeView === 'charts') buildMetricChart();
1707
+ if (activeView === 'efficiency') buildEfficiencyChart();
 
 
 
1708
  }
1709
 
1710
  function buildFilters() {
 
1760
  const tbody = document.getElementById('leaderboard-body');
1761
  const cmp = sortComparators[activeSort] || sortComparators.score;
1762
  const filtered = getFilteredModels().sort(cmp);
1763
+ document.getElementById('model-count-badge').textContent =
1764
+ filtered.length === models.length
1765
+ ? `${models.length} models`
1766
+ : `${filtered.length} of ${models.length} models`;
1767
  const blimps = models.filter(m => m.blimp).map(m => m.blimp);
1768
  const arcs = models.filter(m => m.arc).map(m => m.arc);
1769
  const wikis = models.filter(m => m.wiki).map(m => m.wiki);
 
1771
  const bMin = Math.min(...blimps), bMax = Math.max(...blimps);
1772
  const aMin = Math.min(...arcs), aMax = Math.max(...arcs);
1773
  const wMin = Math.min(...wikis), wMax = Math.max(...wikis);
1774
+ const gcis = models.filter(m => typeof m.gci === 'number').map(m => m.gci);
1775
+ const gMin = Math.min(...gcis), gMax = Math.max(...gcis);
1776
  const eMin = Math.min(...effs), eMax = Math.max(...effs);
1777
 
1778
  tbody.innerHTML = filtered.map((m, idx) => {
 
1810
  ? `<span class="metric-val${isBestArc ? ' best' : ''}">${m.arc}%</span>`
1811
  : '<span class="metric-na">TBD</span>'}
1812
  </td>
1813
+ <td class="cell-metric" style="${typeof m.gci === 'number' ? getColor(m.gci, gMin, gMax, false) : ''}">
1814
+ ${typeof m.gci === 'number'
1815
+ ? `<span class="metric-val${m.gci === gMax ? ' best' : ''}">${m.gci.toFixed(2)}%</span>`
1816
+ : '<span class="metric-na">TBD</span>'}
1817
+ </td>
1818
  <td class="cell-tokens">${m.tokens}</td>
1819
  <td class="cell-date">${formatDate(m.releaseDate)}</td>
1820
  <td class="cell-links">
 
1823
  ${m.links.demo ? `<a href="${m.links.demo}" target="_blank">demo</a>` : ''}
1824
  </td>
1825
  </tr>`;
1826
+ }).join('') || `<tr><td colspan="12" class="tl-empty">No model matches that search.</td></tr>`;
1827
  }
1828
 
1829
  /* ─── Legend ─── */
 
1914
 
1915
  /* ─── Bar charts ─── */
1916
 
1917
+ const METRICS = {
1918
+ blimp: { label: 'BLiMP', sub: 'Grammatical acceptability &middot; higher is better', unit: '%', lowerBetter: false },
1919
+ arc: { label: 'ARC-Easy', sub: 'Science QA accuracy &middot; higher is better', unit: '%', lowerBetter: false },
1920
+ gci: { label: 'GCI', sub: 'Glint Clarity Index &middot; share of attention&times;gradient saliency landing on relevant sentences &middot; 50 = no preference over distractors', unit: '%', lowerBetter: false, dot: true, min: 45, max: 56 },
1921
+ wiki: { label: 'WikiText-2', sub: 'Byte-level perplexity &middot; log scale &middot; lower is better &middot; models above 1000 ppl omitted', unit: '', lowerBetter: true, dot: true, cap: 1000 }
1922
+ };
1923
+ let activeMetric = 'blimp';
1924
+
1925
+ function setupMetricSwitch() {
1926
+ const box = document.getElementById('metric-switch');
1927
+ if (!box) return;
1928
+ box.innerHTML = Object.entries(METRICS).map(([k, m]) =>
1929
+ `<button class="metric-chip${k === activeMetric ? ' active' : ''}" data-metric="${k}">${m.label}</button>`
1930
+ ).join('');
1931
+ box.querySelectorAll('.metric-chip').forEach(btn => {
1932
+ btn.addEventListener('click', () => {
1933
+ activeMetric = btn.dataset.metric;
1934
+ setupMetricSwitch();
1935
+ setupTabs();
1936
+ setupSearch();
1937
+ buildMetricChart();
1938
+ });
1939
+ });
1940
+ }
1941
+
1942
+ function buildMetricChart() {
1943
+ const canvas = document.getElementById('metricChart');
1944
+ if (!canvas) return;
1945
  const existing = Chart.getChart(canvas);
1946
  if (existing) existing.destroy();
1947
 
1948
+ const metric = activeMetric;
1949
+ const meta = METRICS[metric];
1950
+ document.getElementById('metric-title').innerHTML = meta.label;
1951
+
1952
  const sorted = getFilteredModels()
1953
+ .filter(d => typeof d[metric] === 'number')
1954
+ .filter(d => (meta.cap === undefined || d[metric] <= meta.cap) &&
1955
+ (meta.min === undefined || d[metric] >= meta.min))
1956
+ .sort((a, b) => meta.lowerBetter ? a[metric] - b[metric] : b[metric] - a[metric]);
1957
+
1958
+ // never drop a model silently: anything outside a zoomed axis is called out
1959
+ const off = getFilteredModels().filter(d => typeof d[metric] === 'number')
1960
+ .filter(d => (meta.min !== undefined && d[metric] < meta.min) ||
1961
+ (meta.cap !== undefined && d[metric] > meta.cap));
1962
+ document.getElementById('metric-sub').innerHTML = meta.sub +
1963
+ (off.length ? ` &middot; off scale: ${off.map(d => `${d.name} (${d[metric]})`).join(', ')}` : '');
1964
+
1965
+ // one row per model, so the labels stay readable however many models there are
1966
+ canvas.parentElement.style.height = Math.max(220, sorted.length * 21 + 46) + 'px';
1967
+
1968
+ const fmt = v => meta.unit === '%' ? v.toFixed(1) + '%' : (v >= 100 ? v.toExponential(2) : v.toFixed(2));
1969
 
1970
  new Chart(canvas, {
1971
  type: 'bar',
1972
  data: {
1973
  labels: sorted.map(d => d.name),
1974
  datasets: [{
1975
+ // a bar from zero is meaningless on a log perplexity axis, so that
1976
+ // metric is drawn as a dot plot instead
1977
+ type: meta.dot ? 'scatter' : 'bar',
1978
+ data: meta.dot
1979
+ ? sorted.map((d, i) => ({ x: d[metric], y: i }))
1980
+ : sorted.map(d => d[metric]),
1981
+ backgroundColor: sorted.map(d => meta.dot ? colorMap[d.org] : bgMap[d.org]),
1982
  borderColor: sorted.map(d => colorMap[d.org]),
1983
  borderWidth: 1,
1984
  borderRadius: 3,
1985
+ borderSkipped: false,
1986
+ pointRadius: 4.5,
1987
+ pointHoverRadius: 6.5,
1988
+ barPercentage: 0.82,
1989
+ categoryPercentage: 0.9
1990
  }]
1991
  },
1992
  options: {
1993
  indexAxis: 'y',
1994
  responsive: true,
1995
  maintainAspectRatio: false,
1996
+ animation: { duration: 450, easing: 'easeOutQuart' },
1997
  plugins: {
1998
  tooltip: {
1999
+ callbacks: {
2000
+ label: ctx => `${fmt(ctx.parsed.x)} Β· ${sorted[ctx.dataIndex].params} params`
2001
+ },
2002
  ...tooltipStyle
2003
  }
2004
  },
2005
  scales: {
2006
  x: {
2007
+ type: meta.lowerBetter ? 'logarithmic' : 'linear',
2008
+ beginAtZero: !meta.lowerBetter && meta.min === undefined,
2009
+ min: meta.min,
2010
+ max: meta.max,
2011
+ grid: { color: 'rgba(48,54,61,0.6)', drawBorder: false },
2012
+ ticks: { color: '#8b949e', callback: v => meta.unit === '%' ? v + '%' : v }
2013
  },
2014
  y: {
2015
+ type: 'category',
2016
  grid: { display: false },
2017
  ticks: {
2018
+ color: '#8b949e',
2019
+ font: { size: 10 },
2020
  autoSkip: false,
2021
  callback: function(v) {
2022
  const l = this.getLabelForValue(v);
2023
+ return l.length > 22 ? l.slice(0, 21) + '…' : l;
2024
  }
2025
  }
2026
  }
 
2029
  });
2030
  }
2031
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2032
  function buildEfficiencyChart() {
2033
  const canvas = document.getElementById('efficiencyChart');
2034
  const existing = Chart.getChart(canvas);
 
2197
 
2198
  /* ─── Org Count ─── */
2199
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2200
  /* ─── Toggle Banner ─── */
2201
 
2202
  function toggleUnknownBanner() {
 
2208
  if (hint) hint.classList.toggle('rotated');
2209
  }
2210
 
2211
+ /* ─── Views ─── */
2212
+
2213
+ let activeView = 'table';
2214
+
2215
+ function setView(view) {
2216
+ activeView = view;
2217
+ document.querySelectorAll('#tabbar .tab').forEach(t =>
2218
+ t.classList.toggle('active', t.dataset.view === view));
2219
+ const map = { table: 'table-section', charts: 'charts-section',
2220
+ timeline: 'timeline-section', efficiency: 'efficiency-section' };
2221
+ Object.entries(map).forEach(([k, id]) => {
2222
+ const el = document.getElementById(id);
2223
+ if (el) el.hidden = k !== view;
2224
+ });
2225
+ // Chart.js can't measure a hidden canvas, so draw on reveal
2226
+ if (view === 'charts') buildMetricChart();
2227
+ if (view === 'efficiency') buildEfficiencyChart();
2228
+ window.scrollTo({ top: 0, behavior: 'smooth' });
2229
+ }
2230
+
2231
+ function setupTabs() {
2232
+ document.querySelectorAll('#tabbar .tab').forEach(t =>
2233
+ t.addEventListener('click', () => setView(t.dataset.view)));
2234
+ }
2235
+
2236
  /* ─── Init ─── */
2237
 
2238
  window.addEventListener('DOMContentLoaded', () => {
2239
  renderStats();
2240
  buildFilters();
2241
  setupSortControl();
2242
+ setupMetricSwitch();
2243
+ setupTabs();
2244
+ setupSearch();
2245
  renderFilteredViews();
2246
  });
2247