Upload 6 files
Browse files- README.md +9 -5
- background.js +90 -0
- index.html +1 -1
- models.json +122 -0
- script.js +376 -0
- style.css +629 -18
README.md
CHANGED
|
@@ -1,10 +1,14 @@
|
|
| 1 |
---
|
| 2 |
-
title:
|
| 3 |
-
emoji:
|
| 4 |
-
colorFrom:
|
| 5 |
-
colorTo:
|
| 6 |
sdk: static
|
| 7 |
pinned: false
|
|
|
|
| 8 |
---
|
| 9 |
|
| 10 |
-
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
---
|
| 2 |
+
title: Leaderboard
|
| 3 |
+
emoji: 🏆
|
| 4 |
+
colorFrom: green
|
| 5 |
+
colorTo: blue
|
| 6 |
sdk: static
|
| 7 |
pinned: false
|
| 8 |
+
license: apache-2.0
|
| 9 |
---
|
| 10 |
|
| 11 |
+
Model performance across Bench Labs' benchmark suite — Effortless, Easy, Mid, and AGI.
|
| 12 |
+
Reads from `models.json`, no backend required.
|
| 13 |
+
|
| 14 |
+
all rights reserved @bench-labs
|
background.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
(() => {
|
| 2 |
+
document.addEventListener("DOMContentLoaded", () => {
|
| 3 |
+
const bg = document.querySelector(".background");
|
| 4 |
+
const isMobile = window.matchMedia("(max-width: 768px)").matches;
|
| 5 |
+
|
| 6 |
+
// ---- Clouds ----
|
| 7 |
+
if (bg && !bg.querySelector(".cloud")) {
|
| 8 |
+
if (!isMobile && !document.getElementById("cloud-fluff")) {
|
| 9 |
+
const defs = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
| 10 |
+
defs.setAttribute("width", "0");
|
| 11 |
+
defs.setAttribute("height", "0");
|
| 12 |
+
defs.setAttribute("aria-hidden", "true");
|
| 13 |
+
defs.style.position = "absolute";
|
| 14 |
+
defs.innerHTML =
|
| 15 |
+
'<filter id="cloud-fluff" x="-150%" y="-150%" width="400%" height="400%">' +
|
| 16 |
+
'<feTurbulence type="fractalNoise" baseFrequency="0.012 0.02" numOctaves="4" seed="11" result="noise"/>' +
|
| 17 |
+
'<feDisplacementMap in="SourceGraphic" in2="noise" scale="120"/>' +
|
| 18 |
+
"</filter>";
|
| 19 |
+
document.body.appendChild(defs);
|
| 20 |
+
}
|
| 21 |
+
const cloudCount = isMobile ? 2 : 4;
|
| 22 |
+
for (let i = 1; i <= cloudCount; i++) {
|
| 23 |
+
const cloud = document.createElement("div");
|
| 24 |
+
cloud.className = "cloud cloud-" + i + (isMobile ? " cloud-simple" : "");
|
| 25 |
+
cloud.setAttribute("aria-hidden", "true");
|
| 26 |
+
bg.appendChild(cloud);
|
| 27 |
+
}
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
// ---- Grass strip ----
|
| 31 |
+
if (!document.querySelector(".grass")) {
|
| 32 |
+
const NS = "http://www.w3.org/2000/svg";
|
| 33 |
+
const W = isMobile ? 1200 : 2400;
|
| 34 |
+
const H = 70;
|
| 35 |
+
const svg = document.createElementNS(NS, "svg");
|
| 36 |
+
svg.setAttribute("class", "grass");
|
| 37 |
+
svg.setAttribute("viewBox", "0 0 " + W + " " + H);
|
| 38 |
+
svg.setAttribute("preserveAspectRatio", "xMidYMax slice");
|
| 39 |
+
svg.setAttribute("aria-hidden", "true");
|
| 40 |
+
|
| 41 |
+
svg.innerHTML =
|
| 42 |
+
'<defs><linearGradient id="grass-base" x1="0" y1="1" x2="0" y2="0">' +
|
| 43 |
+
'<stop offset="0" stop-color="#3e7a46" stop-opacity="0.55"/>' +
|
| 44 |
+
'<stop offset="1" stop-color="#3e7a46" stop-opacity="0"/>' +
|
| 45 |
+
"</linearGradient></defs>" +
|
| 46 |
+
'<rect x="0" y="' + (H - 16) + '" width="' + W + '" height="16" fill="url(#grass-base)"/>';
|
| 47 |
+
|
| 48 |
+
const layers = isMobile
|
| 49 |
+
? [
|
| 50 |
+
{ count: 50, hMin: 18, hMax: 32, colors: ["#4f9854"], opacity: 0.9 },
|
| 51 |
+
{ count: 40, hMin: 24, hMax: 42, colors: ["#63ad64"], opacity: 1 },
|
| 52 |
+
]
|
| 53 |
+
: [
|
| 54 |
+
{ count: 190, hMin: 18, hMax: 36, colors: ["#3e7a46", "#457f4b", "#4a8a50"], opacity: 0.8 },
|
| 55 |
+
{ count: 160, hMin: 26, hMax: 52, colors: ["#4f9854", "#57a05a", "#63ad64", "#6db36e"], opacity: 1 },
|
| 56 |
+
];
|
| 57 |
+
|
| 58 |
+
layers.forEach((layer) => {
|
| 59 |
+
const g = document.createElementNS(NS, "g");
|
| 60 |
+
g.setAttribute("opacity", layer.opacity);
|
| 61 |
+
for (let i = 0; i < layer.count; i++) {
|
| 62 |
+
const x = Math.random() * W;
|
| 63 |
+
const h = layer.hMin + Math.random() * (layer.hMax - layer.hMin);
|
| 64 |
+
const lean = (Math.random() - 0.5) * 16;
|
| 65 |
+
const w = 3 + Math.random() * 3;
|
| 66 |
+
const color = layer.colors[(Math.random() * layer.colors.length) | 0];
|
| 67 |
+
const blade = document.createElementNS(NS, "path");
|
| 68 |
+
blade.setAttribute(
|
| 69 |
+
"d",
|
| 70 |
+
"M " + x + " " + H +
|
| 71 |
+
" Q " + (x + lean * 0.2) + " " + (H - h * 0.6) + " " + (x + lean) + " " + (H - h) +
|
| 72 |
+
" Q " + (x + lean * 0.6 + w * 0.5) + " " + (H - h * 0.55) + " " + (x + w) + " " + H + " Z"
|
| 73 |
+
);
|
| 74 |
+
blade.setAttribute("fill", color);
|
| 75 |
+
blade.style.transformBox = "fill-box";
|
| 76 |
+
blade.style.transformOrigin = "50% 100%";
|
| 77 |
+
if (!isMobile) {
|
| 78 |
+
blade.style.animation =
|
| 79 |
+
"blade-sway " + (2.6 + Math.random() * 2.4).toFixed(2) + "s ease-in-out " +
|
| 80 |
+
(-(x / W) * 3 - Math.random()).toFixed(2) + "s infinite alternate";
|
| 81 |
+
}
|
| 82 |
+
g.appendChild(blade);
|
| 83 |
+
}
|
| 84 |
+
svg.appendChild(g);
|
| 85 |
+
});
|
| 86 |
+
|
| 87 |
+
document.body.appendChild(svg);
|
| 88 |
+
}
|
| 89 |
+
});
|
| 90 |
+
})();
|
index.html
CHANGED
|
@@ -99,4 +99,4 @@
|
|
| 99 |
|
| 100 |
<script src="script.js" defer></script>
|
| 101 |
</body>
|
| 102 |
-
</html>
|
|
|
|
| 99 |
|
| 100 |
<script src="script.js" defer></script>
|
| 101 |
</body>
|
| 102 |
+
</html>
|
models.json
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"updated": "2026-07-18",
|
| 3 |
+
"benchmarks": [
|
| 4 |
+
{
|
| 5 |
+
"id": "bench-effortless-6-2026",
|
| 6 |
+
"label": "Effortless",
|
| 7 |
+
"tier": 1,
|
| 8 |
+
"rows": 240,
|
| 9 |
+
"metric": "exact_match",
|
| 10 |
+
"dataset_url": "https://huggingface.co/datasets/bench-labs/bench-effortless-6-2026",
|
| 11 |
+
"description": "Sanity-layer benchmark. No ambiguity, no trick questions — tests whether a model can avoid failing on simple tasks."
|
| 12 |
+
},
|
| 13 |
+
{
|
| 14 |
+
"id": "bench-easy-6-2026",
|
| 15 |
+
"label": "Easy",
|
| 16 |
+
"tier": 2,
|
| 17 |
+
"rows": 300,
|
| 18 |
+
"metric": "exact_match",
|
| 19 |
+
"dataset_url": "https://huggingface.co/datasets/bench-labs/bench-easy-6-2026",
|
| 20 |
+
"description": "Effortless-to-Easy tier QA. Structured language understanding and controlled generalization."
|
| 21 |
+
},
|
| 22 |
+
{
|
| 23 |
+
"id": "bench-mid-6-2026",
|
| 24 |
+
"label": "Mid",
|
| 25 |
+
"tier": 3,
|
| 26 |
+
"rows": 155,
|
| 27 |
+
"metric": "acc_norm",
|
| 28 |
+
"dataset_url": "https://huggingface.co/datasets/bench-labs/bench-mid-6-2026",
|
| 29 |
+
"description": "Easy-to-Mid tier multiple-choice QA scored via lm-eval loglikelihood, target_scores dict."
|
| 30 |
+
},
|
| 31 |
+
{
|
| 32 |
+
"id": "bench-AGI",
|
| 33 |
+
"label": "AGI",
|
| 34 |
+
"tier": 4,
|
| 35 |
+
"rows": null,
|
| 36 |
+
"metric": "rank_order",
|
| 37 |
+
"dataset_url": "https://huggingface.co/datasets/bench-labs/bench-AGI",
|
| 38 |
+
"description": "Hard, open-ended questions with human-argued reasoning traces, graded blind by a multi-vendor panel. Rank-order evaluation, not absolute scoring."
|
| 39 |
+
}
|
| 40 |
+
],
|
| 41 |
+
"categories": [
|
| 42 |
+
"Knowledge-basic", "Knowledge-definitions",
|
| 43 |
+
"Math-arithmetic", "Math-pattern", "Math-reasoning",
|
| 44 |
+
"Logic-deduction", "Logic-pattern", "Logic-consistency",
|
| 45 |
+
"Language-comprehension", "Language-transformation", "Language-structure",
|
| 46 |
+
"Commonsense-reasoning", "Commonsense-causality", "Commonsense-simulation",
|
| 47 |
+
"Pattern-matching", "Pattern-recognition", "Pattern-generation"
|
| 48 |
+
],
|
| 49 |
+
"models": [
|
| 50 |
+
{
|
| 51 |
+
"id": "qwen2.5-0.5b",
|
| 52 |
+
"name": "Qwen/Qwen2.5-0.5B",
|
| 53 |
+
"org": "Qwen",
|
| 54 |
+
"params_b": 0.5,
|
| 55 |
+
"url": "https://huggingface.co/Qwen/Qwen2.5-0.5B",
|
| 56 |
+
"eval_source": "https://huggingface.co/spaces/bench-labs/blog?post=bMid-qwen0-5.html",
|
| 57 |
+
"runs": {
|
| 58 |
+
"bench-effortless-6-2026": {
|
| 59 |
+
"score": 0.612,
|
| 60 |
+
"n": 240,
|
| 61 |
+
"notes": "Exact-match, normalized. Extrapolated from Mid-tier category profile."
|
| 62 |
+
},
|
| 63 |
+
"bench-easy-6-2026": {
|
| 64 |
+
"score": 0.547,
|
| 65 |
+
"n": 300,
|
| 66 |
+
"notes": "Exact-match, normalized."
|
| 67 |
+
},
|
| 68 |
+
"bench-mid-6-2026": {
|
| 69 |
+
"score": 0.6103,
|
| 70 |
+
"n": 155,
|
| 71 |
+
"acc": 0.5806,
|
| 72 |
+
"acc_norm": 0.6000,
|
| 73 |
+
"soft_score": 0.5871,
|
| 74 |
+
"soft_score_norm": 0.6103,
|
| 75 |
+
"stderr": 0.0388,
|
| 76 |
+
"categories": {
|
| 77 |
+
"Commonsense-causality": { "n": 5, "acc": 1.000, "acc_norm": 1.000 },
|
| 78 |
+
"Commonsense-reasoning": { "n": 10, "acc": 0.700, "acc_norm": 0.600 },
|
| 79 |
+
"Commonsense-simulation": { "n": 10, "acc": 0.300, "acc_norm": 0.500 },
|
| 80 |
+
"Knowledge-basic": { "n": 8, "acc": 1.000, "acc_norm": 1.000 },
|
| 81 |
+
"Knowledge-definitions": { "n": 10, "acc": 0.700, "acc_norm": 0.900 },
|
| 82 |
+
"Language-comprehension": { "n": 10, "acc": 0.600, "acc_norm": 0.800 },
|
| 83 |
+
"Language-structure": { "n": 10, "acc": 0.000, "acc_norm": 0.100 },
|
| 84 |
+
"Language-transformation": { "n": 10, "acc": 0.500, "acc_norm": 0.600 },
|
| 85 |
+
"Logic-consistency": { "n": 5, "acc": 0.200, "acc_norm": 0.200 },
|
| 86 |
+
"Logic-deduction": { "n": 10, "acc": 0.500, "acc_norm": 0.500 },
|
| 87 |
+
"Logic-pattern": { "n": 10, "acc": 0.400, "acc_norm": 0.400 },
|
| 88 |
+
"Math-arithmetic": { "n": 8, "acc": 0.625, "acc_norm": 0.625 },
|
| 89 |
+
"Math-pattern": { "n": 10, "acc": 0.800, "acc_norm": 0.800 },
|
| 90 |
+
"Math-reasoning": { "n": 10, "acc": 0.600, "acc_norm": 0.500 },
|
| 91 |
+
"Pattern-generation": { "n": 9, "acc": 0.778, "acc_norm": 0.667 },
|
| 92 |
+
"Pattern-matching": { "n": 10, "acc": 1.000, "acc_norm": 0.800 },
|
| 93 |
+
"Pattern-recognition": { "n": 10, "acc": 0.300, "acc_norm": 0.300 }
|
| 94 |
+
}
|
| 95 |
+
},
|
| 96 |
+
"bench-AGI": { "score": null, "n": null, "notes": "Not yet evaluated on this tier." }
|
| 97 |
+
}
|
| 98 |
+
},
|
| 99 |
+
{
|
| 100 |
+
"id": "qwen2.5-1.5b-instruct",
|
| 101 |
+
"name": "Qwen/Qwen2.5-1.5B-Instruct",
|
| 102 |
+
"org": "Qwen",
|
| 103 |
+
"params_b": 1.5,
|
| 104 |
+
"url": "https://huggingface.co/Qwen/Qwen2.5-1.5B-Instruct",
|
| 105 |
+
"eval_source": "https://huggingface.co/spaces/bench-labs/blog?post=evaluatingllm.html",
|
| 106 |
+
"runs": {
|
| 107 |
+
"bench-effortless-6-2026": {
|
| 108 |
+
"score": 0.783,
|
| 109 |
+
"n": 240,
|
| 110 |
+
"notes": "Strong on commonsense & language transformation; weak on symbolic logic per the hybrid evaluator writeup."
|
| 111 |
+
},
|
| 112 |
+
"bench-easy-6-2026": {
|
| 113 |
+
"score": 0.741,
|
| 114 |
+
"n": 300,
|
| 115 |
+
"notes": "Hybrid category-aware scoring (strict / flexible / semantic)."
|
| 116 |
+
},
|
| 117 |
+
"bench-mid-6-2026": { "score": null, "n": null, "notes": "Not yet evaluated on this tier." },
|
| 118 |
+
"bench-AGI": { "score": null, "n": null, "notes": "Not yet evaluated on this tier." }
|
| 119 |
+
}
|
| 120 |
+
}
|
| 121 |
+
]
|
| 122 |
+
}
|
script.js
ADDED
|
@@ -0,0 +1,376 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
(() => {
|
| 2 |
+
"use strict";
|
| 3 |
+
|
| 4 |
+
const state = {
|
| 5 |
+
data: null,
|
| 6 |
+
activeBenchmark: null,
|
| 7 |
+
search: "",
|
| 8 |
+
sort: "score-desc",
|
| 9 |
+
};
|
| 10 |
+
|
| 11 |
+
const els = {};
|
| 12 |
+
|
| 13 |
+
document.addEventListener("DOMContentLoaded", init);
|
| 14 |
+
|
| 15 |
+
async function init() {
|
| 16 |
+
els.tierStrip = document.getElementById("tier-strip");
|
| 17 |
+
els.metricSelect = document.getElementById("metric-select");
|
| 18 |
+
els.sortSelect = document.getElementById("sort-select");
|
| 19 |
+
els.searchInput = document.getElementById("model-search");
|
| 20 |
+
els.tbody = document.getElementById("leaderboard-body");
|
| 21 |
+
els.emptyState = document.getElementById("empty-state");
|
| 22 |
+
els.table = document.getElementById("leaderboard-table");
|
| 23 |
+
els.detailPanel = document.getElementById("detail-panel");
|
| 24 |
+
els.detailTitle = document.getElementById("detail-title");
|
| 25 |
+
els.detailSubtitle = document.getElementById("detail-subtitle");
|
| 26 |
+
els.detailCats = document.getElementById("detail-cats");
|
| 27 |
+
els.detailClose = document.getElementById("detail-close");
|
| 28 |
+
|
| 29 |
+
try {
|
| 30 |
+
const res = await fetch("models.json", { cache: "no-store" });
|
| 31 |
+
if (!res.ok) throw new Error("HTTP " + res.status);
|
| 32 |
+
state.data = await res.json();
|
| 33 |
+
} catch (err) {
|
| 34 |
+
renderLoadError(err);
|
| 35 |
+
return;
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
state.activeBenchmark = state.data.benchmarks[0]?.id || null;
|
| 39 |
+
|
| 40 |
+
buildTierStrip();
|
| 41 |
+
buildMetricSelect();
|
| 42 |
+
bindControls();
|
| 43 |
+
render();
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
function renderLoadError(err) {
|
| 47 |
+
els.tbody = document.getElementById("leaderboard-body");
|
| 48 |
+
els.tbody.innerHTML =
|
| 49 |
+
'<tr><td colspan="4" style="padding:32px;text-align:center;color:var(--muted);">' +
|
| 50 |
+
"Couldn't load <code>models.json</code> (" + escapeHtml(String(err.message || err)) +
|
| 51 |
+
"). Make sure it sits next to index.html." +
|
| 52 |
+
"</td></tr>";
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
// -------------------- TIER STRIP --------------------
|
| 56 |
+
|
| 57 |
+
function buildTierStrip() {
|
| 58 |
+
const frag = document.createDocumentFragment();
|
| 59 |
+
state.data.benchmarks
|
| 60 |
+
.slice()
|
| 61 |
+
.sort((a, b) => a.tier - b.tier)
|
| 62 |
+
.forEach((bench) => {
|
| 63 |
+
const card = document.createElement("button");
|
| 64 |
+
card.type = "button";
|
| 65 |
+
card.className = "tier-card" + (bench.id === state.activeBenchmark ? " active" : "");
|
| 66 |
+
card.dataset.benchmarkId = bench.id;
|
| 67 |
+
|
| 68 |
+
const rowsLabel = bench.rows != null ? bench.rows + " rows" : "open-ended";
|
| 69 |
+
|
| 70 |
+
card.innerHTML =
|
| 71 |
+
'<span class="tier-num">Tier ' + bench.tier + " · " + escapeHtml(bench.label) + "</span>" +
|
| 72 |
+
"<h3>" + escapeHtml(bench.id) + "</h3>" +
|
| 73 |
+
"<p>" + escapeHtml(bench.description) + "</p>" +
|
| 74 |
+
'<div class="tier-meta">' +
|
| 75 |
+
"<span>" + rowsLabel + "</span>" +
|
| 76 |
+
"<span>" + escapeHtml(bench.metric) + "</span>" +
|
| 77 |
+
"</div>";
|
| 78 |
+
|
| 79 |
+
card.addEventListener("click", () => {
|
| 80 |
+
state.activeBenchmark = bench.id;
|
| 81 |
+
closeDetail();
|
| 82 |
+
buildTierStrip();
|
| 83 |
+
buildMetricSelect();
|
| 84 |
+
render();
|
| 85 |
+
});
|
| 86 |
+
|
| 87 |
+
frag.appendChild(card);
|
| 88 |
+
});
|
| 89 |
+
|
| 90 |
+
els.tierStrip.innerHTML = "";
|
| 91 |
+
els.tierStrip.appendChild(frag);
|
| 92 |
+
}
|
| 93 |
+
|
| 94 |
+
// -------------------- METRIC SELECT --------------------
|
| 95 |
+
|
| 96 |
+
function buildMetricSelect() {
|
| 97 |
+
const bench = getActiveBenchmark();
|
| 98 |
+
if (!bench) return;
|
| 99 |
+
|
| 100 |
+
// Collect every metric key present across model runs for this benchmark,
|
| 101 |
+
// beyond the headline "score", so users can pivot (acc vs acc_norm etc).
|
| 102 |
+
const keys = new Set(["score"]);
|
| 103 |
+
state.data.models.forEach((m) => {
|
| 104 |
+
const run = m.runs?.[bench.id];
|
| 105 |
+
if (!run) return;
|
| 106 |
+
Object.keys(run).forEach((k) => {
|
| 107 |
+
if (typeof run[k] === "number" && k !== "n" && k !== "stderr") keys.add(k);
|
| 108 |
+
});
|
| 109 |
+
});
|
| 110 |
+
|
| 111 |
+
const labels = {
|
| 112 |
+
score: "Headline score",
|
| 113 |
+
acc: "acc",
|
| 114 |
+
acc_norm: "acc_norm",
|
| 115 |
+
soft_score: "soft_score",
|
| 116 |
+
soft_score_norm: "soft_score_norm",
|
| 117 |
+
stderr: "stderr",
|
| 118 |
+
};
|
| 119 |
+
|
| 120 |
+
const prev = els.metricSelect.value;
|
| 121 |
+
els.metricSelect.innerHTML = "";
|
| 122 |
+
Array.from(keys).forEach((k) => {
|
| 123 |
+
const opt = document.createElement("option");
|
| 124 |
+
opt.value = k;
|
| 125 |
+
opt.textContent = labels[k] || k;
|
| 126 |
+
els.metricSelect.appendChild(opt);
|
| 127 |
+
});
|
| 128 |
+
if (keys.has(prev)) els.metricSelect.value = prev;
|
| 129 |
+
}
|
| 130 |
+
|
| 131 |
+
// -------------------- CONTROLS --------------------
|
| 132 |
+
|
| 133 |
+
function bindControls() {
|
| 134 |
+
els.searchInput.addEventListener("input", (e) => {
|
| 135 |
+
state.search = e.target.value.trim().toLowerCase();
|
| 136 |
+
render();
|
| 137 |
+
});
|
| 138 |
+
|
| 139 |
+
els.sortSelect.addEventListener("change", (e) => {
|
| 140 |
+
state.sort = e.target.value;
|
| 141 |
+
render();
|
| 142 |
+
});
|
| 143 |
+
|
| 144 |
+
els.metricSelect.addEventListener("change", render);
|
| 145 |
+
|
| 146 |
+
els.table.querySelectorAll("thead th[data-key]").forEach((th) => {
|
| 147 |
+
th.addEventListener("click", () => {
|
| 148 |
+
const key = th.dataset.key;
|
| 149 |
+
if (key === "score") {
|
| 150 |
+
state.sort = state.sort === "score-desc" ? "score-asc" : "score-desc";
|
| 151 |
+
} else if (key === "params") {
|
| 152 |
+
state.sort = state.sort === "params-asc" ? "params-desc" : "params-asc";
|
| 153 |
+
} else if (key === "name") {
|
| 154 |
+
state.sort = "name-asc";
|
| 155 |
+
}
|
| 156 |
+
els.sortSelect.value = state.sort;
|
| 157 |
+
render();
|
| 158 |
+
});
|
| 159 |
+
});
|
| 160 |
+
|
| 161 |
+
els.detailClose.addEventListener("click", closeDetail);
|
| 162 |
+
}
|
| 163 |
+
|
| 164 |
+
// -------------------- HELPERS --------------------
|
| 165 |
+
|
| 166 |
+
function getActiveBenchmark() {
|
| 167 |
+
return state.data.benchmarks.find((b) => b.id === state.activeBenchmark) || null;
|
| 168 |
+
}
|
| 169 |
+
|
| 170 |
+
function getMetricValue(run, metricKey) {
|
| 171 |
+
if (!run) return null;
|
| 172 |
+
const v = run[metricKey];
|
| 173 |
+
return typeof v === "number" ? v : null;
|
| 174 |
+
}
|
| 175 |
+
|
| 176 |
+
function scoreClass(v) {
|
| 177 |
+
if (v == null) return "";
|
| 178 |
+
if (v >= 0.66) return "good";
|
| 179 |
+
if (v >= 0.4) return "ok";
|
| 180 |
+
return "bad";
|
| 181 |
+
}
|
| 182 |
+
|
| 183 |
+
function fmtScore(v) {
|
| 184 |
+
if (v == null) return null;
|
| 185 |
+
return (v * 100).toFixed(1) + "%";
|
| 186 |
+
}
|
| 187 |
+
|
| 188 |
+
function escapeHtml(s) {
|
| 189 |
+
return String(s)
|
| 190 |
+
.replace(/&/g, "&")
|
| 191 |
+
.replace(/</g, "<")
|
| 192 |
+
.replace(/>/g, ">")
|
| 193 |
+
.replace(/"/g, """);
|
| 194 |
+
}
|
| 195 |
+
|
| 196 |
+
// -------------------- RENDER TABLE --------------------
|
| 197 |
+
|
| 198 |
+
function render() {
|
| 199 |
+
const bench = getActiveBenchmark();
|
| 200 |
+
if (!bench) return;
|
| 201 |
+
|
| 202 |
+
const metricKey = els.metricSelect.value || "score";
|
| 203 |
+
|
| 204 |
+
let rows = state.data.models.map((m) => {
|
| 205 |
+
const run = m.runs?.[bench.id] || null;
|
| 206 |
+
const value = getMetricValue(run, metricKey);
|
| 207 |
+
return { model: m, run, value };
|
| 208 |
+
});
|
| 209 |
+
|
| 210 |
+
if (state.search) {
|
| 211 |
+
rows = rows.filter(
|
| 212 |
+
(r) =>
|
| 213 |
+
r.model.name.toLowerCase().includes(state.search) ||
|
| 214 |
+
(r.model.org || "").toLowerCase().includes(state.search)
|
| 215 |
+
);
|
| 216 |
+
}
|
| 217 |
+
|
| 218 |
+
rows = sortRows(rows, state.sort);
|
| 219 |
+
|
| 220 |
+
els.tbody.innerHTML = "";
|
| 221 |
+
if (rows.length === 0) {
|
| 222 |
+
els.emptyState.hidden = false;
|
| 223 |
+
els.table.hidden = true;
|
| 224 |
+
return;
|
| 225 |
+
}
|
| 226 |
+
els.emptyState.hidden = true;
|
| 227 |
+
els.table.hidden = false;
|
| 228 |
+
|
| 229 |
+
const frag = document.createDocumentFragment();
|
| 230 |
+
rows.forEach((r, idx) => {
|
| 231 |
+
frag.appendChild(buildRow(r, idx + 1, bench));
|
| 232 |
+
});
|
| 233 |
+
els.tbody.appendChild(frag);
|
| 234 |
+
|
| 235 |
+
updateSortIndicators();
|
| 236 |
+
}
|
| 237 |
+
|
| 238 |
+
function sortRows(rows, sort) {
|
| 239 |
+
const withScore = (r) => (r.value == null ? -Infinity : r.value);
|
| 240 |
+
const withParams = (r) => (r.model.params_b == null ? Infinity : r.model.params_b);
|
| 241 |
+
|
| 242 |
+
switch (sort) {
|
| 243 |
+
case "score-asc":
|
| 244 |
+
return rows.slice().sort((a, b) => {
|
| 245 |
+
if (a.value == null && b.value == null) return 0;
|
| 246 |
+
if (a.value == null) return 1;
|
| 247 |
+
if (b.value == null) return 1;
|
| 248 |
+
return a.value - b.value;
|
| 249 |
+
});
|
| 250 |
+
case "params-asc":
|
| 251 |
+
return rows.slice().sort((a, b) => withParams(a) - withParams(b));
|
| 252 |
+
case "params-desc":
|
| 253 |
+
return rows.slice().sort((a, b) => withParams(b) - withParams(a));
|
| 254 |
+
case "name-asc":
|
| 255 |
+
return rows.slice().sort((a, b) => a.model.name.localeCompare(b.model.name));
|
| 256 |
+
case "score-desc":
|
| 257 |
+
default:
|
| 258 |
+
return rows.slice().sort((a, b) => {
|
| 259 |
+
if (a.value == null && b.value == null) return 0;
|
| 260 |
+
if (a.value == null) return 1;
|
| 261 |
+
if (b.value == null) return -1;
|
| 262 |
+
return b.value - a.value;
|
| 263 |
+
});
|
| 264 |
+
}
|
| 265 |
+
}
|
| 266 |
+
|
| 267 |
+
function updateSortIndicators() {
|
| 268 |
+
els.table.querySelectorAll("thead th[data-key]").forEach((th) => {
|
| 269 |
+
th.classList.remove("sorted");
|
| 270 |
+
const arrow = th.querySelector(".sort-arrow");
|
| 271 |
+
if (!arrow) return;
|
| 272 |
+
const key = th.dataset.key;
|
| 273 |
+
const active =
|
| 274 |
+
(key === "score" && (state.sort === "score-desc" || state.sort === "score-asc")) ||
|
| 275 |
+
(key === "params" && (state.sort === "params-asc" || state.sort === "params-desc")) ||
|
| 276 |
+
(key === "name" && state.sort === "name-asc");
|
| 277 |
+
if (active) {
|
| 278 |
+
th.classList.add("sorted");
|
| 279 |
+
arrow.textContent = state.sort.endsWith("asc") ? "▲" : "▼";
|
| 280 |
+
}
|
| 281 |
+
});
|
| 282 |
+
}
|
| 283 |
+
|
| 284 |
+
function buildRow(r, rank, bench) {
|
| 285 |
+
const tr = document.createElement("tr");
|
| 286 |
+
const { model, run, value } = r;
|
| 287 |
+
|
| 288 |
+
// rank
|
| 289 |
+
const rankTd = document.createElement("td");
|
| 290 |
+
rankTd.className = "rank-cell" + (rank <= 3 ? " top-" + rank : "");
|
| 291 |
+
rankTd.textContent = value == null ? "–" : String(rank);
|
| 292 |
+
tr.appendChild(rankTd);
|
| 293 |
+
|
| 294 |
+
// model
|
| 295 |
+
const modelTd = document.createElement("td");
|
| 296 |
+
modelTd.innerHTML =
|
| 297 |
+
'<div class="model-cell">' +
|
| 298 |
+
'<span class="model-name"><a href="' + escapeHtml(model.url) + '" target="_blank" rel="noopener">' +
|
| 299 |
+
escapeHtml(model.name) + "</a></span>" +
|
| 300 |
+
'<span class="model-org">' + escapeHtml(model.org || "") + "</span>" +
|
| 301 |
+
"</div>";
|
| 302 |
+
tr.appendChild(modelTd);
|
| 303 |
+
|
| 304 |
+
// params
|
| 305 |
+
const paramsTd = document.createElement("td");
|
| 306 |
+
paramsTd.className = "params-cell";
|
| 307 |
+
paramsTd.textContent = model.params_b != null ? model.params_b + "B" : "—";
|
| 308 |
+
tr.appendChild(paramsTd);
|
| 309 |
+
|
| 310 |
+
// score
|
| 311 |
+
const scoreTd = document.createElement("td");
|
| 312 |
+
scoreTd.className = "score-cell";
|
| 313 |
+
if (value == null) {
|
| 314 |
+
scoreTd.innerHTML = '<span class="score-na">not evaluated</span>';
|
| 315 |
+
} else {
|
| 316 |
+
const pct = Math.max(0, Math.min(100, value * 100));
|
| 317 |
+
const cls = scoreClass(value);
|
| 318 |
+
scoreTd.innerHTML =
|
| 319 |
+
'<span class="score-pill">' +
|
| 320 |
+
'<span class="score-num ' + cls + '">' + fmtScore(value) + "</span>" +
|
| 321 |
+
'<span class="score-bar-track"><span class="score-bar-fill" style="width:' + pct.toFixed(1) + '%"></span></span>' +
|
| 322 |
+
"</span>";
|
| 323 |
+
}
|
| 324 |
+
tr.appendChild(scoreTd);
|
| 325 |
+
|
| 326 |
+
if (run && run.categories) {
|
| 327 |
+
tr.style.cursor = "pointer";
|
| 328 |
+
tr.title = "Click for per-category breakdown";
|
| 329 |
+
tr.addEventListener("click", () => openDetail(model, run, bench));
|
| 330 |
+
}
|
| 331 |
+
|
| 332 |
+
return tr;
|
| 333 |
+
}
|
| 334 |
+
|
| 335 |
+
// -------------------- DETAIL PANEL --------------------
|
| 336 |
+
|
| 337 |
+
function openDetail(model, run, bench) {
|
| 338 |
+
els.detailTitle.textContent = model.name + " on " + bench.id;
|
| 339 |
+
els.detailSubtitle.textContent =
|
| 340 |
+
"Per-category breakdown" + (run.n ? " · n=" + run.n : "") +
|
| 341 |
+
(run.stderr != null ? " · stderr " + run.stderr : "");
|
| 342 |
+
|
| 343 |
+
const cats = run.categories || {};
|
| 344 |
+
const frag = document.createDocumentFragment();
|
| 345 |
+
Object.keys(cats)
|
| 346 |
+
.sort()
|
| 347 |
+
.forEach((catName) => {
|
| 348 |
+
const c = cats[catName];
|
| 349 |
+
const v = typeof c.acc_norm === "number" ? c.acc_norm : c.acc;
|
| 350 |
+
const pct = Math.max(0, Math.min(100, (v || 0) * 100));
|
| 351 |
+
const cls = scoreClass(v);
|
| 352 |
+
const color =
|
| 353 |
+
cls === "good" ? "var(--score-good)" : cls === "ok" ? "var(--score-ok)" : "var(--score-bad)";
|
| 354 |
+
|
| 355 |
+
const row = document.createElement("div");
|
| 356 |
+
row.className = "cat-row";
|
| 357 |
+
row.innerHTML =
|
| 358 |
+
'<div class="cat-row-top">' +
|
| 359 |
+
'<span class="cat-name">' + escapeHtml(catName) + "</span>" +
|
| 360 |
+
'<span class="cat-score" style="color:' + color + '">' + fmtScore(v) + "</span>" +
|
| 361 |
+
"</div>" +
|
| 362 |
+
'<div class="cat-bar-track"><div class="cat-bar-fill" style="width:' + pct.toFixed(1) + "%;background:" + color + ';"></div></div>' +
|
| 363 |
+
'<div class="cat-n">n=' + c.n + "</div>";
|
| 364 |
+
frag.appendChild(row);
|
| 365 |
+
});
|
| 366 |
+
|
| 367 |
+
els.detailCats.innerHTML = "";
|
| 368 |
+
els.detailCats.appendChild(frag);
|
| 369 |
+
els.detailPanel.classList.add("open");
|
| 370 |
+
els.detailPanel.scrollIntoView({ behavior: "smooth", block: "nearest" });
|
| 371 |
+
}
|
| 372 |
+
|
| 373 |
+
function closeDetail() {
|
| 374 |
+
els.detailPanel.classList.remove("open");
|
| 375 |
+
}
|
| 376 |
+
})();
|
style.css
CHANGED
|
@@ -1,28 +1,639 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
body {
|
| 2 |
-
|
| 3 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4 |
}
|
| 5 |
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9 |
}
|
| 10 |
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
margin-bottom: 10px;
|
| 15 |
-
margin-top: 5px;
|
| 16 |
}
|
| 17 |
|
| 18 |
-
.
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
}
|
| 25 |
|
| 26 |
-
.
|
| 27 |
-
|
|
|
|
|
|
|
| 28 |
}
|
|
|
|
| 1 |
+
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap');
|
| 2 |
+
@import url('https://fonts.googleapis.com/css2?family=Newsreader:ital,wght@1,400;1,600&display=swap');
|
| 3 |
+
|
| 4 |
+
:root {
|
| 5 |
+
--bg: #eaf5ee;
|
| 6 |
+
--text: #2d3e50;
|
| 7 |
+
--heading: #1a2b3c;
|
| 8 |
+
--muted: #6b7f92;
|
| 9 |
+
--surface: rgba(255,255,255,0.55);
|
| 10 |
+
--surface-2: rgba(255,255,255,0.75);
|
| 11 |
+
--border: rgba(255,255,255,0.7);
|
| 12 |
+
--border-soft: rgba(120, 160, 200, 0.18);
|
| 13 |
+
--accent: #4a90c2;
|
| 14 |
+
--accent-soft: #7cb8e0;
|
| 15 |
+
--accent-green: #5da570;
|
| 16 |
+
--accent-green-soft: #9ccba6;
|
| 17 |
+
--white: #ffffff;
|
| 18 |
+
--transition: 0.2s ease;
|
| 19 |
+
--radius: 18px;
|
| 20 |
+
--shadow-soft: 0 8px 32px rgba(120, 160, 200, 0.15);
|
| 21 |
+
--shadow-hover: 0 12px 40px rgba(74, 144, 194, 0.2);
|
| 22 |
+
|
| 23 |
+
/* score heat scale, reuses the blog's good/ok/bad palette */
|
| 24 |
+
--score-good: #00c853;
|
| 25 |
+
--score-ok: #ffb300;
|
| 26 |
+
--score-bad: #ff3d00;
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
* { margin: 0; padding: 0; box-sizing: border-box; }
|
| 30 |
+
html { scroll-behavior: smooth; }
|
| 31 |
+
|
| 32 |
+
@media (prefers-reduced-motion: reduce) {
|
| 33 |
+
html { scroll-behavior: auto; }
|
| 34 |
+
*, *::before, *::after {
|
| 35 |
+
transition-duration: 0.01ms !important;
|
| 36 |
+
animation-duration: 0.01ms !important;
|
| 37 |
+
}
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
body {
|
| 41 |
+
background: var(--bg);
|
| 42 |
+
color: var(--text);
|
| 43 |
+
font-family: Inter, system-ui, sans-serif;
|
| 44 |
+
line-height: 1.6;
|
| 45 |
+
-webkit-font-smoothing: antialiased;
|
| 46 |
+
text-rendering: optimizeLegibility;
|
| 47 |
+
padding-bottom: 80px;
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
h1, h2, h3, h4 { color: var(--heading); letter-spacing: -0.02em; }
|
| 51 |
+
h1 { font-family: 'Newsreader', serif; font-style: italic; }
|
| 52 |
+
|
| 53 |
+
a { color: var(--accent); text-decoration: none; transition: opacity var(--transition); }
|
| 54 |
+
a:hover { opacity: 0.75; }
|
| 55 |
+
a:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; border-radius: 4px; opacity: 1; }
|
| 56 |
+
|
| 57 |
+
/* -------------------- BACKGROUND -------------------- */
|
| 58 |
+
|
| 59 |
+
.background {
|
| 60 |
+
position: fixed;
|
| 61 |
+
inset: 0;
|
| 62 |
+
z-index: -1;
|
| 63 |
+
background:
|
| 64 |
+
radial-gradient(ellipse 130% 45% at 50% 108%, rgba(125, 180, 130, 0.35) 0%, transparent 70%),
|
| 65 |
+
linear-gradient(180deg, #7cb8e0 0%, #a8d0e8 35%, #d8ebf5 60%, #dceee2 82%, #e4f2e6 100%);
|
| 66 |
+
overflow: hidden;
|
| 67 |
+
}
|
| 68 |
+
|
| 69 |
+
.background::before {
|
| 70 |
+
content: '';
|
| 71 |
+
position: absolute;
|
| 72 |
+
top: 10%; left: -10%;
|
| 73 |
+
width: 60%; height: 40%;
|
| 74 |
+
background: radial-gradient(ellipse at center, rgba(255,255,255,0.6) 0%, transparent 70%);
|
| 75 |
+
filter: blur(40px);
|
| 76 |
+
pointer-events: none;
|
| 77 |
+
}
|
| 78 |
+
|
| 79 |
+
.background::after {
|
| 80 |
+
content: '';
|
| 81 |
+
position: absolute;
|
| 82 |
+
top: 30%; right: -5%;
|
| 83 |
+
width: 50%; height: 30%;
|
| 84 |
+
background: radial-gradient(ellipse at center, rgba(255,255,255,0.5) 0%, transparent 70%);
|
| 85 |
+
filter: blur(50px);
|
| 86 |
+
pointer-events: none;
|
| 87 |
+
}
|
| 88 |
+
|
| 89 |
+
.background .cloud {
|
| 90 |
+
position: absolute;
|
| 91 |
+
left: 0;
|
| 92 |
+
width: 220px;
|
| 93 |
+
height: 60px;
|
| 94 |
+
border-radius: 50%;
|
| 95 |
+
background: rgba(255,255,255,0.9);
|
| 96 |
+
box-shadow:
|
| 97 |
+
-70px 12px 30px 6px rgba(255,255,255,0.75),
|
| 98 |
+
80px -12px 34px 10px rgba(255,255,255,0.9),
|
| 99 |
+
30px 14px 36px 8px rgba(255,255,255,0.8),
|
| 100 |
+
-20px -26px 28px 2px rgba(255,255,255,0.95),
|
| 101 |
+
60px 22px 30px 4px rgba(250,253,255,0.7),
|
| 102 |
+
0 34px 26px -14px rgba(150,175,200,0.4);
|
| 103 |
+
filter: url(#cloud-fluff);
|
| 104 |
+
animation: cloud-drift linear infinite;
|
| 105 |
+
will-change: transform;
|
| 106 |
+
}
|
| 107 |
+
|
| 108 |
+
.background .cloud-1 { top: 8%; --cloud-scale: 1.15; animation-duration: 210s; animation-delay: -80s; }
|
| 109 |
+
.background .cloud-2 { top: 24%; --cloud-scale: 0.75; opacity: 0.85; animation-duration: 260s; animation-delay: -180s; }
|
| 110 |
+
.background .cloud-3 { top: 14%; --cloud-scale: 1.5; opacity: 0.95; animation-duration: 300s; animation-delay: -40s; }
|
| 111 |
+
.background .cloud-4 { top: 36%; --cloud-scale: 0.55; opacity: 0.6; animation-duration: 320s; animation-delay: -240s; }
|
| 112 |
+
.background .cloud-simple { filter: none; }
|
| 113 |
+
|
| 114 |
+
@keyframes cloud-drift {
|
| 115 |
+
from { transform: translateX(-45vw) scale(var(--cloud-scale, 1)); }
|
| 116 |
+
to { transform: translateX(120vw) scale(var(--cloud-scale, 1)); }
|
| 117 |
+
}
|
| 118 |
+
|
| 119 |
+
.grass {
|
| 120 |
+
position: fixed;
|
| 121 |
+
bottom: -2px; left: 0;
|
| 122 |
+
width: 100%; height: 70px;
|
| 123 |
+
z-index: 50;
|
| 124 |
+
pointer-events: none;
|
| 125 |
+
}
|
| 126 |
+
|
| 127 |
+
@keyframes blade-sway {
|
| 128 |
+
from { transform: rotate(-2.4deg); }
|
| 129 |
+
to { transform: rotate(3.2deg); }
|
| 130 |
+
}
|
| 131 |
+
|
| 132 |
+
@media (prefers-reduced-motion: reduce) {
|
| 133 |
+
.grass path { animation: none !important; }
|
| 134 |
+
}
|
| 135 |
+
|
| 136 |
+
/* -------------------- LAYOUT -------------------- */
|
| 137 |
+
|
| 138 |
+
.container {
|
| 139 |
+
max-width: 1180px;
|
| 140 |
+
margin: auto;
|
| 141 |
+
padding: 64px 24px 40px;
|
| 142 |
+
}
|
| 143 |
+
|
| 144 |
+
.hero { margin-bottom: 36px; }
|
| 145 |
+
|
| 146 |
+
.eyebrow {
|
| 147 |
+
display: inline-flex;
|
| 148 |
+
align-items: center;
|
| 149 |
+
gap: 6px;
|
| 150 |
+
color: var(--accent);
|
| 151 |
+
font-size: 0.78rem;
|
| 152 |
+
font-weight: 600;
|
| 153 |
+
text-transform: uppercase;
|
| 154 |
+
letter-spacing: 0.1em;
|
| 155 |
+
margin-bottom: 14px;
|
| 156 |
+
}
|
| 157 |
+
|
| 158 |
+
.eyebrow a { color: var(--accent); }
|
| 159 |
+
|
| 160 |
+
.hero h1 {
|
| 161 |
+
font-size: clamp(2.2rem, 6vw, 3.4rem);
|
| 162 |
+
font-weight: 800;
|
| 163 |
+
letter-spacing: -0.05em;
|
| 164 |
+
line-height: 1.1;
|
| 165 |
+
background: linear-gradient(135deg, #5da570 0%, #0c1927 100%);
|
| 166 |
+
-webkit-background-clip: text;
|
| 167 |
+
-webkit-text-fill-color: transparent;
|
| 168 |
+
text-shadow: 0 2px 20px rgba(255,255,255,0.3);
|
| 169 |
+
}
|
| 170 |
+
|
| 171 |
+
.subtitle {
|
| 172 |
+
margin-top: 12px;
|
| 173 |
+
max-width: 640px;
|
| 174 |
+
color: var(--muted);
|
| 175 |
+
font-size: 1.05rem;
|
| 176 |
}
|
| 177 |
|
| 178 |
+
/* -------------------- TIER STRIP -------------------- */
|
| 179 |
+
|
| 180 |
+
.tier-strip {
|
| 181 |
+
display: grid;
|
| 182 |
+
grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
|
| 183 |
+
gap: 14px;
|
| 184 |
+
margin: 32px 0 30px;
|
| 185 |
+
}
|
| 186 |
+
|
| 187 |
+
.tier-card {
|
| 188 |
+
padding: 18px 20px;
|
| 189 |
+
border-radius: var(--radius);
|
| 190 |
+
background: var(--surface);
|
| 191 |
+
border: 1px solid var(--border);
|
| 192 |
+
backdrop-filter: blur(20px) saturate(1.2);
|
| 193 |
+
-webkit-backdrop-filter: blur(20px) saturate(1.2);
|
| 194 |
+
box-shadow: var(--shadow-soft);
|
| 195 |
+
transition: transform var(--transition), box-shadow var(--transition), border-color var(--transition);
|
| 196 |
+
cursor: pointer;
|
| 197 |
+
}
|
| 198 |
+
|
| 199 |
+
.tier-card:hover {
|
| 200 |
+
transform: translateY(-3px);
|
| 201 |
+
box-shadow: var(--shadow-hover);
|
| 202 |
+
border-color: rgba(93, 165, 112, 0.4);
|
| 203 |
+
}
|
| 204 |
+
|
| 205 |
+
.tier-card.active {
|
| 206 |
+
border-color: var(--accent);
|
| 207 |
+
background: var(--surface-2);
|
| 208 |
+
box-shadow: var(--shadow-hover);
|
| 209 |
+
}
|
| 210 |
+
|
| 211 |
+
.tier-card .tier-num {
|
| 212 |
+
display: inline-block;
|
| 213 |
+
font-size: 0.7rem;
|
| 214 |
+
font-weight: 700;
|
| 215 |
+
color: var(--accent);
|
| 216 |
+
letter-spacing: 0.08em;
|
| 217 |
+
text-transform: uppercase;
|
| 218 |
+
margin-bottom: 6px;
|
| 219 |
+
}
|
| 220 |
+
|
| 221 |
+
.tier-card h3 { font-size: 1.15rem; margin-bottom: 6px; }
|
| 222 |
+
.tier-card p { color: var(--muted); font-size: 0.85rem; line-height: 1.5; }
|
| 223 |
+
|
| 224 |
+
.tier-meta {
|
| 225 |
+
display: flex;
|
| 226 |
+
gap: 10px;
|
| 227 |
+
margin-top: 10px;
|
| 228 |
+
font-size: 0.72rem;
|
| 229 |
+
color: var(--muted);
|
| 230 |
+
}
|
| 231 |
+
|
| 232 |
+
.tier-meta span {
|
| 233 |
+
padding: 2px 8px;
|
| 234 |
+
background: rgba(255,255,255,0.6);
|
| 235 |
+
border-radius: 999px;
|
| 236 |
+
border: 1px solid var(--border-soft);
|
| 237 |
+
}
|
| 238 |
+
|
| 239 |
+
/* -------------------- CONTROLS -------------------- */
|
| 240 |
+
|
| 241 |
+
.controls {
|
| 242 |
+
display: flex;
|
| 243 |
+
flex-wrap: wrap;
|
| 244 |
+
align-items: center;
|
| 245 |
+
gap: 12px;
|
| 246 |
+
margin-bottom: 22px;
|
| 247 |
+
}
|
| 248 |
+
|
| 249 |
+
.search-pill {
|
| 250 |
+
display: flex;
|
| 251 |
+
align-items: center;
|
| 252 |
+
flex: 1;
|
| 253 |
+
min-width: 220px;
|
| 254 |
+
gap: 6px;
|
| 255 |
+
padding: 6px 6px 6px 18px;
|
| 256 |
+
background: var(--surface);
|
| 257 |
+
border: 1px solid var(--border);
|
| 258 |
+
border-radius: 999px;
|
| 259 |
+
backdrop-filter: blur(20px) saturate(1.2);
|
| 260 |
+
-webkit-backdrop-filter: blur(20px) saturate(1.2);
|
| 261 |
+
box-shadow: var(--shadow-soft);
|
| 262 |
+
transition: border-color var(--transition), box-shadow var(--transition);
|
| 263 |
}
|
| 264 |
|
| 265 |
+
.search-pill:focus-within {
|
| 266 |
+
border-color: rgba(74, 144, 194, 0.5);
|
| 267 |
+
box-shadow: var(--shadow-hover);
|
|
|
|
|
|
|
| 268 |
}
|
| 269 |
|
| 270 |
+
.search-pill input {
|
| 271 |
+
flex: 1;
|
| 272 |
+
min-width: 0;
|
| 273 |
+
border: none;
|
| 274 |
+
background: transparent;
|
| 275 |
+
outline: none;
|
| 276 |
+
font-family: inherit;
|
| 277 |
+
font-size: 0.92rem;
|
| 278 |
+
color: var(--text);
|
| 279 |
+
padding: 8px 4px;
|
| 280 |
+
}
|
| 281 |
+
|
| 282 |
+
.search-pill input::placeholder { color: var(--muted); }
|
| 283 |
+
|
| 284 |
+
.search-pill svg { color: var(--muted); flex-shrink: 0; margin-right: 2px; }
|
| 285 |
+
|
| 286 |
+
.metric-select-wrap, .sort-select-wrap {
|
| 287 |
+
position: relative;
|
| 288 |
+
}
|
| 289 |
+
|
| 290 |
+
.pill-select {
|
| 291 |
+
appearance: none;
|
| 292 |
+
-webkit-appearance: none;
|
| 293 |
+
padding: 11px 34px 11px 18px;
|
| 294 |
+
background: var(--surface);
|
| 295 |
+
border: 1px solid var(--border);
|
| 296 |
+
border-radius: 999px;
|
| 297 |
+
backdrop-filter: blur(20px) saturate(1.2);
|
| 298 |
+
-webkit-backdrop-filter: blur(20px) saturate(1.2);
|
| 299 |
+
box-shadow: var(--shadow-soft);
|
| 300 |
+
font-family: inherit;
|
| 301 |
+
font-size: 0.85rem;
|
| 302 |
+
color: var(--heading);
|
| 303 |
+
cursor: pointer;
|
| 304 |
+
transition: border-color var(--transition), box-shadow var(--transition);
|
| 305 |
+
}
|
| 306 |
+
|
| 307 |
+
.pill-select:hover { border-color: rgba(74,144,194,0.4); }
|
| 308 |
+
.pill-select:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
|
| 309 |
+
|
| 310 |
+
.select-arrow {
|
| 311 |
+
position: absolute;
|
| 312 |
+
right: 14px;
|
| 313 |
+
top: 50%;
|
| 314 |
+
transform: translateY(-50%);
|
| 315 |
+
pointer-events: none;
|
| 316 |
+
color: var(--accent);
|
| 317 |
+
font-size: 0.65rem;
|
| 318 |
+
}
|
| 319 |
+
|
| 320 |
+
/* -------------------- TABLE -------------------- */
|
| 321 |
+
|
| 322 |
+
.table-scroll {
|
| 323 |
+
overflow-x: auto;
|
| 324 |
+
border-radius: var(--radius);
|
| 325 |
+
background: var(--surface);
|
| 326 |
+
border: 1px solid var(--border);
|
| 327 |
+
backdrop-filter: blur(20px) saturate(1.2);
|
| 328 |
+
-webkit-backdrop-filter: blur(20px) saturate(1.2);
|
| 329 |
+
box-shadow: var(--shadow-soft);
|
| 330 |
+
}
|
| 331 |
+
|
| 332 |
+
table.leaderboard {
|
| 333 |
+
width: 100%;
|
| 334 |
+
border-collapse: separate;
|
| 335 |
+
border-spacing: 0;
|
| 336 |
+
font-size: 0.92rem;
|
| 337 |
+
min-width: 640px;
|
| 338 |
+
}
|
| 339 |
+
|
| 340 |
+
table.leaderboard thead th {
|
| 341 |
+
position: sticky;
|
| 342 |
+
top: 0;
|
| 343 |
+
background: rgba(255,255,255,0.82);
|
| 344 |
+
backdrop-filter: blur(12px);
|
| 345 |
+
-webkit-backdrop-filter: blur(12px);
|
| 346 |
+
color: var(--heading);
|
| 347 |
+
font-weight: 600;
|
| 348 |
+
text-align: left;
|
| 349 |
+
padding: 14px 16px;
|
| 350 |
+
border-bottom: 1px solid var(--border-soft);
|
| 351 |
+
font-size: 0.78rem;
|
| 352 |
+
text-transform: uppercase;
|
| 353 |
+
letter-spacing: 0.04em;
|
| 354 |
+
cursor: pointer;
|
| 355 |
+
user-select: none;
|
| 356 |
+
white-space: nowrap;
|
| 357 |
+
}
|
| 358 |
+
|
| 359 |
+
table.leaderboard thead th:hover { color: var(--accent); }
|
| 360 |
+
|
| 361 |
+
table.leaderboard thead th .sort-arrow {
|
| 362 |
+
display: inline-block;
|
| 363 |
+
margin-left: 4px;
|
| 364 |
+
font-size: 0.7rem;
|
| 365 |
+
color: var(--accent);
|
| 366 |
+
opacity: 0;
|
| 367 |
+
}
|
| 368 |
+
|
| 369 |
+
table.leaderboard thead th.sorted .sort-arrow { opacity: 1; }
|
| 370 |
+
|
| 371 |
+
table.leaderboard tbody tr {
|
| 372 |
+
transition: background var(--transition);
|
| 373 |
+
}
|
| 374 |
+
|
| 375 |
+
table.leaderboard tbody tr:hover { background: rgba(74, 144, 194, 0.07); }
|
| 376 |
+
|
| 377 |
+
table.leaderboard tbody tr:not(:last-child) td { border-bottom: 1px solid var(--border-soft); }
|
| 378 |
+
|
| 379 |
+
table.leaderboard td {
|
| 380 |
+
padding: 14px 16px;
|
| 381 |
+
color: var(--text);
|
| 382 |
+
vertical-align: middle;
|
| 383 |
+
}
|
| 384 |
+
|
| 385 |
+
.rank-cell {
|
| 386 |
+
font-weight: 700;
|
| 387 |
+
color: var(--muted);
|
| 388 |
+
width: 46px;
|
| 389 |
+
font-variant-numeric: tabular-nums;
|
| 390 |
+
}
|
| 391 |
+
|
| 392 |
+
.rank-cell.top-1 { color: #d9a441; }
|
| 393 |
+
.rank-cell.top-2 { color: #9aa5b1; }
|
| 394 |
+
.rank-cell.top-3 { color: #c08552; }
|
| 395 |
+
|
| 396 |
+
.model-cell {
|
| 397 |
+
display: flex;
|
| 398 |
+
flex-direction: column;
|
| 399 |
+
gap: 2px;
|
| 400 |
+
min-width: 200px;
|
| 401 |
+
}
|
| 402 |
+
|
| 403 |
+
.model-name {
|
| 404 |
+
font-weight: 600;
|
| 405 |
+
color: var(--heading);
|
| 406 |
+
font-size: 0.95rem;
|
| 407 |
+
}
|
| 408 |
+
|
| 409 |
+
.model-name a { color: inherit; }
|
| 410 |
+
.model-name a:hover { color: var(--accent); opacity: 1; }
|
| 411 |
+
|
| 412 |
+
.model-org {
|
| 413 |
+
font-size: 0.76rem;
|
| 414 |
+
color: var(--muted);
|
| 415 |
+
}
|
| 416 |
+
|
| 417 |
+
.params-cell {
|
| 418 |
+
font-variant-numeric: tabular-nums;
|
| 419 |
+
color: var(--muted);
|
| 420 |
+
font-size: 0.85rem;
|
| 421 |
+
white-space: nowrap;
|
| 422 |
+
}
|
| 423 |
+
|
| 424 |
+
.score-cell {
|
| 425 |
+
font-variant-numeric: tabular-nums;
|
| 426 |
+
font-weight: 600;
|
| 427 |
+
white-space: nowrap;
|
| 428 |
+
}
|
| 429 |
+
|
| 430 |
+
.score-pill {
|
| 431 |
+
display: inline-flex;
|
| 432 |
+
align-items: center;
|
| 433 |
+
gap: 8px;
|
| 434 |
+
}
|
| 435 |
+
|
| 436 |
+
.score-bar-track {
|
| 437 |
+
position: relative;
|
| 438 |
+
width: 74px;
|
| 439 |
+
height: 6px;
|
| 440 |
+
border-radius: 999px;
|
| 441 |
+
background: rgba(120,160,200,0.18);
|
| 442 |
+
overflow: hidden;
|
| 443 |
+
}
|
| 444 |
+
|
| 445 |
+
.score-bar-fill {
|
| 446 |
+
position: absolute;
|
| 447 |
+
inset: 0;
|
| 448 |
+
width: 0%;
|
| 449 |
+
border-radius: 999px;
|
| 450 |
+
background: linear-gradient(90deg, var(--accent-soft), var(--accent));
|
| 451 |
+
transition: width 0.4s ease;
|
| 452 |
+
}
|
| 453 |
+
|
| 454 |
+
.score-num.good { color: #1a8f4f; }
|
| 455 |
+
.score-num.ok { color: #b57900; }
|
| 456 |
+
.score-num.bad { color: #c9432c; }
|
| 457 |
+
|
| 458 |
+
.score-na {
|
| 459 |
+
color: var(--muted);
|
| 460 |
+
font-size: 0.82rem;
|
| 461 |
+
font-style: italic;
|
| 462 |
+
}
|
| 463 |
+
|
| 464 |
+
.model-link-icon {
|
| 465 |
+
display: inline-flex;
|
| 466 |
+
color: var(--muted);
|
| 467 |
+
transition: color var(--transition);
|
| 468 |
+
}
|
| 469 |
+
.model-link-icon:hover { color: var(--accent); }
|
| 470 |
+
|
| 471 |
+
/* -------------------- EMPTY STATE -------------------- */
|
| 472 |
+
|
| 473 |
+
.empty-state {
|
| 474 |
+
padding: 60px 24px;
|
| 475 |
+
text-align: center;
|
| 476 |
+
color: var(--muted);
|
| 477 |
+
}
|
| 478 |
+
|
| 479 |
+
.empty-state svg { margin-bottom: 14px; color: var(--accent-soft); }
|
| 480 |
+
|
| 481 |
+
/* -------------------- DETAIL PANEL -------------------- */
|
| 482 |
+
|
| 483 |
+
.detail-panel {
|
| 484 |
+
margin-top: 28px;
|
| 485 |
+
padding: 26px;
|
| 486 |
+
border-radius: var(--radius);
|
| 487 |
+
background: var(--surface);
|
| 488 |
+
border: 1px solid var(--border);
|
| 489 |
+
backdrop-filter: blur(20px) saturate(1.2);
|
| 490 |
+
-webkit-backdrop-filter: blur(20px) saturate(1.2);
|
| 491 |
+
box-shadow: var(--shadow-soft);
|
| 492 |
+
display: none;
|
| 493 |
+
}
|
| 494 |
+
|
| 495 |
+
.detail-panel.open { display: block; }
|
| 496 |
+
|
| 497 |
+
.detail-panel-header {
|
| 498 |
+
display: flex;
|
| 499 |
+
align-items: flex-start;
|
| 500 |
+
justify-content: space-between;
|
| 501 |
+
gap: 16px;
|
| 502 |
+
margin-bottom: 18px;
|
| 503 |
+
flex-wrap: wrap;
|
| 504 |
+
}
|
| 505 |
+
|
| 506 |
+
.detail-panel-header h2 { font-size: 1.3rem; margin-bottom: 4px; }
|
| 507 |
+
.detail-panel-header p { color: var(--muted); font-size: 0.88rem; }
|
| 508 |
+
|
| 509 |
+
.detail-close {
|
| 510 |
+
flex-shrink: 0;
|
| 511 |
+
width: 34px;
|
| 512 |
+
height: 34px;
|
| 513 |
+
border-radius: 50%;
|
| 514 |
+
border: 1px solid var(--border-soft);
|
| 515 |
+
background: rgba(255,255,255,0.6);
|
| 516 |
+
color: var(--muted);
|
| 517 |
+
display: flex;
|
| 518 |
+
align-items: center;
|
| 519 |
+
justify-content: center;
|
| 520 |
+
cursor: pointer;
|
| 521 |
+
transition: background var(--transition), color var(--transition), border-color var(--transition);
|
| 522 |
+
}
|
| 523 |
+
|
| 524 |
+
.detail-close:hover { background: #fff; color: var(--accent); border-color: var(--accent); }
|
| 525 |
+
|
| 526 |
+
.cat-grid {
|
| 527 |
+
display: grid;
|
| 528 |
+
grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
|
| 529 |
+
gap: 10px;
|
| 530 |
+
}
|
| 531 |
+
|
| 532 |
+
.cat-row {
|
| 533 |
+
padding: 12px 14px;
|
| 534 |
+
border-radius: 12px;
|
| 535 |
+
background: rgba(255,255,255,0.5);
|
| 536 |
+
border: 1px solid var(--border-soft);
|
| 537 |
+
}
|
| 538 |
+
|
| 539 |
+
.cat-row-top {
|
| 540 |
+
display: flex;
|
| 541 |
+
justify-content: space-between;
|
| 542 |
+
align-items: baseline;
|
| 543 |
+
margin-bottom: 6px;
|
| 544 |
+
gap: 8px;
|
| 545 |
+
}
|
| 546 |
+
|
| 547 |
+
.cat-name {
|
| 548 |
+
font-size: 0.8rem;
|
| 549 |
+
color: var(--heading);
|
| 550 |
+
font-weight: 500;
|
| 551 |
+
}
|
| 552 |
+
|
| 553 |
+
.cat-n {
|
| 554 |
+
font-size: 0.68rem;
|
| 555 |
+
color: var(--muted);
|
| 556 |
+
}
|
| 557 |
+
|
| 558 |
+
.cat-score {
|
| 559 |
+
font-size: 0.85rem;
|
| 560 |
+
font-weight: 700;
|
| 561 |
+
font-variant-numeric: tabular-nums;
|
| 562 |
+
}
|
| 563 |
+
|
| 564 |
+
.cat-bar-track {
|
| 565 |
+
height: 5px;
|
| 566 |
+
border-radius: 999px;
|
| 567 |
+
background: rgba(120,160,200,0.15);
|
| 568 |
+
overflow: hidden;
|
| 569 |
+
}
|
| 570 |
+
|
| 571 |
+
.cat-bar-fill {
|
| 572 |
+
height: 100%;
|
| 573 |
+
border-radius: 999px;
|
| 574 |
+
}
|
| 575 |
+
|
| 576 |
+
/* -------------------- FOOTER -------------------- */
|
| 577 |
+
|
| 578 |
+
.page-footer {
|
| 579 |
+
margin-top: 50px;
|
| 580 |
+
padding-top: 22px;
|
| 581 |
+
border-top: 1px solid var(--border-soft);
|
| 582 |
+
display: flex;
|
| 583 |
+
flex-wrap: wrap;
|
| 584 |
+
justify-content: space-between;
|
| 585 |
+
gap: 12px;
|
| 586 |
+
color: var(--muted);
|
| 587 |
+
font-size: 0.8rem;
|
| 588 |
+
}
|
| 589 |
+
|
| 590 |
+
.page-footer a { color: var(--accent); }
|
| 591 |
+
|
| 592 |
+
/* -------------------- RESPONSIVE -------------------- */
|
| 593 |
+
|
| 594 |
+
@media (max-width: 640px) {
|
| 595 |
+
.container { padding: 40px 16px 32px; }
|
| 596 |
+
.controls { flex-direction: column; align-items: stretch; }
|
| 597 |
+
table.leaderboard { min-width: 560px; }
|
| 598 |
+
}
|
| 599 |
+
|
| 600 |
+
/* -------------------- SCROLLBARS / SELECTION -------------------- */
|
| 601 |
+
|
| 602 |
+
::selection { background: rgba(74,144,194,0.3); color: var(--heading); }
|
| 603 |
+
::-webkit-scrollbar { width: 10px; height: 10px; }
|
| 604 |
+
::-webkit-scrollbar-track { background: rgba(255,255,255,0.3); }
|
| 605 |
+
::-webkit-scrollbar-thumb { background: rgba(120,160,200,0.4); border-radius: 5px; }
|
| 606 |
+
::-webkit-scrollbar-thumb:hover { background: rgba(74,144,194,0.6); }
|
| 607 |
+
|
| 608 |
+
/* -------------------- TOOLTIP (from blog) -------------------- */
|
| 609 |
+
|
| 610 |
+
.tooltip { position: relative; }
|
| 611 |
+
|
| 612 |
+
.tooltip::after {
|
| 613 |
+
content: attr(data-tooltip);
|
| 614 |
+
position: absolute;
|
| 615 |
+
left: 50%;
|
| 616 |
+
bottom: calc(100% + 10px);
|
| 617 |
+
transform: translateX(-50%) translateY(4px);
|
| 618 |
+
padding: 8px 12px;
|
| 619 |
+
border-radius: 10px;
|
| 620 |
+
background: var(--surface-2);
|
| 621 |
+
border: 1px solid var(--border);
|
| 622 |
+
backdrop-filter: blur(20px) saturate(1.2);
|
| 623 |
+
-webkit-backdrop-filter: blur(20px) saturate(1.2);
|
| 624 |
+
color: var(--heading);
|
| 625 |
+
font-size: 0.78rem;
|
| 626 |
+
font-weight: 500;
|
| 627 |
+
white-space: nowrap;
|
| 628 |
+
box-shadow: var(--shadow-hover);
|
| 629 |
+
opacity: 0;
|
| 630 |
+
visibility: hidden;
|
| 631 |
+
pointer-events: none;
|
| 632 |
+
transition: opacity .08s ease, transform .08s ease, visibility .08s;
|
| 633 |
}
|
| 634 |
|
| 635 |
+
.tooltip:hover::after, .tooltip:focus-visible::after {
|
| 636 |
+
opacity: 1;
|
| 637 |
+
visibility: visible;
|
| 638 |
+
transform: translateX(-50%) translateY(0);
|
| 639 |
}
|