lvwerra HF Staff commited on
Commit
00fee0f
·
1 Parent(s): d02f03d

feat: ship widget (extracted from blog-preview.html)

Browse files
Files changed (3) hide show
  1. README.md +13 -5
  2. index.html +1252 -18
  3. style.css +0 -28
README.md CHANGED
@@ -1,10 +1,18 @@
1
  ---
2
- title: Carbon Tokenization 04 Conditional Bases
3
- emoji: 🔥
4
- colorFrom: pink
5
- colorTo: indigo
6
  sdk: static
7
  pinned: false
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: Conditioning the base distributions: fix a base, the rest adapt
3
+ emoji: 🧬
4
+ colorFrom: green
5
+ colorTo: yellow
6
  sdk: static
7
  pinned: false
8
  ---
9
 
10
+ # Conditioning the base distributions: fix a base, the rest adapt
11
+
12
+ Standalone widget from the Carbon tokenization article. Embed via:
13
+
14
+ ```html
15
+ <iframe src="https://huggingfacebio-carbon-tokenization-04-conditional-bases.hf.space" loading="lazy"></iframe>
16
+ ```
17
+
18
+ Generated from [`blog-preview.html`](https://github.com/HuggingFaceBio/carbon-tokenization) by `widgets/_extract.py` — edit the source there, not here.
index.html CHANGED
@@ -1,19 +1,1253 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  </html>
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Conditioning the base distributions: fix a base, the rest adapt</title>
7
+ <meta name="color-scheme" content="light">
8
+ <link rel="preconnect" href="https://fonts.googleapis.com">
9
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
10
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;400;500;600;700&family=Inter:wght@300;400;500;600&display=swap">
11
+ <style>
12
+ :root {
13
+ --bg: #f7f5ee;
14
+ --ink: #1f1f1d;
15
+ --ink-soft: #5b5b56;
16
+ --ink-faint: #8a8a83;
17
+ --rule: #e3e1d6;
18
+ --hair: #eee;
19
+ --green: #317f3f;
20
+ --green-dark: #1f5024;
21
+ --green-tint: #f4f8f4;
22
+ --amber: #b8862c;
23
+ --amber-dark: #6b4d18;
24
+ --red: #b00020;
25
+ --blue: #2c5aa0;
26
+ --card: #fff;
27
+ --soft-cream: #fafaf6;
28
+ --base-a: #1A7A40;
29
+ --base-t: #b00020;
30
+ --base-c: #2c5aa0;
31
+ --base-g: #b8862c;
32
+ }
33
+ * { margin: 0; padding: 0; box-sizing: border-box; }
34
+ html { scroll-behavior: smooth; }
35
+ body {
36
+ font-family: "Inter", "Helvetica Neue", sans-serif;
37
+ font-size: 14px; font-weight: 300; line-height: 1.7;
38
+ color: var(--ink);
39
+ background: var(--bg);
40
+ }
41
+ ::-webkit-scrollbar { width: 8px; height: 8px; }
42
+ ::-webkit-scrollbar-thumb { background: #ccc; border-radius: 4px; }
43
+ ::-webkit-scrollbar-track { background: transparent; }
44
+
45
+ /* --- Page header ----------------------------------------------------- */
46
+ .page-header {
47
+ border-bottom: 1px solid var(--rule);
48
+ background: var(--bg);
49
+ position: sticky; top: 0; z-index: 50;
50
+ backdrop-filter: saturate(180%) blur(6px);
51
+ }
52
+ .page-header__inner {
53
+ max-width: 1200px;
54
+ margin: 0 auto;
55
+ padding: 14px 32px;
56
+ display: flex; align-items: baseline; gap: 16px;
57
+ }
58
+ .wordmark {
59
+ font-family: "JetBrains Mono", monospace;
60
+ font-weight: 700;
61
+ font-size: 16px;
62
+ letter-spacing: 1px;
63
+ }
64
+ .wordmark .caret { color: var(--green); margin-right: 4px; }
65
+ .wordmark__sub {
66
+ font-family: "JetBrains Mono", monospace;
67
+ font-size: 11px; font-weight: 500;
68
+ text-transform: uppercase; letter-spacing: 2px;
69
+ color: var(--ink-soft);
70
+ margin-left: 4px;
71
+ }
72
+ .page-header__spacer { flex: 1; }
73
+ .page-header__crumbs {
74
+ font-family: "JetBrains Mono", monospace;
75
+ font-size: 10px; letter-spacing: 1.4px;
76
+ text-transform: uppercase; color: var(--ink-faint);
77
+ }
78
+ .page-header__crumbs a { color: var(--ink-soft); text-decoration: none; }
79
+ .page-header__crumbs a:hover { color: var(--green); }
80
+
81
+ /* --- Lede ----------------------------------------------------------- */
82
+ .tab-lede {
83
+ max-width: 1200px; margin: 56px auto 0;
84
+ padding: 0 32px;
85
+ }
86
+ .tab-lede__rail {
87
+ border-left: 3px solid var(--green);
88
+ padding: 4px 0 4px 22px;
89
+ max-width: 820px;
90
+ }
91
+ .tab-lede__eyebrow {
92
+ display: block;
93
+ font-family: "JetBrains Mono", monospace;
94
+ font-size: 11px; font-weight: 500;
95
+ letter-spacing: 0.22em; text-transform: uppercase;
96
+ color: var(--green); margin-bottom: 12px;
97
+ }
98
+ .tab-lede__title {
99
+ margin: 0 0 22px;
100
+ font-family: "JetBrains Mono", monospace;
101
+ font-size: 34px; font-weight: 500;
102
+ letter-spacing: -0.01em; line-height: 1.12;
103
+ color: var(--ink);
104
+ }
105
+ .tab-lede__lead {
106
+ margin: 0; max-width: 760px;
107
+ font-family: "Inter", sans-serif;
108
+ font-size: 19px; font-weight: 300; line-height: 1.5;
109
+ letter-spacing: -0.005em; color: #2d2d2a;
110
+ }
111
+
112
+ /* --- Post body ------------------------------------------------------ */
113
+ .post {
114
+ max-width: 760px;
115
+ margin: 32px auto 0;
116
+ padding: 0 32px 96px;
117
+ }
118
+ .post h2 {
119
+ margin: 64px 0 18px;
120
+ font-family: "JetBrains Mono", monospace;
121
+ font-size: 22px; font-weight: 500;
122
+ letter-spacing: -0.005em; line-height: 1.3;
123
+ color: var(--ink);
124
+ padding-top: 12px;
125
+ border-top: 1px solid var(--rule);
126
+ }
127
+ .post h2:first-child { border-top: none; padding-top: 0; }
128
+ .post h3 {
129
+ margin: 40px 0 12px;
130
+ font-family: "JetBrains Mono", monospace;
131
+ font-size: 15px; font-weight: 500;
132
+ letter-spacing: 0;
133
+ color: var(--ink);
134
+ text-transform: uppercase;
135
+ letter-spacing: 0.5px;
136
+ }
137
+ .post p { margin: 0 0 14px; }
138
+ .post p > code, .post li > code {
139
+ font-family: "JetBrains Mono", monospace;
140
+ font-size: 0.86em;
141
+ background: var(--soft-cream);
142
+ border: 1px solid var(--rule);
143
+ padding: 1px 5px;
144
+ border-radius: 2px;
145
+ color: var(--green-dark);
146
+ }
147
+ .post pre {
148
+ margin: 14px 0 18px;
149
+ padding: 14px 16px;
150
+ background: var(--card);
151
+ border: 1px solid #ddd;
152
+ overflow-x: auto;
153
+ }
154
+ .post pre code {
155
+ font-family: "JetBrains Mono", monospace;
156
+ font-size: 12px; line-height: 1.6;
157
+ color: var(--ink);
158
+ background: transparent; border: none; padding: 0;
159
+ }
160
+ .post a {
161
+ color: var(--green-dark);
162
+ text-decoration: underline;
163
+ text-decoration-thickness: 1px;
164
+ text-underline-offset: 2px;
165
+ }
166
+ .post a:hover { color: var(--green); }
167
+ .post strong { font-weight: 600; color: var(--ink); }
168
+ .post-image {
169
+ margin: 24px 0;
170
+ }
171
+ .post-image img {
172
+ display: block;
173
+ width: 100%; height: auto;
174
+ border: 1px solid var(--rule);
175
+ }
176
+
177
+ /* --- Widget shell (carbon-demo style) ------------------------------- */
178
+ .widget {
179
+ max-width: 920px;
180
+ margin: 40px auto 8px;
181
+ }
182
+ .widget__head {
183
+ display: flex; align-items: baseline; gap: 14px;
184
+ margin-bottom: 6px;
185
+ }
186
+ .widget__eyebrow {
187
+ font-family: "JetBrains Mono", monospace;
188
+ font-size: 10px; font-weight: 500;
189
+ letter-spacing: 0.22em; text-transform: uppercase;
190
+ color: var(--green);
191
+ }
192
+ .widget__title {
193
+ font-family: "JetBrains Mono", monospace;
194
+ font-size: 14px; font-weight: 500;
195
+ color: var(--ink); letter-spacing: 0;
196
+ }
197
+ .widget__caption {
198
+ font-family: "Inter", sans-serif;
199
+ font-size: 12px; color: var(--ink-soft);
200
+ margin: 8px 4px 14px;
201
+ line-height: 1.5;
202
+ }
203
+ .demo {
204
+ background: var(--card); border: 1px solid #ddd;
205
+ padding: 22px; margin: 8px 0;
206
+ }
207
+ .demo-toolbar {
208
+ display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
209
+ margin-bottom: 14px;
210
+ font-family: "JetBrains Mono", monospace; font-size: 10px;
211
+ color: #666; text-transform: uppercase; letter-spacing: 1.4px;
212
+ }
213
+ .demo-toolbar .spacer { flex: 1; }
214
+ .demo-label {
215
+ font-family: "JetBrains Mono", monospace;
216
+ font-size: 9.5px; color: #6b7a6e;
217
+ text-transform: uppercase; letter-spacing: 1.6px;
218
+ margin: 6px 0 6px;
219
+ }
220
+
221
+ .pill, button.action {
222
+ font-family: "JetBrains Mono", monospace;
223
+ font-size: 11px; font-weight: 400;
224
+ padding: 5px 11px; border: 1px solid #ccc; border-radius: 3px;
225
+ background: #fff; color: #555; cursor: pointer;
226
+ text-transform: uppercase; letter-spacing: 1.5px;
227
+ transition: all 0.12s;
228
+ }
229
+ .pill:hover, button.action:hover { border-color: #888; color: var(--ink); }
230
+ .pill.active, button.action.primary { background: var(--ink); color: #fff; border-color: var(--ink); }
231
+ .pill.active:hover, button.action.primary:hover { background: #000; }
232
+ .pill.gh { background: var(--green); color: #fff; border-color: var(--green); }
233
+ .pill.gh:hover { background: var(--green-dark); border-color: var(--green-dark); }
234
+ .pills { display: inline-flex; flex-wrap: wrap; gap: 6px; }
235
+ .status {
236
+ font-family: "JetBrains Mono", monospace;
237
+ font-size: 10px; color: #666;
238
+ text-transform: uppercase; letter-spacing: 1.5px;
239
+ display: inline-flex; align-items: center; gap: 6px;
240
+ margin-left: 8px;
241
+ }
242
+ .status .dot {
243
+ display: inline-block; width: 6px; height: 6px; border-radius: 50%;
244
+ background: var(--green);
245
+ }
246
+
247
+ input.seq-input, textarea.seq-input {
248
+ width: 100%;
249
+ font-family: "JetBrains Mono", monospace;
250
+ font-size: 13px;
251
+ padding: 9px 12px;
252
+ border: 1px solid #ccc;
253
+ border-radius: 3px;
254
+ letter-spacing: 1px;
255
+ text-transform: uppercase;
256
+ color: var(--ink);
257
+ background: var(--soft-cream);
258
+ resize: vertical;
259
+ }
260
+ textarea.seq-input { letter-spacing: 0.5px; }
261
+ input.seq-input:focus, textarea.seq-input:focus {
262
+ outline: none;
263
+ border-color: var(--green);
264
+ background: #fff;
265
+ }
266
+
267
+ /* base + token chips */
268
+ .base, .tok {
269
+ font-family: "JetBrains Mono", monospace;
270
+ font-size: 11px;
271
+ letter-spacing: 0.5px;
272
+ }
273
+ .base {
274
+ display: inline-block;
275
+ padding: 2px 5px;
276
+ font-weight: 500;
277
+ margin: 1px;
278
+ color: #fff;
279
+ border-radius: 2px;
280
+ min-width: 16px;
281
+ text-align: center;
282
+ }
283
+ .base.A { background: var(--base-a); }
284
+ .base.T { background: var(--base-t); }
285
+ .base.C { background: var(--base-c); }
286
+ .base.G { background: var(--base-g); }
287
+ .base.dim { opacity: 0.4; }
288
+ .base.outline {
289
+ background: transparent;
290
+ border: 1px solid currentColor;
291
+ }
292
+ .base.outline.A { color: var(--base-a); }
293
+ .base.outline.T { color: var(--base-t); }
294
+ .base.outline.C { color: var(--base-c); }
295
+ .base.outline.G { color: var(--base-g); }
296
+
297
+ .tok {
298
+ display: inline-flex;
299
+ align-items: center;
300
+ padding: 4px 8px;
301
+ margin: 2px;
302
+ border: 1px solid #ccc;
303
+ border-radius: 3px;
304
+ background: #fff;
305
+ color: var(--ink);
306
+ }
307
+ .tok.kmer {
308
+ background: rgba(49,127,63,0.10);
309
+ border-color: rgba(49,127,63,0.5);
310
+ color: var(--green-dark);
311
+ font-weight: 500;
312
+ }
313
+ .tok.bpe {
314
+ background: rgba(184,134,44,0.10);
315
+ border-color: rgba(184,134,44,0.5);
316
+ color: var(--amber-dark);
317
+ }
318
+ .tok.text {
319
+ background: #fff;
320
+ border-color: #ccc;
321
+ color: var(--ink);
322
+ }
323
+ .tok.boundary {
324
+ background: var(--ink);
325
+ color: #fff;
326
+ border-color: var(--ink);
327
+ text-transform: uppercase;
328
+ letter-spacing: 1px;
329
+ font-size: 10px;
330
+ }
331
+ .tok.dim { color: #888; background: var(--soft-cream); }
332
+ .tok.ok { background: var(--green); color: #fff; border-color: var(--green); }
333
+ .tok.bad { color: var(--red); border-color: rgba(176,0,32,0.4); background: rgba(176,0,32,0.05); }
334
+ .tok.selected {
335
+ outline: 2px solid var(--green);
336
+ outline-offset: 1px;
337
+ }
338
+ .token-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0; }
339
+
340
+ /* count badges */
341
+ .count-badge {
342
+ display: inline-block;
343
+ font-family: "JetBrains Mono", monospace;
344
+ font-size: 10px; font-weight: 600;
345
+ background: var(--ink); color: var(--bg);
346
+ padding: 2px 7px; border-radius: 2px;
347
+ letter-spacing: 1px;
348
+ }
349
+ .count-badge.green { background: var(--green); color: #fff; }
350
+ .count-badge.amber { background: var(--amber); color: #fff; }
351
+
352
+ /* W1 · animated tokenization (source on top, schemes drop down) ------ */
353
+ .tk-anim { margin-top: 18px; }
354
+ .tk-source, .tk-scheme {
355
+ display: grid;
356
+ grid-template-columns: 124px 1fr;
357
+ gap: 18px;
358
+ align-items: start;
359
+ padding: 8px 0;
360
+ }
361
+ .tk-scheme { padding: 10px 0; min-height: 32px; }
362
+ .tk-source { padding-bottom: 14px; border-bottom: 1px solid var(--rule); margin-bottom: 6px; }
363
+ .tk-meta {
364
+ display: flex;
365
+ flex-direction: column;
366
+ gap: 3px;
367
+ padding-top: 2px;
368
+ }
369
+ .tk-label {
370
+ font-family: "JetBrains Mono", monospace;
371
+ font-size: 9.5px;
372
+ font-weight: 500;
373
+ color: var(--ink-soft);
374
+ text-transform: uppercase;
375
+ letter-spacing: 1.6px;
376
+ }
377
+ .tk-stat {
378
+ font-family: "JetBrains Mono", monospace;
379
+ font-size: 10px;
380
+ color: var(--ink-faint);
381
+ letter-spacing: 0.5px;
382
+ font-variant-numeric: tabular-nums;
383
+ }
384
+ .tk-stat .n {
385
+ font-weight: 600;
386
+ color: var(--ink);
387
+ }
388
+ .tk-scheme[data-scheme="bpe"] .tk-stat .n { color: var(--amber-dark); }
389
+ .tk-scheme[data-scheme="kmer"] .tk-stat .n { color: var(--green-dark); }
390
+
391
+ /* Source: tight grid of small chips */
392
+ .tk-source-strip {
393
+ display: flex;
394
+ flex-wrap: wrap;
395
+ row-gap: 2px;
396
+ }
397
+ .tk-source-strip .tk-base {
398
+ display: inline-flex;
399
+ align-items: center;
400
+ justify-content: center;
401
+ width: 13px;
402
+ height: 17px;
403
+ color: #fff;
404
+ font-family: "JetBrains Mono", monospace;
405
+ font-size: 10px;
406
+ font-weight: 500;
407
+ border-radius: 1px;
408
+ flex: 0 0 13px;
409
+ transition: opacity 0.35s ease, filter 0.35s ease;
410
+ }
411
+ .tk-source-strip .tk-base + .tk-base { margin-left: 1px; }
412
+ .tk-source-strip .tk-base.consumed { opacity: 0.18; filter: grayscale(0.6); }
413
+ .tk-base.A { background: var(--base-a); }
414
+ .tk-base.T { background: var(--base-t); }
415
+ .tk-base.C { background: var(--base-c); }
416
+ .tk-base.G { background: var(--base-g); }
417
+
418
+ /* Scheme strips: hold dropped tokens with <> brackets */
419
+ .tk-scheme-strip {
420
+ display: flex;
421
+ flex-wrap: wrap;
422
+ gap: 1px 8px;
423
+ min-height: 20px;
424
+ }
425
+ .tk-token {
426
+ font-family: "JetBrains Mono", monospace;
427
+ font-size: 12px;
428
+ font-weight: 500;
429
+ letter-spacing: 0.5px;
430
+ display: inline-flex;
431
+ align-items: center;
432
+ opacity: 0;
433
+ will-change: transform, opacity;
434
+ }
435
+ .tk-token.dropped {
436
+ opacity: 1;
437
+ transition:
438
+ transform 0.48s cubic-bezier(0.22, 1, 0.36, 1),
439
+ opacity 0.32s ease;
440
+ }
441
+ .tk-token .br { color: var(--ink-faint); font-weight: 400; }
442
+ .tk-token.tail .br { color: var(--ink-faint); }
443
+ .tk-token.tail { opacity: 0.55; }
444
+ .tk-token.tail.dropped { opacity: 0.55; }
445
+
446
+
447
+ /* Layouts */
448
+ .grid-3 {
449
+ display: grid;
450
+ grid-template-columns: 1fr 1fr 1fr;
451
+ gap: 14px;
452
+ margin-top: 14px;
453
+ }
454
+ .grid-2 {
455
+ display: grid;
456
+ grid-template-columns: 1fr 1fr;
457
+ gap: 14px;
458
+ margin-top: 14px;
459
+ }
460
+ @media (max-width: 720px) {
461
+ .grid-3, .grid-2 { grid-template-columns: 1fr; }
462
+ }
463
+ .col-card {
464
+ background: var(--soft-cream);
465
+ border: 1px solid var(--rule);
466
+ padding: 14px;
467
+ }
468
+ .col-card .col-title {
469
+ font-family: "JetBrains Mono", monospace;
470
+ font-size: 10px; font-weight: 500;
471
+ letter-spacing: 1.6px; text-transform: uppercase;
472
+ color: var(--ink-soft);
473
+ margin-bottom: 8px;
474
+ }
475
+ .col-card .col-foot {
476
+ margin-top: 10px;
477
+ display: flex; align-items: center; gap: 8px;
478
+ font-family: "JetBrains Mono", monospace;
479
+ font-size: 10px; color: var(--ink-soft);
480
+ text-transform: uppercase; letter-spacing: 1.4px;
481
+ }
482
+
483
+ /* Bar chart helpers */
484
+ .bar-row {
485
+ display: grid;
486
+ grid-template-columns: 18px 1fr 64px;
487
+ align-items: center;
488
+ gap: 8px;
489
+ margin: 3px 0;
490
+ font-family: "JetBrains Mono", monospace;
491
+ font-size: 11px;
492
+ }
493
+ .bar-row .bar-label { color: var(--ink-soft); font-weight: 500; text-align: center; }
494
+ .bar-row .bar-track {
495
+ position: relative;
496
+ height: 14px;
497
+ background: var(--soft-cream);
498
+ border: 1px solid var(--rule);
499
+ }
500
+ .bar-row .bar-fill {
501
+ height: 100%;
502
+ transition: width 220ms ease, background-color 220ms ease;
503
+ }
504
+ .bar-row .bar-val { text-align: right; color: var(--ink); font-variant-numeric: tabular-nums; }
505
+ .bar-row.highlight .bar-track { box-shadow: 0 0 0 2px var(--green-tint); }
506
+
507
+ /* 6-position grid (used in W4, W5, W6) */
508
+ .posgrid {
509
+ display: grid;
510
+ grid-template-columns: repeat(6, 1fr);
511
+ gap: 8px;
512
+ }
513
+ .posgrid__col {
514
+ background: var(--soft-cream);
515
+ border: 1px solid var(--rule);
516
+ border-radius: 2px;
517
+ padding: 8px 6px 6px;
518
+ }
519
+ .posgrid__pos {
520
+ font-family: "JetBrains Mono", monospace;
521
+ font-size: 9px; color: var(--ink-faint);
522
+ text-transform: uppercase; letter-spacing: 1.4px;
523
+ text-align: center; margin-bottom: 6px;
524
+ }
525
+ .posgrid__bars {
526
+ display: flex; flex-direction: column; gap: 3px;
527
+ }
528
+ .posgrid .mini-row {
529
+ display: grid; grid-template-columns: 12px 1fr 32px;
530
+ align-items: center; gap: 4px;
531
+ font-family: "JetBrains Mono", monospace; font-size: 10px;
532
+ }
533
+ .posgrid .mini-row .ml { color: var(--ink-soft); text-align: center; font-weight: 500; }
534
+ .posgrid .mini-row .mt { position: relative; height: 10px; background: #fff; border: 1px solid var(--rule); }
535
+ .posgrid .mini-row .mf { display: block; height: 100%; transition: width 200ms ease; }
536
+ .posgrid .mini-row .mv { text-align: right; color: var(--ink); font-variant-numeric: tabular-nums; font-size: 9.5px; }
537
+ .posgrid__col.argmax-A { box-shadow: inset 0 0 0 1px var(--base-a); }
538
+ .posgrid__col.argmax-T { box-shadow: inset 0 0 0 1px var(--base-t); }
539
+ .posgrid__col.argmax-C { box-shadow: inset 0 0 0 1px var(--base-c); }
540
+ .posgrid__col.argmax-G { box-shadow: inset 0 0 0 1px var(--base-g); }
541
+ .posgrid__col.locked { background: #fff; }
542
+ .posgrid__col.frozen .posgrid__bars { opacity: 0.4; }
543
+ .posgrid__sel { display: flex; gap: 3px; margin-top: 8px; }
544
+ .cond-pick {
545
+ flex: 1 1 0; min-width: 0;
546
+ font-family: "JetBrains Mono", monospace; font-size: 10px; font-weight: 600;
547
+ padding: 3px 0; border: 1px solid var(--rule); border-radius: 2px;
548
+ background: #fff; cursor: pointer;
549
+ transition: background 0.12s, border-color 0.12s, color 0.12s;
550
+ }
551
+ .cond-pick:hover { border-color: #888; }
552
+ .cond-pick.active { color: #fff; }
553
+ .cond-pick.active.b-A { background: var(--base-a); border-color: var(--base-a); }
554
+ .cond-pick.active.b-T { background: var(--base-t); border-color: var(--base-t); }
555
+ .cond-pick.active.b-C { background: var(--base-c); border-color: var(--base-c); }
556
+ .cond-pick.active.b-G { background: var(--base-g); border-color: var(--base-g); }
557
+
558
+ /* W3 · real Carbon-500M per-token scoring --------------------------- */
559
+ .w3-itok { cursor: pointer; transition: outline-color 0.12s; }
560
+ .w3-itok:hover { border-color: #888; }
561
+ .w3-sub {
562
+ font-family: "JetBrains Mono", monospace;
563
+ font-size: 11px; color: var(--ink-soft);
564
+ margin: 2px 0 10px; line-height: 1.7;
565
+ }
566
+ .w3-sub b { color: var(--ink); font-weight: 600; }
567
+ .w3-sub .tok { margin: 0 2px; }
568
+ .w3-toprow {
569
+ display: grid;
570
+ grid-template-columns: 92px 1fr 52px;
571
+ gap: 12px; align-items: center;
572
+ margin: 4px 0;
573
+ font-family: "JetBrains Mono", monospace; font-size: 11px;
574
+ }
575
+ .w3-toprow .km { font-weight: 500; letter-spacing: 0.5px; }
576
+ .w3-toprow .bar { height: 13px; background: var(--soft-cream); border: 1px solid var(--rule); }
577
+ .w3-toprow .fill { height: 100%; background: var(--green); transition: width 0.35s ease; }
578
+ .w3-toprow .pct { text-align: right; font-variant-numeric: tabular-nums; color: var(--ink); }
579
+ .w3-toprow.observed .km { color: var(--ink); }
580
+ .w3-toprow.observed .fill { background: var(--amber); }
581
+ .w3-io { display: flex; align-items: flex-end; gap: 18px; flex-wrap: wrap; margin-top: 6px; }
582
+ .w3-io__group { display: flex; flex-direction: column; gap: 6px; }
583
+ .w3-io__lab {
584
+ font-family: "JetBrains Mono", monospace;
585
+ font-size: 9.5px; letter-spacing: 1.6px; text-transform: uppercase; color: var(--ink-faint);
586
+ }
587
+ .w3-io__arrow { font-family: "JetBrains Mono", monospace; font-size: 16px; color: var(--ink-faint); padding-bottom: 5px; }
588
+ .w3-gt-tok { background: rgba(184,134,44,0.12); border-color: rgba(184,134,44,0.5) !important; }
589
+ .w3-chart { display: block; width: 100%; height: auto; margin-top: 6px; background: #fff; border: 1px solid #eee; }
590
+ .w3-legend {
591
+ display: flex; gap: 20px; flex-wrap: wrap; margin-top: 8px;
592
+ font-family: "JetBrains Mono", monospace; font-size: 10px;
593
+ color: var(--ink-soft); text-transform: uppercase; letter-spacing: 1px;
594
+ }
595
+ .w3-legend span { display: inline-flex; align-items: center; gap: 6px; }
596
+ .w3-legend i { width: 12px; height: 3px; display: inline-block; }
597
+ .w3-top { display: flex; gap: 6px; margin-top: 12px; }
598
+ .w3-topchip {
599
+ flex: 1 1 0; min-width: 0;
600
+ display: inline-flex; flex-direction: column; align-items: center; gap: 2px;
601
+ font-family: "JetBrains Mono", monospace;
602
+ border: 1px solid var(--rule); background: var(--soft-cream);
603
+ border-radius: 3px; padding: 6px 4px;
604
+ }
605
+ .w3-topchip .km { font-size: 12px; font-weight: 500; letter-spacing: 0.5px; }
606
+ .w3-topchip .pct { font-size: 9px; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
607
+ .posgrid__col.clickable { cursor: pointer; }
608
+ .posgrid__col.sel { outline: 2px solid var(--ink); outline-offset: 2px; }
609
+ .w3-allgrid {
610
+ display: grid;
611
+ grid-template-columns: repeat(128, 1fr);
612
+ gap: 1px;
613
+ margin-top: 8px;
614
+ }
615
+ .w3-cell { aspect-ratio: 1; background: #d3d0c4; transition: background 0.15s ease; }
616
+ .w3-cell.first {
617
+ outline: 2px solid var(--ink);
618
+ outline-offset: 1px;
619
+ position: relative; z-index: 2;
620
+ }
621
+ .w3-order {
622
+ display: inline-flex; align-items: center; gap: 8px;
623
+ font-family: "JetBrains Mono", monospace; font-size: 9.5px;
624
+ text-transform: uppercase; letter-spacing: 1.4px; color: var(--ink-faint);
625
+ }
626
+ .w3-snake { width: 42px; height: auto; color: var(--ink-soft); display: block; }
627
+
628
+ /* WCOND · conditional single-nucleotide decoding -------------------- */
629
+ .cond-slots { display: flex; gap: 6px; }
630
+ .cond-slot {
631
+ width: 40px; height: 40px;
632
+ display: flex; align-items: center; justify-content: center;
633
+ border: 1px solid var(--rule); border-radius: 3px; background: var(--soft-cream);
634
+ font-family: "JetBrains Mono", monospace; font-size: 17px; font-weight: 600;
635
+ color: var(--ink);
636
+ }
637
+ .cond-slot.active { outline: 2px solid var(--ink); outline-offset: 1px; color: var(--ink-faint); }
638
+ .cond-slot.pending { color: var(--ink-faint); background: transparent; border-style: dashed; }
639
+ .cond-slot.A { background: rgba(26,122,64,0.13); border-color: rgba(26,122,64,0.42); color: var(--base-a); }
640
+ .cond-slot.T { background: rgba(176,0,32,0.09); border-color: rgba(176,0,32,0.36); color: var(--base-t); }
641
+ .cond-slot.C { background: rgba(44,90,160,0.11); border-color: rgba(44,90,160,0.40); color: var(--base-c); }
642
+ .cond-slot.G { background: rgba(184,134,44,0.14); border-color: rgba(184,134,44,0.42); color: var(--amber-dark); }
643
+ .cond-choices { display: flex; gap: 10px; }
644
+ .cond-choice {
645
+ flex: 1 1 0; cursor: pointer; border: 1px solid var(--rule); border-radius: 3px;
646
+ padding: 10px 12px; background: var(--soft-cream);
647
+ display: flex; flex-direction: column; gap: 7px;
648
+ transition: background 0.12s, border-color 0.12s;
649
+ }
650
+ .cond-choice:hover { background: #fff; border-color: #888; }
651
+ .cond-choice__top { display: flex; justify-content: space-between; align-items: baseline; font-family: "JetBrains Mono", monospace; }
652
+ .cond-choice__base { font-size: 16px; font-weight: 600; }
653
+ .cond-choice__pct { font-size: 11px; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
654
+ .cond-choice__bar { height: 8px; background: #fff; border: 1px solid var(--rule); }
655
+ .cond-choice__fill { display: block; height: 100%; transition: width 0.25s ease; }
656
+ .cond-done { font-family: "JetBrains Mono", monospace; font-size: 13px; color: var(--ink); display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
657
+ .cond-note {
658
+ font-family: "Inter", sans-serif; font-size: 12px; color: var(--ink-soft);
659
+ background: var(--soft-cream); border-left: 2px solid var(--green);
660
+ padding: 9px 12px; margin-top: 14px; line-height: 1.5;
661
+ }
662
+ .cond-note .tok { margin: 0 2px; }
663
+
664
+ /* FNS factorization figure ------------------------------------------ */
665
+ .fns-seq-input {
666
+ width: 120px;
667
+ text-align: center;
668
+ text-transform: uppercase;
669
+ }
670
+ .fns-viz {
671
+ font-family: "JetBrains Mono", monospace;
672
+ padding: 10px 0 6px;
673
+ }
674
+ .fns-truth, .fns-row {
675
+ display: grid;
676
+ grid-template-columns: 222px repeat(6, 34px) 28px;
677
+ align-items: center;
678
+ column-gap: 7px;
679
+ min-width: 480px;
680
+ }
681
+ .fns-truth { margin-bottom: 16px; }
682
+ .fns-row { margin: 12px 0; }
683
+ .fns-gtlabel {
684
+ font-family: "JetBrains Mono", monospace;
685
+ font-size: 10px;
686
+ font-weight: 400;
687
+ letter-spacing: 1.6px;
688
+ text-transform: uppercase;
689
+ color: var(--ink-faint);
690
+ }
691
+ .fns-eq {
692
+ font-size: 16px;
693
+ color: var(--ink);
694
+ text-align: right;
695
+ white-space: nowrap;
696
+ }
697
+ .fns-eq sub, .fns-eq sup { font-size: 11px; }
698
+ .fns-eq .sum { color: var(--ink-soft); }
699
+ .fns-bracket {
700
+ font-family: "Inter", sans-serif;
701
+ font-size: 34px;
702
+ font-weight: 200;
703
+ line-height: 0;
704
+ color: var(--ink-soft);
705
+ vertical-align: middle;
706
+ transform: scaleX(0.7);
707
+ display: inline-block;
708
+ }
709
+ .fns-box {
710
+ width: 30px; height: 30px;
711
+ display: inline-flex; align-items: center; justify-content: center;
712
+ font-family: "JetBrains Mono", monospace;
713
+ font-size: 14px; font-weight: 600;
714
+ border-radius: 3px; border: 1px solid;
715
+ transition: background 0.15s, border-color 0.15s, color 0.15s;
716
+ }
717
+ .fns-box.A { background: rgba(26,122,64,0.13); border-color: rgba(26,122,64,0.42); color: var(--base-a); }
718
+ .fns-box.T { background: rgba(176,0,32,0.09); border-color: rgba(176,0,32,0.36); color: var(--base-t); }
719
+ .fns-box.C { background: rgba(44,90,160,0.11); border-color: rgba(44,90,160,0.40); color: var(--base-c); }
720
+ .fns-box.G { background: rgba(184,134,44,0.14); border-color: rgba(184,134,44,0.42); color: var(--amber-dark); }
721
+ .fns-box.wild { opacity: 0.38; }
722
+ .fns-loss {
723
+ margin-top: 20px;
724
+ padding-top: 16px;
725
+ border-top: 1px solid var(--rule);
726
+ font-family: "JetBrains Mono", monospace;
727
+ font-size: 16px;
728
+ color: var(--ink);
729
+ text-align: center;
730
+ }
731
+ .fns-loss sup, .fns-loss sub { font-size: 11px; }
732
+ .fns-loss .frac { display: inline-block; margin: 0 1px; }
733
+ .fns-loss .fns-term { margin: 0 3px; white-space: nowrap; }
734
+ .fns-explain {
735
+ margin-top: 18px;
736
+ padding-top: 16px;
737
+ border-top: 1px solid var(--rule);
738
+ font-family: "Inter", sans-serif;
739
+ font-size: 13px;
740
+ line-height: 1.62;
741
+ color: var(--ink-soft);
742
+ }
743
+ .fns-explain p { margin: 0 0 11px; }
744
+ .fns-explain p:last-child { margin-bottom: 0; }
745
+ .fns-explain strong { color: var(--ink); font-weight: 600; }
746
+ .fns-explain .mono {
747
+ font-family: "JetBrains Mono", monospace;
748
+ font-size: 12px;
749
+ color: var(--ink);
750
+ }
751
+ .fns-explain .mono sup, .fns-explain .mono sub { font-size: 9px; }
752
+
753
+ /* Big stat tile */
754
+ .stat-tile {
755
+ background: var(--soft-cream);
756
+ border: 1px solid var(--rule);
757
+ padding: 14px 16px;
758
+ text-align: left;
759
+ }
760
+ .stat-tile__label {
761
+ font-family: "JetBrains Mono", monospace;
762
+ font-size: 10px; color: var(--ink-soft);
763
+ text-transform: uppercase; letter-spacing: 1.6px;
764
+ margin-bottom: 6px;
765
+ }
766
+ .stat-tile__value {
767
+ font-family: "JetBrains Mono", monospace;
768
+ font-size: 26px; font-weight: 500;
769
+ color: var(--ink);
770
+ }
771
+ .stat-tile__sub {
772
+ font-family: "JetBrains Mono", monospace;
773
+ font-size: 10px; color: var(--ink-soft);
774
+ margin-top: 4px; letter-spacing: 0.5px;
775
+ }
776
+ .stat-tile.green .stat-tile__value { color: var(--green-dark); }
777
+ .stat-tile.red .stat-tile__value { color: var(--red); }
778
+
779
+ /* Footer */
780
+ .post-foot {
781
+ max-width: 760px;
782
+ margin: 64px auto 0;
783
+ padding: 24px 32px 64px;
784
+ border-top: 1px solid var(--rule);
785
+ font-family: "JetBrains Mono", monospace;
786
+ font-size: 11px; color: var(--ink-soft);
787
+ text-transform: uppercase; letter-spacing: 1.4px;
788
+ }
789
+ .post-foot a { color: var(--green-dark); text-decoration: none; }
790
+ .post-foot a:hover { color: var(--green); }
791
+
792
+ /* Position picker (W7) */
793
+ .seq-track {
794
+ font-family: "JetBrains Mono", monospace;
795
+ font-size: 14px;
796
+ letter-spacing: 0;
797
+ background: var(--soft-cream);
798
+ border: 1px solid var(--rule);
799
+ padding: 10px 12px;
800
+ display: flex; flex-wrap: wrap; gap: 1px;
801
+ user-select: none;
802
+ }
803
+ .seq-track__b {
804
+ display: inline-flex; align-items: center; justify-content: center;
805
+ width: 22px; height: 26px;
806
+ cursor: pointer;
807
+ border-radius: 2px;
808
+ color: #fff;
809
+ font-weight: 500;
810
+ transition: transform 0.1s ease, box-shadow 0.1s ease;
811
+ }
812
+ .seq-track__b:hover { transform: translateY(-1px); }
813
+ .seq-track__b.A { background: var(--base-a); }
814
+ .seq-track__b.T { background: var(--base-t); }
815
+ .seq-track__b.C { background: var(--base-c); }
816
+ .seq-track__b.G { background: var(--base-g); }
817
+ .seq-track__b.selected {
818
+ box-shadow: 0 0 0 2px var(--ink), 0 0 0 4px var(--bg);
819
+ }
820
+
821
+ /* Per-base text color (used wherever DNA letters appear in prose) */
822
+ .b-A, .b-T, .b-C, .b-G { font-weight: 500; }
823
+ .b-A { color: var(--base-a); }
824
+ .b-T { color: var(--base-t); }
825
+ .b-C { color: var(--base-c); }
826
+ .b-G { color: var(--base-g); }
827
+
828
+ /* k-mer token: colored bases inside <>, no chrome */
829
+ .kmer-token, .raw-seq {
830
+ font-family: "JetBrains Mono", monospace;
831
+ font-size: 12px;
832
+ font-weight: 500;
833
+ letter-spacing: 0.5px;
834
+ }
835
+ .kmer-token {
836
+ display: inline-flex;
837
+ align-items: center;
838
+ padding: 2px 0;
839
+ white-space: nowrap;
840
+ }
841
+ .kmer-token .br { color: var(--ink-faint); font-weight: 400; }
842
+ .kmer-token.muted { opacity: 0.45; }
843
+ .raw-seq { display: inline-flex; padding: 2px 0; }
844
+
845
+ .bpe-flow {
846
+ display: flex; align-items: center; flex-wrap: wrap;
847
+ gap: 18px;
848
+ margin: 10px 0 8px;
849
+ }
850
+ .bpe-flow .arrow {
851
+ font-family: "JetBrains Mono", monospace;
852
+ font-size: 16px;
853
+ color: var(--ink-faint);
854
+ }
855
+
856
+ /* Line 2: source token, SVG fan-out, candidate rows ----------------- */
857
+ .bpe-branches {
858
+ display: grid;
859
+ grid-template-columns: auto 96px 1fr;
860
+ grid-template-rows: auto 150px;
861
+ gap: 0;
862
+ margin-top: 12px;
863
+ }
864
+ .branch-source {
865
+ grid-column: 1; grid-row: 2;
866
+ align-self: center;
867
+ display: flex; flex-direction: column; align-items: center; gap: 6px;
868
+ padding-right: 8px;
869
+ }
870
+ .branch-source__hint {
871
+ font-family: "JetBrains Mono", monospace;
872
+ font-size: 9px; color: var(--ink-faint);
873
+ text-transform: uppercase; letter-spacing: 1.6px;
874
+ }
875
+ .branch-lines {
876
+ grid-column: 2; grid-row: 2;
877
+ width: 96px; height: 150px;
878
+ display: block;
879
+ }
880
+ .branch-lines path {
881
+ fill: none;
882
+ stroke: #ccc;
883
+ stroke-width: 1.4;
884
+ transition: stroke 0.15s, stroke-width 0.15s;
885
+ }
886
+ .branch-lines path.selected { stroke: var(--green); stroke-width: 2.2; }
887
+ .branch-header {
888
+ grid-column: 3; grid-row: 1;
889
+ display: grid;
890
+ grid-template-columns: 100px 60px 60px;
891
+ gap: 18px;
892
+ padding: 0 12px 10px;
893
+ font-family: "JetBrains Mono", monospace;
894
+ font-size: 9.5px;
895
+ font-weight: 500;
896
+ letter-spacing: 1.6px;
897
+ text-transform: uppercase;
898
+ color: var(--ink-soft);
899
+ }
900
+ .branch-header > span { text-align: center; }
901
+ .branch-header > span:first-child { text-align: left; color: var(--ink-faint); }
902
+ .branch-targets {
903
+ grid-column: 3; grid-row: 2;
904
+ display: grid;
905
+ grid-template-rows: repeat(5, 26px);
906
+ row-gap: 5px;
907
+ align-content: center;
908
+ justify-content: start;
909
+ height: 150px;
910
+ }
911
+ .cand-row {
912
+ display: grid;
913
+ grid-template-columns: 100px 60px 60px;
914
+ gap: 18px;
915
+ align-items: center;
916
+ padding: 2px 12px;
917
+ cursor: pointer;
918
+ border-radius: 2px;
919
+ transition: background 0.12s;
920
+ }
921
+ .cand-row:hover { background: rgba(0,0,0,0.03); }
922
+ .cand-row.selected { background: var(--green-tint); }
923
+ .mark {
924
+ font-family: "JetBrains Mono", monospace;
925
+ font-size: 14px;
926
+ font-weight: 500;
927
+ text-align: center;
928
+ line-height: 1;
929
+ user-select: none;
930
+ }
931
+ .mark.ok { color: var(--green); }
932
+ .mark.bad { color: var(--red); }
933
+
934
+ /* explanation note */
935
+ .note {
936
+ font-family: "Inter", sans-serif;
937
+ font-size: 12px; line-height: 1.55;
938
+ color: var(--ink-soft);
939
+ background: var(--soft-cream);
940
+ border-left: 2px solid var(--green);
941
+ padding: 10px 12px;
942
+ margin-top: 14px;
943
+ }
944
+ .note code {
945
+ font-family: "JetBrains Mono", monospace;
946
+ font-size: 11px;
947
+ background: #fff;
948
+ border: 1px solid var(--rule);
949
+ padding: 0 4px; border-radius: 2px;
950
+ color: var(--green-dark);
951
+ }
952
+ .formula {
953
+ font-family: "JetBrains Mono", monospace;
954
+ font-size: 12px;
955
+ background: var(--soft-cream);
956
+ border: 1px solid var(--rule);
957
+ padding: 10px 12px;
958
+ margin-top: 10px;
959
+ color: var(--ink);
960
+ overflow-x: auto;
961
+ }
962
+ .formula .hl { color: var(--green-dark); font-weight: 600; }
963
+
964
+
965
+
966
+ /* Iframe wrapper: tighten margins so the widget sits flush in an embed. */
967
+ body { padding: 20px 24px; background: var(--bg); }
968
+ .widget { max-width: 880px; margin: 0 auto; padding: 0; border: 0; }
969
+ </style>
970
+ </head>
971
+ <body>
972
+ <aside class="widget" id="wcond">
973
+ <div class="widget__head">
974
+ <span class="widget__eyebrow">§ Widget · 04</span>
975
+ <span class="widget__title">Conditioning the base distributions: fix a base, the rest adapt</span>
976
+ </div>
977
+ <p class="widget__caption">
978
+ Same Carbon-500M next-token distribution as Widget 03. Fix a base under any position and the open positions
979
+ re-marginalize over only the six-mers consistent with your choices; a fixed position freezes at its current
980
+ distribution, and the grid below greys out the six-mers that are no longer reachable.
981
+ </p>
982
+ <div class="demo">
983
+ <div class="demo-toolbar">
984
+ <span id="wcond-meta"></span>
985
+ <span class="spacer"></span>
986
+ <button class="pill" id="wcond-reset">CLEAR FIXED</button>
987
+ </div>
988
+
989
+ <div class="demo-label">Per-position base distribution · fix a base and the rest re-condition</div>
990
+ <div class="posgrid" id="wcond-grid"></div>
991
+
992
+ <div class="demo-label" style="margin-top: 18px">All <span id="wcond-vocab"></span> six-mers, ranked by probability · <span id="wcond-hint"></span></div>
993
+ <div class="w3-allgrid" id="wcond-allgrid"></div>
994
+ </div>
995
+ </aside>
996
+ <script>
997
+
998
+ // ============================================================
999
+ // Shared utilities
1000
+ // ============================================================
1001
+ const BASES = ['A', 'T', 'C', 'G'];
1002
+ const BASE_IDX = {A: 0, T: 1, C: 2, G: 3};
1003
+ const BASE_COLOR = { A: 'var(--base-a)', T: 'var(--base-t)', C: 'var(--base-c)', G: 'var(--base-g)' };
1004
+
1005
+ // FNV-1a 32-bit
1006
+ function hash32(s) {
1007
+ let h = 0x811c9dc5;
1008
+ for (let i = 0; i < s.length; i++) {
1009
+ h ^= s.charCodeAt(i);
1010
+ h = Math.imul(h, 0x01000193);
1011
+ }
1012
+ return h >>> 0;
1013
+ }
1014
+ function rand01(seed) {
1015
+ const h = hash32(String(seed));
1016
+ return (h % 1000003) / 1000003;
1017
+ }
1018
+ function softmax(arr) {
1019
+ let m = -Infinity;
1020
+ for (let i = 0; i < arr.length; i++) if (arr[i] > m) m = arr[i];
1021
+ const out = new Float64Array(arr.length);
1022
+ let s = 0;
1023
+ for (let i = 0; i < arr.length; i++) {
1024
+ out[i] = Math.exp(arr[i] - m);
1025
+ s += out[i];
1026
+ }
1027
+ for (let i = 0; i < arr.length; i++) out[i] /= s;
1028
+ return out;
1029
+ }
1030
+ function cleanDNA(s) {
1031
+ return (s || '').toUpperCase().replace(/[^ACGT]/g, '');
1032
+ }
1033
+ function escapeHTML(s) {
1034
+ return String(s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
1035
+ }
1036
+
1037
+ // 6-mer integer <-> string helpers
1038
+ function kmerToIdx(k) {
1039
+ let i = 0;
1040
+ for (let p = 0; p < k.length; p++) {
1041
+ const b = BASE_IDX[k[p]];
1042
+ if (b == null) return -1;
1043
+ i = i * 4 + b;
1044
+ }
1045
+ return i;
1046
+ }
1047
+ function idxToKmer(i, k = 6) {
1048
+ let s = '';
1049
+ for (let p = k - 1; p >= 0; p--) {
1050
+ s = BASES[(i >> (2 * p)) & 3] + s;
1051
+ }
1052
+ return s;
1053
+ }
1054
+ function baseAt(i, p) {
1055
+ // p in [0..5], 0 is leftmost
1056
+ return (i >> (2 * (5 - p))) & 3;
1057
+ }
1058
+
1059
+ // generate a 4096-d distribution conditioned on a string seed
1060
+ function distribution4096(seed) {
1061
+ const logits = new Float64Array(4096);
1062
+ for (let i = 0; i < 4096; i++) {
1063
+ const a = rand01(seed + ':a:' + i);
1064
+ const b = rand01(seed + ':b:' + (i * 7919));
1065
+ const c = rand01(seed + ':c:' + (i * 65537));
1066
+ // mix a few uniforms → roughly-normal logit centered near 0
1067
+ logits[i] = (a + b + c - 1.5) * 3.2;
1068
+ }
1069
+ return softmax(logits);
1070
+ }
1071
+ function marginals6x4(probs) {
1072
+ const m = [[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]];
1073
+ for (let i = 0; i < 4096; i++) {
1074
+ const p = probs[i];
1075
+ for (let pos = 0; pos < 6; pos++) {
1076
+ m[pos][baseAt(i, pos)] += p;
1077
+ }
1078
+ }
1079
+ return m;
1080
+ }
1081
+ function fmtPct(p) { return (p * 100).toFixed(2) + '%'; }
1082
+ function fmt(p, d=4) { return Number(p).toFixed(d); }
1083
+
1084
+ // Render a row of per-base bars (used for variants of W4/W6/W7)
1085
+ function renderPosCol(parent, posIndex, dist4, mode) {
1086
+ const max = Math.max(0.0001, ...dist4);
1087
+ let argmax = 0;
1088
+ for (let i = 1; i < 4; i++) if (dist4[i] > dist4[argmax]) argmax = i;
1089
+ const col = document.createElement('div');
1090
+ col.className = 'posgrid__col' + (mode === 'argmax' ? ' argmax-' + BASES[argmax] : '');
1091
+ col.innerHTML =
1092
+ `<div class="posgrid__pos">pos ${posIndex + 1}</div>` +
1093
+ `<div class="posgrid__bars">` +
1094
+ BASES.map((b, j) => {
1095
+ const w = (dist4[j] / max) * 100;
1096
+ const isMax = j === argmax;
1097
+ return `<div class="mini-row">
1098
+ <span class="ml">${b}</span>
1099
+ <span class="mt"><span class="mf" style="width:${w.toFixed(1)}%;background:${BASE_COLOR[b]};opacity:${isMax ? 1 : 0.55}"></span></span>
1100
+ <span class="mv">${(dist4[j] * 100).toFixed(1)}</span>
1101
+ </div>`;
1102
+ }).join('') +
1103
+ `</div>`;
1104
+ parent.appendChild(col);
1105
+ }
1106
+
1107
+ function basesHTML(seq) {
1108
+ return Array.from(seq).map((c) => `<span class="base ${c}">${c}</span>`).join('');
1109
+ }
1110
+
1111
+ (function setupCond() {
1112
+ const DATA = {"model":"HuggingFaceBio/Carbon-500M","k":6,"vocab":4096,"inputs":["AGCCCT","CCAGGA","CAGGCT","GCATCA","GAAGAG","GCCATC","AAGCAG","GTCTGT"],"probs_ppm":[802,251,284,417,172,164,227,305,331,226,272,77,321,166,251,353,188,140,164,133,106,151,142,100,212,219,244,38,203,181,176,241,267,181,209,359,112,181,190,245,238,236,196,59,58,75,73,85,541,306,283,447,153,179,203,223,400,309,319,83,539,296,302,351,177,102,87,113,68,129,90,88,128,111,102,33,87,74,99,117,100,81,108,100,89,187,137,114,121,183,153,25,66,83,88,91,138,108,153,259,82,163,157,216,186,233,178,45,34,31,44,43,197,131,155,244,90,134,126,135,172,183,164,30,180,148,192,233,264,98,223,240,102,147,210,228,285,164,212,93,280,137,320,303,87,83,117,101,79,205,217,132,212,185,215,43,177,149,196,176,195,134,182,306,124,252,317,347,225,229,234,54,56,42,55,66,51,45,58,91,34,55,62,77,86,63,68,22,94,52,90,91,446,155,264,694,113,127,211,304,331,189,242,86,345,137,216,334,109,91,114,126,89,123,118,88,168,154,166,48,174,145,151,172,203,141,164,404,95,133,173,261,207,145,166,58,60,52,60,59,514,323,337,770,173,159,243,239,357,315,303,84,328,153,207,319,171,125,105,192,74,67,68,110,113,89,87,27,82,65,71,106,75,155,63,50,80,111,81,69,82,97,99,19,73,99,79,86,83,108,94,128,44,83,54,104,101,110,75,25,20,33,22,34,151,88,80,145,75,58,60,77,156,118,88,32,132,71,68,100,164,106,86,108,66,155,97,82,151,125,115,31,94,73,83,91,165,176,144,115,191,299,217,232,247,292,266,38,153,173,145,185,144,152,150,251,99,170,201,224,192,193,192,37,43,34,31,50,136,119,102,153,81,128,107,116,165,220,136,30,127,127,131,123,218,110,139,219,93,132,295,201,278,232,257,65,256,152,287,269,97,131,140,111,114,221,340,193,254,284,266,58,190,254,234,227,215,196,247,447,140,250,319,310,298,287,225,72,67,60,69,77,52,49,42,69,34,38,62,53,63,75,73,22,54,53,68,63,199,135,137,363,76,93,142,196,200,152,187,74,180,104,134,227,109,159,140,131,94,149,146,158,183,211,189,43,140,229,163,189,161,161,144,271,85,117,113,264,162,156,127,43,40,71,49,44,291,218,167,387,125,141,137,223,304,278,254,103,269,141,165,285,248,142,195,307,80,72,86,152,300,139,141,67,183,110,167,224,90,95,168,91,94,144,120,97,224,213,196,51,155,188,180,205,186,153,526,339,76,123,113,197,205,164,127,43,57,65,78,91,355,224,271,492,180,127,142,211,554,340,314,124,369,273,221,254,133,71,67,93,52,73,63,93,138,151,96,36,94,63,88,124,94,68,193,83,113,199,171,177,207,253,222,46,122,139,137,168,151,127,228,276,95,162,130,222,224,210,127,46,43,43,58,69,262,158,161,304,150,167,148,222,286,314,234,81,212,146,168,275,259,121,197,284,107,125,237,236,328,267,387,107,274,162,304,405,125,104,170,123,110,259,304,229,221,264,304,78,217,281,353,357,225,176,237,457,154,185,253,336,261,225,274,63,68,59,73,88,67,54,54,129,39,35,62,91,100,64,94,39,89,54,90,106,41,24,32,89,24,26,32,73,59,39,51,34,56,30,48,72,27,44,49,53,33,41,50,45,73,56,60,22,71,62,61,95,41,38,67,104,29,33,45,90,56,48,51,32,13,18,18,28,75,46,69,144,46,32,42,70,91,79,99,49,79,44,59,89,307,191,198,330,79,100,117,135,202,175,142,53,418,198,257,420,120,77,87,105,63,109,83,64,160,159,123,30,163,129,109,189,148,145,127,298,63,117,101,125,139,170,102,32,49,44,41,66,322,216,201,498,75,102,114,111,272,248,201,51,383,212,158,225,116,87,74,123,55,94,80,87,118,108,85,26,88,98,107,120,77,72,78,63,81,144,146,115,130,156,128,26,62,83,77,96,109,111,111,191,51,127,138,169,128,153,111,36,33,31,38,37,160,136,118,208,68,119,108,144,129,175,133,33,135,124,125,156,243,131,208,316,97,141,208,235,259,207,226,78,337,225,452,401,102,77,129,101,97,178,253,156,205,243,242,53,202,254,252,237,210,176,222,366,130,232,265,303,239,233,186,60,57,64,76,86,51,50,55,91,28,42,46,71,53,74,81,28,67,57,82,86,368,163,211,579,108,147,180,223,296,193,194,74,397,142,272,528,134,100,90,133,92,151,140,130,236,189,171,42,185,170,157,202,193,137,133,325,89,134,133,227,167,169,140,47,47,47,46,69,381,209,218,404,87,159,140,160,255,278,206,61,263,163,138,292,389,177,145,275,102,103,107,146,175,126,122,38,195,136,172,250,141,83,77,85,89,119,100,72,126,123,144,27,153,115,92,130,114,110,123,180,69,111,107,119,132,141,111,27,35,41,34,45,207,109,111,190,71,94,90,119,144,114,108,30,206,142,118,147,124,73,60,76,98,90,65,75,101,81,79,19,61,52,68,71,114,121,99,78,125,217,171,117,139,141,164,28,92,104,115,114,114,120,131,202,97,187,172,175,185,191,144,34,34,38,42,44,128,105,114,134,80,113,93,113,117,126,106,26,139,110,130,141,193,89,128,180,101,142,157,186,228,129,148,48,210,144,229,235,86,79,136,86,108,199,203,133,192,164,153,45,145,203,203,198,153,138,185,276,119,246,264,379,192,195,201,53,52,64,68,60,35,32,36,58,36,33,45,54,48,43,40,14,62,40,61,50,224,87,108,297,65,80,105,112,129,95,106,28,196,77,130,213,84,63,61,101,59,104,108,69,116,114,126,26,105,118,85,122,187,129,142,228,105,122,147,212,143,142,128,44,41,39,41,55,263,137,111,284,70,109,115,118,139,151,129,35,225,131,112,178,364,181,146,294,104,131,117,129,138,117,113,38,157,99,103,196,92,116,79,93,161,280,148,134,170,212,167,36,87,127,86,128,164,195,131,302,96,193,137,225,161,240,136,42,35,48,38,44,218,126,101,216,80,107,88,118,211,189,123,40,190,127,102,200,346,195,141,248,104,282,149,130,215,189,181,49,148,123,141,199,347,237,238,228,233,1506,319,241,346,455,456,68,218,280,224,306,258,298,281,554,187,538,403,434,418,522,340,93,74,64,68,84,346,250,189,341,150,361,203,219,285,348,267,71,266,220,201,393,278,132,191,296,110,210,304,246,322,254,268,75,334,244,382,447,198,182,232,228,208,470,628,300,434,526,567,91,345,417,459,461,386,362,364,722,237,566,574,630,513,563,423,105,111,108,118,150,65,56,55,93,35,55,89,65,60,63,63,20,70,60,67,91,271,169,201,494,90,166,216,219,213,185,207,68,221,150,191,287,135,149,153,182,136,380,274,273,252,315,308,54,213,323,186,263,253,223,226,494,166,277,292,520,273,287,231,84,49,71,60,82,414,281,252,552,118,264,246,261,297,410,337,82,355,223,264,446,256,179,184,378,87,87,122,149,227,129,157,56,223,138,142,282,83,116,118,95,120,232,208,161,371,312,290,81,170,182,172,224,197,212,249,404,102,228,206,266,292,286,188,73,69,86,75,80,464,265,258,552,150,211,246,269,465,412,352,125,437,287,232,390,149,117,88,165,71,112,117,120,193,153,165,38,132,106,88,167,166,114,180,129,155,256,327,242,400,457,477,80,171,214,201,229,231,217,253,436,189,329,534,442,456,531,284,86,55,70,66,105,385,281,277,485,229,293,344,354,465,551,375,91,393,232,234,404,358,146,219,412,135,207,359,305,376,236,345,111,443,285,481,601,168,131,210,183,165,409,580,314,473,440,712,128,347,393,422,464,389,308,347,789,193,419,563,685,403,361,424,107,112,100,115,142,80,64,82,162,51,58,78,107,102,76,101,40,106,76,97,113,51,31,42,88,17,32,46,57,47,34,46,22,54,31,38,72,29,34,36,36,30,45,59,42,64,61,71,29,47,60,48,51,43,42,43,93,30,49,64,110,59,55,56,26,16,14,20,26,68,53,78,158,39,53,67,66,78,75,81,40,84,46,57,96,198,144,121,279,58,95,97,110,147,127,106,39,235,142,164,246,77,72,68,80,59,121,87,89,141,161,140,36,180,136,108,188,138,139,109,206,64,149,116,125,138,200,117,41,45,48,39,46,228,169,113,211,79,123,86,134,213,201,163,45,239,161,163,187,105,77,75,119,53,99,83,106,119,103,94,29,76,85,96,112,96,76,103,106,89,196,139,129,159,186,165,30,104,191,132,138,129,168,145,222,71,191,175,227,193,250,171,48,27,45,38,49,163,139,143,198,94,169,139,399,139,180,141,43,132,136,170,180,166,87,104,170,64,107,116,150,169,120,128,53,206,150,241,237,96,88,109,105,74,175,207,135,162,191,182,43,188,228,334,242,181,174,162,299,96,194,215,252,194,185,175,61,50,49,50,72,27,30,31,43,18,32,32,56,44,31,30,15,39,42,49,55,283,151,167,451,94,142,179,206,199,164,162,74,306,172,240,371,103,122,111,120,97,201,188,137,203,237,245,52,182,205,184,288,218,188,182,367,134,219,225,337,246,238,183,87,61,60,61,82,374,254,224,458,93,211,174,196,274,220,200,90,369,200,179,384,418,245,273,355,124,124,167,189,308,217,209,70,260,216,252,339,118,101,110,89,76,106,122,70,291,162,195,39,158,144,135,204,286,241,267,414,98,167,194,212,251,234,214,53,69,89,86,101,439,248,229,417,137,149,176,174,335,293,220,61,387,258,308,281,141,107,93,117,74,137,112,105,198,123,157,45,100,98,125,114,146,132,171,133,147,339,255,174,231,230,229,51,137,173,190,204,270,288,351,554,196,414,401,399,369,402,362,90,79,106,118,105,243,189,256,319,160,209,204,252,309,249,216,83,292,253,292,263,298,162,259,375,169,193,294,320,879,292,314,159,320,265,540,422,150,124,174,165,153,280,439,231,378,260,315,92,268,323,428,328,352,352,538,676,209,516,646,679,477,373,424,108,157,104,147,160,86,72,89,109,62,80,92,150,173,101,127,41,129,117,178,141,724,362,467,1228,205,256,432,524,615,413,432,158,722,326,608,938,238,233,316,256,148,297,340,225,444,446,407,100,323,369,323,475,619,500,708,1367,256,515,679,728,555,525,511,161,183,180,234,216,939,550,608,1244,344,367,412,498,663,625,512,156,736,398,525,610,220,119,115,204,68,77,91,103,119,111,121,41,121,88,121,125,72,84,64,76,57,108,96,66,126,187,126,34,94,108,72,137,165,164,152,262,98,172,142,195,145,200,127,38,36,50,51,56,228,121,111,205,94,94,111,114,175,207,124,49,163,124,130,158,204,109,118,163,76,162,161,108,219,199,195,42,110,89,122,140,292,229,172,205,184,479,380,276,328,498,439,73,247,306,325,321,345,440,402,691,234,582,685,647,463,638,549,96,85,102,87,104,260,215,190,302,135,289,204,210,234,335,260,73,261,215,226,236,379,186,252,420,137,243,371,325,433,323,394,135,364,321,512,507,188,191,273,241,185,521,709,336,435,1188,638,110,453,570,654,526,464,427,529,1116,273,650,906,829,479,552,575,149,143,132,206,166,84,64,77,108,54,69,104,100,102,115,106,34,132,109,134,140,527,276,403,996,167,216,406,424,414,370,448,149,458,287,509,596,256,263,304,309,224,372,428,342,527,802,841,120,427,614,427,490,509,488,456,1138,296,500,629,1193,452,622,567,154,121,183,155,190,779,500,400,1075,206,288,351,461,553,642,524,143,648,459,510,652,455,226,293,451,72,100,249,164,303,183,269,84,301,178,243,358,112,153,139,125,129,227,196,155,458,452,511,106,208,258,232,337,258,261,371,502,151,201,250,310,435,350,290,104,104,109,141,152,656,357,377,824,169,217,274,285,686,542,507,166,625,418,448,524,288,148,159,236,106,136,125,153,292,236,214,64,191,108,171,229,175,146,206,174,212,363,360,305,484,613,672,114,245,269,274,375,287,335,467,798,192,450,466,628,628,798,468,153,97,127,140,175,619,383,400,793,280,377,377,390,722,630,514,160,570,386,448,679,527,190,317,524,160,250,404,325,442,312,430,171,474,315,661,678,243,153,230,227,158,386,594,291,458,533,702,140,365,425,524,545,543,363,475,988,198,477,587,646,478,444,1964,176,147,130,237,251,148,79,109,234,58,80,120,137,142,133,168,56,140,106,174,209,92,55,70,153,34,35,69,67,94,76,62,46,97,65,105,146,40,45,75,51,39,60,86,64,104,135,152,43,75,113,84,121,75,66,96,203,52,60,110,150,118,120,127,93,32,33,44,50,123,90,107,224,48,59,87,109,140,112,157,74,130,90,126,172,58,36,40,58,20,25,30,29,48,38,45,18,75,45,61,87,28,32,30,28,23,33,38,24,58,58,65,20,53,53,44,85,50,42,53,87,25,44,50,49,53,61,43,16,26,23,26,28,95,60,70,140,26,33,45,47,78,83,64,29,117,87,77,119,43,32,25,48,14,35,39,33,48,38,37,18,34,31,46,49,33,28,39,48,26,62,56,50,54,73,79,17,35,52,54,58,59,86,89,98,38,95,75,96,82,88,79,30,28,37,37,44,53,64,67,107,38,63,77,122,83,77,68,22,73,86,94,100,74,39,49,87,24,54,65,77,91,44,64,38,88,89,126,146,33,36,60,38,39,69,95,60,95,93,95,41,87,108,136,114,74,95,114,158,38,89,123,164,94,93,103,39,37,46,74,61,20,18,24,37,9,15,22,33,23,23,25,16,32,30,47,40,144,51,76,225,32,54,78,87,117,63,75,37,119,65,125,165,54,48,56,56,33,54,85,58,102,94,94,30,71,88,91,105,104,89,101,227,54,80,129,136,116,111,119,54,51,56,50,94,169,115,118,228,48,59,89,91,133,105,120,46,154,109,134,167,764,457,519,749,301,312,407,511,512,353,405,162,628,311,489,678,193,223,198,161,196,269,309,193,307,312,370,98,355,295,305,464,422,391,518,672,218,369,533,635,386,368,283,89,134,155,164,194,1306,760,747,1252,427,430,557,675,959,737,754,197,1224,716,804,995,330,207,228,274,156,277,245,212,276,236,256,70,235,142,194,204,196,185,214,153,220,491,448,334,271,380,359,73,189,182,225,409,342,418,415,728,273,586,621,625,584,564,506,142,103,107,115,172,598,497,474,662,264,493,537,473,429,675,529,103,666,487,568,620,593,280,482,586,252,427,692,602,727,395,568,229,784,430,785,696,179,180,247,180,241,531,753,420,398,462,489,131,362,415,463,491,492,390,513,872,377,924,1053,1052,567,571,788,168,184,168,228,170,131,113,149,223,117,130,257,183,168,133,162,44,201,119,211,192,981,400,666,1703,290,386,562,807,675,428,622,210,1036,316,606,866,197,179,252,226,200,347,405,268,414,390,378,97,379,331,370,440,538,438,610,1428,346,497,764,1054,606,523,470,205,183,153,192,242,1328,794,893,2143,422,498,748,794,865,877,798,251,1072,495,737,836,376,235,238,381,163,135,172,201,258,199,200,70,243,283,184,299,146,207,119,130,174,260,222,175,208,289,240,75,203,445,202,225,294,331,256,441,142,272,210,330,247,297,225,73,83,128,87,95,337,234,217,353,181,187,191,257,348,340,306,86,319,224,193,308,324,186,157,301,128,271,223,209,345,310,275,57,183,141,206,230,285,332,316,272,344,719,526,514,445,689,601,97,334,471,390,511,409,401,457,785,273,598,615,715,426,628,570,123,117,102,115,138,390,292,233,431,244,454,313,373,379,581,476,91,437,339,303,442,411,202,290,481,222,360,688,456,556,483,691,182,634,404,648,695,164,225,307,198,214,535,779,402,496,819,707,147,444,822,659,575,488,575,527,1039,326,605,926,995,621,723,744,186,178,186,213,187,80,80,117,134,65,85,148,102,121,136,150,46,129,96,128,166,596,356,408,931,230,302,412,680,658,498,648,176,487,515,484,682,284,469,386,300,282,555,605,521,540,693,830,153,593,3525,654,716,472,402,464,1029,275,528,522,1081,508,574,503,178,135,239,162,220,841,586,521,1093,382,418,496,839,748,821,828,228,733,445,519,1013,601,328,389,709,172,174,205,346,514,289,336,139,424,250,324,561,157,190,174,150,213,318,245,237,462,394,468,130,289,440,465,358,326,326,582,694,191,284,265,473,395,386,273,118,99,152,183,168,1024,497,598,1249,347,317,381,634,1452,824,768,295,983,575,536,882,336,211,273,394,146,236,215,271,439,357,426,128,225,209,227,293,196,215,243,248,342,510,543,504,614,761,703,137,286,426,385,388,416,439,571,1014,256,615,551,955,640,748,544,196,120,158,179,247,886,644,700,1361,470,623,655,959,1129,1824,1000,328,957,635,690,1062,710,341,474,868,246,431,734,720,798,538,819,265,664,470,988,1185,228,225,405,270,221,605,877,545,593,645,796,175,536,572,690,848,522,459,709,1347,291,661,839,1052,558,647,752,194,198,227,234,319,189,128,160,345,96,123,161,263,208,209,342,107,225,147,314,431,91,48,73,204,50,59,88,172,117,81,109,74,131,82,109,203,56,50,73,77,58,101,114,104,112,142,139,55,103,203,155,188,93,88,107,273,56,94,130,248,104,133,107,56,43,41,83,97,146,114,132,324,79,75,120,206,190,150,218,159,210,110,168,252,783,439,471,793,233,245,259,347,484,381,296,144,749,508,566,922,212,205,225,168,197,314,280,206,415,472,389,106,441,366,331,609,381,387,462,860,173,351,313,470,358,412,301,100,148,151,118,199,1145,634,763,1351,289,389,385,414,887,859,598,199,1343,709,614,923,323,197,202,481,138,231,244,247,404,305,290,119,216,173,251,368,221,207,242,245,227,518,395,372,351,649,414,75,204,266,329,348,404,406,473,827,205,515,659,635,482,586,443,125,96,116,129,149,484,539,533,878,250,459,438,611,450,634,466,161,518,638,575,738,568,293,522,568,229,386,594,662,685,500,573,216,759,539,885,883,234,192,449,250,224,573,770,425,611,659,693,141,574,648,765,729,573,530,660,1009,295,725,875,878,548,578,612,197,218,200,216,314,114,141,173,311,82,146,137,240,135,176,206,64,200,159,306,216,915,419,559,1848,260,456,605,710,825,466,568,216,777,379,604,1091,277,232,286,290,296,538,424,380,538,540,536,150,421,380,426,611,587,486,574,1262,279,565,618,847,562,545,497,232,191,241,235,236,1317,647,849,1596,377,586,635,689,835,924,789,248,825,504,526,2976]};
1113
+ const k = DATA.k, V = DATA.vocab, P = DATA.probs_ppm;
1114
+ const GREY = '#d3d0c4';
1115
+ const gridEl = document.getElementById('wcond-grid');
1116
+ const allgrid = document.getElementById('wcond-allgrid');
1117
+ const hintEl = document.getElementById('wcond-hint');
1118
+ document.getElementById('wcond-meta').textContent = DATA.model.split('/').pop() + ' · next 6-mer';
1119
+ document.getElementById('wcond-vocab').textContent = V.toLocaleString();
1120
+
1121
+ const baseAt = (idx, p) => (idx >> (2 * (k - 1 - p))) & 3;
1122
+ let locks = new Array(k).fill(null); // base index 0..3, or null
1123
+ let frozen = new Array(k).fill(null); // snapshot sums[4] captured when a position is fixed
1124
+
1125
+ function matchesLocks(flat) {
1126
+ for (let p = 0; p < k; p++) if (locks[p] !== null && baseAt(flat, p) !== locks[p]) return false;
1127
+ return true;
1128
+ }
1129
+ function condSums(p) {
1130
+ const s = [0, 0, 0, 0];
1131
+ for (let f = 0; f < V; f++) if (matchesLocks(f)) s[baseAt(f, p)] += P[f];
1132
+ return s;
1133
+ }
1134
+
1135
+ // Stable per-column display order: sort base indices by the UNCONDITIONAL marginal once,
1136
+ // so conditioning only changes bar lengths, never their order.
1137
+ const colOrder = [];
1138
+ for (let p = 0; p < k; p++) {
1139
+ const s = [0, 0, 0, 0];
1140
+ for (let f = 0; f < V; f++) s[baseAt(f, p)] += P[f];
1141
+ colOrder.push([0, 1, 2, 3].sort((a, b) => s[b] - s[a]));
1142
+ }
1143
+
1144
+ // Grid cells, one per six-mer, initially in probability-rank order.
1145
+ const order = [...Array(V).keys()].sort((a, b) => P[b] - P[a]);
1146
+ allgrid.innerHTML = order.map(() => '<span class="w3-cell"></span>').join('');
1147
+ const cellByFlat = {};
1148
+ order.forEach((flat, i) => { cellByFlat[flat] = allgrid.children[i]; });
1149
+ const COLS = 128; // grid-template-columns: repeat(128, 1fr)
1150
+ const posOf = {}; // flat -> current cell index in the grid
1151
+ order.forEach((flat, i) => { posOf[flat] = i; });
1152
+
1153
+ function renderCols() {
1154
+ gridEl.innerHTML = '';
1155
+ // Per-column percentages (these are what the numbers show); bars are scaled to the
1156
+ // largest percentage across columns, so they track the numbers as you condition.
1157
+ const cols = [];
1158
+ let gmaxPct = 0.0001;
1159
+ for (let p = 0; p < k; p++) {
1160
+ const locked = locks[p] !== null;
1161
+ const sums = locked ? frozen[p] : condSums(p);
1162
+ const total = sums[0] + sums[1] + sums[2] + sums[3];
1163
+ const pct = sums.map((s) => (total ? s / total : 0));
1164
+ gmaxPct = Math.max(gmaxPct, pct[0], pct[1], pct[2], pct[3]);
1165
+ cols.push({ locked, sums, pct });
1166
+ }
1167
+ for (let p = 0; p < k; p++) {
1168
+ const { locked, sums, pct } = cols[p];
1169
+ let am = 0; for (let j = 1; j < 4; j++) if (sums[j] > sums[am]) am = j;
1170
+ const bars = colOrder[p].map((j) => {
1171
+ const b = BASES[j];
1172
+ const w = (pct[j] / gmaxPct) * 100;
1173
+ return '<div class="mini-row"><span class="ml" style="color:' + BASE_COLOR[b] + '">' + b + '</span>' +
1174
+ '<span class="mt"><span class="mf" style="width:' + w.toFixed(1) + '%;background:' + BASE_COLOR[b] + '"></span></span>' +
1175
+ '<span class="mv">' + (pct[j] * 100).toFixed(0) + '</span></div>';
1176
+ }).join('');
1177
+ const sel = BASES.map((b, j) =>
1178
+ '<button class="cond-pick b-' + b + (locks[p] === j ? ' active' : '') + '" data-p="' + p + '" data-b="' + j + '">' + b + '</button>'
1179
+ ).join('');
1180
+ const col = document.createElement('div');
1181
+ col.className = 'posgrid__col argmax-' + BASES[am] + (locked ? ' frozen' : '');
1182
+ col.innerHTML =
1183
+ '<div class="posgrid__pos">Position ' + (p + 1) + '</div>' +
1184
+ '<div class="posgrid__bars">' + bars + '</div>' +
1185
+ '<div class="posgrid__sel">' + sel + '</div>';
1186
+ gridEl.appendChild(col);
1187
+ }
1188
+ gridEl.querySelectorAll('.cond-pick').forEach((btn) => btn.addEventListener('click', () => {
1189
+ const p = +btn.dataset.p, b = +btn.dataset.b;
1190
+ if (locks[p] === b) { locks[p] = null; frozen[p] = null; }
1191
+ else { frozen[p] = condSums(p); locks[p] = b; } // snapshot current dist, then fix
1192
+ renderCols(); recolorGrid();
1193
+ }));
1194
+ }
1195
+
1196
+ function recolorGrid() {
1197
+ let lop = -1;
1198
+ for (let p = 0; p < k; p++) if (locks[p] === null) { lop = p; break; }
1199
+
1200
+ // Attainable six-mers (prob-ranked) move to the front; unattainable (grey) follow.
1201
+ const attainFlats = [], restFlats = [];
1202
+ for (const flat of order) (matchesLocks(flat) ? attainFlats : restFlats).push(flat);
1203
+ const display = attainFlats.concat(restFlats);
1204
+
1205
+ // Cell pitch (column/row step) measured once per update — no per-cell layout reads.
1206
+ const stepX = allgrid.children[1].offsetLeft - allgrid.children[0].offsetLeft;
1207
+ const stepY = allgrid.children[COLS].offsetTop - allgrid.children[0].offsetTop;
1208
+
1209
+ // Reorder + recolor. FLIP only the colored cells; grey cells are identical so they
1210
+ // can snap to their new slots invisibly (this is what keeps it smooth at 4,096 cells).
1211
+ const frag = document.createDocumentFragment();
1212
+ const moved = [];
1213
+ display.forEach((flat, newIdx) => {
1214
+ const el = cellByFlat[flat];
1215
+ const attain = matchesLocks(flat);
1216
+ el.style.background = attain ? BASE_COLOR[BASES[baseAt(flat, lop === -1 ? 0 : lop)]] : GREY;
1217
+ frag.appendChild(el);
1218
+ if (attain) {
1219
+ const oldIdx = posOf[flat];
1220
+ const dx = ((oldIdx % COLS) - (newIdx % COLS)) * stepX;
1221
+ const dy = (Math.floor(oldIdx / COLS) - Math.floor(newIdx / COLS)) * stepY;
1222
+ el.style.transition = 'none';
1223
+ if (dx || dy) { el.style.transform = 'translate(' + dx + 'px,' + dy + 'px)'; moved.push(el); }
1224
+ else el.style.transform = '';
1225
+ } else {
1226
+ el.style.transition = 'none';
1227
+ el.style.transform = '';
1228
+ }
1229
+ });
1230
+ allgrid.appendChild(frag);
1231
+ display.forEach((flat, i) => { posOf[flat] = i; });
1232
+
1233
+ requestAnimationFrame(() => moved.forEach((el) => {
1234
+ el.style.transition = 'transform 0.4s ease';
1235
+ el.style.transform = '';
1236
+ }));
1237
+
1238
+ const anyLock = locks.some((x) => x !== null);
1239
+ hintEl.innerHTML = (lop === -1 ? 'fully fixed' : 'colored by base at position ' + (lop + 1)) +
1240
+ (anyLock ? ' · <b>' + attainFlats.length.toLocaleString() + '</b> attainable' : '');
1241
+ }
1242
+
1243
+ document.getElementById('wcond-reset').addEventListener('click', () => {
1244
+ locks = new Array(k).fill(null); frozen = new Array(k).fill(null);
1245
+ renderCols(); recolorGrid();
1246
+ });
1247
+
1248
+ renderCols();
1249
+ recolorGrid();
1250
+ })();
1251
+ </script>
1252
+ </body>
1253
  </html>
style.css DELETED
@@ -1,28 +0,0 @@
1
- body {
2
- padding: 2rem;
3
- font-family: -apple-system, BlinkMacSystemFont, "Arial", sans-serif;
4
- }
5
-
6
- h1 {
7
- font-size: 16px;
8
- margin-top: 0;
9
- }
10
-
11
- p {
12
- color: rgb(107, 114, 128);
13
- font-size: 15px;
14
- margin-bottom: 10px;
15
- margin-top: 5px;
16
- }
17
-
18
- .card {
19
- max-width: 620px;
20
- margin: 0 auto;
21
- padding: 16px;
22
- border: 1px solid lightgray;
23
- border-radius: 16px;
24
- }
25
-
26
- .card p:last-child {
27
- margin-bottom: 0;
28
- }