tfrere HF Staff Cursor commited on
Commit
5dfaccc
·
1 Parent(s): d001974

Footer: editorial site footer with collab credit + partner logos

Browse files

Adds a multi-row site footer in demo.html (collab block with 4 partner
stamps, three-column identity/resources/sections strip, legal hairline)
backed by a full rewrite of assets/styles/footer.css. Drops partner
artwork under img/partners/ (Hugging Face, Zhongguancun Academy, TIGEM,
Federico II) plus their raw sources for traceability.

Also bundles a few small fixes uncovered while wiring the footer:
- demo.html banner: point Tech report to the paperswithcode landing
- sandbox.js: clear the .empty placeholder when incrementalRender takes
over straight from idle, so generated lines stop rendering inline
- section-vep.css: allow horizontal scroll on .vep-window so the 60bp
mono stack survives narrow viewports without breaking row alignment
- intro/species/controls/recipe/banner CSS: footer-adjacent polish

Co-authored-by: Cursor <cursoragent@cursor.com>

assets/js/sections/sandbox.js CHANGED
@@ -242,6 +242,18 @@
242
  }
243
  function incrementalRender(bpl) {
244
  const total = promptBases + genText;
 
 
 
 
 
 
 
 
 
 
 
 
245
  const totalLines = Math.ceil(total.length / bpl);
246
  const lineDivs = els.seq.children;
247
  if (lineDivs.length > 0) {
 
242
  }
243
  function incrementalRender(bpl) {
244
  const total = promptBases + genText;
245
+ // Transition out of the empty-placeholder state: when generation
246
+ // kicks in straight from the idle placeholder, renderSequence() picks
247
+ // the incremental path (no mode/bpl change, totalLines >= renderedLines),
248
+ // so we never go through fullRender(). Without this guard the `.empty`
249
+ // class (display:flex + align-items:center) stays applied and the
250
+ // placeholder text node lingers next to the new <div class="sb-seq-line">
251
+ // children, which makes every line render as a flex-row item, all on a
252
+ // single overflowing horizontal line instead of a normal stack.
253
+ if (els.seq.classList.contains("empty")) {
254
+ els.seq.classList.remove("empty");
255
+ els.seq.textContent = "";
256
+ }
257
  const totalLines = Math.ceil(total.length / bpl);
258
  const lineDivs = els.seq.children;
259
  if (lineDivs.length > 0) {
assets/styles/banner.css CHANGED
@@ -513,17 +513,46 @@ a.banner-path:focus-visible { outline: none; }
513
  min-height: auto;
514
  padding: 18px 18px 0;
515
  }
 
 
 
516
  .banner-helix {
517
- height: 460px;
518
- order: -1; /* helix above headline on narrow viewports */
519
- }
520
- .cb-helix-canvas {
521
- top: -40px; right: 0; bottom: -40px;
522
- width: 100%; height: calc(100% + 80px);
523
- transform: rotate(8deg);
524
- transform-origin: center;
525
  }
526
  .banner-wordmark { font-size: clamp(56px, 16vw, 96px); }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
527
  /* Let the four tabs split the row evenly so they fit a narrow viewport
528
  without horizontal scroll. min-width: 0 overrides the desktop 150px
529
  floor; nowrap stays on so "Carbon Recipe" doesn't wrap mid-tab. */
 
513
  min-height: auto;
514
  padding: 18px 18px 0;
515
  }
516
+ /* Hide the DNA helix on narrow viewports: the canvas animation is
517
+ expensive on mobile and the banner already feels dense without it.
518
+ We keep the element semantically present but visually removed. */
519
  .banner-helix {
520
+ display: none;
 
 
 
 
 
 
 
521
  }
522
  .banner-wordmark { font-size: clamp(56px, 16vw, 96px); }
523
+
524
+ /* Stack the spec list vertically on narrow viewports: at desktop sizes the
525
+ three specs read as a comma-separated tagline thanks to the inline "·"
526
+ separators, but on mobile that row crams into ~320px and the dots end up
527
+ looking like accidental punctuation. Switching to column drops the
528
+ separators (hidden below) and gives each spec its own line, matching the
529
+ stacked links treatment underneath. The bumped top margin opens a small
530
+ breathing room above the first spec so the block doesn't collide with
531
+ the wordmark/subtitle stack. */
532
+ .banner-specs {
533
+ flex-direction: column;
534
+ align-items: flex-start;
535
+ margin-top: 18px;
536
+ }
537
+ .banner-spec + .banner-spec::before {
538
+ content: none;
539
+ }
540
+
541
+ /* Same treatment for the resource links (Models / Tech report / Code).
542
+ Each <li> takes its own row; the anchor stays inline so the underline
543
+ hugs the text instead of stretching the full column width. The extra
544
+ margin-bottom matches the new top spacing on .banner-specs and keeps a
545
+ clear gap before the tab strip below. */
546
+ .banner-links {
547
+ flex-direction: column;
548
+ align-items: flex-start;
549
+ gap: 10px;
550
+ margin-bottom: 24px;
551
+ }
552
+ .banner-links li {
553
+ width: auto;
554
+ }
555
+
556
  /* Let the four tabs split the row evenly so they fit a narrow viewport
557
  without horizontal scroll. min-width: 0 overrides the desktop 150px
558
  floor; nowrap stays on so "Carbon Recipe" doesn't wrap mid-tab. */
assets/styles/controls.css CHANGED
@@ -36,7 +36,22 @@ button.action.primary:hover { background: #000; }
36
  button.action:disabled { opacity: 0.4; cursor: not-allowed; }
37
  button.action.primary:disabled { background: #888; border-color: #888; }
38
  .pill.active { background: #1f1f1d; color: #fff; border-color: #1f1f1d; }
39
- .pills { display: inline-flex; gap: 6px; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
 
41
  /* --- Stub placeholder for unbuilt demos --- */
42
  .stub {
 
36
  button.action:disabled { opacity: 0.4; cursor: not-allowed; }
37
  button.action.primary:disabled { background: #888; border-color: #888; }
38
  .pill.active { background: #1f1f1d; color: #fff; border-color: #1f1f1d; }
39
+ /* flex-wrap so pill rows (variants, genes, species…) break onto a second
40
+ line on narrow viewports instead of overflowing the .demo-toolbar to
41
+ the right. The 6px gap doubles as the row-gap when wrapping kicks in. */
42
+ .pills { display: inline-flex; flex-wrap: wrap; gap: 6px; }
43
+
44
+ /* Mobile: force the pills span onto its own toolbar row (`flex-basis: 100%`)
45
+ so labels like "color by" / "highlights" stack above and the pills get
46
+ the full card width to wrap into. Without this, the label eats horizontal
47
+ space, the pills get squeezed, and you end up with awkward orphan-pill
48
+ rows ("GENE LENGTH" alone, "MITOCHONDRIAL" alone). The spacer is dropped
49
+ too, otherwise it leaves a phantom blank row before the trailing action
50
+ buttons (which then wrap to their own row at their natural width). */
51
+ @media (max-width: 600px) {
52
+ .demo-toolbar .pills { flex: 0 0 100%; }
53
+ .demo-toolbar .spacer { display: none; }
54
+ }
55
 
56
  /* --- Stub placeholder for unbuilt demos --- */
57
  .stub {
assets/styles/footer.css CHANGED
@@ -1,11 +1,436 @@
1
- /* footer.css, page footer: model identifier line at the bottom. */
2
 
3
- footer {
4
- text-align: center; padding: 48px 32px;
5
- color: #999; font-size: 11px;
6
- font-family: "JetBrains Mono", monospace;
7
- letter-spacing: 1px; text-transform: uppercase;
8
- border-top: 1px solid #eee;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  }
10
- footer a { color: #666; text-decoration: none; }
11
- footer a:hover { color: #1f1f1d; }
 
1
+ /* footer.css · editorial site footer.
2
 
3
+ Composition (top → bottom):
4
+ 1. Collaboration block eyebrow + headline + lede, then a row of 4
5
+ partner stamps (logo + name + sub). The stamps are bare (no card
6
+ background) and separated by vertical hairlines so the row reads
7
+ as one editorial credit line, not four buttons.
8
+ 2. Three-column lower strip — Carbon identity (logo + name + path)
9
+ on the left, then "Resources" (external) and "Sections" (in-page
10
+ tabs) link columns on the right.
11
+ 3. Legal hairline strip — copyright + license on the left, model
12
+ spec recap on the right, all mono caps.
13
+
14
+ Sits on the same --paper as the rest of the page; a soft top hairline
15
+ plus a subtle radial-dot texture (echoing the banner) makes the footer
16
+ feel like the bottom trim of the editorial sheet rather than a
17
+ detached UI block. */
18
+
19
+ .site-footer {
20
+ position: relative;
21
+ /* Tight against the preceding section: the panels above already carry
22
+ their own bottom padding (.container's 96px), so we don't add any
23
+ extra outer margin — just a hairline + a comfortable inner top pad. */
24
+ margin-top: 0;
25
+ background:
26
+ radial-gradient(circle at 18% 26%, rgba(0, 0, 0, 0.05), transparent 1px),
27
+ radial-gradient(circle at 82% 74%, rgba(0, 0, 0, 0.045), transparent 1px),
28
+ linear-gradient(180deg, transparent 0%, rgba(49, 127, 63, 0.02) 100%),
29
+ var(--paper, #f7f5ee);
30
+ background-size: 9px 9px, 13px 13px, auto, auto;
31
+ border-top: 1px solid var(--hairline, #d6d3c4);
32
+ color: var(--ink, #1f1f1d);
33
+ font-family: "Inter", "Helvetica Neue", sans-serif;
34
+ }
35
+ .site-footer__inner {
36
+ max-width: 1200px;
37
+ margin: 0 auto;
38
+ padding: 40px 32px 24px;
39
+ }
40
+
41
+ /* ---------------------------------------------------------------------
42
+ 1) COLLABORATION BLOCK
43
+ --------------------------------------------------------------------- */
44
+ .cb-collab {
45
+ padding-bottom: 56px;
46
+ margin-bottom: 44px;
47
+ border-bottom: 1px solid var(--hairline, #d6d3c4);
48
+ }
49
+ .cb-collab__head {
50
+ max-width: 760px;
51
+ margin-bottom: 40px;
52
+ }
53
+ .cb-collab__eyebrow {
54
+ display: inline-block;
55
+ margin-bottom: 12px;
56
+ font-family: "JetBrains Mono", ui-monospace, monospace;
57
+ font-size: 11px;
58
+ font-weight: 500;
59
+ letter-spacing: 0.22em;
60
+ text-transform: uppercase;
61
+ color: var(--green, #317f3f);
62
+ }
63
+ .cb-collab__title {
64
+ margin: 0 0 12px;
65
+ font-family: "JetBrains Mono", ui-monospace, monospace;
66
+ font-size: 24px;
67
+ font-weight: 600;
68
+ letter-spacing: -0.01em;
69
+ line-height: 1.25;
70
+ color: var(--ink, #1f1f1d);
71
+ }
72
+ .cb-collab__lede {
73
+ margin: 0;
74
+ font-size: 14px;
75
+ line-height: 1.7;
76
+ color: #5b5b56;
77
+ }
78
+ .cb-collab__lede em {
79
+ font-style: normal;
80
+ color: var(--ink, #1f1f1d);
81
+ font-weight: 500;
82
+ }
83
+
84
+ /* Partner stamps row.
85
+ Four equal columns, no card chrome, separated by vertical hairlines
86
+ so the strip reads as a single editorial credit line. The hairlines
87
+ are drawn as 1px backgrounds on the left edge of each item, with the
88
+ first item suppressed. */
89
+ .cb-partners {
90
+ list-style: none;
91
+ margin: 0;
92
+ padding: 0;
93
+ display: grid;
94
+ grid-template-columns: repeat(4, 1fr);
95
+ }
96
+ .cb-partner {
97
+ position: relative;
98
+ }
99
+ .cb-partner + .cb-partner::before {
100
+ content: "";
101
+ position: absolute;
102
+ top: 12px;
103
+ bottom: 12px;
104
+ left: 0;
105
+ width: 1px;
106
+ background: var(--hairline, #d6d3c4);
107
+ }
108
+ .cb-partner__link {
109
+ display: flex;
110
+ flex-direction: column;
111
+ align-items: center;
112
+ text-align: center;
113
+ gap: 14px;
114
+ padding: 16px 18px;
115
+ text-decoration: none;
116
+ color: var(--ink, #1f1f1d);
117
+ border-radius: 4px;
118
+ transition: color 0.18s ease, background 0.18s ease, transform 0.18s ease;
119
+ }
120
+ .cb-partner__link:hover,
121
+ .cb-partner__link:focus-visible {
122
+ color: var(--green, #317f3f);
123
+ background: rgba(49, 127, 63, 0.04);
124
+ outline: none;
125
+ transform: translateY(-1px);
126
+ }
127
+ /* Mark is sized by HEIGHT only so each partner's official logo can render
128
+ at its natural aspect ratio. HF and Zhongguancun are wide landscape
129
+ wordmarks (~3.8:1), TIGEM is gently landscape (~1.4:1), Federico II is
130
+ square. A fixed 56×56 box (the old behaviour) would either crop the
131
+ wordmarks or shrink them to illegibility. */
132
+ .cb-partner__mark {
133
+ display: flex;
134
+ align-items: center;
135
+ justify-content: center;
136
+ height: 56px;
137
+ max-width: 100%;
138
+ color: inherit;
139
+ }
140
+ .cb-partner__mark img,
141
+ .cb-partner__mark svg {
142
+ height: 100%;
143
+ width: auto;
144
+ max-width: 100%;
145
+ object-fit: contain;
146
+ display: block;
147
+ /* Calm the colorful logos at rest so the row reads as one credit line,
148
+ not four competing brand stamps; hover restores full saturation. */
149
+ filter: saturate(0.9);
150
+ transition: filter 0.18s ease, transform 0.18s ease;
151
+ }
152
+ .cb-partner__link:hover .cb-partner__mark img,
153
+ .cb-partner__link:hover .cb-partner__mark svg,
154
+ .cb-partner__link:focus-visible .cb-partner__mark img,
155
+ .cb-partner__link:focus-visible .cb-partner__mark svg {
156
+ filter: saturate(1);
157
+ transform: scale(1.04);
158
+ }
159
+ .cb-partner__body {
160
+ display: flex;
161
+ flex-direction: column;
162
+ align-items: center;
163
+ gap: 4px;
164
+ min-width: 0;
165
+ width: 100%;
166
+ }
167
+ /* Both text labels (name + sub) are visually hidden: each partner is
168
+ already named in the .cb-collab__lede paragraph just above this
169
+ strip, and each logo carries its own wordmark. We keep both spans in
170
+ the DOM as sr-only so screen readers still get the explicit label
171
+ for every partner link. */
172
+ .cb-partner__name,
173
+ .cb-partner__sub {
174
+ position: absolute;
175
+ width: 1px;
176
+ height: 1px;
177
+ padding: 0;
178
+ margin: -1px;
179
+ overflow: hidden;
180
+ clip: rect(0, 0, 0, 0);
181
+ white-space: nowrap;
182
+ border: 0;
183
+ }
184
+
185
+ /* ---------------------------------------------------------------------
186
+ 2) LOWER STRIP — IDENTITY + LINK COLUMNS
187
+ --------------------------------------------------------------------- */
188
+ .site-footer__cols {
189
+ display: grid;
190
+ grid-template-columns: minmax(260px, 2fr) 1fr 1fr;
191
+ gap: 56px;
192
+ padding-bottom: 40px;
193
+ }
194
+ .site-footer__brand {
195
+ display: grid;
196
+ grid-template-columns: 44px 1fr;
197
+ gap: 14px;
198
+ align-items: start;
199
+ }
200
+ .site-footer__brand .logo-card {
201
+ width: 44px;
202
+ height: 44px;
203
+ display: block;
204
+ flex-shrink: 0;
205
+ text-decoration: none;
206
+ }
207
+ .site-footer__brand .logo-img { width: 100%; height: 100%; display: block; }
208
+ .site-footer__brand-meta { display: flex; flex-direction: column; }
209
+ .site-footer__brand-name {
210
+ font-family: "JetBrains Mono", ui-monospace, monospace;
211
+ font-size: 14px;
212
+ font-weight: 500;
213
+ letter-spacing: 0.18em;
214
+ text-transform: uppercase;
215
+ color: var(--ink, #1f1f1d);
216
+ line-height: 1.2;
217
+ }
218
+ .site-footer__brand-path {
219
+ margin-top: 2px;
220
+ font-family: "JetBrains Mono", ui-monospace, monospace;
221
+ font-size: 11px;
222
+ letter-spacing: 0.18em;
223
+ text-transform: uppercase;
224
+ color: #8a8a85;
225
+ line-height: 1.2;
226
+ }
227
+ .site-footer__brand-lede {
228
+ margin: 14px 0 0;
229
+ font-size: 13px;
230
+ line-height: 1.65;
231
+ color: #5b5b56;
232
+ max-width: 320px;
233
+ }
234
+
235
+ .site-footer__col-title {
236
+ margin: 0 0 14px;
237
+ font-family: "JetBrains Mono", ui-monospace, monospace;
238
+ font-size: 11px;
239
+ font-weight: 500;
240
+ letter-spacing: 0.22em;
241
+ text-transform: uppercase;
242
+ color: var(--green, #317f3f);
243
+ }
244
+ .site-footer__list {
245
+ list-style: none;
246
+ margin: 0;
247
+ padding: 0;
248
+ display: flex;
249
+ flex-direction: column;
250
+ gap: 8px;
251
+ }
252
+ .site-footer__list a {
253
+ font-family: "JetBrains Mono", ui-monospace, monospace;
254
+ font-size: 12px;
255
+ letter-spacing: 0.05em;
256
+ color: var(--ink, #1f1f1d);
257
+ text-decoration: none;
258
+ border-bottom: 1px solid rgba(31, 31, 29, 0.18);
259
+ padding-bottom: 1px;
260
+ transition: color 0.15s ease, border-color 0.15s ease;
261
+ }
262
+ .site-footer__list a:hover,
263
+ .site-footer__list a:focus-visible {
264
+ color: var(--green, #317f3f);
265
+ border-bottom-color: var(--green, #317f3f);
266
+ outline: none;
267
+ }
268
+ .site-footer__list .arrow {
269
+ margin-left: 4px;
270
+ display: inline-block;
271
+ font-size: 10px;
272
+ transform: translateY(-1px);
273
+ letter-spacing: 0;
274
+ }
275
+
276
+ /* ---------------------------------------------------------------------
277
+ 3) LEGAL STRIP
278
+ --------------------------------------------------------------------- */
279
+ .site-footer__legal {
280
+ border-top: 1px solid var(--hairline, #d6d3c4);
281
+ padding-top: 22px;
282
+ display: flex;
283
+ justify-content: space-between;
284
+ align-items: center;
285
+ flex-wrap: wrap;
286
+ gap: 10px 24px;
287
+ font-family: "JetBrains Mono", ui-monospace, monospace;
288
+ font-size: 10.5px;
289
+ letter-spacing: 0.18em;
290
+ text-transform: uppercase;
291
+ color: #8a8a85;
292
+ }
293
+ .site-footer__legal .dot {
294
+ display: inline-block;
295
+ margin: 0 8px;
296
+ color: #c2bfaf;
297
+ }
298
+ .site-footer__legal a {
299
+ color: #6f6c63;
300
+ text-decoration: none;
301
+ border-bottom: 1px solid rgba(111, 108, 99, 0.3);
302
+ padding-bottom: 1px;
303
+ transition: color 0.15s ease, border-color 0.15s ease;
304
+ }
305
+ .site-footer__legal a:hover,
306
+ .site-footer__legal a:focus-visible {
307
+ color: var(--green, #317f3f);
308
+ border-bottom-color: var(--green, #317f3f);
309
+ outline: none;
310
+ }
311
+
312
+ /* ---------------------------------------------------------------------
313
+ Responsive
314
+ --------------------------------------------------------------------- */
315
+ @media (max-width: 960px) {
316
+ .site-footer__inner { padding: 36px 24px 22px; }
317
+ .cb-partners { grid-template-columns: repeat(2, 1fr); }
318
+ .cb-partner:nth-child(3)::before { display: none; }
319
+ .cb-partner:nth-child(2n + 1)::before { display: none; }
320
+ .cb-partner:nth-child(n + 3) {
321
+ border-top: 1px solid var(--hairline, #d6d3c4);
322
+ padding-top: 12px;
323
+ margin-top: 12px;
324
+ }
325
+ .site-footer__cols {
326
+ grid-template-columns: 1fr 1fr;
327
+ gap: 36px 40px;
328
+ }
329
+ .site-footer__brand { grid-column: 1 / -1; }
330
+ .cb-collab__title { font-size: 20px; }
331
+ }
332
+
333
+ /* ---------------------------------------------------------------------
334
+ Mobile (<= 540px)
335
+ Goals:
336
+ - Keep the partner strip as a 2×2 grid: a single-column stack with
337
+ row-flex looks unbalanced because the name/sub spans are sr-only,
338
+ so the row would render as "logo + empty space".
339
+ - Tighter vertical rhythm on the collaboration block.
340
+ - Keep Resources / Sections columns side-by-side so the footer
341
+ doesn't grow into a tall vertical scroll on phones.
342
+ - Stack the legal hairline with proper spacing.
343
+ --------------------------------------------------------------------- */
344
+ @media (max-width: 540px) {
345
+ .site-footer__inner { padding: 36px 20px 24px; }
346
+
347
+ /* Collaboration block — compressed editorial rhythm. */
348
+ .cb-collab {
349
+ padding-bottom: 32px;
350
+ margin-bottom: 28px;
351
+ }
352
+ .cb-collab__head { margin-bottom: 24px; }
353
+ .cb-collab__title {
354
+ font-size: 19px;
355
+ line-height: 1.3;
356
+ margin-bottom: 10px;
357
+ }
358
+ .cb-collab__lede {
359
+ font-size: 13px;
360
+ line-height: 1.6;
361
+ }
362
+
363
+ /* Partner stamps: 2×2 grid with both vertical and horizontal hairlines.
364
+ Each cell stays a centered logo block (labels remain sr-only). */
365
+ .cb-partners { grid-template-columns: repeat(2, 1fr); }
366
+ .cb-partner::before { display: none !important; }
367
+ .cb-partner {
368
+ position: relative;
369
+ padding-top: 0;
370
+ margin-top: 0;
371
+ border-top: none;
372
+ }
373
+ /* Vertical hairline between the two columns (drawn on the right cell). */
374
+ .cb-partner:nth-child(2n) {
375
+ border-left: 1px solid var(--hairline, #d6d3c4);
376
+ }
377
+ /* Horizontal hairline between rows (drawn on the top two cells). */
378
+ .cb-partner:nth-child(-n + 2) {
379
+ border-bottom: 1px solid var(--hairline, #d6d3c4);
380
+ }
381
+ .cb-partner__link {
382
+ flex-direction: column;
383
+ align-items: center;
384
+ text-align: center;
385
+ gap: 6px;
386
+ padding: 16px 10px;
387
+ }
388
+ .cb-partner__mark { height: 40px; flex-shrink: 0; }
389
+ .cb-partner__body { align-items: center; }
390
+
391
+ /* Lower strip: brand spans full width, link columns stay side-by-side
392
+ to keep the footer compact vertically. */
393
+ .site-footer__cols {
394
+ grid-template-columns: 1fr 1fr;
395
+ gap: 28px 20px;
396
+ padding-bottom: 28px;
397
+ }
398
+ .site-footer__brand {
399
+ grid-column: 1 / -1;
400
+ grid-template-columns: 40px 1fr;
401
+ gap: 12px;
402
+ }
403
+ .site-footer__brand-lede {
404
+ margin-top: 12px;
405
+ max-width: none;
406
+ font-size: 12.5px;
407
+ }
408
+ .site-footer__col-title { margin-bottom: 12px; }
409
+ .site-footer__list { gap: 10px; }
410
+
411
+ /* Legal strip: stack with breathing room; tighten the dot separators
412
+ so the line wraps gracefully on very narrow screens. */
413
+ .site-footer__legal {
414
+ flex-direction: column;
415
+ align-items: flex-start;
416
+ gap: 6px;
417
+ padding-top: 18px;
418
+ letter-spacing: 0.14em;
419
+ font-size: 10px;
420
+ }
421
+ .site-footer__legal .dot { margin: 0 6px; }
422
+ }
423
+
424
+ /* Very narrow screens — drop the partner row to a single column, since
425
+ four logos compressed into 2×2 start to crowd one another below this
426
+ width. The cell still centers the logo so the strip stays editorial. */
427
+ @media (max-width: 380px) {
428
+ .cb-partners { grid-template-columns: 1fr; }
429
+ .cb-partner:nth-child(2n) { border-left: none; }
430
+ .cb-partner:nth-child(-n + 2) { border-bottom: none; }
431
+ .cb-partner + .cb-partner {
432
+ border-top: 1px solid var(--hairline, #d6d3c4);
433
+ }
434
+ .cb-partner__link { padding: 14px 8px; }
435
+ .cb-partner__mark { height: 36px; }
436
  }
 
 
assets/styles/recipe.css CHANGED
@@ -7,4 +7,22 @@
7
  @media (max-width: 720px) {
8
  #demo7 #d7-cols { grid-template-columns: 1fr !important; }
9
  #demo9 > div:first-child { grid-template-columns: 1fr !important; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  }
 
7
  @media (max-width: 720px) {
8
  #demo7 #d7-cols { grid-template-columns: 1fr !important; }
9
  #demo9 > div:first-child { grid-template-columns: 1fr !important; }
10
+
11
+ /* On narrow viewports the input is placed on its own row underneath
12
+ the "type DNA" label so it can take the full toolbar width instead
13
+ of fighting for space with the label + status pill. */
14
+ #demo7 #d7-input { flex-basis: 100%; width: 100%; min-width: 0; }
15
+
16
+ /* Allow the rendered token chips (1-mer and 6-mer) to wrap to the next
17
+ line instead of scrolling horizontally. The seq-block defaults to
18
+ `white-space: pre; overflow-x: auto;` for desktop where horizontal
19
+ scroll is fine, but on mobile that pushes the DNA sequence off-screen.
20
+ `word-break: break-all` lets the chain break between chips (and, as a
21
+ safety net, between letters) so nothing extends past the demo card. */
22
+ #demo7 #d7-1mer,
23
+ #demo7 #d7-6mer {
24
+ white-space: normal;
25
+ overflow-x: visible;
26
+ word-break: break-all;
27
+ }
28
  }
assets/styles/section-intro.css CHANGED
@@ -443,4 +443,67 @@
443
 
444
  @media (max-width: 720px) {
445
  .cd-mols { grid-template-columns: repeat(2, 1fr); }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
446
  }
 
443
 
444
  @media (max-width: 720px) {
445
  .cd-mols { grid-template-columns: repeat(2, 1fr); }
446
+
447
+ /* §3 / §4 splice / §5 translate: the inner diagrams are sized by mono
448
+ letters / 30px circles and cannot shrink below their natural width
449
+ (cd-genex segments are flex: 0 0 auto; cd-translate is an 11-column
450
+ max-content grid). On a narrow viewport they overflow the .demo
451
+ card. Promote each diagram to its own horizontally-scrollable
452
+ viewport so the card edge stays clean and the rest of the layout
453
+ keeps working — content remains fully accessible by scrolling. */
454
+
455
+ /* §3 standalone gene strip: switch from flex-wrap: wrap to a single
456
+ horizontal scroll lane so the bar/letters stay aligned in one row
457
+ instead of breaking mid-sequence. Mirrors the §4 splice behaviour
458
+ below. The .cd-splice .cd-gene-strip override further down resets
459
+ overflow back to visible so the parent .cd-splice owns the scroll
460
+ in §4 rather than each inner strip scrolling on its own. */
461
+ .cd-gene-strip {
462
+ flex-wrap: nowrap;
463
+ justify-content: flex-start;
464
+ width: 100%;
465
+ max-width: 100%;
466
+ margin-left: 0;
467
+ margin-right: 0;
468
+ overflow-x: auto;
469
+ overflow-y: hidden;
470
+ -webkit-overflow-scrolling: touch;
471
+ }
472
+
473
+ .cd-translate {
474
+ width: 100%;
475
+ max-width: 100%;
476
+ margin-left: 0;
477
+ margin-right: 0;
478
+ overflow-x: auto;
479
+ overflow-y: hidden;
480
+ -webkit-overflow-scrolling: touch;
481
+ justify-content: start;
482
+ }
483
+
484
+ /* For .cd-splice we collapse the three rows (DNA strip → arrows →
485
+ mRNA strip) into a single max-content grid column so they all
486
+ resolve to the same width — the widest row's natural width. That
487
+ keeps the transcribe arrows aligned with the letters above and
488
+ below them, and produces a clean horizontal scroll on the whole
489
+ stack rather than each row scrolling independently. */
490
+ .cd-splice {
491
+ display: grid;
492
+ grid-template-columns: max-content;
493
+ justify-content: start;
494
+ width: 100%;
495
+ max-width: 100%;
496
+ margin-left: 0;
497
+ margin-right: 0;
498
+ overflow-x: auto;
499
+ overflow-y: hidden;
500
+ -webkit-overflow-scrolling: touch;
501
+ }
502
+ .cd-splice .cd-gene-strip {
503
+ width: auto;
504
+ max-width: none;
505
+ margin: 0;
506
+ overflow: visible;
507
+ }
508
+ .cd-splice-arrows { width: 100%; }
509
  }
assets/styles/section-species.css CHANGED
@@ -10,6 +10,13 @@
10
  padding: 14px 0;
11
  border-top: 1px solid #eee;
12
  }
 
 
 
 
 
 
 
13
  .species-row:first-child { border-top: none; }
14
  .species-meta {
15
  font-family: "JetBrains Mono", monospace;
@@ -37,3 +44,35 @@
37
  line-height: 1.7; letter-spacing: 0.5px;
38
  }
39
  .species-seq.empty { color: #ccc; padding: 18px 12px; text-align: center; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  padding: 14px 0;
11
  border-top: 1px solid #eee;
12
  }
13
+ /* Grid tracks default to min-width: auto, which lets the .species-seq
14
+ box (white-space: pre + the longest 60-char line) push the 1fr column
15
+ wider than the demo card. That defeats the inner overflow-x: auto and
16
+ forces the whole page to scroll horizontally on narrow viewports. Pin
17
+ both children to min-width: 0 so the column collapses to the card
18
+ width and .species-seq owns the horizontal scroll itself. */
19
+ .species-row > * { min-width: 0; }
20
  .species-row:first-child { border-top: none; }
21
  .species-meta {
22
  font-family: "JetBrains Mono", monospace;
 
44
  line-height: 1.7; letter-spacing: 0.5px;
45
  }
46
  .species-seq.empty { color: #ccc; padding: 18px 12px; text-align: center; }
47
+
48
+ /* On narrow viewports the 140px meta column eats half the .demo card
49
+ and squeezes the DNA block down to ~20 bases per line. Stack the row
50
+ so the sequence gets the full card width — the existing overflow-x
51
+ on .species-seq keeps it horizontally scrollable when 60 bp + spaces
52
+ still don't fit. Meta lays out as a single inline row so the species
53
+ name, sub-meta and identity stat read as a compact header above the
54
+ sequence rather than a tall left rail. */
55
+ @media (max-width: 720px) {
56
+ .species-row {
57
+ grid-template-columns: 1fr;
58
+ gap: 8px;
59
+ }
60
+ .species-meta {
61
+ display: flex;
62
+ flex-wrap: wrap;
63
+ align-items: baseline;
64
+ column-gap: 14px;
65
+ row-gap: 4px;
66
+ }
67
+ .species-name { padding-left: 6px; }
68
+ .species-sub { margin-top: 0; padding-left: 0; }
69
+ .species-stats {
70
+ margin-top: 0;
71
+ padding-left: 0;
72
+ display: flex;
73
+ align-items: baseline;
74
+ gap: 6px;
75
+ }
76
+ .species-stats .stat-id { font-size: 13px; }
77
+ .species-stats .stat-sub { margin-top: 0; }
78
+ }
assets/styles/section-vep.css CHANGED
@@ -10,6 +10,13 @@
10
  background: #f7f7f7; border: 1px solid #e0e0e0;
11
  padding: 16px 20px; margin: 12px 0;
12
  text-align: left;
 
 
 
 
 
 
 
13
  }
14
  .vep-window .vep-stack {
15
  display: inline-grid;
 
10
  background: #f7f7f7; border: 1px solid #e0e0e0;
11
  padding: 16px 20px; margin: 12px 0;
12
  text-align: left;
13
+ /* The .vep-stack inside is an inline-grid whose middle column is a
14
+ 60bp mono sequence (~550px wide). On narrow viewports that overflows
15
+ the window, so we let the window scroll horizontally as a single
16
+ unit. Critically, we do NOT introduce a line-break inside .seq-line
17
+ / .arrow-line (those keep `white-space: pre`) so the original row,
18
+ arrow row, and mutation row stay character-for-character aligned. */
19
+ overflow-x: auto;
20
  }
21
  .vep-window .vep-stack {
22
  display: inline-grid;
demo.html CHANGED
@@ -191,8 +191,6 @@
191
  <li class="banner-spec"><strong>6-mer</strong> tokenizer</li>
192
  <li class="banner-spec"><strong>1T</strong> train tokens</li>
193
  </ul>
194
- <!-- TODO: replace the tech-report href with the canonical URL once
195
- the report is published. -->
196
  <ul class="banner-links" aria-label="Resources">
197
  <li>
198
  <a href="https://huggingface.co/HuggingFaceBio/Carbon-3B" target="_blank" rel="noopener">
@@ -200,7 +198,7 @@
200
  </a>
201
  </li>
202
  <li>
203
- <a href="#" target="_blank" rel="noopener">
204
  Tech report<span class="arrow" aria-hidden="true">↗</span>
205
  </a>
206
  </li>
@@ -2154,6 +2152,124 @@ print(f"log P(alt) - log P(ref) at pos 20: {delta:+.3f}")</code></pre></div>
2154
  </div>
2155
  </div> <!-- /panel-sandbox -->
2156
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2157
  <!-- Modular JS, served from /assets/js/. Load order matters because
2158
  section IIFEs reference shared globals (lerp, logprobRgb, GENES,
2159
  loadConfig, etc.) defined in shared/. Each file ends with its own
 
191
  <li class="banner-spec"><strong>6-mer</strong> tokenizer</li>
192
  <li class="banner-spec"><strong>1T</strong> train tokens</li>
193
  </ul>
 
 
194
  <ul class="banner-links" aria-label="Resources">
195
  <li>
196
  <a href="https://huggingface.co/HuggingFaceBio/Carbon-3B" target="_blank" rel="noopener">
 
198
  </a>
199
  </li>
200
  <li>
201
+ <a href="https://paperswithcode.co/paper/83340" target="_blank" rel="noopener">
202
  Tech report<span class="arrow" aria-hidden="true">↗</span>
203
  </a>
204
  </li>
 
2152
  </div>
2153
  </div> <!-- /panel-sandbox -->
2154
 
2155
+ <!-- ============================================================ -->
2156
+ <!-- SITE FOOTER · always visible across tabs. -->
2157
+ <!-- Composition: collaboration block (eyebrow + headline + lede -->
2158
+ <!-- + 4 partner stamps), then a three-column strip (Carbon -->
2159
+ <!-- identity / Resources / Sections), then a thin legal hairline -->
2160
+ <!-- with copyright + license + model spec recap. -->
2161
+ <!-- ============================================================ -->
2162
+ <footer class="site-footer" role="contentinfo">
2163
+ <div class="site-footer__inner">
2164
+
2165
+ <!-- 1) Collaboration block -->
2166
+ <section class="cb-collab" aria-labelledby="cb-collab-title">
2167
+ <div class="cb-collab__head">
2168
+ <span class="cb-collab__eyebrow">§ Collaboration</span>
2169
+ <h2 id="cb-collab-title" class="cb-collab__title">A joint research effort</h2>
2170
+ <p class="cb-collab__lede">
2171
+ Carbon was built together by the research teams at
2172
+ <em>Hugging Face</em>, the <em>Zhongguancun Academy</em>,
2173
+ <em>TIGEM</em> and the <em>Università di Napoli Federico II</em>.
2174
+ </p>
2175
+ </div>
2176
+
2177
+ <!-- Each <img> uses an aspect-correct width/height pair (height fixed
2178
+ at 56, width derived from each logo's natural ratio) to prevent
2179
+ CLS while the CSS lets the mark display at its full landscape
2180
+ ratio. The .cb-partner__name span is hidden visually because
2181
+ each real logo already carries its own wordmark; it stays in
2182
+ the DOM as an accessible label for screen readers. -->
2183
+ <ul class="cb-partners">
2184
+ <li class="cb-partner">
2185
+ <a class="cb-partner__link" href="https://huggingface.co" target="_blank" rel="noopener">
2186
+ <span class="cb-partner__mark"><img src="/img/partners/hugging-face.svg" alt="Hugging Face" width="211" height="56"></span>
2187
+ <span class="cb-partner__body">
2188
+ <span class="cb-partner__name">Hugging Face</span>
2189
+ <span class="cb-partner__sub">open-source AI</span>
2190
+ </span>
2191
+ </a>
2192
+ </li>
2193
+ <li class="cb-partner">
2194
+ <a class="cb-partner__link" href="https://www.bza.edu.cn/en/" target="_blank" rel="noopener">
2195
+ <span class="cb-partner__mark"><img src="/img/partners/zhongguancun.png" alt="Zhongguancun Academy" width="217" height="56"></span>
2196
+ <span class="cb-partner__body">
2197
+ <span class="cb-partner__name">Zhongguancun Academy</span>
2198
+ <span class="cb-partner__sub">Beijing · China</span>
2199
+ </span>
2200
+ </a>
2201
+ </li>
2202
+ <li class="cb-partner">
2203
+ <a class="cb-partner__link" href="https://www.tigem.it/" target="_blank" rel="noopener">
2204
+ <span class="cb-partner__mark"><img src="/img/partners/tigem.svg" alt="TIGEM, Telethon Institute of Genetics and Medicine" width="80" height="56"></span>
2205
+ <span class="cb-partner__body">
2206
+ <span class="cb-partner__name">TIGEM</span>
2207
+ <span class="cb-partner__sub">genetics &amp; medicine</span>
2208
+ </span>
2209
+ </a>
2210
+ </li>
2211
+ <li class="cb-partner">
2212
+ <a class="cb-partner__link" href="https://www.unina.it/" target="_blank" rel="noopener">
2213
+ <span class="cb-partner__mark"><img src="/img/partners/federico-ii.svg" alt="Università degli Studi di Napoli Federico II" width="56" height="56"></span>
2214
+ <span class="cb-partner__body">
2215
+ <span class="cb-partner__name">Federico II</span>
2216
+ <span class="cb-partner__sub">Napoli · Italy</span>
2217
+ </span>
2218
+ </a>
2219
+ </li>
2220
+ </ul>
2221
+ </section>
2222
+
2223
+ <!-- 2) Identity + link columns -->
2224
+ <div class="site-footer__cols">
2225
+ <div class="site-footer__brand">
2226
+ <a class="logo-card" href="#" aria-label="Carbon, go to top">
2227
+ <img class="logo-img" src="/img/logo.svg" alt="" width="44" height="44">
2228
+ </a>
2229
+ <div class="site-footer__brand-meta">
2230
+ <div class="site-footer__brand-name">CARBON</div>
2231
+ <div class="site-footer__brand-path">huggingfacebio/carbon-3b</div>
2232
+ <p class="site-footer__brand-lede">
2233
+ An autoregressive genomic foundation model — open code, open weights, open data.
2234
+ </p>
2235
+ </div>
2236
+ </div>
2237
+
2238
+ <div class="site-footer__col">
2239
+ <h3 class="site-footer__col-title">Resources</h3>
2240
+ <ul class="site-footer__list">
2241
+ <li><a href="https://huggingface.co/HuggingFaceBio/Carbon-3B" target="_blank" rel="noopener">Model card<span class="arrow" aria-hidden="true">↗</span></a></li>
2242
+ <li><a href="#" target="_blank" rel="noopener">Tech report<span class="arrow" aria-hidden="true">↗</span></a></li>
2243
+ <li><a href="https://github.com/huggingface/carbon" target="_blank" rel="noopener">GitHub<span class="arrow" aria-hidden="true">↗</span></a></li>
2244
+ <li><a href="https://huggingface.co/datasets/HuggingFaceBio/carbon-pretraining-corpus" target="_blank" rel="noopener">Dataset<span class="arrow" aria-hidden="true">↗</span></a></li>
2245
+ </ul>
2246
+ </div>
2247
+
2248
+ <div class="site-footer__col">
2249
+ <h3 class="site-footer__col-title">Sections</h3>
2250
+ <ul class="site-footer__list">
2251
+ <li><a href="#intro">Intro</a></li>
2252
+ <li><a href="#dna-lab">DNA Lab</a></li>
2253
+ <li><a href="#recipe">Carbon Recipe</a></li>
2254
+ <li><a href="#sandbox">Sandbox</a></li>
2255
+ </ul>
2256
+ </div>
2257
+ </div>
2258
+
2259
+ <!-- 3) Legal strip -->
2260
+ <div class="site-footer__legal">
2261
+ <span class="site-footer__copy">
2262
+ © 2026 · Carbon <span class="dot">·</span>
2263
+ <a href="https://www.apache.org/licenses/LICENSE-2.0" target="_blank" rel="noopener">Apache 2.0</a>
2264
+ </span>
2265
+ <span class="site-footer__spec">
2266
+ 393,216 bp context <span class="dot">·</span> 6-mer tokenizer <span class="dot">·</span> 1T train tokens
2267
+ </span>
2268
+ </div>
2269
+
2270
+ </div>
2271
+ </footer>
2272
+
2273
  <!-- Modular JS, served from /assets/js/. Load order matters because
2274
  section IIFEs reference shared globals (lerp, logprobRgb, GENES,
2275
  loadConfig, etc.) defined in shared/. Each file ends with its own
img/partners/federico-ii.svg ADDED
img/partners/hugging-face.svg ADDED
img/partners/raw/bza-home.html ADDED
The diff for this file is too large to render. See raw diff
 
img/partners/raw/fed-144edb.svg ADDED
img/partners/raw/fed-4093c8.svg ADDED
img/partners/raw/fed-7e0c6a.svg ADDED
img/partners/raw/fed-c8b88b.svg ADDED
img/partners/raw/fed-da8c1d.svg ADDED
img/partners/raw/fed-de87be.svg ADDED
img/partners/raw/federico2-wp.svg ADDED
img/partners/raw/federico2.png ADDED

Git LFS Details

  • SHA256: f69dbc5a711724d08d5e2d37cd9c1e1925c306a88540c983cfcae0f535cdd61f
  • Pointer size: 131 Bytes
  • Size of remote file: 475 kB
img/partners/raw/federico2.svg ADDED
img/partners/raw/hf-hf-logo.svg ADDED
img/partners/raw/hf-huggingface_logo-noborder.svg ADDED
img/partners/raw/hf-huggingface_logo.svg ADDED
img/partners/raw/tigem-logo.png ADDED

Git LFS Details

  • SHA256: c651e58370fd74643a1a3bad7b331ef1734e0b560c1eca8b05779803a94eeed8
  • Pointer size: 130 Bytes
  • Size of remote file: 28.4 kB
img/partners/raw/tigem-logo.svg ADDED
img/partners/raw/unina-home.html ADDED
File without changes
img/partners/raw/zgca-logo.png ADDED

Git LFS Details

  • SHA256: 9f796ca9c2651c82c9abfc91dab31c7fa2b0951fcd0fd9a105f21691546a8c3e
  • Pointer size: 130 Bytes
  • Size of remote file: 18.7 kB
img/partners/raw/zgca-nuxt.png ADDED

Git LFS Details

  • SHA256: b4f5bc76e83fc6f16ccdb02f343b9530c946ba73e00b96b2f738905b6f2ca278
  • Pointer size: 130 Bytes
  • Size of remote file: 28 kB
img/partners/tigem.svg ADDED
img/partners/zhongguancun.png ADDED

Git LFS Details

  • SHA256: 9f796ca9c2651c82c9abfc91dab31c7fa2b0951fcd0fd9a105f21691546a8c3e
  • Pointer size: 130 Bytes
  • Size of remote file: 18.7 kB