Publish the interactive token-routing paper companion
Browse files- README.md +25 -4
- index.html +747 -17
- visualize.css +853 -0
README.md
CHANGED
|
@@ -1,10 +1,31 @@
|
|
| 1 |
---
|
| 2 |
title: Token Routing Interactive Paper
|
| 3 |
-
emoji:
|
| 4 |
-
colorFrom:
|
| 5 |
-
colorTo:
|
| 6 |
sdk: static
|
|
|
|
| 7 |
pinned: false
|
|
|
|
|
|
|
| 8 |
---
|
| 9 |
|
| 10 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
---
|
| 2 |
title: Token Routing Interactive Paper
|
| 3 |
+
emoji: 🧭
|
| 4 |
+
colorFrom: purple
|
| 5 |
+
colorTo: green
|
| 6 |
sdk: static
|
| 7 |
+
app_file: index.html
|
| 8 |
pinned: false
|
| 9 |
+
license: apache-2.0
|
| 10 |
+
short_description: Interactive companion for the 306.5M routing study.
|
| 11 |
---
|
| 12 |
|
| 13 |
+
# Token Identity Routing — Interactive Paper
|
| 14 |
+
|
| 15 |
+
Interactive companion for **Token Identity as a Routing Signal for Residual MLP Experts**.
|
| 16 |
+
|
| 17 |
+
The Space provides:
|
| 18 |
+
|
| 19 |
+
- an architecture explorer for the shared SwiGLU and fixed top-2 residual path;
|
| 20 |
+
- checkpoint-derived tokenizer IDs and expert assignments for selected tokens;
|
| 21 |
+
- the reported matched-run measurements and their stated limitations;
|
| 22 |
+
- live side-by-side SSE generation from `Pacific-i64/TR-MOE-306` and `Pacific-i64/Dense-306`.
|
| 23 |
+
|
| 24 |
+
The interactive interface is a presentation and inspection companion. It is not additional experimental evidence.
|
| 25 |
+
|
| 26 |
+
## Sources
|
| 27 |
+
|
| 28 |
+
- [Paper and reproducibility artifacts](https://github.com/Complexity-ML/tmlr-paper-pool)
|
| 29 |
+
- [TR-MOE-306](https://huggingface.co/Pacific-i64/TR-MOE-306)
|
| 30 |
+
- [Dense-306](https://huggingface.co/Pacific-i64/Dense-306)
|
| 31 |
+
- [vllm-i64](https://github.com/Complexity-ML/vllm-i64)
|
index.html
CHANGED
|
@@ -1,19 +1,749 @@
|
|
| 1 |
<!doctype html>
|
| 2 |
-
<html>
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
</html>
|
|
|
|
| 1 |
<!doctype html>
|
| 2 |
+
<html lang="en" data-theme="dark">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="utf-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
| 6 |
+
<meta name="description" content="Interactive companion for Token Identity as a Routing Signal for Residual MLP Experts.">
|
| 7 |
+
<title>Token Identity Routing — Interactive Paper</title>
|
| 8 |
+
<link rel="stylesheet" href="./visualize.css">
|
| 9 |
+
<script defer src="https://unpkg.com/lucide@1.17.0/dist/umd/lucide.js"></script>
|
| 10 |
+
<style>
|
| 11 |
+
html { background: var(--background); }
|
| 12 |
+
body { max-width: 1280px; margin: 0 auto; padding: clamp(14px, 3vw, 34px); }
|
| 13 |
+
</style>
|
| 14 |
+
</head>
|
| 15 |
+
<body>
|
| 16 |
+
<div id="tr-paper-demo">
|
| 17 |
+
<style>
|
| 18 |
+
#tr-paper-demo {
|
| 19 |
+
--tr-gap: clamp(12px, 2.2vw, 22px);
|
| 20 |
+
color: var(--foreground);
|
| 21 |
+
width: 100%;
|
| 22 |
+
}
|
| 23 |
+
#tr-paper-demo * { box-sizing: border-box; }
|
| 24 |
+
#tr-paper-demo .tr-shell { display: grid; gap: var(--tr-gap); }
|
| 25 |
+
#tr-paper-demo .tr-topbar,
|
| 26 |
+
#tr-paper-demo .tr-brand,
|
| 27 |
+
#tr-paper-demo .tr-actions,
|
| 28 |
+
#tr-paper-demo .tr-tabs,
|
| 29 |
+
#tr-paper-demo .tr-chip-row,
|
| 30 |
+
#tr-paper-demo .tr-run-head,
|
| 31 |
+
#tr-paper-demo .tr-legend,
|
| 32 |
+
#tr-paper-demo .tr-node-head {
|
| 33 |
+
display: flex;
|
| 34 |
+
align-items: center;
|
| 35 |
+
gap: 10px;
|
| 36 |
+
flex-wrap: wrap;
|
| 37 |
+
}
|
| 38 |
+
#tr-paper-demo .tr-topbar { justify-content: space-between; }
|
| 39 |
+
#tr-paper-demo .tr-mark {
|
| 40 |
+
display: grid;
|
| 41 |
+
place-items: center;
|
| 42 |
+
width: 34px;
|
| 43 |
+
height: 34px;
|
| 44 |
+
border-radius: 10px;
|
| 45 |
+
color: var(--primary);
|
| 46 |
+
background: color-mix(in srgb, var(--primary) 12%, transparent);
|
| 47 |
+
}
|
| 48 |
+
#tr-paper-demo .tr-brand-copy { display: grid; gap: 1px; }
|
| 49 |
+
#tr-paper-demo .tr-brand-copy strong { font-weight: 500; letter-spacing: .08em; }
|
| 50 |
+
#tr-paper-demo .tr-brand-copy span { color: var(--muted-foreground); }
|
| 51 |
+
#tr-paper-demo .tr-hero {
|
| 52 |
+
display: grid;
|
| 53 |
+
grid-template-columns: minmax(0, 1.35fr) minmax(250px, .65fr);
|
| 54 |
+
gap: var(--tr-gap);
|
| 55 |
+
align-items: end;
|
| 56 |
+
padding: clamp(10px, 2vw, 18px) 0;
|
| 57 |
+
}
|
| 58 |
+
#tr-paper-demo .tr-hero-copy { display: grid; gap: 12px; }
|
| 59 |
+
#tr-paper-demo .tr-kicker {
|
| 60 |
+
color: var(--muted-foreground);
|
| 61 |
+
letter-spacing: .12em;
|
| 62 |
+
text-transform: uppercase;
|
| 63 |
+
}
|
| 64 |
+
#tr-paper-demo .tr-hero h2 {
|
| 65 |
+
margin: 0;
|
| 66 |
+
max-width: 760px;
|
| 67 |
+
font-size: clamp(1.7rem, 4.6vw, 3.25rem);
|
| 68 |
+
line-height: 1.02;
|
| 69 |
+
letter-spacing: -.045em;
|
| 70 |
+
font-weight: 500;
|
| 71 |
+
}
|
| 72 |
+
#tr-paper-demo .tr-hero p {
|
| 73 |
+
margin: 0;
|
| 74 |
+
max-width: 680px;
|
| 75 |
+
color: var(--muted-foreground);
|
| 76 |
+
}
|
| 77 |
+
#tr-paper-demo .tr-note {
|
| 78 |
+
border-left: 2px solid var(--primary);
|
| 79 |
+
padding-left: 12px;
|
| 80 |
+
color: var(--muted-foreground);
|
| 81 |
+
}
|
| 82 |
+
#tr-paper-demo .tr-tabs {
|
| 83 |
+
border-bottom: 1px solid var(--border);
|
| 84 |
+
padding-bottom: 10px;
|
| 85 |
+
}
|
| 86 |
+
#tr-paper-demo .tr-tab[aria-selected="true"] {
|
| 87 |
+
color: var(--primary-foreground);
|
| 88 |
+
background: var(--primary);
|
| 89 |
+
}
|
| 90 |
+
#tr-paper-demo .tr-view { display: none; }
|
| 91 |
+
#tr-paper-demo .tr-view.is-active { display: grid; gap: var(--tr-gap); }
|
| 92 |
+
#tr-paper-demo .tr-overview {
|
| 93 |
+
grid-template-columns: minmax(0, 1.45fr) minmax(230px, .55fr);
|
| 94 |
+
align-items: stretch;
|
| 95 |
+
}
|
| 96 |
+
#tr-paper-demo .tr-architecture {
|
| 97 |
+
min-height: 370px;
|
| 98 |
+
position: relative;
|
| 99 |
+
display: grid;
|
| 100 |
+
grid-template-columns: repeat(12, 1fr);
|
| 101 |
+
grid-template-rows: repeat(7, minmax(36px, auto));
|
| 102 |
+
gap: 10px;
|
| 103 |
+
padding: 18px 0;
|
| 104 |
+
}
|
| 105 |
+
#tr-paper-demo .tr-lines {
|
| 106 |
+
position: absolute;
|
| 107 |
+
inset: 0;
|
| 108 |
+
width: 100%;
|
| 109 |
+
height: 100%;
|
| 110 |
+
pointer-events: none;
|
| 111 |
+
color: var(--border);
|
| 112 |
+
}
|
| 113 |
+
#tr-paper-demo .tr-lines .active {
|
| 114 |
+
color: var(--viz-series-1);
|
| 115 |
+
transition: color .2s ease, stroke-width .2s ease;
|
| 116 |
+
stroke-width: 2.5;
|
| 117 |
+
}
|
| 118 |
+
#tr-paper-demo .tr-node {
|
| 119 |
+
position: relative;
|
| 120 |
+
z-index: 1;
|
| 121 |
+
display: grid;
|
| 122 |
+
align-content: center;
|
| 123 |
+
gap: 4px;
|
| 124 |
+
min-width: 0;
|
| 125 |
+
padding: 12px;
|
| 126 |
+
border: 1px solid var(--border);
|
| 127 |
+
border-radius: 12px;
|
| 128 |
+
background: color-mix(in srgb, var(--card) 88%, transparent);
|
| 129 |
+
color: var(--card-foreground);
|
| 130 |
+
}
|
| 131 |
+
#tr-paper-demo .tr-node strong { font-weight: 500; }
|
| 132 |
+
#tr-paper-demo .tr-node span { color: var(--muted-foreground); }
|
| 133 |
+
#tr-paper-demo .tr-node.route-active {
|
| 134 |
+
border-color: var(--viz-series-1);
|
| 135 |
+
background: color-mix(in srgb, var(--viz-series-1) 12%, var(--card));
|
| 136 |
+
}
|
| 137 |
+
#tr-paper-demo .tr-context { grid-column: 2 / 7; grid-row: 1 / 2; }
|
| 138 |
+
#tr-paper-demo .tr-token { grid-column: 8 / 12; grid-row: 1 / 2; }
|
| 139 |
+
#tr-paper-demo .tr-shared { grid-column: 1 / 6; grid-row: 3 / 5; }
|
| 140 |
+
#tr-paper-demo .tr-table { grid-column: 9 / 13; grid-row: 3 / 5; }
|
| 141 |
+
#tr-paper-demo .tr-experts {
|
| 142 |
+
grid-column: 6 / 9;
|
| 143 |
+
grid-row: 3 / 5;
|
| 144 |
+
display: grid;
|
| 145 |
+
gap: 6px;
|
| 146 |
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
| 147 |
+
}
|
| 148 |
+
#tr-paper-demo .tr-expert {
|
| 149 |
+
display: grid;
|
| 150 |
+
place-items: center;
|
| 151 |
+
min-height: 42px;
|
| 152 |
+
border-radius: 8px;
|
| 153 |
+
border: 1px solid var(--border);
|
| 154 |
+
color: var(--muted-foreground);
|
| 155 |
+
background: color-mix(in srgb, var(--muted) 45%, transparent);
|
| 156 |
+
transition: background .2s ease, color .2s ease, border-color .2s ease;
|
| 157 |
+
}
|
| 158 |
+
#tr-paper-demo .tr-expert.route-active {
|
| 159 |
+
color: var(--foreground);
|
| 160 |
+
border-color: var(--viz-series-1);
|
| 161 |
+
background: color-mix(in srgb, var(--viz-series-1) 18%, transparent);
|
| 162 |
+
}
|
| 163 |
+
#tr-paper-demo .tr-sum {
|
| 164 |
+
grid-column: 5 / 9;
|
| 165 |
+
grid-row: 6 / 7;
|
| 166 |
+
place-self: center;
|
| 167 |
+
width: 46px;
|
| 168 |
+
height: 46px;
|
| 169 |
+
border-radius: 50%;
|
| 170 |
+
text-align: center;
|
| 171 |
+
padding: 0;
|
| 172 |
+
font-size: 1.3rem;
|
| 173 |
+
}
|
| 174 |
+
#tr-paper-demo .tr-output { grid-column: 9 / 13; grid-row: 6 / 7; }
|
| 175 |
+
#tr-paper-demo .tr-side { display: grid; gap: 12px; align-content: start; }
|
| 176 |
+
#tr-paper-demo .tr-metric-grid {
|
| 177 |
+
display: grid;
|
| 178 |
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
| 179 |
+
gap: 10px;
|
| 180 |
+
}
|
| 181 |
+
#tr-paper-demo .tr-route-detail { min-height: 52px; }
|
| 182 |
+
#tr-paper-demo .tr-routing-layout,
|
| 183 |
+
#tr-paper-demo .tr-results-layout,
|
| 184 |
+
#tr-paper-demo .tr-compare-grid {
|
| 185 |
+
display: grid;
|
| 186 |
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
| 187 |
+
gap: var(--tr-gap);
|
| 188 |
+
}
|
| 189 |
+
#tr-paper-demo .tr-token-grid {
|
| 190 |
+
display: grid;
|
| 191 |
+
grid-template-columns: repeat(4, minmax(0, 1fr));
|
| 192 |
+
gap: 8px;
|
| 193 |
+
}
|
| 194 |
+
#tr-paper-demo .tr-token-btn { justify-content: center; }
|
| 195 |
+
#tr-paper-demo .tr-token-btn.is-selected {
|
| 196 |
+
background: var(--primary);
|
| 197 |
+
color: var(--primary-foreground);
|
| 198 |
+
}
|
| 199 |
+
#tr-paper-demo .tr-route-matrix {
|
| 200 |
+
display: grid;
|
| 201 |
+
grid-template-columns: 70px repeat(4, minmax(0, 1fr));
|
| 202 |
+
gap: 7px;
|
| 203 |
+
align-items: center;
|
| 204 |
+
}
|
| 205 |
+
#tr-paper-demo .tr-route-cell {
|
| 206 |
+
display: grid;
|
| 207 |
+
place-items: center;
|
| 208 |
+
min-height: 38px;
|
| 209 |
+
border-radius: 8px;
|
| 210 |
+
background: color-mix(in srgb, var(--muted) 55%, transparent);
|
| 211 |
+
color: var(--muted-foreground);
|
| 212 |
+
}
|
| 213 |
+
#tr-paper-demo .tr-route-cell.is-on {
|
| 214 |
+
background: color-mix(in srgb, var(--viz-series-1) 20%, transparent);
|
| 215 |
+
color: var(--foreground);
|
| 216 |
+
}
|
| 217 |
+
#tr-paper-demo .tr-result-chart {
|
| 218 |
+
min-height: 250px;
|
| 219 |
+
display: flex;
|
| 220 |
+
align-items: end;
|
| 221 |
+
gap: 22px;
|
| 222 |
+
padding: 30px 18px 24px;
|
| 223 |
+
border-bottom: 1px solid var(--border);
|
| 224 |
+
position: relative;
|
| 225 |
+
}
|
| 226 |
+
#tr-paper-demo .tr-bar-group {
|
| 227 |
+
flex: 1;
|
| 228 |
+
display: grid;
|
| 229 |
+
grid-template-columns: repeat(2, minmax(24px, 60px));
|
| 230 |
+
justify-content: center;
|
| 231 |
+
gap: 8px;
|
| 232 |
+
align-items: end;
|
| 233 |
+
height: 190px;
|
| 234 |
+
position: relative;
|
| 235 |
+
}
|
| 236 |
+
#tr-paper-demo .tr-bar {
|
| 237 |
+
border-radius: 8px 8px 2px 2px;
|
| 238 |
+
min-height: 20px;
|
| 239 |
+
background: color-mix(in srgb, var(--viz-series-2) 58%, var(--muted));
|
| 240 |
+
position: relative;
|
| 241 |
+
transition: height .25s ease;
|
| 242 |
+
}
|
| 243 |
+
#tr-paper-demo .tr-bar.routed {
|
| 244 |
+
background: color-mix(in srgb, var(--viz-series-1) 68%, var(--muted));
|
| 245 |
+
}
|
| 246 |
+
#tr-paper-demo .tr-bar span {
|
| 247 |
+
position: absolute;
|
| 248 |
+
left: 50%;
|
| 249 |
+
bottom: calc(100% + 7px);
|
| 250 |
+
transform: translateX(-50%);
|
| 251 |
+
color: var(--foreground);
|
| 252 |
+
white-space: nowrap;
|
| 253 |
+
}
|
| 254 |
+
#tr-paper-demo .tr-bar-label {
|
| 255 |
+
position: absolute;
|
| 256 |
+
top: calc(100% + 9px);
|
| 257 |
+
left: 0;
|
| 258 |
+
right: 0;
|
| 259 |
+
text-align: center;
|
| 260 |
+
color: var(--muted-foreground);
|
| 261 |
+
}
|
| 262 |
+
#tr-paper-demo .tr-legend { justify-content: center; }
|
| 263 |
+
#tr-paper-demo .tr-swatch {
|
| 264 |
+
width: 10px;
|
| 265 |
+
height: 10px;
|
| 266 |
+
border-radius: 3px;
|
| 267 |
+
background: color-mix(in srgb, var(--viz-series-2) 58%, var(--muted));
|
| 268 |
+
}
|
| 269 |
+
#tr-paper-demo .tr-swatch.routed {
|
| 270 |
+
background: color-mix(in srgb, var(--viz-series-1) 68%, var(--muted));
|
| 271 |
+
}
|
| 272 |
+
#tr-paper-demo .tr-generation {
|
| 273 |
+
min-height: 172px;
|
| 274 |
+
white-space: pre-wrap;
|
| 275 |
+
overflow-wrap: anywhere;
|
| 276 |
+
}
|
| 277 |
+
#tr-paper-demo .tr-caret {
|
| 278 |
+
display: inline-block;
|
| 279 |
+
width: 1px;
|
| 280 |
+
height: 1em;
|
| 281 |
+
margin-left: 2px;
|
| 282 |
+
vertical-align: -.12em;
|
| 283 |
+
background: var(--primary);
|
| 284 |
+
animation: tr-blink .8s steps(1) infinite;
|
| 285 |
+
}
|
| 286 |
+
#tr-paper-demo .tr-prompt-row {
|
| 287 |
+
display: grid;
|
| 288 |
+
grid-template-columns: minmax(0, 1fr) auto;
|
| 289 |
+
gap: 10px;
|
| 290 |
+
align-items: end;
|
| 291 |
+
}
|
| 292 |
+
#tr-paper-demo .tr-status { color: var(--muted-foreground); }
|
| 293 |
+
#tr-paper-demo .tr-status.is-live { color: var(--foreground); }
|
| 294 |
+
@keyframes tr-blink { 50% { opacity: 0; } }
|
| 295 |
+
@media (prefers-reduced-motion: reduce) {
|
| 296 |
+
#tr-paper-demo .tr-caret { animation: none; }
|
| 297 |
+
}
|
| 298 |
+
@media (max-width: 680px) {
|
| 299 |
+
#tr-paper-demo .tr-hero,
|
| 300 |
+
#tr-paper-demo .tr-overview,
|
| 301 |
+
#tr-paper-demo .tr-routing-layout,
|
| 302 |
+
#tr-paper-demo .tr-results-layout,
|
| 303 |
+
#tr-paper-demo .tr-compare-grid {
|
| 304 |
+
grid-template-columns: 1fr;
|
| 305 |
+
}
|
| 306 |
+
#tr-paper-demo .tr-actions { display: none; }
|
| 307 |
+
#tr-paper-demo .tr-architecture { min-height: 440px; }
|
| 308 |
+
#tr-paper-demo .tr-context { grid-column: 1 / 8; }
|
| 309 |
+
#tr-paper-demo .tr-token { grid-column: 8 / 13; }
|
| 310 |
+
#tr-paper-demo .tr-shared { grid-column: 1 / 6; grid-row: 3 / 5; }
|
| 311 |
+
#tr-paper-demo .tr-experts { grid-column: 6 / 10; grid-row: 3 / 5; }
|
| 312 |
+
#tr-paper-demo .tr-table { grid-column: 10 / 13; grid-row: 3 / 5; }
|
| 313 |
+
#tr-paper-demo .tr-sum { grid-column: 4 / 7; }
|
| 314 |
+
#tr-paper-demo .tr-output { grid-column: 7 / 13; }
|
| 315 |
+
#tr-paper-demo .tr-token-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
| 316 |
+
#tr-paper-demo .tr-prompt-row { grid-template-columns: 1fr; }
|
| 317 |
+
}
|
| 318 |
+
@media (max-width: 430px) {
|
| 319 |
+
#tr-paper-demo .tr-tabs { gap: 6px; }
|
| 320 |
+
#tr-paper-demo .tr-tab { padding-inline: 9px; }
|
| 321 |
+
#tr-paper-demo .tr-architecture {
|
| 322 |
+
display: flex;
|
| 323 |
+
flex-direction: column;
|
| 324 |
+
min-height: auto;
|
| 325 |
+
}
|
| 326 |
+
#tr-paper-demo .tr-lines, #tr-paper-demo .tr-sum { display: none; }
|
| 327 |
+
#tr-paper-demo .tr-node,
|
| 328 |
+
#tr-paper-demo .tr-context,
|
| 329 |
+
#tr-paper-demo .tr-token,
|
| 330 |
+
#tr-paper-demo .tr-shared,
|
| 331 |
+
#tr-paper-demo .tr-table,
|
| 332 |
+
#tr-paper-demo .tr-experts,
|
| 333 |
+
#tr-paper-demo .tr-output {
|
| 334 |
+
width: 100%;
|
| 335 |
+
}
|
| 336 |
+
#tr-paper-demo .tr-route-matrix { grid-template-columns: 54px repeat(4, minmax(0, 1fr)); }
|
| 337 |
+
}
|
| 338 |
+
</style>
|
| 339 |
+
|
| 340 |
+
<div class="tr-shell">
|
| 341 |
+
<header class="tr-topbar">
|
| 342 |
+
<div class="tr-brand">
|
| 343 |
+
<span class="tr-mark"><i data-lucide="git-branch" aria-hidden="true"></i></span>
|
| 344 |
+
<span class="tr-brand-copy">
|
| 345 |
+
<strong>COMPLEXITY</strong>
|
| 346 |
+
<span class="text-small">Research companion</span>
|
| 347 |
+
</span>
|
| 348 |
+
<span class="viz-badge">Nature submission</span>
|
| 349 |
+
</div>
|
| 350 |
+
<nav class="tr-actions" aria-label="Research links">
|
| 351 |
+
<a class="btn btn-ghost" href="https://www.complexity-ai.fr/papers/token-identity-routing-residual-experts.pdf" target="_blank" rel="noopener noreferrer"><i data-lucide="file-text" aria-hidden="true"></i> Paper</a>
|
| 352 |
+
<a class="btn btn-ghost" href="https://github.com/Complexity-ML/tmlr-paper-pool" target="_blank" rel="noopener noreferrer"><i data-lucide="package-open" aria-hidden="true"></i> Supplement</a>
|
| 353 |
+
<a class="btn btn-ghost" href="https://github.com/Complexity-ML/tmlr-paper-pool" target="_blank" rel="noopener noreferrer"><i data-lucide="github" aria-hidden="true"></i> Code</a>
|
| 354 |
+
</nav>
|
| 355 |
+
</header>
|
| 356 |
+
|
| 357 |
+
<section class="tr-hero">
|
| 358 |
+
<div class="tr-hero-copy">
|
| 359 |
+
<span class="tr-kicker text-small">Interactive architecture study</span>
|
| 360 |
+
<h2>Token identity as a routing signal for residual MLP experts</h2>
|
| 361 |
+
<p>Explore how a fixed lexical lookup selects a narrow residual parameter subspace while a shared dense SwiGLU path handles contextual computation.</p>
|
| 362 |
+
<div class="tr-chip-row">
|
| 363 |
+
<span class="viz-badge">306.5M parameters</span>
|
| 364 |
+
<span class="viz-badge">8B training tokens</span>
|
| 365 |
+
<span class="viz-badge">fixed top-2 routing</span>
|
| 366 |
+
</div>
|
| 367 |
+
</div>
|
| 368 |
+
<div class="tr-note text-small">
|
| 369 |
+
Interactive companion — not additional experimental evidence.
|
| 370 |
+
</div>
|
| 371 |
+
</section>
|
| 372 |
+
|
| 373 |
+
<nav class="tr-tabs" aria-label="Interactive paper sections">
|
| 374 |
+
<button class="btn tr-tab" type="button" role="tab" aria-selected="true" data-view="overview">Architecture</button>
|
| 375 |
+
<button class="btn tr-tab" type="button" role="tab" aria-selected="false" data-view="routing">Routing lab</button>
|
| 376 |
+
<button class="btn tr-tab" type="button" role="tab" aria-selected="false" data-view="results">Results</button>
|
| 377 |
+
<button class="btn tr-tab" type="button" role="tab" aria-selected="false" data-view="compare">Live compare</button>
|
| 378 |
+
</nav>
|
| 379 |
+
|
| 380 |
+
<section class="tr-view tr-overview is-active" data-panel="overview" role="tabpanel">
|
| 381 |
+
<div>
|
| 382 |
+
<div class="tr-chip-row" aria-label="Select a token">
|
| 383 |
+
<span class="text-small text-muted">Token</span>
|
| 384 |
+
<button class="btn tr-token-choice is-selected" type="button" data-token="routing">routing</button>
|
| 385 |
+
<button class="btn tr-token-choice" type="button" data-token="context">context</button>
|
| 386 |
+
<button class="btn tr-token-choice" type="button" data-token="expert">expert</button>
|
| 387 |
+
<button class="btn tr-token-choice" type="button" data-token="shared">shared</button>
|
| 388 |
+
</div>
|
| 389 |
+
|
| 390 |
+
<div class="tr-architecture" role="img" aria-label="The contextual hidden state enters both a shared SwiGLU branch and two selected residual experts. Token identity controls only the fixed route table.">
|
| 391 |
+
<svg class="tr-lines" viewBox="0 0 1000 500" preserveAspectRatio="none" aria-hidden="true">
|
| 392 |
+
<path d="M330 72 C280 120 210 140 205 190" fill="none" stroke="currentColor" stroke-width="1.5"/>
|
| 393 |
+
<path class="active" d="M330 72 C410 115 550 135 580 190" fill="none" stroke="currentColor"/>
|
| 394 |
+
<path class="active" d="M800 72 C850 110 860 135 850 190" fill="none" stroke="currentColor"/>
|
| 395 |
+
<path class="active" d="M840 255 C790 270 730 250 690 225" fill="none" stroke="currentColor" stroke-dasharray="7 7"/>
|
| 396 |
+
<path d="M220 310 C300 360 405 400 485 415" fill="none" stroke="currentColor" stroke-width="1.5"/>
|
| 397 |
+
<path class="active" d="M630 310 C610 350 560 395 520 415" fill="none" stroke="currentColor"/>
|
| 398 |
+
<path class="active" d="M535 420 C630 430 720 430 805 420" fill="none" stroke="currentColor"/>
|
| 399 |
+
</svg>
|
| 400 |
+
|
| 401 |
+
<div class="tr-node tr-context">
|
| 402 |
+
<strong>Contextual hidden state <em>x<sub>t</sub></em></strong>
|
| 403 |
+
<span class="text-small">The same contextual vector enters both branches</span>
|
| 404 |
+
</div>
|
| 405 |
+
<div class="tr-node tr-token route-active">
|
| 406 |
+
<strong>Token identifier <em>t</em></strong>
|
| 407 |
+
<span class="text-small" data-token-id>routing · tokenizer ID 22447</span>
|
| 408 |
+
</div>
|
| 409 |
+
<div class="tr-node tr-shared">
|
| 410 |
+
<strong>Shared SwiGLU</strong>
|
| 411 |
+
<span class="text-small">Width 3,840 · all tokens · contextual computation</span>
|
| 412 |
+
</div>
|
| 413 |
+
<div class="tr-node tr-table route-active">
|
| 414 |
+
<strong>Fixed route table <em>r<sub>l</sub>(t)</em></strong>
|
| 415 |
+
<span class="text-small">Selects two of four experts</span>
|
| 416 |
+
</div>
|
| 417 |
+
<div class="tr-node tr-experts route-active">
|
| 418 |
+
<strong style="grid-column:1/-1">Residual experts</strong>
|
| 419 |
+
<span class="tr-expert" data-expert="0">E0</span>
|
| 420 |
+
<span class="tr-expert route-active" data-expert="1">E1</span>
|
| 421 |
+
<span class="tr-expert route-active" data-expert="2">E2</span>
|
| 422 |
+
<span class="tr-expert" data-expert="3">E3</span>
|
| 423 |
+
</div>
|
| 424 |
+
<button class="btn tr-sum" type="button" data-tooltip="Element-wise branch sum" aria-label="Add the branch outputs">+</button>
|
| 425 |
+
<div class="tr-node tr-output">
|
| 426 |
+
<strong>Feed-forward output</strong>
|
| 427 |
+
<span class="text-small">Shared path + 0.5 E<span data-route-a>1</span> + 0.5 E<span data-route-b>2</span></span>
|
| 428 |
+
</div>
|
| 429 |
+
</div>
|
| 430 |
+
</div>
|
| 431 |
+
|
| 432 |
+
<aside class="tr-side">
|
| 433 |
+
<div class="tr-metric-grid">
|
| 434 |
+
<div class="card viz-stat">
|
| 435 |
+
<span class="text-muted text-small">Matched pair</span>
|
| 436 |
+
<span class="viz-stat-value">306.5M</span>
|
| 437 |
+
<span class="text-small">trainable parameters</span>
|
| 438 |
+
</div>
|
| 439 |
+
<div class="card viz-stat">
|
| 440 |
+
<span class="text-muted text-small">Primary run</span>
|
| 441 |
+
<span class="viz-stat-value">8B</span>
|
| 442 |
+
<span class="text-small">FineWeb-Edu tokens</span>
|
| 443 |
+
</div>
|
| 444 |
+
</div>
|
| 445 |
+
<div class="card tr-route-detail">
|
| 446 |
+
<div class="tr-node-head">
|
| 447 |
+
<i data-lucide="route" aria-hidden="true"></i>
|
| 448 |
+
<strong>Selected route</strong>
|
| 449 |
+
</div>
|
| 450 |
+
<p data-route-copy>“routing” selects E1 + E2 in layer 1. The primary route is checkpoint-derived; the published inference runtime derives the cyclic secondary route.</p>
|
| 451 |
+
</div>
|
| 452 |
+
<div class="card">
|
| 453 |
+
<strong>Scope of evidence</strong>
|
| 454 |
+
<p class="text-muted">One matched 306.5M run pair. The result is reported as an observation, not a claim of statistical significance.</p>
|
| 455 |
+
</div>
|
| 456 |
+
</aside>
|
| 457 |
+
</section>
|
| 458 |
+
|
| 459 |
+
<section class="tr-view" data-panel="routing" role="tabpanel">
|
| 460 |
+
<div class="tr-routing-layout">
|
| 461 |
+
<div>
|
| 462 |
+
<div class="tr-run-head">
|
| 463 |
+
<div>
|
| 464 |
+
<strong>Layer-specific deterministic routes</strong>
|
| 465 |
+
<div class="text-small text-muted">Checkpoint-derived tokenizer IDs and fixed top-2 assignments.</div>
|
| 466 |
+
</div>
|
| 467 |
+
</div>
|
| 468 |
+
<div class="tr-token-grid" style="margin-top:12px">
|
| 469 |
+
<button class="btn tr-token-btn is-selected" type="button" data-lab-token="routing">routing</button>
|
| 470 |
+
<button class="btn tr-token-btn" type="button" data-lab-token="context">context</button>
|
| 471 |
+
<button class="btn tr-token-btn" type="button" data-lab-token="expert">expert</button>
|
| 472 |
+
<button class="btn tr-token-btn" type="button" data-lab-token="shared">shared</button>
|
| 473 |
+
<button class="btn tr-token-btn" type="button" data-lab-token="token">token</button>
|
| 474 |
+
<button class="btn tr-token-btn" type="button" data-lab-token="model">model</button>
|
| 475 |
+
<button class="btn tr-token-btn" type="button" data-lab-token="dense">dense</button>
|
| 476 |
+
<button class="btn tr-token-btn" type="button" data-lab-token="learned">learned</button>
|
| 477 |
+
</div>
|
| 478 |
+
</div>
|
| 479 |
+
<div class="card">
|
| 480 |
+
<div class="tr-route-matrix" aria-label="Expert assignment matrix">
|
| 481 |
+
<span></span><span class="text-small text-center">E0</span><span class="text-small text-center">E1</span><span class="text-small text-center">E2</span><span class="text-small text-center">E3</span>
|
| 482 |
+
<span class="text-small">Layer 1</span><span class="tr-route-cell" data-cell="1-0">—</span><span class="tr-route-cell is-on" data-cell="1-1">0.5</span><span class="tr-route-cell is-on" data-cell="1-2">0.5</span><span class="tr-route-cell" data-cell="1-3">—</span>
|
| 483 |
+
<span class="text-small">Layer 6</span><span class="tr-route-cell" data-cell="6-0">—</span><span class="tr-route-cell" data-cell="6-1">—</span><span class="tr-route-cell is-on" data-cell="6-2">0.5</span><span class="tr-route-cell is-on" data-cell="6-3">0.5</span>
|
| 484 |
+
<span class="text-small">Layer 12</span><span class="tr-route-cell is-on" data-cell="12-0">0.5</span><span class="tr-route-cell" data-cell="12-1">—</span><span class="tr-route-cell" data-cell="12-2">—</span><span class="tr-route-cell is-on" data-cell="12-3">0.5</span>
|
| 485 |
+
<span class="text-small">Layer 18</span><span class="tr-route-cell" data-cell="18-0">—</span><span class="tr-route-cell" data-cell="18-1">—</span><span class="tr-route-cell is-on" data-cell="18-2">0.5</span><span class="tr-route-cell is-on" data-cell="18-3">0.5</span>
|
| 486 |
+
</div>
|
| 487 |
+
</div>
|
| 488 |
+
</div>
|
| 489 |
+
<div class="tr-note text-small" data-lab-detail>Token “routing” follows a reproducible, layer-specific route. A different occurrence of the same token keeps the same route, while its hidden-state input still changes with context.</div>
|
| 490 |
+
</section>
|
| 491 |
+
|
| 492 |
+
<section class="tr-view" data-panel="results" role="tabpanel">
|
| 493 |
+
<div class="tr-results-layout">
|
| 494 |
+
<div>
|
| 495 |
+
<div class="tr-run-head">
|
| 496 |
+
<div>
|
| 497 |
+
<strong>Last common evaluation point</strong>
|
| 498 |
+
<div class="text-small text-muted">Fixed evaluation stream from the FineWeb-Edu training split · lower is better</div>
|
| 499 |
+
</div>
|
| 500 |
+
</div>
|
| 501 |
+
<div class="tr-result-chart" role="img" aria-label="Evaluation NLL: dense 2.9482, token-routed 2.9329.">
|
| 502 |
+
<div class="tr-bar-group">
|
| 503 |
+
<div class="tr-bar" style="height:81%"><span>2.9482</span></div>
|
| 504 |
+
<div class="tr-bar routed" style="height:68%"><span>2.9329</span></div>
|
| 505 |
+
<div class="tr-bar-label text-small">Evaluation NLL</div>
|
| 506 |
+
</div>
|
| 507 |
+
<div class="tr-bar-group">
|
| 508 |
+
<div class="tr-bar" style="height:75%"><span>1.00×</span></div>
|
| 509 |
+
<div class="tr-bar routed" style="height:96%"><span>0.79×</span></div>
|
| 510 |
+
<div class="tr-bar-label text-small">Training throughput</div>
|
| 511 |
+
</div>
|
| 512 |
+
</div>
|
| 513 |
+
<div class="tr-legend text-small" style="margin-top:30px">
|
| 514 |
+
<span class="tr-swatch"></span><span>Dense</span>
|
| 515 |
+
<span class="tr-swatch routed"></span><span>Token-routed</span>
|
| 516 |
+
</div>
|
| 517 |
+
</div>
|
| 518 |
+
<div class="card">
|
| 519 |
+
<table class="table table-sm">
|
| 520 |
+
<thead>
|
| 521 |
+
<tr><th>Measurement</th><th class="text-end">Dense</th><th class="text-end">Routed</th></tr>
|
| 522 |
+
</thead>
|
| 523 |
+
<tbody>
|
| 524 |
+
<tr><td>Parameters</td><td class="text-end">306.5M</td><td class="text-end">306.5M</td></tr>
|
| 525 |
+
<tr><td>Evaluation NLL</td><td class="text-end">2.9482</td><td class="text-end">2.9329</td></tr>
|
| 526 |
+
<tr><td>NLL difference</td><td class="text-end">—</td><td class="text-end">−0.0153</td></tr>
|
| 527 |
+
<tr><td>Training tokens</td><td class="text-end">8B</td><td class="text-end">8B</td></tr>
|
| 528 |
+
<tr><td>Seeds</td><td class="text-end">1</td><td class="text-end">1</td></tr>
|
| 529 |
+
</tbody>
|
| 530 |
+
</table>
|
| 531 |
+
<p class="text-small text-muted">Single-seed matched-run observation. Evaluation is not held out; downstream multiple-choice differences are within one reported standard error.</p>
|
| 532 |
+
</div>
|
| 533 |
+
</div>
|
| 534 |
+
</section>
|
| 535 |
+
|
| 536 |
+
<section class="tr-view" data-panel="compare" role="tabpanel">
|
| 537 |
+
<div class="tr-prompt-row">
|
| 538 |
+
<label class="form-label">
|
| 539 |
+
Prompt
|
| 540 |
+
<input class="form-control" data-prompt value="Machine learning is a branch of artificial intelligence that" />
|
| 541 |
+
</label>
|
| 542 |
+
<button class="btn btn-primary" type="button" data-run>
|
| 543 |
+
<i data-lucide="play" aria-hidden="true"></i> Run comparison
|
| 544 |
+
</button>
|
| 545 |
+
</div>
|
| 546 |
+
<div class="tr-compare-grid">
|
| 547 |
+
<div class="card">
|
| 548 |
+
<div class="tr-run-head">
|
| 549 |
+
<strong>Dense-306</strong>
|
| 550 |
+
<span class="viz-badge" data-dense-state>ready</span>
|
| 551 |
+
</div>
|
| 552 |
+
<p class="tr-generation" data-dense-output aria-live="polite">Dense output will stream here token by token.</p>
|
| 553 |
+
</div>
|
| 554 |
+
<div class="card">
|
| 555 |
+
<div class="tr-run-head">
|
| 556 |
+
<strong>TR-MOE-306</strong>
|
| 557 |
+
<span class="viz-badge" data-routed-state>ready</span>
|
| 558 |
+
</div>
|
| 559 |
+
<p class="tr-generation" data-routed-output aria-live="polite">Token-routed output will stream here token by token.</p>
|
| 560 |
+
</div>
|
| 561 |
+
</div>
|
| 562 |
+
<div class="tr-status text-small" data-status>Public CPU inference · SSE streaming · qualitative comparison only</div>
|
| 563 |
+
</section>
|
| 564 |
+
</div>
|
| 565 |
+
|
| 566 |
+
<script>
|
| 567 |
+
(() => {
|
| 568 |
+
const root = document.getElementById("tr-paper-demo");
|
| 569 |
+
if (!root) return;
|
| 570 |
+
|
| 571 |
+
const routes = {
|
| 572 |
+
routing: { id: 22447, layers: [[1, 2], [2, 3], [3, 0], [2, 3]] },
|
| 573 |
+
context: { id: 4057, layers: [[0, 1], [1, 2], [2, 3], [0, 1]] },
|
| 574 |
+
expert: { id: 5217, layers: [[0, 1], [1, 2], [2, 3], [0, 1]] },
|
| 575 |
+
shared: { id: 5586, layers: [[3, 0], [0, 1], [1, 2], [3, 0]] },
|
| 576 |
+
token: { id: 23394, layers: [[3, 0], [0, 1], [1, 2], [3, 0]] },
|
| 577 |
+
model: { id: 2181, layers: [[0, 1], [1, 2], [2, 3], [0, 1]] },
|
| 578 |
+
dense: { id: 8581, layers: [[0, 1], [1, 2], [2, 3], [0, 1]] },
|
| 579 |
+
learned: { id: 4273, layers: [[0, 1], [1, 2], [2, 3], [0, 1]] }
|
| 580 |
+
};
|
| 581 |
+
|
| 582 |
+
const tabs = [...root.querySelectorAll(".tr-tab")];
|
| 583 |
+
const panels = [...root.querySelectorAll(".tr-view")];
|
| 584 |
+
tabs.forEach((tab) => {
|
| 585 |
+
tab.addEventListener("click", () => {
|
| 586 |
+
tabs.forEach((item) => item.setAttribute("aria-selected", String(item === tab)));
|
| 587 |
+
panels.forEach((panel) => panel.classList.toggle("is-active", panel.dataset.panel === tab.dataset.view));
|
| 588 |
+
});
|
| 589 |
+
});
|
| 590 |
+
|
| 591 |
+
const updateArchitecture = (token) => {
|
| 592 |
+
const route = routes[token];
|
| 593 |
+
if (!route) return;
|
| 594 |
+
const pair = route.layers[0];
|
| 595 |
+
root.querySelector("[data-token-id]").textContent = `${token} · tokenizer ID ${route.id}`;
|
| 596 |
+
root.querySelector("[data-route-a]").textContent = String(pair[0]);
|
| 597 |
+
root.querySelector("[data-route-b]").textContent = String(pair[1]);
|
| 598 |
+
root.querySelector("[data-route-copy]").textContent =
|
| 599 |
+
`“${token}” selects E${pair[0]} + E${pair[1]} in layer 1. The primary route is checkpoint-derived; the published inference runtime derives the cyclic secondary route.`;
|
| 600 |
+
root.querySelectorAll("[data-expert]").forEach((expert) => {
|
| 601 |
+
expert.classList.toggle("route-active", pair.includes(Number(expert.dataset.expert)));
|
| 602 |
+
});
|
| 603 |
+
root.querySelectorAll(".tr-token-choice").forEach((button) => {
|
| 604 |
+
button.classList.toggle("is-selected", button.dataset.token === token);
|
| 605 |
+
});
|
| 606 |
+
};
|
| 607 |
+
|
| 608 |
+
root.querySelectorAll(".tr-token-choice").forEach((button) => {
|
| 609 |
+
button.addEventListener("click", () => updateArchitecture(button.dataset.token));
|
| 610 |
+
});
|
| 611 |
+
|
| 612 |
+
const updateMatrix = (token) => {
|
| 613 |
+
const route = routes[token];
|
| 614 |
+
if (!route) return;
|
| 615 |
+
const layers = [1, 6, 12, 18];
|
| 616 |
+
layers.forEach((layer, layerIndex) => {
|
| 617 |
+
const [a, b] = route.layers[layerIndex];
|
| 618 |
+
for (let expert = 0; expert < 4; expert += 1) {
|
| 619 |
+
const cell = root.querySelector(`[data-cell="${layer}-${expert}"]`);
|
| 620 |
+
const active = expert === a || expert === b;
|
| 621 |
+
cell.classList.toggle("is-on", active);
|
| 622 |
+
cell.textContent = active ? "0.5" : "—";
|
| 623 |
+
}
|
| 624 |
+
});
|
| 625 |
+
root.querySelectorAll(".tr-token-btn").forEach((button) => {
|
| 626 |
+
button.classList.toggle("is-selected", button.dataset.labToken === token);
|
| 627 |
+
});
|
| 628 |
+
root.querySelector("[data-lab-detail]").textContent =
|
| 629 |
+
`Token “${token}” (ID ${route.id}) follows these routes in the published inference runtime. Primary routes come from the checkpoint; cyclic secondary routes are deterministic.`;
|
| 630 |
+
};
|
| 631 |
+
|
| 632 |
+
root.querySelectorAll(".tr-token-btn").forEach((button) => {
|
| 633 |
+
button.addEventListener("click", () => updateMatrix(button.dataset.labToken));
|
| 634 |
+
});
|
| 635 |
+
|
| 636 |
+
const COMPARE_ENDPOINT = "https://pacific-i64-compare-306.hf.space/v1/compare";
|
| 637 |
+
let activeController = null;
|
| 638 |
+
|
| 639 |
+
const consumeSSE = async (response, onEvent) => {
|
| 640 |
+
if (!response.body) throw new Error("Streaming response body is unavailable.");
|
| 641 |
+
const reader = response.body.getReader();
|
| 642 |
+
const decoder = new TextDecoder();
|
| 643 |
+
let buffer = "";
|
| 644 |
+
while (true) {
|
| 645 |
+
const { done, value } = await reader.read();
|
| 646 |
+
if (done) break;
|
| 647 |
+
buffer += decoder.decode(value, { stream: true });
|
| 648 |
+
const lines = buffer.split("\n");
|
| 649 |
+
buffer = lines.pop() || "";
|
| 650 |
+
for (const line of lines) {
|
| 651 |
+
const trimmed = line.trim();
|
| 652 |
+
if (!trimmed.startsWith("data:")) continue;
|
| 653 |
+
const payload = trimmed.slice(5).trim();
|
| 654 |
+
if (payload === "[DONE]") return;
|
| 655 |
+
try {
|
| 656 |
+
onEvent(JSON.parse(payload));
|
| 657 |
+
} catch {
|
| 658 |
+
// Ignore malformed transport fragments.
|
| 659 |
+
}
|
| 660 |
+
}
|
| 661 |
+
}
|
| 662 |
+
};
|
| 663 |
+
|
| 664 |
+
root.querySelector("[data-run]").addEventListener("click", async () => {
|
| 665 |
+
const runButton = root.querySelector("[data-run]");
|
| 666 |
+
const denseOutput = root.querySelector("[data-dense-output]");
|
| 667 |
+
const routedOutput = root.querySelector("[data-routed-output]");
|
| 668 |
+
const denseState = root.querySelector("[data-dense-state]");
|
| 669 |
+
const routedState = root.querySelector("[data-routed-state]");
|
| 670 |
+
const status = root.querySelector("[data-status]");
|
| 671 |
+
const prompt = root.querySelector("[data-prompt]").value.trim();
|
| 672 |
+
|
| 673 |
+
if (activeController) {
|
| 674 |
+
activeController.abort();
|
| 675 |
+
activeController = null;
|
| 676 |
+
runButton.textContent = "Run comparison";
|
| 677 |
+
denseState.textContent = "stopped";
|
| 678 |
+
routedState.textContent = "stopped";
|
| 679 |
+
status.textContent = "Generation stopped.";
|
| 680 |
+
status.classList.remove("is-live");
|
| 681 |
+
return;
|
| 682 |
+
}
|
| 683 |
+
if (!prompt) {
|
| 684 |
+
status.textContent = "Enter a prompt before running the comparison.";
|
| 685 |
+
return;
|
| 686 |
+
}
|
| 687 |
+
|
| 688 |
+
const controller = new AbortController();
|
| 689 |
+
activeController = controller;
|
| 690 |
+
denseOutput.textContent = "";
|
| 691 |
+
routedOutput.textContent = "";
|
| 692 |
+
denseState.textContent = "connecting";
|
| 693 |
+
routedState.textContent = "connecting";
|
| 694 |
+
runButton.textContent = "Stop generation";
|
| 695 |
+
status.textContent = "Connecting to both public 306.5M CPU endpoints…";
|
| 696 |
+
status.classList.add("is-live");
|
| 697 |
+
|
| 698 |
+
try {
|
| 699 |
+
const response = await fetch(COMPARE_ENDPOINT, {
|
| 700 |
+
method: "POST",
|
| 701 |
+
headers: { "Content-Type": "application/json" },
|
| 702 |
+
body: JSON.stringify({
|
| 703 |
+
prompt,
|
| 704 |
+
max_tokens: 128,
|
| 705 |
+
temperature: 0.7,
|
| 706 |
+
stream: true
|
| 707 |
+
}),
|
| 708 |
+
signal: controller.signal
|
| 709 |
+
});
|
| 710 |
+
if (!response.ok) {
|
| 711 |
+
const detail = (await response.text()).slice(0, 240);
|
| 712 |
+
throw new Error(`Compare endpoint returned HTTP ${response.status}${detail ? `: ${detail}` : ""}`);
|
| 713 |
+
}
|
| 714 |
+
denseState.textContent = "streaming";
|
| 715 |
+
routedState.textContent = "streaming";
|
| 716 |
+
status.textContent = "Receiving two real SSE streams token by token…";
|
| 717 |
+
await consumeSSE(response, (event) => {
|
| 718 |
+
if (event.error) {
|
| 719 |
+
if (event.type === "dense") denseState.textContent = "error";
|
| 720 |
+
if (event.type === "tr_moe") routedState.textContent = "error";
|
| 721 |
+
return;
|
| 722 |
+
}
|
| 723 |
+
if (!event.text) return;
|
| 724 |
+
if (event.type === "dense") denseOutput.textContent += event.text;
|
| 725 |
+
if (event.type === "tr_moe") routedOutput.textContent += event.text;
|
| 726 |
+
});
|
| 727 |
+
denseState.textContent = denseOutput.textContent ? "complete" : "no output";
|
| 728 |
+
routedState.textContent = routedOutput.textContent ? "complete" : "no output";
|
| 729 |
+
status.textContent = "Comparison complete · qualitative output only";
|
| 730 |
+
} catch (error) {
|
| 731 |
+
if (error.name === "AbortError") return;
|
| 732 |
+
denseState.textContent = "unavailable";
|
| 733 |
+
routedState.textContent = "unavailable";
|
| 734 |
+
status.textContent = `Inference temporarily unavailable: ${error.message}`;
|
| 735 |
+
} finally {
|
| 736 |
+
if (activeController === controller) activeController = null;
|
| 737 |
+
runButton.textContent = "Run comparison";
|
| 738 |
+
status.classList.remove("is-live");
|
| 739 |
+
}
|
| 740 |
+
});
|
| 741 |
+
|
| 742 |
+
window.addEventListener("DOMContentLoaded", () => {
|
| 743 |
+
globalThis.lucide?.createIcons({ attrs: { width: 16, height: 16 } });
|
| 744 |
+
}, { once: true });
|
| 745 |
+
})();
|
| 746 |
+
</script>
|
| 747 |
+
</div>
|
| 748 |
+
</body>
|
| 749 |
</html>
|
visualize.css
ADDED
|
@@ -0,0 +1,853 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
:root {
|
| 2 |
+
color-scheme: light dark;
|
| 3 |
+
background-color: var(
|
| 4 |
+
--background,
|
| 5 |
+
var(--color-background-primary, light-dark(rgb(255 255 255), rgb(24 24 24)))
|
| 6 |
+
) !important;
|
| 7 |
+
|
| 8 |
+
/* Agent-facing contract; keep in sync with SKILL.md. */
|
| 9 |
+
--background: var(
|
| 10 |
+
--color-background-primary,
|
| 11 |
+
light-dark(rgb(255 255 255), rgb(24 24 24))
|
| 12 |
+
);
|
| 13 |
+
--foreground: var(
|
| 14 |
+
--color-text-primary,
|
| 15 |
+
light-dark(rgb(26 28 31), rgb(255 255 255))
|
| 16 |
+
);
|
| 17 |
+
--card: color-mix(in oklab, var(--foreground) 5%, transparent);
|
| 18 |
+
--card-foreground: var(
|
| 19 |
+
--color-text-primary,
|
| 20 |
+
light-dark(rgb(26 28 31), rgb(255 255 255))
|
| 21 |
+
);
|
| 22 |
+
--popover: var(
|
| 23 |
+
--color-background-secondary,
|
| 24 |
+
light-dark(rgb(255 255 255), rgb(45 45 45))
|
| 25 |
+
);
|
| 26 |
+
--popover-foreground: var(
|
| 27 |
+
--color-text-primary,
|
| 28 |
+
light-dark(rgb(26 28 31), rgb(255 255 255))
|
| 29 |
+
);
|
| 30 |
+
--primary: var(
|
| 31 |
+
--color-text-info,
|
| 32 |
+
light-dark(rgb(51 156 255), rgb(131 195 255))
|
| 33 |
+
);
|
| 34 |
+
--primary-foreground: var(
|
| 35 |
+
--color-text-inverse,
|
| 36 |
+
light-dark(rgb(255 255 255), rgb(13 13 13))
|
| 37 |
+
);
|
| 38 |
+
--secondary: var(
|
| 39 |
+
--color-background-secondary,
|
| 40 |
+
light-dark(rgb(255 255 255 / 96%), rgb(54 54 54 / 96%))
|
| 41 |
+
);
|
| 42 |
+
--secondary-foreground: var(
|
| 43 |
+
--color-text-primary,
|
| 44 |
+
light-dark(rgb(26 28 31), rgb(255 255 255))
|
| 45 |
+
);
|
| 46 |
+
--muted: color-mix(in srgb, var(--foreground) 10%, transparent);
|
| 47 |
+
--muted-foreground: var(
|
| 48 |
+
--color-text-secondary,
|
| 49 |
+
light-dark(rgb(26 28 31 / 49.4%), rgb(255 255 255 / 49.8%))
|
| 50 |
+
);
|
| 51 |
+
--accent: var(
|
| 52 |
+
--color-background-info,
|
| 53 |
+
light-dark(rgb(229 242 255), rgb(13 39 63))
|
| 54 |
+
);
|
| 55 |
+
--accent-foreground: var(
|
| 56 |
+
--color-text-info,
|
| 57 |
+
light-dark(rgb(51 156 255), rgb(131 195 255))
|
| 58 |
+
);
|
| 59 |
+
--destructive: var(
|
| 60 |
+
--color-text-warning,
|
| 61 |
+
light-dark(rgb(226 85 7), rgb(255 133 73))
|
| 62 |
+
);
|
| 63 |
+
--border: var(
|
| 64 |
+
--color-border-secondary,
|
| 65 |
+
light-dark(rgb(26 28 31 / 8%), rgb(255 255 255 / 8.2%))
|
| 66 |
+
);
|
| 67 |
+
--input: var(
|
| 68 |
+
--color-border-primary,
|
| 69 |
+
light-dark(
|
| 70 |
+
rgb(26 28 31 / 11.8%),
|
| 71 |
+
color-mix(in oklab, rgb(0 0 0) 10%, transparent)
|
| 72 |
+
)
|
| 73 |
+
);
|
| 74 |
+
--ring: var(
|
| 75 |
+
--color-ring-primary,
|
| 76 |
+
light-dark(rgb(51 156 255), rgb(131 195 255 / 76%))
|
| 77 |
+
);
|
| 78 |
+
--font-size-base: var(--font-text-md-size, 14px);
|
| 79 |
+
--red: light-dark(rgb(186 38 35), rgb(250 66 62));
|
| 80 |
+
--green: light-dark(rgb(0 162 64), rgb(64 201 119));
|
| 81 |
+
--viz-series-1: var(--primary);
|
| 82 |
+
--viz-series-2: light-dark(rgb(243 136 59), rgb(245 154 86));
|
| 83 |
+
--viz-series-3: light-dark(rgb(93 201 119), rgb(116 213 139));
|
| 84 |
+
--viz-series-4: light-dark(rgb(235 119 177), rgb(240 143 192));
|
| 85 |
+
--viz-series-5: light-dark(rgb(155 121 236), rgb(170 145 239));
|
| 86 |
+
--viz-series-6: light-dark(rgb(58 185 177), rgb(90 203 194));
|
| 87 |
+
|
| 88 |
+
/* Internal implementation variables; not part of the agent contract. */
|
| 89 |
+
--font-sans: -apple-system, system-ui, "Segoe UI", sans-serif;
|
| 90 |
+
--font-mono:
|
| 91 |
+
ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono",
|
| 92 |
+
monospace;
|
| 93 |
+
--font-size-normal: max(11px, var(--font-size-base));
|
| 94 |
+
--font-size-tooltip: calc(var(--font-size-base) - 1px);
|
| 95 |
+
--font-size-small: max(11px, calc(var(--font-size-base) - 2px));
|
| 96 |
+
--font-size-h1: calc(var(--font-size-normal) * 1.7142857143);
|
| 97 |
+
--font-size-h2: calc(var(--font-size-normal) * 1.4285714286);
|
| 98 |
+
--font-size-h3: calc(var(--font-size-normal) * 1.2857142857);
|
| 99 |
+
--font-weight-normal: 430;
|
| 100 |
+
--font-weight-medium: 500;
|
| 101 |
+
--line-height-normal: calc(var(--font-size-normal) * 1.5);
|
| 102 |
+
--line-height-tooltip: calc(var(--font-size-tooltip) * 1.4285714286);
|
| 103 |
+
--line-height-small: calc(var(--font-size-small) + 4px);
|
| 104 |
+
--radius: var(--border-radius-lg, 12.5px);
|
| 105 |
+
--radius-sm: calc(var(--radius) * 0.6);
|
| 106 |
+
--radius-md: calc(var(--radius) * 0.8);
|
| 107 |
+
--radius-lg: var(--radius);
|
| 108 |
+
--radius-2xl: calc(var(--radius) * 1.6);
|
| 109 |
+
--radius-full: 9999px;
|
| 110 |
+
--shadow-sm: 0 1px 2px -1px rgb(0 0 0 / 8%);
|
| 111 |
+
--checkmark-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 17 17'%3E%3Cpath d='M12.8961 3.64101C13.1297 3.41418 13.4984 3.37523 13.7779 3.56581C14.0571 3.75635 14.1554 4.11331 14.0299 4.41347L13.9615 4.53847L7.71151 13.7045C7.59411 13.8767 7.4063 13.9877 7.19881 14.0072C6.99136 14.0267 6.78564 13.9533 6.63826 13.806L2.88826 10.056L2.79842 9.9457C2.6192 9.67407 2.64927 9.30496 2.88826 9.06581C3.12738 8.82669 3.49647 8.79676 3.76815 8.97597L3.8785 9.06581L7.03084 12.2182L12.8053 3.74941L12.8961 3.64101Z'/%3E%3C/svg%3E");
|
| 112 |
+
|
| 113 |
+
/* Legacy aliases; not part of the current agent contract. */
|
| 114 |
+
--viz-bg: transparent;
|
| 115 |
+
--viz-panel: var(--card);
|
| 116 |
+
--viz-border: var(--border);
|
| 117 |
+
--viz-text: var(--foreground);
|
| 118 |
+
--viz-muted: var(--muted-foreground);
|
| 119 |
+
--viz-accent: var(--primary);
|
| 120 |
+
--viz-accent-text: var(--primary-foreground);
|
| 121 |
+
--viz-accent-bg: var(--accent);
|
| 122 |
+
--viz-font-size: var(--font-size-base);
|
| 123 |
+
--viz-warning: var(--destructive);
|
| 124 |
+
}
|
| 125 |
+
|
| 126 |
+
:root[data-theme="light"] {
|
| 127 |
+
color-scheme: light;
|
| 128 |
+
}
|
| 129 |
+
|
| 130 |
+
:root[data-theme="dark"] {
|
| 131 |
+
color-scheme: dark;
|
| 132 |
+
}
|
| 133 |
+
|
| 134 |
+
* {
|
| 135 |
+
box-sizing: border-box;
|
| 136 |
+
}
|
| 137 |
+
|
| 138 |
+
html > body {
|
| 139 |
+
/* Preserve MCP aliases for older inline renderers without creating :root cycles. */
|
| 140 |
+
--color-background-primary: var(
|
| 141 |
+
--background,
|
| 142 |
+
light-dark(rgb(255 255 255), rgb(24 24 24))
|
| 143 |
+
);
|
| 144 |
+
--color-text-primary: var(
|
| 145 |
+
--foreground,
|
| 146 |
+
light-dark(rgb(26 28 31), rgb(255 255 255))
|
| 147 |
+
);
|
| 148 |
+
--color-border-secondary: var(
|
| 149 |
+
--border,
|
| 150 |
+
light-dark(rgb(26 28 31 / 8%), rgb(255 255 255 / 8.2%))
|
| 151 |
+
);
|
| 152 |
+
|
| 153 |
+
margin: 0;
|
| 154 |
+
padding: 5px;
|
| 155 |
+
color: var(--foreground);
|
| 156 |
+
background: transparent !important;
|
| 157 |
+
font-family: var(--font-sans);
|
| 158 |
+
font-size: var(--font-size-normal);
|
| 159 |
+
font-weight: var(--font-weight-normal);
|
| 160 |
+
line-height: var(--line-height-normal);
|
| 161 |
+
}
|
| 162 |
+
|
| 163 |
+
a {
|
| 164 |
+
color: color-mix(in srgb, var(--viz-accent) 80%, var(--viz-text) 20%);
|
| 165 |
+
cursor: pointer;
|
| 166 |
+
font-weight: var(--font-weight-medium, 500);
|
| 167 |
+
text-decoration: none;
|
| 168 |
+
text-underline-offset: 2px;
|
| 169 |
+
}
|
| 170 |
+
|
| 171 |
+
a:is(:hover, :focus-visible) {
|
| 172 |
+
text-decoration-line: underline;
|
| 173 |
+
text-decoration-style: dashed;
|
| 174 |
+
text-decoration-thickness: 0.5px;
|
| 175 |
+
}
|
| 176 |
+
|
| 177 |
+
h1,
|
| 178 |
+
h2,
|
| 179 |
+
h3,
|
| 180 |
+
h4,
|
| 181 |
+
h5,
|
| 182 |
+
h6,
|
| 183 |
+
p {
|
| 184 |
+
margin-block: 0;
|
| 185 |
+
}
|
| 186 |
+
|
| 187 |
+
h1 {
|
| 188 |
+
font-size: var(--font-size-h1);
|
| 189 |
+
font-weight: var(--font-weight-medium);
|
| 190 |
+
line-height: 1.25;
|
| 191 |
+
}
|
| 192 |
+
|
| 193 |
+
h2 {
|
| 194 |
+
font-size: var(--font-size-h2);
|
| 195 |
+
font-weight: var(--font-weight-medium);
|
| 196 |
+
line-height: 1.25;
|
| 197 |
+
}
|
| 198 |
+
|
| 199 |
+
h3,
|
| 200 |
+
h4,
|
| 201 |
+
h5,
|
| 202 |
+
h6 {
|
| 203 |
+
font-size: var(--font-size-h3);
|
| 204 |
+
font-weight: var(--font-weight-medium);
|
| 205 |
+
line-height: 1.3;
|
| 206 |
+
}
|
| 207 |
+
|
| 208 |
+
b,
|
| 209 |
+
strong,
|
| 210 |
+
th {
|
| 211 |
+
font-weight: var(--font-weight-medium);
|
| 212 |
+
}
|
| 213 |
+
|
| 214 |
+
code:not(pre code) {
|
| 215 |
+
display: inline;
|
| 216 |
+
padding: 1px 6px;
|
| 217 |
+
border-radius: var(--radius-sm);
|
| 218 |
+
corner-shape: superellipse(1.5);
|
| 219 |
+
background: var(--muted);
|
| 220 |
+
font-family: var(--font-mono);
|
| 221 |
+
font-size: 0.92em;
|
| 222 |
+
overflow-wrap: anywhere;
|
| 223 |
+
-webkit-box-decoration-break: clone;
|
| 224 |
+
box-decoration-break: clone;
|
| 225 |
+
word-break: break-word;
|
| 226 |
+
}
|
| 227 |
+
|
| 228 |
+
.table-responsive {
|
| 229 |
+
width: 100%;
|
| 230 |
+
overflow-x: auto;
|
| 231 |
+
scrollbar-width: thin;
|
| 232 |
+
}
|
| 233 |
+
|
| 234 |
+
.table {
|
| 235 |
+
width: 100%;
|
| 236 |
+
border-collapse: collapse;
|
| 237 |
+
color: var(--foreground);
|
| 238 |
+
font: inherit;
|
| 239 |
+
text-align: start;
|
| 240 |
+
}
|
| 241 |
+
|
| 242 |
+
.table :is(th, td) {
|
| 243 |
+
padding-block: 10px;
|
| 244 |
+
padding-inline: 0 24px;
|
| 245 |
+
overflow-wrap: anywhere;
|
| 246 |
+
border-bottom: 1px solid var(--border);
|
| 247 |
+
text-align: start;
|
| 248 |
+
vertical-align: top;
|
| 249 |
+
}
|
| 250 |
+
|
| 251 |
+
.table-responsive > .table :is(th, td) {
|
| 252 |
+
overflow-wrap: break-word;
|
| 253 |
+
}
|
| 254 |
+
|
| 255 |
+
.table :is(th, td):last-child {
|
| 256 |
+
padding-inline-end: 0;
|
| 257 |
+
}
|
| 258 |
+
|
| 259 |
+
.table :is(caption, thead th) {
|
| 260 |
+
font-weight: 600;
|
| 261 |
+
}
|
| 262 |
+
|
| 263 |
+
.table thead th {
|
| 264 |
+
padding-block: 8px;
|
| 265 |
+
border-bottom-color: color-mix(in srgb, var(--foreground) 16%, transparent);
|
| 266 |
+
}
|
| 267 |
+
|
| 268 |
+
.table tbody tr:last-child :is(th, td) {
|
| 269 |
+
border-bottom: 0;
|
| 270 |
+
}
|
| 271 |
+
|
| 272 |
+
.table.table-sm :is(th, td) {
|
| 273 |
+
padding-block: 6px;
|
| 274 |
+
}
|
| 275 |
+
|
| 276 |
+
.table.table-sm :is(th, td):not(:last-child) {
|
| 277 |
+
padding-inline-end: 16px;
|
| 278 |
+
}
|
| 279 |
+
|
| 280 |
+
.table :is(.text-end, [align="right"]) {
|
| 281 |
+
text-align: end;
|
| 282 |
+
font-variant-numeric: tabular-nums;
|
| 283 |
+
}
|
| 284 |
+
|
| 285 |
+
.table :is(.text-center, [align="center"]) {
|
| 286 |
+
text-align: center;
|
| 287 |
+
}
|
| 288 |
+
|
| 289 |
+
.table .text-nowrap {
|
| 290 |
+
white-space: nowrap;
|
| 291 |
+
}
|
| 292 |
+
|
| 293 |
+
#widget {
|
| 294 |
+
display: flex;
|
| 295 |
+
flex-direction: column;
|
| 296 |
+
gap: 12px;
|
| 297 |
+
width: 100%;
|
| 298 |
+
padding: 0;
|
| 299 |
+
background: transparent !important;
|
| 300 |
+
}
|
| 301 |
+
|
| 302 |
+
.card {
|
| 303 |
+
min-width: 0;
|
| 304 |
+
padding: 12px;
|
| 305 |
+
overflow: hidden;
|
| 306 |
+
overflow-wrap: break-word;
|
| 307 |
+
border-radius: var(--radius-2xl);
|
| 308 |
+
corner-shape: superellipse(1.5);
|
| 309 |
+
color: var(--card-foreground);
|
| 310 |
+
background: var(--card);
|
| 311 |
+
}
|
| 312 |
+
|
| 313 |
+
#widget > :not(.card) {
|
| 314 |
+
width: 100% !important;
|
| 315 |
+
max-width: none !important;
|
| 316 |
+
margin: 0 !important;
|
| 317 |
+
padding: 0 !important;
|
| 318 |
+
border: 0 !important;
|
| 319 |
+
border-radius: 0 !important;
|
| 320 |
+
background: transparent !important;
|
| 321 |
+
box-shadow: none !important;
|
| 322 |
+
}
|
| 323 |
+
|
| 324 |
+
.tooltip {
|
| 325 |
+
position: fixed;
|
| 326 |
+
z-index: 50;
|
| 327 |
+
top: 0;
|
| 328 |
+
left: 0;
|
| 329 |
+
width: max-content;
|
| 330 |
+
max-width: min(
|
| 331 |
+
20rem,
|
| 332 |
+
var(--tooltip-available-width, calc(100vw - 10px)),
|
| 333 |
+
calc(100vw - 10px)
|
| 334 |
+
);
|
| 335 |
+
max-height: min(
|
| 336 |
+
var(--tooltip-available-height, calc(100vh - 10px)),
|
| 337 |
+
calc(100vh - 10px)
|
| 338 |
+
);
|
| 339 |
+
padding: 4px 8px;
|
| 340 |
+
border: 1px solid var(--border);
|
| 341 |
+
border-radius: var(--radius-lg);
|
| 342 |
+
corner-shape: superellipse(1.5);
|
| 343 |
+
color: var(--popover-foreground);
|
| 344 |
+
background: var(--popover);
|
| 345 |
+
box-shadow: none;
|
| 346 |
+
font-size: var(--font-size-tooltip);
|
| 347 |
+
line-height: var(--line-height-tooltip);
|
| 348 |
+
overflow-wrap: break-word;
|
| 349 |
+
white-space: normal;
|
| 350 |
+
pointer-events: none;
|
| 351 |
+
user-select: none;
|
| 352 |
+
}
|
| 353 |
+
|
| 354 |
+
.viz-grid {
|
| 355 |
+
display: grid;
|
| 356 |
+
grid-template-columns: repeat(auto-fit, minmax(max(180px, 24%), 1fr));
|
| 357 |
+
gap: 10px;
|
| 358 |
+
}
|
| 359 |
+
|
| 360 |
+
.viz-stat {
|
| 361 |
+
display: flex;
|
| 362 |
+
flex-direction: column;
|
| 363 |
+
gap: 2px;
|
| 364 |
+
}
|
| 365 |
+
|
| 366 |
+
.viz-stat-value {
|
| 367 |
+
font-size: var(--font-size-h2);
|
| 368 |
+
font-weight: var(--font-weight-medium);
|
| 369 |
+
line-height: 1.25;
|
| 370 |
+
}
|
| 371 |
+
|
| 372 |
+
.viz-row {
|
| 373 |
+
display: flex;
|
| 374 |
+
flex-wrap: wrap;
|
| 375 |
+
align-items: center;
|
| 376 |
+
gap: 10px;
|
| 377 |
+
}
|
| 378 |
+
|
| 379 |
+
.viz-badge {
|
| 380 |
+
padding: 3px 8px;
|
| 381 |
+
border-radius: var(--radius-full);
|
| 382 |
+
color: var(--accent-foreground);
|
| 383 |
+
background: var(--accent);
|
| 384 |
+
font-weight: var(--font-weight-medium);
|
| 385 |
+
}
|
| 386 |
+
|
| 387 |
+
small,
|
| 388 |
+
.text-small,
|
| 389 |
+
.viz-badge {
|
| 390 |
+
font-size: var(--font-size-small);
|
| 391 |
+
line-height: var(--line-height-small);
|
| 392 |
+
}
|
| 393 |
+
|
| 394 |
+
.text-muted {
|
| 395 |
+
color: var(--muted-foreground);
|
| 396 |
+
}
|
| 397 |
+
|
| 398 |
+
.sr-only {
|
| 399 |
+
position: absolute;
|
| 400 |
+
width: 1px;
|
| 401 |
+
height: 1px;
|
| 402 |
+
padding: 0;
|
| 403 |
+
overflow: hidden;
|
| 404 |
+
clip: rect(0, 0, 0, 0);
|
| 405 |
+
white-space: nowrap;
|
| 406 |
+
border: 0;
|
| 407 |
+
}
|
| 408 |
+
|
| 409 |
+
.viz-controls {
|
| 410 |
+
display: flex;
|
| 411 |
+
flex-wrap: wrap;
|
| 412 |
+
align-items: center;
|
| 413 |
+
gap: 8px;
|
| 414 |
+
}
|
| 415 |
+
|
| 416 |
+
.viz-controls > .form-label {
|
| 417 |
+
display: grid;
|
| 418 |
+
min-width: min(100%, 260px);
|
| 419 |
+
flex: 1 1 280px;
|
| 420 |
+
grid-template-columns: minmax(0, 1fr) auto;
|
| 421 |
+
align-items: baseline;
|
| 422 |
+
gap: 2px 12px;
|
| 423 |
+
margin-bottom: 0;
|
| 424 |
+
}
|
| 425 |
+
|
| 426 |
+
.viz-controls > .form-label > :is(.form-control, .form-range, .form-select) {
|
| 427 |
+
grid-column: 1 / -1;
|
| 428 |
+
}
|
| 429 |
+
|
| 430 |
+
.btn,
|
| 431 |
+
.form-check-input,
|
| 432 |
+
.form-control,
|
| 433 |
+
.form-range,
|
| 434 |
+
.form-select {
|
| 435 |
+
font: inherit;
|
| 436 |
+
}
|
| 437 |
+
|
| 438 |
+
.btn {
|
| 439 |
+
appearance: button;
|
| 440 |
+
display: inline-flex;
|
| 441 |
+
inline-size: fit-content;
|
| 442 |
+
max-inline-size: 100%;
|
| 443 |
+
min-height: 28px;
|
| 444 |
+
align-items: center;
|
| 445 |
+
justify-content: center;
|
| 446 |
+
gap: 4px;
|
| 447 |
+
margin: 0;
|
| 448 |
+
padding: 0 8px;
|
| 449 |
+
-webkit-app-region: no-drag;
|
| 450 |
+
border: 1px solid var(--input);
|
| 451 |
+
border-radius: var(--radius-lg);
|
| 452 |
+
corner-shape: superellipse(1.5);
|
| 453 |
+
color: var(--secondary-foreground);
|
| 454 |
+
background: var(--secondary);
|
| 455 |
+
cursor: var(--cursor-interaction, pointer);
|
| 456 |
+
text-align: center;
|
| 457 |
+
text-decoration: none;
|
| 458 |
+
white-space: nowrap;
|
| 459 |
+
user-select: none;
|
| 460 |
+
-webkit-font-smoothing: antialiased;
|
| 461 |
+
}
|
| 462 |
+
|
| 463 |
+
.btn:is(.btn-block, .viz-tile) {
|
| 464 |
+
inline-size: 100%;
|
| 465 |
+
}
|
| 466 |
+
|
| 467 |
+
.btn.viz-tile {
|
| 468 |
+
min-width: 0;
|
| 469 |
+
overflow-wrap: anywhere;
|
| 470 |
+
white-space: normal;
|
| 471 |
+
}
|
| 472 |
+
|
| 473 |
+
a.btn {
|
| 474 |
+
cursor: pointer;
|
| 475 |
+
text-decoration: none;
|
| 476 |
+
}
|
| 477 |
+
|
| 478 |
+
.btn:not(:disabled):hover {
|
| 479 |
+
background: color-mix(in srgb, var(--foreground) 6%, var(--secondary));
|
| 480 |
+
}
|
| 481 |
+
|
| 482 |
+
.btn-primary {
|
| 483 |
+
border-color: transparent;
|
| 484 |
+
color: var(--primary-foreground);
|
| 485 |
+
background: var(--foreground);
|
| 486 |
+
background-clip: padding-box;
|
| 487 |
+
}
|
| 488 |
+
|
| 489 |
+
.btn-primary .text-muted {
|
| 490 |
+
color: color-mix(in srgb, var(--primary-foreground) 50%, transparent);
|
| 491 |
+
}
|
| 492 |
+
|
| 493 |
+
.btn-primary:not(:disabled):hover {
|
| 494 |
+
background: color-mix(in srgb, var(--foreground) 80%, transparent);
|
| 495 |
+
background-clip: padding-box;
|
| 496 |
+
}
|
| 497 |
+
|
| 498 |
+
.btn-ghost {
|
| 499 |
+
border-color: transparent;
|
| 500 |
+
color: var(--muted-foreground);
|
| 501 |
+
background: transparent;
|
| 502 |
+
}
|
| 503 |
+
|
| 504 |
+
.btn-ghost:not(:disabled):hover {
|
| 505 |
+
color: var(--foreground);
|
| 506 |
+
background: color-mix(in srgb, var(--foreground) 6%, var(--secondary));
|
| 507 |
+
}
|
| 508 |
+
|
| 509 |
+
.btn:disabled {
|
| 510 |
+
cursor: not-allowed;
|
| 511 |
+
opacity: 0.4;
|
| 512 |
+
}
|
| 513 |
+
|
| 514 |
+
[data-lucide] {
|
| 515 |
+
stroke-width: 1.6;
|
| 516 |
+
}
|
| 517 |
+
|
| 518 |
+
.form-label {
|
| 519 |
+
display: block;
|
| 520 |
+
margin-bottom: 6px;
|
| 521 |
+
color: var(--foreground);
|
| 522 |
+
}
|
| 523 |
+
|
| 524 |
+
.form-control {
|
| 525 |
+
display: block;
|
| 526 |
+
width: 100%;
|
| 527 |
+
min-height: 28px;
|
| 528 |
+
padding: 0 8px;
|
| 529 |
+
outline: none;
|
| 530 |
+
border: 1px solid var(--input);
|
| 531 |
+
border-radius: var(--radius-lg);
|
| 532 |
+
corner-shape: superellipse(1.5);
|
| 533 |
+
color: var(--foreground);
|
| 534 |
+
background: var(--secondary);
|
| 535 |
+
}
|
| 536 |
+
|
| 537 |
+
.form-control::placeholder {
|
| 538 |
+
color: var(--muted-foreground);
|
| 539 |
+
}
|
| 540 |
+
|
| 541 |
+
.form-control[type="file"] {
|
| 542 |
+
padding: 0;
|
| 543 |
+
overflow: hidden;
|
| 544 |
+
cursor: var(--cursor-interaction, pointer);
|
| 545 |
+
}
|
| 546 |
+
|
| 547 |
+
.form-control[type="file"]::file-selector-button {
|
| 548 |
+
min-height: 26px;
|
| 549 |
+
margin-right: 8px;
|
| 550 |
+
padding: 0 8px;
|
| 551 |
+
border: 0;
|
| 552 |
+
border-right: 1px solid var(--input);
|
| 553 |
+
color: var(--secondary-foreground);
|
| 554 |
+
background: var(--secondary);
|
| 555 |
+
cursor: inherit;
|
| 556 |
+
font: inherit;
|
| 557 |
+
}
|
| 558 |
+
|
| 559 |
+
.form-control[type="file"]:not(:disabled):hover::file-selector-button {
|
| 560 |
+
background: color-mix(in srgb, var(--foreground) 6%, var(--secondary));
|
| 561 |
+
}
|
| 562 |
+
|
| 563 |
+
.form-control-color[type="color"] {
|
| 564 |
+
width: 40px;
|
| 565 |
+
height: 28px;
|
| 566 |
+
padding: 3px;
|
| 567 |
+
cursor: var(--cursor-interaction, pointer);
|
| 568 |
+
}
|
| 569 |
+
|
| 570 |
+
.form-control-color[type="color"]::-webkit-color-swatch-wrapper {
|
| 571 |
+
padding: 0;
|
| 572 |
+
}
|
| 573 |
+
|
| 574 |
+
.form-control-color[type="color"]::-webkit-color-swatch {
|
| 575 |
+
border: 0;
|
| 576 |
+
border-radius: calc(var(--radius-lg) - 4px);
|
| 577 |
+
corner-shape: superellipse(1.5);
|
| 578 |
+
}
|
| 579 |
+
|
| 580 |
+
textarea.form-control {
|
| 581 |
+
height: auto;
|
| 582 |
+
min-height: 72px;
|
| 583 |
+
padding: 8px 10px;
|
| 584 |
+
resize: vertical;
|
| 585 |
+
}
|
| 586 |
+
|
| 587 |
+
.form-control:focus-visible {
|
| 588 |
+
border-color: var(--ring);
|
| 589 |
+
box-shadow: inset 0 0 0 1px var(--ring);
|
| 590 |
+
}
|
| 591 |
+
|
| 592 |
+
.form-control:disabled,
|
| 593 |
+
.form-select:disabled {
|
| 594 |
+
cursor: not-allowed;
|
| 595 |
+
opacity: 0.4;
|
| 596 |
+
}
|
| 597 |
+
|
| 598 |
+
.form-select {
|
| 599 |
+
appearance: none;
|
| 600 |
+
display: block;
|
| 601 |
+
width: 100%;
|
| 602 |
+
min-height: 28px;
|
| 603 |
+
margin: 0;
|
| 604 |
+
padding: 0 32px 0 8px;
|
| 605 |
+
outline: none;
|
| 606 |
+
border: 1px solid var(--input);
|
| 607 |
+
border-radius: var(--radius-lg);
|
| 608 |
+
corner-shape: superellipse(1.5);
|
| 609 |
+
color: var(--foreground);
|
| 610 |
+
background-color: var(--secondary);
|
| 611 |
+
background-image:
|
| 612 |
+
linear-gradient(45deg, transparent 50%, var(--muted-foreground) 50%),
|
| 613 |
+
linear-gradient(135deg, var(--muted-foreground) 50%, transparent 50%);
|
| 614 |
+
background-position:
|
| 615 |
+
calc(100% - 14px) 50%,
|
| 616 |
+
calc(100% - 10px) 50%;
|
| 617 |
+
background-repeat: no-repeat;
|
| 618 |
+
background-size: 4px 4px;
|
| 619 |
+
cursor: var(--cursor-interaction, default);
|
| 620 |
+
}
|
| 621 |
+
|
| 622 |
+
.form-select:not(:disabled):hover {
|
| 623 |
+
background-color: color-mix(in srgb, var(--foreground) 6%, var(--secondary));
|
| 624 |
+
}
|
| 625 |
+
|
| 626 |
+
.form-select:focus-visible {
|
| 627 |
+
border-color: var(--ring);
|
| 628 |
+
box-shadow: inset 0 0 0 1px var(--ring);
|
| 629 |
+
}
|
| 630 |
+
|
| 631 |
+
.form-check {
|
| 632 |
+
display: flex;
|
| 633 |
+
min-height: 20px;
|
| 634 |
+
align-items: center;
|
| 635 |
+
gap: 6px;
|
| 636 |
+
}
|
| 637 |
+
|
| 638 |
+
.form-check-input {
|
| 639 |
+
appearance: none;
|
| 640 |
+
width: 14px;
|
| 641 |
+
height: 14px;
|
| 642 |
+
flex: 0 0 auto;
|
| 643 |
+
margin: 0;
|
| 644 |
+
border: 1px solid var(--input);
|
| 645 |
+
color: var(--primary-foreground);
|
| 646 |
+
background-color: transparent;
|
| 647 |
+
cursor: var(--cursor-interaction, default);
|
| 648 |
+
transition:
|
| 649 |
+
background-color 150ms,
|
| 650 |
+
border-color 150ms,
|
| 651 |
+
box-shadow 150ms;
|
| 652 |
+
}
|
| 653 |
+
|
| 654 |
+
.form-check:not(.form-switch) .form-check-input[type="checkbox"] {
|
| 655 |
+
border-color: var(--input);
|
| 656 |
+
border-radius: var(--radius-sm);
|
| 657 |
+
corner-shape: superellipse(1.5);
|
| 658 |
+
background-color: var(--secondary);
|
| 659 |
+
box-shadow: var(--shadow-sm);
|
| 660 |
+
}
|
| 661 |
+
|
| 662 |
+
.form-check:not(.form-switch)
|
| 663 |
+
.form-check-input:not(:disabled):not(:checked):hover {
|
| 664 |
+
background-color: var(--card);
|
| 665 |
+
}
|
| 666 |
+
|
| 667 |
+
.form-check:not(.form-switch) .form-check-input[type="checkbox"]:checked {
|
| 668 |
+
border-color: var(--primary);
|
| 669 |
+
background-color: var(--primary);
|
| 670 |
+
}
|
| 671 |
+
|
| 672 |
+
.form-check:not(.form-switch)
|
| 673 |
+
.form-check-input[type="checkbox"]:checked::before {
|
| 674 |
+
display: block;
|
| 675 |
+
width: 100%;
|
| 676 |
+
height: 100%;
|
| 677 |
+
background: var(--primary-foreground);
|
| 678 |
+
content: "";
|
| 679 |
+
mask: var(--checkmark-image) center / 12px 12px no-repeat;
|
| 680 |
+
}
|
| 681 |
+
|
| 682 |
+
.form-check-input[type="radio"] {
|
| 683 |
+
width: 14px;
|
| 684 |
+
height: 14px;
|
| 685 |
+
border-radius: var(--radius-full);
|
| 686 |
+
}
|
| 687 |
+
|
| 688 |
+
.form-check-input[type="radio"]:checked {
|
| 689 |
+
border: 2px solid var(--primary);
|
| 690 |
+
background:
|
| 691 |
+
radial-gradient(circle, var(--primary-foreground) 0 2.5px, transparent 3px),
|
| 692 |
+
var(--primary);
|
| 693 |
+
}
|
| 694 |
+
|
| 695 |
+
.form-check:not(.form-switch) .form-check-input:focus-visible {
|
| 696 |
+
outline: 2px solid var(--ring);
|
| 697 |
+
outline-offset: 2px;
|
| 698 |
+
}
|
| 699 |
+
|
| 700 |
+
.form-check:not(.form-switch) .form-check-input:disabled {
|
| 701 |
+
cursor: not-allowed;
|
| 702 |
+
pointer-events: none;
|
| 703 |
+
}
|
| 704 |
+
|
| 705 |
+
.form-check:not(.form-switch) .form-check-input:disabled + .form-check-label {
|
| 706 |
+
cursor: not-allowed;
|
| 707 |
+
}
|
| 708 |
+
|
| 709 |
+
.form-switch .form-check-input:disabled,
|
| 710 |
+
.form-switch .form-check-input:disabled + .form-check-label {
|
| 711 |
+
cursor: not-allowed;
|
| 712 |
+
opacity: 0.6;
|
| 713 |
+
}
|
| 714 |
+
|
| 715 |
+
.form-check-label {
|
| 716 |
+
color: var(--foreground);
|
| 717 |
+
cursor: var(--cursor-interaction, default);
|
| 718 |
+
}
|
| 719 |
+
|
| 720 |
+
.form-switch .form-check-input {
|
| 721 |
+
position: relative;
|
| 722 |
+
width: 32px;
|
| 723 |
+
height: 20px;
|
| 724 |
+
border: 0;
|
| 725 |
+
border-radius: var(--radius-full);
|
| 726 |
+
background: var(--muted);
|
| 727 |
+
box-shadow: none;
|
| 728 |
+
transition: background-color 200ms cubic-bezier(0, 0, 0.2, 1);
|
| 729 |
+
}
|
| 730 |
+
|
| 731 |
+
.form-switch .form-check-input::before {
|
| 732 |
+
position: absolute;
|
| 733 |
+
top: 50%;
|
| 734 |
+
left: 0;
|
| 735 |
+
width: 16px;
|
| 736 |
+
height: 16px;
|
| 737 |
+
box-sizing: border-box;
|
| 738 |
+
border: 1px solid light-dark(var(--primary-foreground), var(--foreground));
|
| 739 |
+
border-radius: var(--radius-full);
|
| 740 |
+
background: light-dark(var(--primary-foreground), var(--foreground));
|
| 741 |
+
box-shadow: var(--shadow-sm);
|
| 742 |
+
content: "";
|
| 743 |
+
transform: translate(2px, -50%);
|
| 744 |
+
transition: transform 200ms cubic-bezier(0, 0, 0.2, 1);
|
| 745 |
+
}
|
| 746 |
+
|
| 747 |
+
.form-switch .form-check-input:checked {
|
| 748 |
+
background: var(--primary);
|
| 749 |
+
}
|
| 750 |
+
|
| 751 |
+
.form-switch .form-check-input:checked::before {
|
| 752 |
+
transform: translate(14px, -50%);
|
| 753 |
+
}
|
| 754 |
+
|
| 755 |
+
.form-switch .form-check-input:focus-visible {
|
| 756 |
+
box-shadow: 0 0 0 2px var(--ring);
|
| 757 |
+
}
|
| 758 |
+
|
| 759 |
+
.form-range {
|
| 760 |
+
appearance: none;
|
| 761 |
+
display: block;
|
| 762 |
+
width: 100%;
|
| 763 |
+
height: 28px;
|
| 764 |
+
flex: 1;
|
| 765 |
+
margin: 0;
|
| 766 |
+
padding: 0;
|
| 767 |
+
outline: none;
|
| 768 |
+
border: 0;
|
| 769 |
+
accent-color: var(--primary);
|
| 770 |
+
background: linear-gradient(
|
| 771 |
+
color-mix(in srgb, var(--foreground) 7%, transparent),
|
| 772 |
+
color-mix(in srgb, var(--foreground) 7%, transparent)
|
| 773 |
+
)
|
| 774 |
+
center / 100% 2px no-repeat;
|
| 775 |
+
}
|
| 776 |
+
|
| 777 |
+
.form-range::-webkit-slider-runnable-track {
|
| 778 |
+
height: 28px;
|
| 779 |
+
background: transparent;
|
| 780 |
+
}
|
| 781 |
+
|
| 782 |
+
.form-range::-webkit-slider-thumb {
|
| 783 |
+
appearance: none;
|
| 784 |
+
width: 20px;
|
| 785 |
+
height: 20px;
|
| 786 |
+
margin-top: 4px;
|
| 787 |
+
border: 1px solid var(--border);
|
| 788 |
+
border-radius: var(--radius-full);
|
| 789 |
+
background: light-dark(var(--primary-foreground), var(--foreground));
|
| 790 |
+
}
|
| 791 |
+
|
| 792 |
+
.form-range:focus-visible::-webkit-slider-thumb {
|
| 793 |
+
border-color: var(--ring);
|
| 794 |
+
box-shadow: inset 0 0 0 1px var(--ring);
|
| 795 |
+
}
|
| 796 |
+
|
| 797 |
+
.form-range::-moz-range-track {
|
| 798 |
+
height: 28px;
|
| 799 |
+
background: transparent;
|
| 800 |
+
}
|
| 801 |
+
|
| 802 |
+
.form-range::-moz-range-thumb {
|
| 803 |
+
width: 20px;
|
| 804 |
+
height: 20px;
|
| 805 |
+
border: 1px solid var(--border);
|
| 806 |
+
border-radius: var(--radius-full);
|
| 807 |
+
background: light-dark(var(--primary-foreground), var(--foreground));
|
| 808 |
+
}
|
| 809 |
+
|
| 810 |
+
.form-range:focus-visible::-moz-range-thumb {
|
| 811 |
+
border-color: var(--ring);
|
| 812 |
+
box-shadow: inset 0 0 0 1px var(--ring);
|
| 813 |
+
}
|
| 814 |
+
|
| 815 |
+
.form-range:disabled {
|
| 816 |
+
cursor: not-allowed;
|
| 817 |
+
opacity: 0.4;
|
| 818 |
+
}
|
| 819 |
+
|
| 820 |
+
.btn:not(.btn-primary, .viz-tile):is(
|
| 821 |
+
[aria-pressed="true"],
|
| 822 |
+
[aria-selected="true"],
|
| 823 |
+
.is-selected
|
| 824 |
+
) {
|
| 825 |
+
border-color: var(--primary);
|
| 826 |
+
color: var(--primary-foreground);
|
| 827 |
+
background: var(--primary);
|
| 828 |
+
}
|
| 829 |
+
|
| 830 |
+
.btn.viz-tile:is([aria-pressed="true"], [aria-selected="true"], .is-selected) {
|
| 831 |
+
border-color: var(--primary);
|
| 832 |
+
box-shadow: inset 0 0 0 1px var(--primary);
|
| 833 |
+
}
|
| 834 |
+
|
| 835 |
+
.btn:focus-visible {
|
| 836 |
+
outline: 2px solid var(--ring);
|
| 837 |
+
outline-offset: 2px;
|
| 838 |
+
}
|
| 839 |
+
|
| 840 |
+
svg {
|
| 841 |
+
display: block;
|
| 842 |
+
max-width: 100%;
|
| 843 |
+
height: auto;
|
| 844 |
+
}
|
| 845 |
+
|
| 846 |
+
#widget > svg {
|
| 847 |
+
width: 100%;
|
| 848 |
+
}
|
| 849 |
+
|
| 850 |
+
.text-warning,
|
| 851 |
+
.text-destructive {
|
| 852 |
+
color: var(--destructive);
|
| 853 |
+
}
|