JonnaMat commited on
Commit
884798e
Β·
verified Β·
1 Parent(s): 2cd72aa

Upload 8 files

Browse files
Files changed (3) hide show
  1. app.js +19 -13
  2. config.json +2 -2
  3. style.css +404 -269
app.js CHANGED
@@ -257,13 +257,16 @@ function renderBtnGroup(container, items, activeValue) {
257
  function populateFilters() {
258
  renderSidebar();
259
 
 
 
 
260
  // Metric buttons
261
  const metricEl = document.getElementById("filter-metric");
262
  renderBtnGroup(metricEl,
263
  config.metrics.map(m => ({ value: m.column, label: m.short || m.column })),
264
  filters.metric
265
  );
266
- metricEl.closest(".filter-group").style.display = config.metrics.length <= 1 ? "none" : "";
267
 
268
  updateDependentFilters();
269
  }
@@ -329,14 +332,13 @@ function buildChart(filtered) {
329
 
330
  const metricCol = filters.metric;
331
  const metricCfg = config.metrics.find(m => m.column === metricCol) || {};
332
- const groupCol = GROUP_BY;
333
- const groupFilterCfg = config.filters.find(f => f.column === groupCol);
334
 
335
- const groupVal = filters[groupCol];
336
  if (groupVal === "all") return;
337
 
338
  const groupLabel = groupFilterCfg?.value_labels?.[groupVal] || String(groupVal);
339
- const gRows = filtered.filter(r => String(r[groupCol]) === String(groupVal));
340
  if (!gRows.length) return;
341
 
342
  // If no scenarios configured, show one chart with all rows
@@ -423,7 +425,7 @@ function buildChart(filtered) {
423
  },
424
  },
425
  scales: {
426
- y: { beginAtZero: true, title: { display: true, text: yLabel, color: cssVar("--text-muted") }, grid: { color: cssVar("--chart-grid") }, ticks: { color: cssVar("--text-dim") } },
427
  x: { grid: { display: false }, ticks: { color: cssVar("--text-muted"), font: { size: 14 } } },
428
  },
429
  },
@@ -437,11 +439,10 @@ function buildChart(filtered) {
437
  function buildTables(filtered, chartsShown) {
438
  const section = document.getElementById("tables-section");
439
  section.innerHTML = "";
440
- const groupCol = GROUP_BY;
441
- const groupFilterCfg = config.filters.find(f => f.column === groupCol);
442
- const groupVal = filters[groupCol];
443
  const opts = availableOptions(filters.family);
444
- const groupVals = groupVal === "all" ? (opts[groupCol] || []) : [groupVal];
445
 
446
  // Determine which display columns are visible given current filter state
447
  const visibleDisplay = (config.display_columns || []).filter(dc => {
@@ -464,7 +465,7 @@ function buildTables(filtered, chartsShown) {
464
  const tableGroupBy = familyCfg.table_group_by || config.table_group_by || "";
465
 
466
  groupVals.forEach(gv => {
467
- const rows = filtered.filter(r => String(r[groupCol]) === String(gv));
468
  if (!rows.length) return;
469
  rows.sort((a, b) => {
470
  for (const rule of sortRules) {
@@ -551,8 +552,7 @@ function buildExperimentSetup() {
551
  section.innerHTML = "";
552
  const familyCfg = config.model_families?.[filters.family] || {};
553
  const setupMap = familyCfg.experiment_setup || {};
554
- const groupCol = GROUP_BY;
555
- const groupVal = filters[groupCol];
556
 
557
  const deviceVals = groupVal === "all"
558
  ? []
@@ -592,6 +592,12 @@ function render() {
592
 
593
  buildChart(filtered);
594
  const chartsShown = filters[GROUP_BY] !== "all";
 
 
 
 
 
 
595
  buildTables(filtered, chartsShown);
596
  buildExperimentSetup();
597
  }
 
257
  function populateFilters() {
258
  renderSidebar();
259
 
260
+ const chartsShown = filters[GROUP_BY] !== "all";
261
+
262
+
263
  // Metric buttons
264
  const metricEl = document.getElementById("filter-metric");
265
  renderBtnGroup(metricEl,
266
  config.metrics.map(m => ({ value: m.column, label: m.short || m.column })),
267
  filters.metric
268
  );
269
+ metricEl.closest(".filter-group").style.display = (config.metrics.length <= 1 || !chartsShown) ? "none" : "";
270
 
271
  updateDependentFilters();
272
  }
 
332
 
333
  const metricCol = filters.metric;
334
  const metricCfg = config.metrics.find(m => m.column === metricCol) || {};
335
+ const groupFilterCfg = config.filters.find(f => f.column === GROUP_BY);
 
336
 
337
+ const groupVal = filters[GROUP_BY];
338
  if (groupVal === "all") return;
339
 
340
  const groupLabel = groupFilterCfg?.value_labels?.[groupVal] || String(groupVal);
341
+ const gRows = filtered.filter(r => String(r[GROUP_BY]) === String(groupVal));
342
  if (!gRows.length) return;
343
 
344
  // If no scenarios configured, show one chart with all rows
 
425
  },
426
  },
427
  scales: {
428
+ y: { beginAtZero: true, title: { display: true, text: yLabel, color: cssVar("--text-muted") }, grid: { color: cssVar("--border") }, ticks: { color: cssVar("--text-dim") } },
429
  x: { grid: { display: false }, ticks: { color: cssVar("--text-muted"), font: { size: 14 } } },
430
  },
431
  },
 
439
  function buildTables(filtered, chartsShown) {
440
  const section = document.getElementById("tables-section");
441
  section.innerHTML = "";
442
+ const groupFilterCfg = config.filters.find(f => f.column === GROUP_BY);
443
+ const groupVal = filters[GROUP_BY];
 
444
  const opts = availableOptions(filters.family);
445
+ const groupVals = groupVal === "all" ? (opts[GROUP_BY] || []) : [groupVal];
446
 
447
  // Determine which display columns are visible given current filter state
448
  const visibleDisplay = (config.display_columns || []).filter(dc => {
 
465
  const tableGroupBy = familyCfg.table_group_by || config.table_group_by || "";
466
 
467
  groupVals.forEach(gv => {
468
+ const rows = filtered.filter(r => String(r[GROUP_BY]) === String(gv));
469
  if (!rows.length) return;
470
  rows.sort((a, b) => {
471
  for (const rule of sortRules) {
 
552
  section.innerHTML = "";
553
  const familyCfg = config.model_families?.[filters.family] || {};
554
  const setupMap = familyCfg.experiment_setup || {};
555
+ const groupVal = filters[GROUP_BY];
 
556
 
557
  const deviceVals = groupVal === "all"
558
  ? []
 
592
 
593
  buildChart(filtered);
594
  const chartsShown = filters[GROUP_BY] !== "all";
595
+ // Toggle metric selector visibility
596
+ const metricEl = document.getElementById("filter-metric");
597
+ if (metricEl) {
598
+ metricEl.closest(".filter-group").style.display =
599
+ (config.metrics.length <= 1 || !chartsShown) ? "none" : "";
600
+ }
601
  buildTables(filtered, chartsShown);
602
  buildExperimentSetup();
603
  }
config.json CHANGED
@@ -8,7 +8,7 @@
8
  "filters": [
9
  {
10
  "column": "type",
11
- "label": "Inference Type"
12
  },
13
  {
14
  "column": "batch",
@@ -50,7 +50,7 @@
50
  },
51
  {
52
  "column": "e2e",
53
- "label": "End-to-End Latency (s)",
54
  "short": "E2E ↓",
55
  "higher_is_better": false,
56
  "description": "End-to-end latency in seconds (lower is better). Total time from request submission to completion of the full generated response. This reflects real user-perceived latency."
 
8
  "filters": [
9
  {
10
  "column": "type",
11
+ "label": "Modality"
12
  },
13
  {
14
  "column": "batch",
 
50
  },
51
  {
52
  "column": "e2e",
53
+ "label": "End-to-End Latency (sec)",
54
  "short": "E2E ↓",
55
  "higher_is_better": false,
56
  "description": "End-to-end latency in seconds (lower is better). Total time from request submission to completion of the full generated response. This reflects real user-perceived latency."
style.css CHANGED
@@ -1,378 +1,513 @@
1
  /* ── Palette ──────────────────────────────────────────── */
2
  :root {
3
- --bg: #0B1527;
4
- --bg-opaque: rgba(11, 21, 39,0.45);
5
- --bg-surface: #1a1a2e;
6
- --teal: #58b1c3;
7
- --green: #6fcf97;
8
- --red: #ff4d6d;
9
- --pink: #ff6ec7;
10
- --purple: #9b5de5;
11
- --blue: #007F9E;
12
- --neutral: #667788;
13
- --text: #e8e8e8;
14
- --text-muted: #8899aa;
15
- --text-dim: #5a6a7a;
16
- --border: rgba(255,255,255,0.06);
17
- --chart-grid: rgba(255,255,255,0.06);
18
- --btn-hover-bg: rgba(255,255,255,0.03);
19
- --btn-active-bg: rgba(88,177,195,0.12);
20
- --btn-active-border: rgba(88,177,195,0.3);
21
- --sidebar-hover-bg: rgba(255,255,255,0.02);
22
- --sidebar-active-bg: rgba(88,177,195,0.04);
23
- --row-hover-bg: rgba(255,255,255,0.02);
24
- --row-border: rgba(255,255,255,0.03);
25
- --code-bg: rgba(88,177,195,0.1);
26
- --tooltip-bg: #2c3e50;
27
- --tooltip-text: #f1f1f1;
28
- --tooltip-body: #d9d9d9;
29
  }
30
 
31
  /* ── Reset & Base ─────────────────────────────────────── */
32
- *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
33
- html { font-size: 16px; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  body {
35
- font-family: "Montserrat", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
36
- background: var(--bg);
37
- color: var(--text);
38
- line-height: 1.6;
39
- -webkit-font-smoothing: antialiased;
40
- position: relative;
41
- }
42
- body::before {
43
- content: "";
44
- position: fixed;
45
- top: -260px;
46
- left: 50%;
47
- transform: translateX(-50%);
48
- width: 69rem;
49
- height: 42rem;
50
- background: radial-gradient(circle, rgba(0,226,213,0.25) 0%, rgba(18,208,254,0.15) 30%, transparent 70%);
51
- filter: blur(80px);
52
- pointer-events: none;
53
- z-index: 0;
54
  }
 
55
  code {
56
- background: var(--code-bg);
57
- color: var(--teal);
58
- padding: 0.15em 0.45em;
59
- border-radius: 4px;
60
- font-size: 0.95em;
61
  }
62
 
63
  /* ── Page Layout ─────────────────────────────────────── */
64
  .page {
65
- position: relative;
66
- z-index: 1;
67
- display: flex;
68
- flex-direction: row;
69
- min-height: 100vh;
70
- max-width: 1440px;
71
- margin: 0 auto;
72
  }
73
 
74
  /* ── Sidebar ─────────────────────────────────────────── */
75
  .sidebar {
76
- width: 280px;
77
- max-width: 300px;
78
- flex-shrink: 0;
79
- padding: 2rem 0;
80
- position: sticky;
81
- top: 0;
82
- height: 100vh;
83
- overflow-y: auto;
84
  }
 
85
  .sidebar-logo {
86
- display: block;
87
- padding: 0 1.25rem 3.25rem;
88
  }
 
89
  .sidebar-nav {
90
- display: flex;
91
- flex-direction: column;
92
  }
 
93
  .sidebar-item {
94
- display: block;
95
- padding: 0.5rem 1.25rem;
96
- font-size: 1.25rem;
97
- font-weight: 400;
98
- color: var(--text-dim);
99
- text-decoration: none;
100
- cursor: pointer;
101
- border-left: 2px solid transparent;
102
- transition: color 0.15s, background 0.15s, border-color 0.15s;
103
  }
 
104
  .sidebar-item:hover {
105
- color: var(--text-muted);
106
  }
 
107
  .sidebar-item.active {
108
- color: var(--teal);
109
- font-weight: 600;
110
  }
111
 
112
  /* ── Main Column ─────────────────────────────────────── */
113
  .main {
114
- flex: 1;
115
- min-width: 0;
116
  }
 
117
  .main-inner {
118
- max-width: 1100px;
119
- width: 100%;
120
- padding: 0 2rem 2rem;
121
  }
122
 
123
  /* ── Hero ────────────────────────────────────────────── */
124
  .hero {
125
- position: relative;
126
- padding: 2rem 0 2.5rem;
127
  }
 
128
  .hero-badge {
129
- display: inline-block;
130
- padding: 1px;
131
- border-radius: 999px;
132
- background: linear-gradient(90deg, var(--teal),var(--blue));
133
- margin-bottom: 1rem;
134
  }
 
135
  .hero-badge span {
136
- display: inline-block;
137
- padding: 0.35rem 1rem;
138
- border-radius: 999px;
139
- background: var(--bg-opaque);
140
- color: var(--teal);
141
- font-size: 1rem;
142
- font-weight: 600;
143
- letter-spacing: 0.03em;
144
- text-transform: uppercase;
145
  }
 
146
  .hero h1 {
147
- font-size: clamp(1.8rem, 3.5vw, 3.0rem);
148
- font-weight: 700;
149
- margin-bottom: 0.5rem;
150
- letter-spacing: -0.02em;
 
 
 
 
151
  }
152
- .hero .accent { color: var(--teal); }
153
  .hero-sub {
154
- color: var(--text-muted);
155
- font-size: 1.1rem;
156
- max-width: 620px;
157
- line-height: 1.6;
158
  }
159
 
160
  /* ── Filters ─────────────────────────────────────────── */
161
  .filters-bar {
162
- display: flex;
163
- flex-wrap: wrap;
164
- gap: 1.25rem;
165
- padding: 1rem 0;
166
- top: 0;
167
- z-index: 10;
168
  }
 
169
  .filter-group label {
170
- display: block;
171
- font-size: 0.8rem;
172
- font-weight: 600;
173
- text-transform: uppercase;
174
- letter-spacing: 0.08em;
175
- color: var(--text-dim);
176
- margin-bottom: 0.25rem;
177
- }
178
- .btn-group { display: flex; gap: 0; }
 
 
 
 
179
  .btn {
180
- background: transparent;
181
- border: 1px solid var(--border);
182
- color: var(--text-muted);
183
- font-size: 1rem;
184
- font-weight: 400;
185
- padding: 0.45rem 1rem;
186
- cursor: pointer;
187
- transition: all 0.15s;
188
- }
189
- .btn:first-child { border-radius: 6px 0 0 6px; }
190
- .btn:last-child { border-radius: 0 6px 6px 0; }
191
- .btn:not(:first-child) { margin-left: -1px; }
 
 
 
 
 
 
 
 
 
 
192
  .btn:hover {
193
- color: var(--text);
194
- background: var(--btn-hover-bg);
195
  }
 
196
  .btn.active {
197
- background: var(--btn-active-bg);
198
- color: var(--teal);
199
- border-color: var(--btn-active-border);
200
- font-weight: 600;
201
- z-index: 1;
202
- position: relative;
203
  }
204
 
205
  /* ── Chart ───────────────────────────────────────────── */
206
  .chart-block {
207
- margin: 1.5rem 0;
208
  }
 
209
  .chart-heading {
210
- font-size: 1.25rem;
211
- font-weight: 600;
212
- color: var(--text);
213
- margin-bottom: 0.25rem;
214
  }
 
215
  .chart-subtitle {
216
- font-size: 1rem;
217
- color: var(--text-muted);
218
- margin-bottom: 0.75rem;
219
  }
 
220
  .chart-wrap {
221
- height: 340px;
222
  }
223
 
224
  /* ── Tables ──────────────────────────────────────────── */
225
  .table-card {
226
- margin: 1.5rem 0 2rem;
227
  }
 
228
  .table-card h3 {
229
- font-size: 1.15rem;
230
- font-weight: 600;
231
- color: var(--text);
232
- margin-bottom: 0.5rem;
233
- padding-bottom: 0.5rem;
234
- border-bottom: 1px solid var(--border);
235
  }
 
236
  .table-scroll {
237
- overflow-x: auto;
238
- scrollbar-color: var(--text-dim) var(--border);
239
- scrollbar-width: thin;
240
- }
241
- .table-scroll::-webkit-scrollbar { height: 8px; }
242
- .table-scroll::-webkit-scrollbar-track { background: var(--border); border-radius: 4px; }
243
- .table-scroll::-webkit-scrollbar-thumb { background: var(--text-dim); border-radius: 4px; }
244
- .table-scroll::-webkit-scrollbar-thumb:hover { background: var(--text-muted); }
245
- table { width: 100%; border-collapse: collapse; font-size: 1rem; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
246
  thead th {
247
- text-align: left;
248
- font-weight: 600;
249
- font-size: 0.8rem;
250
- text-transform: uppercase;
251
- letter-spacing: 0.05em;
252
- color: var(--text-dim);
253
- padding: 0.5rem 0.75rem;
254
- border-bottom: 1px solid var(--border);
255
- white-space: nowrap;
256
  }
 
257
  tbody td {
258
- padding: 0.5rem 0.75rem;
259
- border-bottom: 1px solid var(--row-border);
260
- white-space: nowrap;
261
- color: var(--text-muted);
262
- }
263
- tbody tr:last-child td { border-bottom: none; }
264
- tbody tr:hover { background: var(--row-hover-bg); }
265
- .model-cell { display: flex; align-items: center; gap: 0.5rem; font-weight: 500; color: var(--text); }
266
- .model-cell a { color: var(--teal); text-decoration: none; transition: color 0.15s; }
267
- .model-cell a:hover { text-decoration: underline; }
268
- .model-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
269
- .oom { color: var(--red); font-weight: 600; }
270
- tbody tr.row-group-break td { border-top: 2px solid var(--border); }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
271
 
272
  /* ── Legend ───────────────────────────────────────────── */
273
  .legend-section {
274
- margin: 2rem 0;
275
- padding-top: 1.5rem;
276
  }
 
277
  .legend-grid {
278
- display: grid;
279
- grid-template-columns: 1fr;
280
- gap: 0.25rem;
281
- font-size: 0.8rem;
282
- color: var(--text-dim);
 
 
 
 
 
283
  }
284
- .legend-grid strong { color: var(--text-muted); font-weight: 500; }
285
  .experiment-setup {
286
- margin-top: 0.75rem;
287
- font-size: 0.95rem;
288
- color: var(--text-dim);
289
- font-style: italic;
290
- line-height: 1.6;
 
 
 
 
291
  }
292
- .experiment-setup p { margin-bottom: 0.25rem; }
293
 
294
  /* ── Footer ──────────────────────────────────────────── */
295
  .footer {
296
- padding: 2.5rem 0;
297
- margin-top: 2rem;
298
  }
 
299
  .footer-inner {
300
- max-width: 1440px;
301
- margin: 0 auto;
302
- padding: 0 2rem;
303
  }
 
304
  .footer-grid {
305
- display: flex;
306
- gap: 3rem;
307
- flex-wrap: wrap;
308
  }
 
309
  .footer-col {
310
- font-size: 1rem;
311
- color: var(--text-dim);
312
- line-height: 1.7;
313
  }
314
- .footer-col p { margin: 0; }
 
 
 
 
315
  .footer-col-title {
316
- font-size: 0.85rem;
317
- font-weight: 600;
318
- text-transform: uppercase;
319
- letter-spacing: 0.08em;
320
- color: var(--text);
321
  }
 
322
  .footer-logo-img {
323
- display: block;
324
- margin-bottom: 0.5rem;
325
  }
 
326
  .footer-logo {
327
- font-size: 1rem;
328
- color: var(--text-muted);
329
- margin-bottom: 1.2rem;
 
 
 
 
 
330
  }
331
- .footer-logo a { color: var(--text-muted); text-decoration: none; }
332
- .footer-logo a:hover { text-decoration: underline; }
 
 
 
333
  .footer-social {
334
- display: flex;
335
- gap: 0.75rem;
336
  }
 
337
  .footer-social a {
338
- color: var(--text-dim);
339
- transition: color 0.15s;
340
- display: flex;
341
- align-items: center;
342
  }
 
343
  .footer-social a:hover {
344
- color: var(--teal);
345
  }
346
 
347
  /* ── Responsive ──────────────────────────────────────── */
348
  @media (max-width: 768px) {
349
- .page { flex-direction: column; }
350
- .sidebar {
351
- width: 100%;
352
- max-width: none;
353
- height: auto;
354
- position: static;
355
- border-right: none;
356
- border-bottom: 1px solid var(--border);
357
- padding: 0.75rem 0;
358
- }
359
- .sidebar-nav {
360
- flex-direction: row;
361
- flex-wrap: wrap;
362
- padding: 0 0.75rem;
363
- }
364
- .sidebar-item {
365
- border-left: none;
366
- border-bottom: 2px solid transparent;
367
- padding: 0.4rem 0.75rem;
368
- font-size: 0.9rem;
369
- }
370
- .sidebar-item.active {
371
- border-left-color: transparent;
372
- border-bottom-color: var(--teal);
373
- }
374
- .main-inner { padding: 0 1rem 2rem; }
375
- .filters-bar { gap: 0.75rem; }
376
- .btn { font-size: 0.85rem; padding: 0.35rem 0.7rem; }
377
- .chart-wrap { height: 260px; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
378
  }
 
1
  /* ── Palette ──────────────────────────────────────────── */
2
  :root {
3
+ --bg: #0B1527;
4
+ --bg-opaque: rgba(11, 21, 39, 0.45);
5
+ --bg-surface: #1a1a2e;
6
+ --teal: #58b1c3;
7
+ --green: #6fcf97;
8
+ --red: #ff4d6d;
9
+ --pink: #ff6ec7;
10
+ --purple: #9b5de5;
11
+ --blue: #007F9E;
12
+ --neutral: #667788;
13
+ --text: #e8e8e8;
14
+ --text-muted: #8899aa;
15
+ --text-dim: #5a6a7a;
16
+ --border: rgba(255, 255, 255, 0.06);
17
+ --btn-hover-bg: rgba(255, 255, 255, 0.03);
18
+ --btn-active-bg: rgba(88, 177, 195, 0.12);
19
+ --btn-active-border: rgba(88, 177, 195, 0.3);
20
+ --sidebar-active-bg: rgba(88, 177, 195, 0.04);
21
+ --row-hover-bg: rgba(255, 255, 255, 0.02);
22
+ --row-border: rgba(255, 255, 255, 0.03);
23
+ --code-bg: rgba(88, 177, 195, 0.1);
24
+ --tooltip-bg: #2c3e50;
25
+ --tooltip-text: #f1f1f1;
26
+ --tooltip-body: #d9d9d9;
 
 
27
  }
28
 
29
  /* ── Reset & Base ─────────────────────────────────────── */
30
+ *, *::before, *::after {
31
+ box-sizing: border-box;
32
+ margin: 0;
33
+ padding: 0;
34
+ }
35
+
36
+ html {
37
+ font-size: 16px;
38
+ background: radial-gradient(
39
+ 800px 500px at 50% -40px,
40
+ rgba(0, 226, 213, 0.25),
41
+ rgba(18, 208, 254, 0.15) 30%,
42
+ transparent 70%
43
+ ), var(--bg);
44
+ }
45
+
46
  body {
47
+ font-family: "Montserrat", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
48
+ color: var(--text);
49
+ line-height: 1.6;
50
+ -webkit-font-smoothing: antialiased;
51
+ position: relative;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  }
53
+
54
  code {
55
+ background: var(--code-bg);
56
+ color: var(--teal);
57
+ padding: 0.15em 0.45em;
58
+ border-radius: 4px;
59
+ font-size: 0.95em;
60
  }
61
 
62
  /* ── Page Layout ─────────────────────────────────────── */
63
  .page {
64
+ position: relative;
65
+ z-index: 1;
66
+ display: flex;
67
+ flex-direction: row;
68
+ min-height: 100vh;
69
+ max-width: 1440px;
70
+ margin: 0 auto;
71
  }
72
 
73
  /* ── Sidebar ─────────────────────────────────────────── */
74
  .sidebar {
75
+ width: 280px;
76
+ max-width: 300px;
77
+ flex-shrink: 0;
78
+ padding: 2rem 0;
79
+ position: sticky;
80
+ top: 0;
81
+ height: 100vh;
82
+ overflow-y: auto;
83
  }
84
+
85
  .sidebar-logo {
86
+ display: block;
87
+ padding: 0 1.25rem 3.25rem;
88
  }
89
+
90
  .sidebar-nav {
91
+ display: flex;
92
+ flex-direction: column;
93
  }
94
+
95
  .sidebar-item {
96
+ display: block;
97
+ padding: 0.5rem 1.25rem;
98
+ font-size: 1.25rem;
99
+ font-weight: 400;
100
+ color: var(--text-dim);
101
+ text-decoration: none;
102
+ cursor: pointer;
103
+ border-left: 2px solid transparent;
104
+ transition: color 0.15s, background 0.15s, border-color 0.15s;
105
  }
106
+
107
  .sidebar-item:hover {
108
+ color: var(--text-muted);
109
  }
110
+
111
  .sidebar-item.active {
112
+ color: var(--teal);
113
+ font-weight: 600;
114
  }
115
 
116
  /* ── Main Column ─────────────────────────────────────── */
117
  .main {
118
+ flex: 1;
119
+ min-width: 0;
120
  }
121
+
122
  .main-inner {
123
+ max-width: 1100px;
124
+ width: 100%;
125
+ padding: 0 2rem 2rem;
126
  }
127
 
128
  /* ── Hero ────────────────────────────────────────────── */
129
  .hero {
130
+ position: relative;
131
+ padding: 2rem 0 2.5rem;
132
  }
133
+
134
  .hero-badge {
135
+ display: inline-block;
136
+ padding: 1px;
137
+ border-radius: 999px;
138
+ background: linear-gradient(90deg, var(--teal), var(--blue));
139
+ margin-bottom: 1rem;
140
  }
141
+
142
  .hero-badge span {
143
+ display: inline-block;
144
+ padding: 0.35rem 1rem;
145
+ border-radius: 999px;
146
+ background: var(--bg-opaque);
147
+ color: var(--teal);
148
+ font-size: 1rem;
149
+ font-weight: 600;
150
+ letter-spacing: 0.03em;
151
+ text-transform: uppercase;
152
  }
153
+
154
  .hero h1 {
155
+ font-size: clamp(1.8rem, 3.5vw, 3.0rem);
156
+ font-weight: 700;
157
+ margin-bottom: 0.5rem;
158
+ letter-spacing: -0.02em;
159
+ }
160
+
161
+ .hero .accent {
162
+ color: var(--teal);
163
  }
164
+
165
  .hero-sub {
166
+ color: var(--text-muted);
167
+ font-size: 1.1rem;
168
+ max-width: 620px;
169
+ line-height: 1.6;
170
  }
171
 
172
  /* ── Filters ─────────────────────────────────────────── */
173
  .filters-bar {
174
+ display: flex;
175
+ flex-wrap: wrap;
176
+ gap: 1.25rem;
177
+ padding: 1rem 0;
178
+ top: 0;
179
+ z-index: 10;
180
  }
181
+
182
  .filter-group label {
183
+ display: block;
184
+ font-size: 0.8rem;
185
+ font-weight: 600;
186
+ text-transform: uppercase;
187
+ letter-spacing: 0.08em;
188
+ color: var(--text-dim);
189
+ margin-bottom: 0.25rem;
190
+ }
191
+
192
+ .btn-group {
193
+ display: flex;
194
+ }
195
+
196
  .btn {
197
+ background: transparent;
198
+ border: 1px solid var(--border);
199
+ color: var(--text-muted);
200
+ font-size: 1rem;
201
+ font-weight: 400;
202
+ padding: 0.45rem 1rem;
203
+ cursor: pointer;
204
+ transition: all 0.15s;
205
+ }
206
+
207
+ .btn:first-child {
208
+ border-radius: 6px 0 0 6px;
209
+ }
210
+
211
+ .btn:last-child {
212
+ border-radius: 0 6px 6px 0;
213
+ }
214
+
215
+ .btn:not(:first-child) {
216
+ margin-left: -1px;
217
+ }
218
+
219
  .btn:hover {
220
+ color: var(--text);
221
+ background: var(--btn-hover-bg);
222
  }
223
+
224
  .btn.active {
225
+ background: var(--btn-active-bg);
226
+ color: var(--teal);
227
+ border-color: var(--btn-active-border);
228
+ font-weight: 600;
229
+ z-index: 1;
230
+ position: relative;
231
  }
232
 
233
  /* ── Chart ───────────────────────────────────────────── */
234
  .chart-block {
235
+ margin: 1.5rem 0;
236
  }
237
+
238
  .chart-heading {
239
+ font-size: 1.25rem;
240
+ font-weight: 600;
241
+ color: var(--text);
242
+ margin-bottom: 0.25rem;
243
  }
244
+
245
  .chart-subtitle {
246
+ font-size: 1rem;
247
+ color: var(--text-muted);
248
+ margin-bottom: 0.75rem;
249
  }
250
+
251
  .chart-wrap {
252
+ height: 340px;
253
  }
254
 
255
  /* ── Tables ──────────────────────────────────────────── */
256
  .table-card {
257
+ margin: 1.5rem 0 2rem;
258
  }
259
+
260
  .table-card h3 {
261
+ font-size: 1.15rem;
262
+ font-weight: 600;
263
+ color: var(--text);
264
+ margin-bottom: 0.5rem;
265
+ padding-bottom: 0.5rem;
266
+ border-bottom: 1px solid var(--border);
267
  }
268
+
269
  .table-scroll {
270
+ overflow-x: auto;
271
+ scrollbar-color: var(--text-dim) var(--border);
272
+ scrollbar-width: thin;
273
+ }
274
+
275
+ .table-scroll::-webkit-scrollbar {
276
+ height: 8px;
277
+ }
278
+
279
+ .table-scroll::-webkit-scrollbar-track {
280
+ background: var(--border);
281
+ border-radius: 4px;
282
+ }
283
+
284
+ .table-scroll::-webkit-scrollbar-thumb {
285
+ background: var(--text-dim);
286
+ border-radius: 4px;
287
+ }
288
+
289
+ .table-scroll::-webkit-scrollbar-thumb:hover {
290
+ background: var(--text-muted);
291
+ }
292
+
293
+ table {
294
+ width: 100%;
295
+ border-collapse: collapse;
296
+ font-size: 1rem;
297
+ }
298
+
299
  thead th {
300
+ text-align: left;
301
+ font-weight: 600;
302
+ font-size: 0.8rem;
303
+ text-transform: uppercase;
304
+ letter-spacing: 0.05em;
305
+ color: var(--text-dim);
306
+ padding: 0.5rem 0.75rem;
307
+ border-bottom: 1px solid var(--border);
308
+ white-space: nowrap;
309
  }
310
+
311
  tbody td {
312
+ padding: 0.5rem 0.75rem;
313
+ border-bottom: 1px solid var(--row-border);
314
+ white-space: nowrap;
315
+ color: var(--text-muted);
316
+ }
317
+
318
+ tbody tr:last-child td {
319
+ border-bottom: none;
320
+ }
321
+
322
+ tbody tr:hover {
323
+ background: var(--row-hover-bg);
324
+ }
325
+
326
+ .model-cell {
327
+ display: flex;
328
+ align-items: center;
329
+ gap: 0.5rem;
330
+ font-weight: 500;
331
+ color: var(--text);
332
+ }
333
+
334
+ .model-cell a {
335
+ color: var(--teal);
336
+ text-decoration: none;
337
+ transition: color 0.15s;
338
+ }
339
+
340
+ .model-cell a:hover {
341
+ text-decoration: underline;
342
+ }
343
+
344
+ .model-dot {
345
+ width: 8px;
346
+ height: 8px;
347
+ border-radius: 50%;
348
+ flex-shrink: 0;
349
+ }
350
+
351
+ .oom {
352
+ color: var(--red);
353
+ font-weight: 600;
354
+ }
355
+
356
+ tbody tr.row-group-break td {
357
+ border-top: 2px solid var(--border);
358
+ }
359
 
360
  /* ── Legend ───────────────────────────────────────────── */
361
  .legend-section {
362
+ margin: 2rem 0;
363
+ padding-top: 1.5rem;
364
  }
365
+
366
  .legend-grid {
367
+ display: grid;
368
+ grid-template-columns: 1fr;
369
+ gap: 0.25rem;
370
+ font-size: 0.8rem;
371
+ color: var(--text-dim);
372
+ }
373
+
374
+ .legend-grid strong {
375
+ color: var(--text-muted);
376
+ font-weight: 500;
377
  }
378
+
379
  .experiment-setup {
380
+ margin-top: 0.75rem;
381
+ font-size: 0.95rem;
382
+ color: var(--text-dim);
383
+ font-style: italic;
384
+ line-height: 1.6;
385
+ }
386
+
387
+ .experiment-setup p {
388
+ margin-bottom: 0.25rem;
389
  }
 
390
 
391
  /* ── Footer ──────────────────────────────────────────── */
392
  .footer {
393
+ padding: 2.5rem 0;
394
+ margin-top: 2rem;
395
  }
396
+
397
  .footer-inner {
398
+ max-width: 1440px;
399
+ margin: 0 auto;
400
+ padding: 0 2rem;
401
  }
402
+
403
  .footer-grid {
404
+ display: flex;
405
+ gap: 3rem;
406
+ flex-wrap: wrap;
407
  }
408
+
409
  .footer-col {
410
+ font-size: 1rem;
411
+ color: var(--text-dim);
412
+ line-height: 1.7;
413
  }
414
+
415
+ .footer-col p {
416
+ margin: 0;
417
+ }
418
+
419
  .footer-col-title {
420
+ font-size: 0.85rem;
421
+ font-weight: 600;
422
+ text-transform: uppercase;
423
+ letter-spacing: 0.08em;
424
+ color: var(--text);
425
  }
426
+
427
  .footer-logo-img {
428
+ display: block;
429
+ margin-bottom: 0.5rem;
430
  }
431
+
432
  .footer-logo {
433
+ font-size: 1rem;
434
+ color: var(--text-muted);
435
+ margin-bottom: 1.2rem;
436
+ }
437
+
438
+ .footer-logo a {
439
+ color: var(--text-muted);
440
+ text-decoration: none;
441
  }
442
+
443
+ .footer-logo a:hover {
444
+ text-decoration: underline;
445
+ }
446
+
447
  .footer-social {
448
+ display: flex;
449
+ gap: 0.75rem;
450
  }
451
+
452
  .footer-social a {
453
+ color: var(--text-dim);
454
+ transition: color 0.15s;
455
+ display: flex;
456
+ align-items: center;
457
  }
458
+
459
  .footer-social a:hover {
460
+ color: var(--teal);
461
  }
462
 
463
  /* ── Responsive ──────────────────────────────────────── */
464
  @media (max-width: 768px) {
465
+ .page {
466
+ flex-direction: column;
467
+ }
468
+
469
+ .sidebar {
470
+ width: 100%;
471
+ max-width: none;
472
+ height: auto;
473
+ position: static;
474
+ border-right: none;
475
+ border-bottom: 1px solid var(--border);
476
+ padding: 0.75rem 0;
477
+ }
478
+
479
+ .sidebar-nav {
480
+ flex-direction: row;
481
+ flex-wrap: wrap;
482
+ padding: 0 0.75rem;
483
+ }
484
+
485
+ .sidebar-item {
486
+ border-left: none;
487
+ border-bottom: 2px solid transparent;
488
+ padding: 0.4rem 0.75rem;
489
+ font-size: 0.9rem;
490
+ }
491
+
492
+ .sidebar-item.active {
493
+ border-left-color: transparent;
494
+ border-bottom-color: var(--teal);
495
+ }
496
+
497
+ .main-inner {
498
+ padding: 0 1rem 2rem;
499
+ }
500
+
501
+ .filters-bar {
502
+ gap: 0.75rem;
503
+ }
504
+
505
+ .btn {
506
+ font-size: 0.85rem;
507
+ padding: 0.35rem 0.7rem;
508
+ }
509
+
510
+ .chart-wrap {
511
+ height: 260px;
512
+ }
513
  }