AlicanKiraz0 commited on
Commit
67a64b0
·
verified ·
1 Parent(s): f1ef2a4

Upload 8 files

Browse files
Files changed (3) hide show
  1. README.md +8 -5
  2. index.html +368 -76
  3. styles.css +299 -58
README.md CHANGED
@@ -13,11 +13,14 @@ pinned: false
13
  Bu depo, `leaderboard_data.csv` dosyasındaki metriklere göre bir LLM leaderboard arayüzü sağlar. Esinlenilen kaynak: [HF Space – llm_leaderboard_fr](https://huggingface.co/spaces/fr-gouv-coordination-ia/llm_leaderboard_fr/tree/main).
14
 
15
  ## Özellikler
16
- - Sütun bazlı sıralama (varsayılan: Combined Score azalan)
17
- - Arama kutusu (model adına göre)
18
- - Sağlayıcı filtresi (model adından türetilir, örn. `deepseek-ai`, `openai`, `anthropic`, `google`, `meta`)
19
- - İlk 3 modelin görsel vurgusu (🥇🥈🥉)
20
- - Karanlık tema, duyarlı (responsive) tasarım
 
 
 
21
 
22
  ## Dosyalar
23
  - `index.html` – Uygulama HTML iskeleti
 
13
  Bu depo, `leaderboard_data.csv` dosyasındaki metriklere göre bir LLM leaderboard arayüzü sağlar. Esinlenilen kaynak: [HF Space – llm_leaderboard_fr](https://huggingface.co/spaces/fr-gouv-coordination-ia/llm_leaderboard_fr/tree/main).
14
 
15
  ## Özellikler
16
+ - 🎯 Sütun bazlı sıralama (varsayılan: Combined Score azalan)
17
+ - 🔍 Arama kutusu (model adına göre)
18
+ - 🏢 Sağlayıcı filtresi (model adından türetilir, örn. `deepseek-ai`, `openai`, `anthropic`, `google`, `meta`)
19
+ - 🏆 İlk 3 modelin görsel vurgusu (altın, gümüş, bronz)
20
+ - 🎨 Modern gradient tasarım, cam efekti (glassmorphism)
21
+ - ✨ Yumuş animasyonlar ve hover efektleri
22
+ - 📱 Duyarlı (responsive) tasarım
23
+ - 🌙 Karanlık tema optimizasyonu
24
 
25
  ## Dosyalar
26
  - `index.html` – Uygulama HTML iskeleti
index.html CHANGED
@@ -3,123 +3,366 @@
3
  <head>
4
  <meta charset="utf-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
- <title>LLM Leaderboard (Local)</title>
7
  <link rel="stylesheet" href="./styles.css">
8
  <style>
9
  :root {
10
- --bg: #0b0f17;
11
- --panel: #121826;
12
- --text: #e5e7eb;
13
- --muted: #9ca3af;
14
- --accent: #8b5cf6;
15
- --border: #1f2937;
16
- --row-hover: #111827;
17
- --gold: #ffe27a33;
18
- --silver: #c0c0c033;
19
- --bronze: #cd7f3233;
20
- }
21
-
22
- * { box-sizing: border-box; }
 
 
 
 
 
 
 
23
  html, body { height: 100%; }
 
24
  body {
25
  margin: 0;
26
- background: var(--bg);
 
27
  color: var(--text);
28
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", Arial, sans-serif;
29
- line-height: 1.45;
 
30
  }
31
 
32
  .container {
33
- max-width: 1100px;
34
  margin: 0 auto;
35
- padding: 16px;
36
  }
37
 
38
  .topbar {
39
  display: flex;
40
  align-items: center;
41
  justify-content: space-between;
42
- padding: 12px 16px;
43
- border-bottom: 1px solid var(--border);
44
  background: var(--panel);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  }
46
- .topbar__left { display: flex; align-items: center; gap: 12px; }
47
- .topbar__right { display: flex; align-items: center; gap: 12px; }
48
- .app-title { font-size: 20px; margin: 0; }
49
- .muted { color: var(--muted); }
50
- .link { color: var(--accent); text-decoration: none; }
51
- .link:hover { text-decoration: underline; }
52
 
53
  .controls {
54
  display: flex;
55
- gap: 8px;
56
  align-items: center;
57
  flex-wrap: wrap;
58
- margin: 16px 0 8px;
59
  }
 
60
  .control input[type="search"],
61
  .control select {
62
  background: var(--panel);
 
63
  color: var(--text);
64
  border: 1px solid var(--border);
65
- border-radius: 8px;
66
- padding: 8px 10px;
 
 
 
 
67
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
68
  .control button {
69
- background: var(--accent);
70
  color: #fff;
71
  border: none;
72
- border-radius: 8px;
73
- padding: 8px 12px;
 
74
  cursor: pointer;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
  }
76
- .control button:hover { opacity: 0.95; }
77
 
78
- .table-wrap { border: 1px solid var(--border); border-radius: 10px; overflow: hidden; background: var(--panel); }
79
- table.table { width: 100%; border-collapse: separate; border-spacing: 0; }
80
  thead th {
81
  text-align: left;
82
- font-weight: 600;
83
- padding: 12px;
84
- border-bottom: 1px solid var(--border);
85
- background: #0f1524;
86
  position: sticky;
87
  top: 0;
88
- z-index: 1;
89
  cursor: pointer;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  }
91
- tbody td { padding: 12px; border-bottom: 1px solid var(--border); }
92
- tbody tr:hover { background: var(--row-hover); }
93
 
94
  /* Sıralama göstergeleri */
95
  th[aria-sort="ascending"]::after,
96
  th[aria-sort="descending"]::after {
97
  content: '';
98
  display: inline-block;
99
- margin-left: 6px;
100
- width: 0; height: 0;
 
101
  border-left: 5px solid transparent;
102
  border-right: 5px solid transparent;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
  }
104
- th[aria-sort="ascending"]::after { border-bottom: 6px solid var(--muted); }
105
- th[aria-sort="descending"]::after { border-top: 6px solid var(--muted); }
106
 
107
- /* İlk 3 vurgusu */
108
- tr.rank-1 { background: var(--gold); }
109
- tr.rank-2 { background: var(--silver); }
110
- tr.rank-3 { background: var(--bronze); }
111
- td.rank-cell { font-weight: 700; }
 
 
 
 
112
 
113
- .footer { display: flex; align-items: center; justify-content: space-between; padding: 12px 0 0; gap: 12px; }
114
- .disclaimer { color: var(--muted); font-size: 14px; }
 
 
 
 
115
 
116
- .visually-hidden { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117
 
118
- @media (max-width: 720px) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
  thead th:nth-child(3),
120
- thead th:nth-child(4) { display: none; }
 
 
 
121
  tbody td:nth-child(3),
122
- tbody td:nth-child(4) { display: none; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
  }
124
  </style>
125
  </head>
@@ -286,24 +529,65 @@ const state = {
286
  let fullData = [];
287
 
288
  async function loadData() {
289
- const res = await fetch("./leaderboard_data.csv", { cache: "no-cache" });
290
- const text = await res.text();
291
- const { headers, records } = parseCSV(text);
292
- const keys = headers.map(normalizeHeader);
293
- const data = records.map(cols => {
294
- const obj = {};
295
- for (let i = 0; i < keys.length; i += 1) {
296
- obj[keys[i]] = cols[i];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
297
  }
298
- const mcq = toNumber(obj.mcq);
299
- const saq = toNumber(obj.saq);
300
- const combined = toNumber(obj.combined);
301
- const rank = toNumber(obj.rank);
302
- const model = obj.model;
303
- const provider = detectProvider(model);
304
- return { model, provider, mcq, saq, combined, csvRank: rank };
305
- });
306
- return data;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
307
  }
308
 
309
  function uniqueProviders(data) {
@@ -354,6 +638,14 @@ function setSortIndicator() {
354
  function render(data) {
355
  const tbody = document.getElementById("tableBody");
356
  const sorted = sortData(applyFilters(data));
 
 
 
 
 
 
 
 
357
  let html = "";
358
  sorted.forEach((d, idx) => {
359
  const rank = idx + 1;
 
3
  <head>
4
  <meta charset="utf-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <title>🏆 LLM Leaderboard</title>
7
  <link rel="stylesheet" href="./styles.css">
8
  <style>
9
  :root {
10
+ --bg-gradient-start: #0a0e27;
11
+ --bg-gradient-end: #1a1033;
12
+ --panel: rgba(17, 24, 39, 0.8);
13
+ --panel-hover: rgba(30, 41, 59, 0.95);
14
+ --text: #f8fafc;
15
+ --text-secondary: #cbd5e1;
16
+ --muted: #94a3b8;
17
+ --accent: #a78bfa;
18
+ --accent-bright: #c4b5fd;
19
+ --border: rgba(148, 163, 184, 0.15);
20
+ --row-hover: rgba(139, 92, 246, 0.1);
21
+ --gold-bg: linear-gradient(135deg, rgba(251, 191, 36, 0.15), rgba(245, 158, 11, 0.1));
22
+ --silver-bg: linear-gradient(135deg, rgba(203, 213, 225, 0.15), rgba(148, 163, 184, 0.1));
23
+ --bronze-bg: linear-gradient(135deg, rgba(251, 146, 60, 0.15), rgba(234, 88, 12, 0.1));
24
+ --shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.3);
25
+ --shadow-md: 0 4px 16px rgba(0, 0, 0, 0.4);
26
+ --shadow-lg: 0 10px 40px rgba(0, 0, 0, 0.5);
27
+ }
28
+
29
+ * { box-sizing: border-box; margin: 0; padding: 0; }
30
  html, body { height: 100%; }
31
+
32
  body {
33
  margin: 0;
34
+ background: linear-gradient(135deg, var(--bg-gradient-start) 0%, var(--bg-gradient-end) 100%);
35
+ background-attachment: fixed;
36
  color: var(--text);
37
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
38
+ line-height: 1.6;
39
+ font-size: 15px;
40
  }
41
 
42
  .container {
43
+ max-width: 1200px;
44
  margin: 0 auto;
45
+ padding: 24px;
46
  }
47
 
48
  .topbar {
49
  display: flex;
50
  align-items: center;
51
  justify-content: space-between;
52
+ padding: 20px 32px;
 
53
  background: var(--panel);
54
+ backdrop-filter: blur(12px);
55
+ border-bottom: 1px solid var(--border);
56
+ box-shadow: var(--shadow-sm);
57
+ }
58
+
59
+ .topbar__left {
60
+ display: flex;
61
+ align-items: center;
62
+ gap: 16px;
63
+ }
64
+
65
+ .topbar__right {
66
+ display: flex;
67
+ align-items: center;
68
+ gap: 20px;
69
+ font-size: 14px;
70
+ }
71
+
72
+ .app-title {
73
+ font-size: 28px;
74
+ font-weight: 700;
75
+ background: linear-gradient(135deg, var(--accent-bright) 0%, var(--accent) 100%);
76
+ -webkit-background-clip: text;
77
+ -webkit-text-fill-color: transparent;
78
+ background-clip: text;
79
+ letter-spacing: -0.5px;
80
+ }
81
+
82
+ .app-title::before {
83
+ content: "🏆 ";
84
+ -webkit-text-fill-color: var(--accent-bright);
85
+ }
86
+
87
+ .muted {
88
+ color: var(--muted);
89
+ font-size: 14px;
90
+ }
91
+
92
+ .link {
93
+ color: var(--accent-bright);
94
+ text-decoration: none;
95
+ font-weight: 500;
96
+ transition: all 0.2s ease;
97
+ position: relative;
98
+ }
99
+
100
+ .link::after {
101
+ content: '';
102
+ position: absolute;
103
+ bottom: -2px;
104
+ left: 0;
105
+ width: 0;
106
+ height: 2px;
107
+ background: var(--accent-bright);
108
+ transition: width 0.3s ease;
109
+ }
110
+
111
+ .link:hover::after {
112
+ width: 100%;
113
  }
 
 
 
 
 
 
114
 
115
  .controls {
116
  display: flex;
117
+ gap: 12px;
118
  align-items: center;
119
  flex-wrap: wrap;
120
+ margin: 24px 0 16px;
121
  }
122
+
123
  .control input[type="search"],
124
  .control select {
125
  background: var(--panel);
126
+ backdrop-filter: blur(8px);
127
  color: var(--text);
128
  border: 1px solid var(--border);
129
+ border-radius: 12px;
130
+ padding: 12px 16px;
131
+ font-size: 14px;
132
+ transition: all 0.3s ease;
133
+ box-shadow: var(--shadow-sm);
134
+ min-width: 200px;
135
  }
136
+
137
+ .control input[type="search"]:focus,
138
+ .control select:focus {
139
+ outline: none;
140
+ border-color: var(--accent);
141
+ box-shadow: 0 0 0 3px rgba(167, 139, 250, 0.2), var(--shadow-sm);
142
+ transform: translateY(-1px);
143
+ }
144
+
145
+ .control input[type="search"]::placeholder {
146
+ color: var(--muted);
147
+ }
148
+
149
  .control button {
150
+ background: linear-gradient(135deg, var(--accent) 0%, #8b5cf6 100%);
151
  color: #fff;
152
  border: none;
153
+ border-radius: 12px;
154
+ padding: 12px 24px;
155
+ font-weight: 600;
156
  cursor: pointer;
157
+ transition: all 0.3s ease;
158
+ box-shadow: var(--shadow-sm);
159
+ font-size: 14px;
160
+ }
161
+
162
+ .control button:hover {
163
+ transform: translateY(-2px);
164
+ box-shadow: var(--shadow-md);
165
+ background: linear-gradient(135deg, var(--accent-bright) 0%, var(--accent) 100%);
166
+ }
167
+
168
+ .control button:active {
169
+ transform: translateY(0);
170
+ }
171
+
172
+ .table-wrap {
173
+ border: 1px solid var(--border);
174
+ border-radius: 16px;
175
+ overflow: hidden;
176
+ background: var(--panel);
177
+ backdrop-filter: blur(12px);
178
+ box-shadow: var(--shadow-lg);
179
+ animation: fadeInUp 0.6s ease;
180
+ }
181
+
182
+ @keyframes fadeInUp {
183
+ from {
184
+ opacity: 0;
185
+ transform: translateY(20px);
186
+ }
187
+ to {
188
+ opacity: 1;
189
+ transform: translateY(0);
190
+ }
191
+ }
192
+
193
+ table.table {
194
+ width: 100%;
195
+ border-collapse: separate;
196
+ border-spacing: 0;
197
  }
 
198
 
 
 
199
  thead th {
200
  text-align: left;
201
+ font-weight: 700;
202
+ padding: 18px 16px;
203
+ border-bottom: 2px solid var(--border);
204
+ background: linear-gradient(180deg, rgba(139, 92, 246, 0.15) 0%, rgba(139, 92, 246, 0.05) 100%);
205
  position: sticky;
206
  top: 0;
207
+ z-index: 10;
208
  cursor: pointer;
209
+ transition: all 0.2s ease;
210
+ font-size: 13px;
211
+ text-transform: uppercase;
212
+ letter-spacing: 0.5px;
213
+ color: var(--text-secondary);
214
+ }
215
+
216
+ thead th:hover {
217
+ background: linear-gradient(180deg, rgba(139, 92, 246, 0.25) 0%, rgba(139, 92, 246, 0.1) 100%);
218
+ color: var(--accent-bright);
219
+ }
220
+
221
+ tbody td {
222
+ padding: 16px;
223
+ border-bottom: 1px solid var(--border);
224
+ transition: all 0.2s ease;
225
+ font-size: 14px;
226
+ }
227
+
228
+ tbody tr {
229
+ transition: all 0.3s ease;
230
+ }
231
+
232
+ tbody tr:hover {
233
+ background: var(--row-hover);
234
+ transform: scale(1.01);
235
  }
 
 
236
 
237
  /* Sıralama göstergeleri */
238
  th[aria-sort="ascending"]::after,
239
  th[aria-sort="descending"]::after {
240
  content: '';
241
  display: inline-block;
242
+ margin-left: 8px;
243
+ width: 0;
244
+ height: 0;
245
  border-left: 5px solid transparent;
246
  border-right: 5px solid transparent;
247
+ transition: all 0.2s ease;
248
+ }
249
+
250
+ th[aria-sort="ascending"]::after {
251
+ border-bottom: 6px solid var(--accent-bright);
252
+ }
253
+
254
+ th[aria-sort="descending"]::after {
255
+ border-top: 6px solid var(--accent-bright);
256
+ }
257
+
258
+ /* İlk 3 vurgusu - modernize edildi */
259
+ tr.rank-1 {
260
+ background: var(--gold-bg);
261
+ border-left: 4px solid #fbbf24;
262
  }
 
 
263
 
264
+ tr.rank-2 {
265
+ background: var(--silver-bg);
266
+ border-left: 4px solid #cbd5e1;
267
+ }
268
+
269
+ tr.rank-3 {
270
+ background: var(--bronze-bg);
271
+ border-left: 4px solid #fb923c;
272
+ }
273
 
274
+ tr.rank-1:hover,
275
+ tr.rank-2:hover,
276
+ tr.rank-3:hover {
277
+ transform: scale(1.02);
278
+ box-shadow: var(--shadow-md);
279
+ }
280
 
281
+ td.rank-cell {
282
+ font-weight: 800;
283
+ font-size: 16px;
284
+ color: var(--accent-bright);
285
+ }
286
+
287
+ .footer {
288
+ display: flex;
289
+ align-items: center;
290
+ justify-content: space-between;
291
+ padding: 20px 0;
292
+ gap: 16px;
293
+ flex-wrap: wrap;
294
+ }
295
+
296
+ .disclaimer {
297
+ color: var(--muted);
298
+ font-size: 13px;
299
+ line-height: 1.6;
300
+ }
301
 
302
+ .visually-hidden {
303
+ position: absolute;
304
+ width: 1px;
305
+ height: 1px;
306
+ padding: 0;
307
+ margin: -1px;
308
+ overflow: hidden;
309
+ clip: rect(0, 0, 0, 0);
310
+ white-space: nowrap;
311
+ border: 0;
312
+ }
313
+
314
+ #summaryStats {
315
+ font-weight: 600;
316
+ color: var(--text-secondary);
317
+ font-size: 14px;
318
+ }
319
+
320
+ /* Responsive */
321
+ @media (max-width: 768px) {
322
+ .topbar {
323
+ flex-direction: column;
324
+ gap: 12px;
325
+ padding: 16px;
326
+ }
327
+
328
+ .topbar__left,
329
+ .topbar__right {
330
+ width: 100%;
331
+ justify-content: center;
332
+ }
333
+
334
+ .app-title {
335
+ font-size: 24px;
336
+ }
337
+
338
+ .container {
339
+ padding: 16px;
340
+ }
341
+
342
  thead th:nth-child(3),
343
+ thead th:nth-child(4) {
344
+ display: none;
345
+ }
346
+
347
  tbody td:nth-child(3),
348
+ tbody td:nth-child(4) {
349
+ display: none;
350
+ }
351
+
352
+ .control input[type="search"],
353
+ .control select {
354
+ min-width: 100%;
355
+ }
356
+ }
357
+
358
+ /* Pulse animasyonu - yükleme sırasında */
359
+ @keyframes pulse {
360
+ 0%, 100% { opacity: 1; }
361
+ 50% { opacity: 0.6; }
362
+ }
363
+
364
+ .loading {
365
+ animation: pulse 1.5s ease-in-out infinite;
366
  }
367
  </style>
368
  </head>
 
529
  let fullData = [];
530
 
531
  async function loadData() {
532
+ try {
533
+ // HF Spaces için birden fazla yol deneme
534
+ let res;
535
+ const paths = [
536
+ "./leaderboard_data.csv",
537
+ "leaderboard_data.csv",
538
+ "/leaderboard_data.csv"
539
+ ];
540
+
541
+ let text = "";
542
+ for (const path of paths) {
543
+ try {
544
+ res = await fetch(path, { cache: "no-cache" });
545
+ if (res.ok) {
546
+ text = await res.text();
547
+ if (text && text.trim().length > 0) {
548
+ console.log("CSV yüklendi:", path);
549
+ break;
550
+ }
551
+ }
552
+ } catch (e) {
553
+ console.warn("Yol başarısız:", path, e);
554
+ }
555
  }
556
+
557
+ if (!text || text.trim().length === 0) {
558
+ console.error("CSV dosyası yüklenemedi!");
559
+ alert("CSV dosyası yüklenemedi. Dosyanın Space'e yüklendiğinden emin olun.");
560
+ return [];
561
+ }
562
+
563
+ const { headers, records } = parseCSV(text);
564
+ if (!headers || headers.length === 0) {
565
+ console.error("CSV başlıkları bulunamadı!");
566
+ return [];
567
+ }
568
+
569
+ const keys = headers.map(normalizeHeader);
570
+ const data = records.map(cols => {
571
+ const obj = {};
572
+ for (let i = 0; i < keys.length; i += 1) {
573
+ obj[keys[i]] = cols[i];
574
+ }
575
+ const mcq = toNumber(obj.mcq);
576
+ const saq = toNumber(obj.saq);
577
+ const combined = toNumber(obj.combined);
578
+ const rank = toNumber(obj.rank);
579
+ const model = obj.model;
580
+ const provider = detectProvider(model);
581
+ return { model, provider, mcq, saq, combined, csvRank: rank };
582
+ });
583
+
584
+ console.log("Yüklenen veri sayısı:", data.length);
585
+ return data;
586
+ } catch (error) {
587
+ console.error("loadData hatası:", error);
588
+ alert("Veri yükleme hatası: " + error.message);
589
+ return [];
590
+ }
591
  }
592
 
593
  function uniqueProviders(data) {
 
638
  function render(data) {
639
  const tbody = document.getElementById("tableBody");
640
  const sorted = sortData(applyFilters(data));
641
+
642
+ if (!sorted || sorted.length === 0) {
643
+ tbody.innerHTML = '<tr><td colspan="5" style="text-align:center;padding:24px;color:var(--muted);">Veri bulunamadı. CSV dosyasını kontrol edin.</td></tr>';
644
+ const stats = document.getElementById("summaryStats");
645
+ stats.textContent = "0 model listelendi";
646
+ return;
647
+ }
648
+
649
  let html = "";
650
  sorted.forEach((d, idx) => {
651
  const rank = idx + 1;
styles.css CHANGED
@@ -1,117 +1,358 @@
1
  :root {
2
- --bg: #0b0f17;
3
- --panel: #121826;
4
- --text: #e5e7eb;
5
- --muted: #9ca3af;
6
- --accent: #8b5cf6;
7
- --border: #1f2937;
8
- --row-hover: #111827;
9
- --gold: #ffe27a33;
10
- --silver: #c0c0c033;
11
- --bronze: #cd7f3233;
12
- }
13
-
14
- * { box-sizing: border-box; }
 
 
 
 
 
 
 
15
  html, body { height: 100%; }
 
16
  body {
17
  margin: 0;
18
- background: var(--bg);
 
19
  color: var(--text);
20
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", Arial, sans-serif;
21
- line-height: 1.45;
 
22
  }
23
 
24
  .container {
25
- max-width: 1100px;
26
  margin: 0 auto;
27
- padding: 16px;
28
  }
29
 
30
  .topbar {
31
  display: flex;
32
  align-items: center;
33
  justify-content: space-between;
34
- padding: 12px 16px;
35
- border-bottom: 1px solid var(--border);
36
  background: var(--panel);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  }
38
- .topbar__left { display: flex; align-items: center; gap: 12px; }
39
- .topbar__right { display: flex; align-items: center; gap: 12px; }
40
- .app-title { font-size: 20px; margin: 0; }
41
- .muted { color: var(--muted); }
42
- .link { color: var(--accent); text-decoration: none; }
43
- .link:hover { text-decoration: underline; }
44
 
45
  .controls {
46
  display: flex;
47
- gap: 8px;
48
  align-items: center;
49
  flex-wrap: wrap;
50
- margin: 16px 0 8px;
51
  }
 
52
  .control input[type="search"],
53
  .control select {
54
  background: var(--panel);
 
55
  color: var(--text);
56
  border: 1px solid var(--border);
57
- border-radius: 8px;
58
- padding: 8px 10px;
 
 
 
 
59
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  .control button {
61
- background: var(--accent);
62
  color: #fff;
63
  border: none;
64
- border-radius: 8px;
65
- padding: 8px 12px;
 
66
  cursor: pointer;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  }
68
- .control button:hover { opacity: 0.95; }
69
 
70
- .table-wrap { border: 1px solid var(--border); border-radius: 10px; overflow: hidden; background: var(--panel); }
71
- table.table { width: 100%; border-collapse: separate; border-spacing: 0; }
72
  thead th {
73
  text-align: left;
74
- font-weight: 600;
75
- padding: 12px;
76
- border-bottom: 1px solid var(--border);
77
- background: #0f1524;
78
  position: sticky;
79
  top: 0;
80
- z-index: 1;
81
  cursor: pointer;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  }
83
- tbody td { padding: 12px; border-bottom: 1px solid var(--border); }
84
- tbody tr:hover { background: var(--row-hover); }
85
 
86
  /* Sıralama göstergeleri */
87
  th[aria-sort="ascending"]::after,
88
  th[aria-sort="descending"]::after {
89
  content: '';
90
  display: inline-block;
91
- margin-left: 6px;
92
- width: 0; height: 0;
 
93
  border-left: 5px solid transparent;
94
  border-right: 5px solid transparent;
 
 
 
 
 
95
  }
96
- th[aria-sort="ascending"]::after { border-bottom: 6px solid var(--muted); }
97
- th[aria-sort="descending"]::after { border-top: 6px solid var(--muted); }
98
 
99
- /* İlk 3 vurgusu */
100
- tr.rank-1 { background: var(--gold); }
101
- tr.rank-2 { background: var(--silver); }
102
- tr.rank-3 { background: var(--bronze); }
103
- td.rank-cell { font-weight: 700; }
104
 
105
- .footer { display: flex; align-items: center; justify-content: space-between; padding: 12px 0 0; gap: 12px; }
106
- .disclaimer { color: var(--muted); font-size: 14px; }
 
 
 
107
 
108
- .visually-hidden { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
 
 
 
109
 
110
- @media (max-width: 720px) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  thead th:nth-child(3),
112
- thead th:nth-child(4) { display: none; }
 
 
 
113
  tbody td:nth-child(3),
114
- tbody td:nth-child(4) { display: none; }
 
 
 
 
 
 
 
115
  }
116
 
 
 
 
 
 
117
 
 
 
 
 
1
  :root {
2
+ --bg-gradient-start: #0a0e27;
3
+ --bg-gradient-end: #1a1033;
4
+ --panel: rgba(17, 24, 39, 0.8);
5
+ --panel-hover: rgba(30, 41, 59, 0.95);
6
+ --text: #f8fafc;
7
+ --text-secondary: #cbd5e1;
8
+ --muted: #94a3b8;
9
+ --accent: #a78bfa;
10
+ --accent-bright: #c4b5fd;
11
+ --border: rgba(148, 163, 184, 0.15);
12
+ --row-hover: rgba(139, 92, 246, 0.1);
13
+ --gold-bg: linear-gradient(135deg, rgba(251, 191, 36, 0.15), rgba(245, 158, 11, 0.1));
14
+ --silver-bg: linear-gradient(135deg, rgba(203, 213, 225, 0.15), rgba(148, 163, 184, 0.1));
15
+ --bronze-bg: linear-gradient(135deg, rgba(251, 146, 60, 0.15), rgba(234, 88, 12, 0.1));
16
+ --shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.3);
17
+ --shadow-md: 0 4px 16px rgba(0, 0, 0, 0.4);
18
+ --shadow-lg: 0 10px 40px rgba(0, 0, 0, 0.5);
19
+ }
20
+
21
+ * { box-sizing: border-box; margin: 0; padding: 0; }
22
  html, body { height: 100%; }
23
+
24
  body {
25
  margin: 0;
26
+ background: linear-gradient(135deg, var(--bg-gradient-start) 0%, var(--bg-gradient-end) 100%);
27
+ background-attachment: fixed;
28
  color: var(--text);
29
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
30
+ line-height: 1.6;
31
+ font-size: 15px;
32
  }
33
 
34
  .container {
35
+ max-width: 1200px;
36
  margin: 0 auto;
37
+ padding: 24px;
38
  }
39
 
40
  .topbar {
41
  display: flex;
42
  align-items: center;
43
  justify-content: space-between;
44
+ padding: 20px 32px;
 
45
  background: var(--panel);
46
+ backdrop-filter: blur(12px);
47
+ border-bottom: 1px solid var(--border);
48
+ box-shadow: var(--shadow-sm);
49
+ }
50
+
51
+ .topbar__left {
52
+ display: flex;
53
+ align-items: center;
54
+ gap: 16px;
55
+ }
56
+
57
+ .topbar__right {
58
+ display: flex;
59
+ align-items: center;
60
+ gap: 20px;
61
+ font-size: 14px;
62
+ }
63
+
64
+ .app-title {
65
+ font-size: 28px;
66
+ font-weight: 700;
67
+ background: linear-gradient(135deg, var(--accent-bright) 0%, var(--accent) 100%);
68
+ -webkit-background-clip: text;
69
+ -webkit-text-fill-color: transparent;
70
+ background-clip: text;
71
+ letter-spacing: -0.5px;
72
+ }
73
+
74
+ .app-title::before {
75
+ content: "🏆 ";
76
+ -webkit-text-fill-color: var(--accent-bright);
77
+ }
78
+
79
+ .muted {
80
+ color: var(--muted);
81
+ font-size: 14px;
82
+ }
83
+
84
+ .link {
85
+ color: var(--accent-bright);
86
+ text-decoration: none;
87
+ font-weight: 500;
88
+ transition: all 0.2s ease;
89
+ position: relative;
90
+ }
91
+
92
+ .link::after {
93
+ content: '';
94
+ position: absolute;
95
+ bottom: -2px;
96
+ left: 0;
97
+ width: 0;
98
+ height: 2px;
99
+ background: var(--accent-bright);
100
+ transition: width 0.3s ease;
101
+ }
102
+
103
+ .link:hover::after {
104
+ width: 100%;
105
  }
 
 
 
 
 
 
106
 
107
  .controls {
108
  display: flex;
109
+ gap: 12px;
110
  align-items: center;
111
  flex-wrap: wrap;
112
+ margin: 24px 0 16px;
113
  }
114
+
115
  .control input[type="search"],
116
  .control select {
117
  background: var(--panel);
118
+ backdrop-filter: blur(8px);
119
  color: var(--text);
120
  border: 1px solid var(--border);
121
+ border-radius: 12px;
122
+ padding: 12px 16px;
123
+ font-size: 14px;
124
+ transition: all 0.3s ease;
125
+ box-shadow: var(--shadow-sm);
126
+ min-width: 200px;
127
  }
128
+
129
+ .control input[type="search"]:focus,
130
+ .control select:focus {
131
+ outline: none;
132
+ border-color: var(--accent);
133
+ box-shadow: 0 0 0 3px rgba(167, 139, 250, 0.2), var(--shadow-sm);
134
+ transform: translateY(-1px);
135
+ }
136
+
137
+ .control input[type="search"]::placeholder {
138
+ color: var(--muted);
139
+ }
140
+
141
  .control button {
142
+ background: linear-gradient(135deg, var(--accent) 0%, #8b5cf6 100%);
143
  color: #fff;
144
  border: none;
145
+ border-radius: 12px;
146
+ padding: 12px 24px;
147
+ font-weight: 600;
148
  cursor: pointer;
149
+ transition: all 0.3s ease;
150
+ box-shadow: var(--shadow-sm);
151
+ font-size: 14px;
152
+ }
153
+
154
+ .control button:hover {
155
+ transform: translateY(-2px);
156
+ box-shadow: var(--shadow-md);
157
+ background: linear-gradient(135deg, var(--accent-bright) 0%, var(--accent) 100%);
158
+ }
159
+
160
+ .control button:active {
161
+ transform: translateY(0);
162
+ }
163
+
164
+ .table-wrap {
165
+ border: 1px solid var(--border);
166
+ border-radius: 16px;
167
+ overflow: hidden;
168
+ background: var(--panel);
169
+ backdrop-filter: blur(12px);
170
+ box-shadow: var(--shadow-lg);
171
+ animation: fadeInUp 0.6s ease;
172
+ }
173
+
174
+ @keyframes fadeInUp {
175
+ from {
176
+ opacity: 0;
177
+ transform: translateY(20px);
178
+ }
179
+ to {
180
+ opacity: 1;
181
+ transform: translateY(0);
182
+ }
183
+ }
184
+
185
+ table.table {
186
+ width: 100%;
187
+ border-collapse: separate;
188
+ border-spacing: 0;
189
  }
 
190
 
 
 
191
  thead th {
192
  text-align: left;
193
+ font-weight: 700;
194
+ padding: 18px 16px;
195
+ border-bottom: 2px solid var(--border);
196
+ background: linear-gradient(180deg, rgba(139, 92, 246, 0.15) 0%, rgba(139, 92, 246, 0.05) 100%);
197
  position: sticky;
198
  top: 0;
199
+ z-index: 10;
200
  cursor: pointer;
201
+ transition: all 0.2s ease;
202
+ font-size: 13px;
203
+ text-transform: uppercase;
204
+ letter-spacing: 0.5px;
205
+ color: var(--text-secondary);
206
+ }
207
+
208
+ thead th:hover {
209
+ background: linear-gradient(180deg, rgba(139, 92, 246, 0.25) 0%, rgba(139, 92, 246, 0.1) 100%);
210
+ color: var(--accent-bright);
211
+ }
212
+
213
+ tbody td {
214
+ padding: 16px;
215
+ border-bottom: 1px solid var(--border);
216
+ transition: all 0.2s ease;
217
+ font-size: 14px;
218
+ }
219
+
220
+ tbody tr {
221
+ transition: all 0.3s ease;
222
+ }
223
+
224
+ tbody tr:hover {
225
+ background: var(--row-hover);
226
+ transform: scale(1.01);
227
  }
 
 
228
 
229
  /* Sıralama göstergeleri */
230
  th[aria-sort="ascending"]::after,
231
  th[aria-sort="descending"]::after {
232
  content: '';
233
  display: inline-block;
234
+ margin-left: 8px;
235
+ width: 0;
236
+ height: 0;
237
  border-left: 5px solid transparent;
238
  border-right: 5px solid transparent;
239
+ transition: all 0.2s ease;
240
+ }
241
+
242
+ th[aria-sort="ascending"]::after {
243
+ border-bottom: 6px solid var(--accent-bright);
244
  }
 
 
245
 
246
+ th[aria-sort="descending"]::after {
247
+ border-top: 6px solid var(--accent-bright);
248
+ }
 
 
249
 
250
+ /* İlk 3 vurgusu - modernize edildi */
251
+ tr.rank-1 {
252
+ background: var(--gold-bg);
253
+ border-left: 4px solid #fbbf24;
254
+ }
255
 
256
+ tr.rank-2 {
257
+ background: var(--silver-bg);
258
+ border-left: 4px solid #cbd5e1;
259
+ }
260
 
261
+ tr.rank-3 {
262
+ background: var(--bronze-bg);
263
+ border-left: 4px solid #fb923c;
264
+ }
265
+
266
+ tr.rank-1:hover,
267
+ tr.rank-2:hover,
268
+ tr.rank-3:hover {
269
+ transform: scale(1.02);
270
+ box-shadow: var(--shadow-md);
271
+ }
272
+
273
+ td.rank-cell {
274
+ font-weight: 800;
275
+ font-size: 16px;
276
+ color: var(--accent-bright);
277
+ }
278
+
279
+ .footer {
280
+ display: flex;
281
+ align-items: center;
282
+ justify-content: space-between;
283
+ padding: 20px 0;
284
+ gap: 16px;
285
+ flex-wrap: wrap;
286
+ }
287
+
288
+ .disclaimer {
289
+ color: var(--muted);
290
+ font-size: 13px;
291
+ line-height: 1.6;
292
+ }
293
+
294
+ .visually-hidden {
295
+ position: absolute;
296
+ width: 1px;
297
+ height: 1px;
298
+ padding: 0;
299
+ margin: -1px;
300
+ overflow: hidden;
301
+ clip: rect(0, 0, 0, 0);
302
+ white-space: nowrap;
303
+ border: 0;
304
+ }
305
+
306
+ #summaryStats {
307
+ font-weight: 600;
308
+ color: var(--text-secondary);
309
+ font-size: 14px;
310
+ }
311
+
312
+ /* Responsive */
313
+ @media (max-width: 768px) {
314
+ .topbar {
315
+ flex-direction: column;
316
+ gap: 12px;
317
+ padding: 16px;
318
+ }
319
+
320
+ .topbar__left,
321
+ .topbar__right {
322
+ width: 100%;
323
+ justify-content: center;
324
+ }
325
+
326
+ .app-title {
327
+ font-size: 24px;
328
+ }
329
+
330
+ .container {
331
+ padding: 16px;
332
+ }
333
+
334
  thead th:nth-child(3),
335
+ thead th:nth-child(4) {
336
+ display: none;
337
+ }
338
+
339
  tbody td:nth-child(3),
340
+ tbody td:nth-child(4) {
341
+ display: none;
342
+ }
343
+
344
+ .control input[type="search"],
345
+ .control select {
346
+ min-width: 100%;
347
+ }
348
  }
349
 
350
+ /* Pulse animasyonu - yükleme sırasında */
351
+ @keyframes pulse {
352
+ 0%, 100% { opacity: 1; }
353
+ 50% { opacity: 0.6; }
354
+ }
355
 
356
+ .loading {
357
+ animation: pulse 1.5s ease-in-out infinite;
358
+ }