Spaces:
Running
Social banner: HTML-rendered OG share thumbnail (1200x630, static)
Browse files- Compose the OG share image directly in HTML/CSS using the same
.carbon-banner stage as the live header — copying the rendered tile
into img/thumb.png keeps the share image perfectly in sync with the
product, no manual export needed.
- Mark the OG tile's header with data-static so banner.js draws a single
frame on it; the live demo header still animates as before.
- Refactor banner.js to support multiple .carbon-banner instances and
honor data-static to skip the RAF loop / observers cleanly.
- Nudge the OG-only helix slightly right (translateX -18px vs -56px on
wider Twitter/LinkedIn ratios) so the 1200x630 ratio keeps a clean
strip of paper between the wordmark and the strand.
- Drop the now-unused img/logo.png and point all SEO/OG/Twitter/JSON-LD
tags in demo.html at img/thumb.png with its actual 2392x1258 export
dimensions.
Co-authored-by: Cursor <cursoragent@cursor.com>
- assets/js/banner.js +32 -3
- demo.html +16 -15
- img/{logo.png → thumb.png} +2 -2
- social-banner.html +102 -28
|
@@ -10,10 +10,18 @@
|
|
| 10 |
// horizontal: y = sin(theta(x)) * amplitude
|
| 11 |
// vertical: x = sin(theta(y)) * amplitude
|
| 12 |
// Everything else (z-sort, rung gaps, glyph shapes) carries over verbatim.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
// =========================================================================
|
| 14 |
-
(function
|
| 15 |
-
const
|
| 16 |
-
|
|
|
|
|
|
|
| 17 |
const canvas = banner.querySelector(".cb-helix-canvas");
|
| 18 |
if (!canvas) return;
|
| 19 |
const ctx = canvas.getContext("2d");
|
|
@@ -534,6 +542,26 @@
|
|
| 534 |
cancelAnimationFrame(rafId);
|
| 535 |
}
|
| 536 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 537 |
const io = new IntersectionObserver(entries => {
|
| 538 |
inViewport = entries[0].isIntersecting;
|
| 539 |
if (inViewport) start();
|
|
@@ -554,4 +582,5 @@
|
|
| 554 |
|
| 555 |
drawFrame(0);
|
| 556 |
start();
|
|
|
|
| 557 |
})();
|
|
|
|
| 10 |
// horizontal: y = sin(theta(x)) * amplitude
|
| 11 |
// vertical: x = sin(theta(y)) * amplitude
|
| 12 |
// Everything else (z-sort, rung gaps, glyph shapes) carries over verbatim.
|
| 13 |
+
//
|
| 14 |
+
// One init() call per .carbon-banner on the page. social-banner.html
|
| 15 |
+
// renders two instances (the main stage at the top + the OG thumbnail
|
| 16 |
+
// preview lower down), and each carries its own canvas, IntersectionObserver,
|
| 17 |
+
// rAF loop and animation phase so their helices can run independently
|
| 18 |
+
// without sharing state.
|
| 19 |
// =========================================================================
|
| 20 |
+
(function initAllCarbonBanners() {
|
| 21 |
+
const banners = document.querySelectorAll(".carbon-banner");
|
| 22 |
+
banners.forEach(initCarbonBanner);
|
| 23 |
+
|
| 24 |
+
function initCarbonBanner(banner) {
|
| 25 |
const canvas = banner.querySelector(".cb-helix-canvas");
|
| 26 |
if (!canvas) return;
|
| 27 |
const ctx = canvas.getContext("2d");
|
|
|
|
| 542 |
cancelAnimationFrame(rafId);
|
| 543 |
}
|
| 544 |
|
| 545 |
+
// Static banners (data-static on the .carbon-banner root) render a
|
| 546 |
+
// single frozen frame and skip the entire animation pipeline. Used
|
| 547 |
+
// by the OG share thumbnail lower on the page, which is meant to be
|
| 548 |
+
// screenshot for the og:image asset — a moving helix would just make
|
| 549 |
+
// the screenshot unpredictable, and the rAF loop is a waste of CPU
|
| 550 |
+
// since the tile is purely a static preview. A ResizeObserver still
|
| 551 |
+
// keeps the frozen frame crisp when the contact-sheet auto-fit
|
| 552 |
+
// factor changes the on-screen pixel size of the canvas.
|
| 553 |
+
const isStatic = banner.hasAttribute("data-static");
|
| 554 |
+
|
| 555 |
+
if (isStatic) {
|
| 556 |
+
const roStatic = new ResizeObserver(() => {
|
| 557 |
+
resize();
|
| 558 |
+
drawFrame(0);
|
| 559 |
+
});
|
| 560 |
+
roStatic.observe(canvas);
|
| 561 |
+
drawFrame(0);
|
| 562 |
+
return;
|
| 563 |
+
}
|
| 564 |
+
|
| 565 |
const io = new IntersectionObserver(entries => {
|
| 566 |
inViewport = entries[0].isIntersecting;
|
| 567 |
if (inViewport) start();
|
|
|
|
| 582 |
|
| 583 |
drawFrame(0);
|
| 584 |
start();
|
| 585 |
+
}
|
| 586 |
})();
|
|
@@ -19,25 +19,26 @@
|
|
| 19 |
<meta name="color-scheme" content="light">
|
| 20 |
<link rel="canonical" href="{{SITE_URL}}/">
|
| 21 |
|
| 22 |
-
<!-- Favicon.
|
| 23 |
-
|
|
|
|
|
|
|
|
|
|
| 24 |
<link rel="icon" type="image/svg+xml" href="/img/logo.svg">
|
| 25 |
-
<link rel="icon" type="image/png" href="/img/logo.png">
|
| 26 |
-
<link rel="apple-touch-icon" href="/img/logo.png">
|
| 27 |
|
| 28 |
-
<!-- Open Graph (Facebook, LinkedIn, Slack, Discord, iMessage…).
|
| 29 |
-
<!-- og:image points at /img/
|
| 30 |
-
<!--
|
| 31 |
-
<!--
|
| 32 |
<meta property="og:type" content="website">
|
| 33 |
<meta property="og:site_name" content="Carbon">
|
| 34 |
<meta property="og:title" content="Carbon · an open-source autoregressive genomic foundation model">
|
| 35 |
<meta property="og:description" content="An interactive editorial demo of Carbon, Hugging Face's open-source DNA foundation model. Streaming continuation, variant scoring, protein folding, gene-embedding UMAP, and the full training recipe.">
|
| 36 |
<meta property="og:url" content="{{SITE_URL}}/">
|
| 37 |
-
<meta property="og:image" content="{{SITE_URL}}/img/
|
| 38 |
-
<meta property="og:image:width" content="
|
| 39 |
-
<meta property="og:image:height" content="
|
| 40 |
-
<meta property="og:image:alt" content="Carbon —
|
| 41 |
<meta property="og:locale" content="en_US">
|
| 42 |
|
| 43 |
<!-- Twitter / X card. summary_large_image renders the OG image -->
|
|
@@ -47,8 +48,8 @@
|
|
| 47 |
<meta name="twitter:creator" content="@huggingface">
|
| 48 |
<meta name="twitter:title" content="Carbon · an open-source autoregressive genomic foundation model">
|
| 49 |
<meta name="twitter:description" content="An interactive editorial demo of Carbon, Hugging Face's open-source DNA foundation model. Streaming continuation, variant scoring, protein folding, gene-embedding UMAP, and the full training recipe.">
|
| 50 |
-
<meta name="twitter:image" content="{{SITE_URL}}/img/
|
| 51 |
-
<meta name="twitter:image:alt" content="Carbon —
|
| 52 |
|
| 53 |
<!-- JSON-LD structured data. Helps search engines and LLM- -->
|
| 54 |
<!-- powered answer engines (Perplexity, ChatGPT browsing, etc.) -->
|
|
@@ -65,7 +66,7 @@
|
|
| 65 |
"headline": "Carbon · an open-source autoregressive genomic foundation model",
|
| 66 |
"description": "An interactive editorial walkthrough of Carbon, Hugging Face's open-source DNA foundation model: streaming continuation, variant effect prediction, ESMFold-based protein structure prediction, a UMAP of ~500k gene embeddings, and the full training recipe (tokenizer, loss, dataset, results).",
|
| 67 |
"url": "{{SITE_URL}}/",
|
| 68 |
-
"image": "{{SITE_URL}}/img/
|
| 69 |
"inLanguage": "en",
|
| 70 |
"author": { "@type": "Organization", "name": "Hugging Face Bio", "url": "https://huggingface.co/HuggingFaceBio" },
|
| 71 |
"publisher": { "@type": "Organization", "name": "Hugging Face", "url": "https://huggingface.co" },
|
|
|
|
| 19 |
<meta name="color-scheme" content="light">
|
| 20 |
<link rel="canonical" href="{{SITE_URL}}/">
|
| 21 |
|
| 22 |
+
<!-- Favicon. The SVG covers every modern browser engine (Chrome,
|
| 23 |
+
Safari ≥ 14, Firefox, Edge). We dropped the PNG raster fallback
|
| 24 |
+
when img/logo.png was retired in favour of img/thumb.png (the
|
| 25 |
+
dedicated social-card asset), since none of the browsers that
|
| 26 |
+
still need a raster favicon are in the demo's target audience. -->
|
| 27 |
<link rel="icon" type="image/svg+xml" href="/img/logo.svg">
|
|
|
|
|
|
|
| 28 |
|
| 29 |
+
<!-- Open Graph (Facebook, LinkedIn, Slack, Discord, iMessage…). -->
|
| 30 |
+
<!-- og:image points at /img/thumb.png, the 2x export of the OG -->
|
| 31 |
+
<!-- preview tile rendered by /social-banner (2392×1258, drop-in -->
|
| 32 |
+
<!-- 1200×630 ratio at retina resolution). -->
|
| 33 |
<meta property="og:type" content="website">
|
| 34 |
<meta property="og:site_name" content="Carbon">
|
| 35 |
<meta property="og:title" content="Carbon · an open-source autoregressive genomic foundation model">
|
| 36 |
<meta property="og:description" content="An interactive editorial demo of Carbon, Hugging Face's open-source DNA foundation model. Streaming continuation, variant scoring, protein folding, gene-embedding UMAP, and the full training recipe.">
|
| 37 |
<meta property="og:url" content="{{SITE_URL}}/">
|
| 38 |
+
<meta property="og:image" content="{{SITE_URL}}/img/thumb.png">
|
| 39 |
+
<meta property="og:image:width" content="2392">
|
| 40 |
+
<meta property="og:image:height" content="1258">
|
| 41 |
+
<meta property="og:image:alt" content="Carbon — wordmark and four-strand DNA helix on cream paper.">
|
| 42 |
<meta property="og:locale" content="en_US">
|
| 43 |
|
| 44 |
<!-- Twitter / X card. summary_large_image renders the OG image -->
|
|
|
|
| 48 |
<meta name="twitter:creator" content="@huggingface">
|
| 49 |
<meta name="twitter:title" content="Carbon · an open-source autoregressive genomic foundation model">
|
| 50 |
<meta name="twitter:description" content="An interactive editorial demo of Carbon, Hugging Face's open-source DNA foundation model. Streaming continuation, variant scoring, protein folding, gene-embedding UMAP, and the full training recipe.">
|
| 51 |
+
<meta name="twitter:image" content="{{SITE_URL}}/img/thumb.png">
|
| 52 |
+
<meta name="twitter:image:alt" content="Carbon — wordmark and four-strand DNA helix on cream paper.">
|
| 53 |
|
| 54 |
<!-- JSON-LD structured data. Helps search engines and LLM- -->
|
| 55 |
<!-- powered answer engines (Perplexity, ChatGPT browsing, etc.) -->
|
|
|
|
| 66 |
"headline": "Carbon · an open-source autoregressive genomic foundation model",
|
| 67 |
"description": "An interactive editorial walkthrough of Carbon, Hugging Face's open-source DNA foundation model: streaming continuation, variant effect prediction, ESMFold-based protein structure prediction, a UMAP of ~500k gene embeddings, and the full training recipe (tokenizer, loss, dataset, results).",
|
| 68 |
"url": "{{SITE_URL}}/",
|
| 69 |
+
"image": "{{SITE_URL}}/img/thumb.png",
|
| 70 |
"inLanguage": "en",
|
| 71 |
"author": { "@type": "Organization", "name": "Hugging Face Bio", "url": "https://huggingface.co/HuggingFaceBio" },
|
| 72 |
"publisher": { "@type": "Organization", "name": "Hugging Face", "url": "https://huggingface.co" },
|
|
File without changes
|
|
@@ -8,7 +8,6 @@
|
|
| 8 |
<!-- training crawls. The canonical page is demo.html (served at /). -->
|
| 9 |
<meta name="robots" content="noindex, nofollow">
|
| 10 |
<link rel="icon" type="image/svg+xml" href="/img/logo.svg">
|
| 11 |
-
<link rel="icon" type="image/png" href="/img/logo.png">
|
| 12 |
<link rel="preconnect" href="https://fonts.googleapis.com">
|
| 13 |
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
| 14 |
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;400;500;600;700;800&family=Inter:wght@300;400;500;600&display=swap">
|
|
@@ -68,13 +67,23 @@
|
|
| 68 |
transition: width 0.22s ease, height 0.22s ease;
|
| 69 |
}
|
| 70 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 71 |
/* Inside the stage the banner fills it entirely (no max-width cap
|
| 72 |
like on the main page — here the banner IS the canvas). */
|
| 73 |
-
.social-banner-stage .carbon-banner
|
|
|
|
| 74 |
width: 100%;
|
| 75 |
height: 100%;
|
| 76 |
}
|
| 77 |
-
.social-banner-stage .banner-inner
|
|
|
|
| 78 |
max-width: none;
|
| 79 |
height: 100%;
|
| 80 |
/* Tabs are gone — drop the asymmetric bottom-zero padding from the
|
|
@@ -97,12 +106,23 @@
|
|
| 97 |
so the helix doesn't hug the right edge of the social card. The
|
| 98 |
extra width also keeps the bases on the right side from clipping
|
| 99 |
against the stage frame on wider canvases (LinkedIn 1584). */
|
| 100 |
-
.social-banner-stage .cb-helix-canvas
|
|
|
|
| 101 |
right: -72px;
|
| 102 |
width: calc(100% + 132px);
|
| 103 |
transform: translateX(-56px) rotate(5deg);
|
| 104 |
}
|
| 105 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 106 |
/* No more bottom tab row → 2-row layout: identity strip on top,
|
| 107 |
headline filling the rest. */
|
| 108 |
grid-template-rows: auto 1fr;
|
|
@@ -113,23 +133,31 @@
|
|
| 113 |
so the wordmark scales with the social canvas, not the browser
|
| 114 |
window. cqh = container-query-height, falls back to a fixed size
|
| 115 |
on browsers without container queries. */
|
| 116 |
-
.social-banner-stage
|
| 117 |
-
.
|
|
|
|
|
|
|
| 118 |
font-size: clamp(64px, 22cqh, 140px);
|
| 119 |
}
|
| 120 |
-
.social-banner-stage .banner-subtitle
|
|
|
|
| 121 |
font-size: clamp(11px, 2.6cqh, 16px);
|
| 122 |
margin-top: 10px;
|
| 123 |
}
|
| 124 |
-
.social-banner-stage .banner-specs
|
|
|
|
| 125 |
font-size: clamp(10px, 2.2cqh, 13px);
|
| 126 |
margin-top: 10px;
|
| 127 |
}
|
| 128 |
-
.social-banner-stage .banner-title
|
| 129 |
-
.
|
|
|
|
|
|
|
| 130 |
|
| 131 |
/* Slightly stronger inset hairline replaces the bottom one we lose
|
| 132 |
-
with the tabs gone — keeps the banner from looking unfinished.
|
|
|
|
|
|
|
| 133 |
.social-banner-stage .carbon-banner {
|
| 134 |
box-shadow: inset 0 0 0 1px #cfcdbf;
|
| 135 |
}
|
|
@@ -287,12 +315,29 @@
|
|
| 287 |
width: 160px;
|
| 288 |
height: 160px;
|
| 289 |
}
|
| 290 |
-
/* OG / share thumbnail —
|
| 291 |
-
|
| 292 |
-
|
| 293 |
-
|
| 294 |
-
|
| 295 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 296 |
|
| 297 |
.sb-logo-meta {
|
| 298 |
font-family: "JetBrains Mono", ui-monospace, monospace;
|
|
@@ -479,26 +524,55 @@
|
|
| 479 |
|
| 480 |
<!-- ------------------------------------------------------------------ -->
|
| 481 |
<!-- SEO / social-share thumbnail. -->
|
| 482 |
-
<!--
|
| 483 |
-
<!--
|
| 484 |
-
<!--
|
| 485 |
-
<!--
|
|
|
|
|
|
|
|
|
|
| 486 |
<!-- ------------------------------------------------------------------ -->
|
| 487 |
<div class="sb-section-label">
|
| 488 |
<span>seo · share thumbnail</span>
|
| 489 |
-
<span class="sb-section-label__hint">
|
| 490 |
</div>
|
| 491 |
|
| 492 |
<div class="sb-thumbs" id="sb-thumbs">
|
| 493 |
|
| 494 |
<figure class="sb-logo-card">
|
| 495 |
<div class="sb-logo-stage sb-logo-stage--og">
|
| 496 |
-
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 497 |
</div>
|
| 498 |
-
<figcaption class="sb-logo-meta">
|
| 499 |
-
<span class="sb-logo-meta__name" title="logo.png">logo.png</span>
|
| 500 |
-
<button type="button" class="sb-logo-meta__copy" data-copy="/img/logo.png">copy</button>
|
| 501 |
-
</figcaption>
|
| 502 |
</figure>
|
| 503 |
|
| 504 |
</div>
|
|
|
|
| 8 |
<!-- training crawls. The canonical page is demo.html (served at /). -->
|
| 9 |
<meta name="robots" content="noindex, nofollow">
|
| 10 |
<link rel="icon" type="image/svg+xml" href="/img/logo.svg">
|
|
|
|
| 11 |
<link rel="preconnect" href="https://fonts.googleapis.com">
|
| 12 |
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
| 13 |
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;400;500;600;700;800&family=Inter:wght@300;400;500;600&display=swap">
|
|
|
|
| 67 |
transition: width 0.22s ease, height 0.22s ease;
|
| 68 |
}
|
| 69 |
|
| 70 |
+
/* The OG share thumbnail tile lower down on the page reuses the exact
|
| 71 |
+
same .carbon-banner hero markup as the main stage, just frozen at
|
| 72 |
+
1200×630 instead of switching format. Every override below is
|
| 73 |
+
shared between the two contexts (the main stage and the OG tile)
|
| 74 |
+
so the OG screenshot reads as a smaller-ratio crop of the hero,
|
| 75 |
+
not a separate "thumbnail" composition. The .sb-logo-stage--og
|
| 76 |
+
selector picks up exactly the same rules as .social-banner-stage. */
|
| 77 |
+
|
| 78 |
/* Inside the stage the banner fills it entirely (no max-width cap
|
| 79 |
like on the main page — here the banner IS the canvas). */
|
| 80 |
+
.social-banner-stage .carbon-banner,
|
| 81 |
+
.sb-logo-stage--og .carbon-banner {
|
| 82 |
width: 100%;
|
| 83 |
height: 100%;
|
| 84 |
}
|
| 85 |
+
.social-banner-stage .banner-inner,
|
| 86 |
+
.sb-logo-stage--og .banner-inner {
|
| 87 |
max-width: none;
|
| 88 |
height: 100%;
|
| 89 |
/* Tabs are gone — drop the asymmetric bottom-zero padding from the
|
|
|
|
| 106 |
so the helix doesn't hug the right edge of the social card. The
|
| 107 |
extra width also keeps the bases on the right side from clipping
|
| 108 |
against the stage frame on wider canvases (LinkedIn 1584). */
|
| 109 |
+
.social-banner-stage .cb-helix-canvas,
|
| 110 |
+
.sb-logo-stage--og .cb-helix-canvas {
|
| 111 |
right: -72px;
|
| 112 |
width: calc(100% + 132px);
|
| 113 |
transform: translateX(-56px) rotate(5deg);
|
| 114 |
}
|
| 115 |
+
/* OG tile only: nudge the helix back to the right. The 1200×630 ratio
|
| 116 |
+
gives the strand more vertical real estate than the wide formats
|
| 117 |
+
(Twitter 1500×500, LinkedIn 1584×396), so it doesn't need to crowd
|
| 118 |
+
toward the left to balance against the wordmark — letting it sit a
|
| 119 |
+
little further right keeps a clean strip of paper between the
|
| 120 |
+
wordmark and the strand at the OG ratio. */
|
| 121 |
+
.sb-logo-stage--og .cb-helix-canvas {
|
| 122 |
+
transform: translateX(-18px) rotate(5deg);
|
| 123 |
+
}
|
| 124 |
+
.social-banner-stage .banner-left,
|
| 125 |
+
.sb-logo-stage--og .banner-left {
|
| 126 |
/* No more bottom tab row → 2-row layout: identity strip on top,
|
| 127 |
headline filling the rest. */
|
| 128 |
grid-template-rows: auto 1fr;
|
|
|
|
| 133 |
so the wordmark scales with the social canvas, not the browser
|
| 134 |
window. cqh = container-query-height, falls back to a fixed size
|
| 135 |
on browsers without container queries. */
|
| 136 |
+
.social-banner-stage,
|
| 137 |
+
.sb-logo-stage--og { container-type: size; }
|
| 138 |
+
.social-banner-stage .banner-wordmark,
|
| 139 |
+
.sb-logo-stage--og .banner-wordmark {
|
| 140 |
font-size: clamp(64px, 22cqh, 140px);
|
| 141 |
}
|
| 142 |
+
.social-banner-stage .banner-subtitle,
|
| 143 |
+
.sb-logo-stage--og .banner-subtitle {
|
| 144 |
font-size: clamp(11px, 2.6cqh, 16px);
|
| 145 |
margin-top: 10px;
|
| 146 |
}
|
| 147 |
+
.social-banner-stage .banner-specs,
|
| 148 |
+
.sb-logo-stage--og .banner-specs {
|
| 149 |
font-size: clamp(10px, 2.2cqh, 13px);
|
| 150 |
margin-top: 10px;
|
| 151 |
}
|
| 152 |
+
.social-banner-stage .banner-title,
|
| 153 |
+
.sb-logo-stage--og .banner-title { font-size: clamp(12px, 2.6cqh, 16px); }
|
| 154 |
+
.social-banner-stage .banner-path,
|
| 155 |
+
.sb-logo-stage--og .banner-path { font-size: clamp(10px, 2.2cqh, 13px); }
|
| 156 |
|
| 157 |
/* Slightly stronger inset hairline replaces the bottom one we lose
|
| 158 |
+
with the tabs gone — keeps the banner from looking unfinished.
|
| 159 |
+
Only on the main stage: the OG tile already has a hairline coming
|
| 160 |
+
from .sb-logo-card and a second inset stroke would double up. */
|
| 161 |
.social-banner-stage .carbon-banner {
|
| 162 |
box-shadow: inset 0 0 0 1px #cfcdbf;
|
| 163 |
}
|
|
|
|
| 315 |
width: 160px;
|
| 316 |
height: 160px;
|
| 317 |
}
|
| 318 |
+
/* OG / share thumbnail — laid out at the canonical 1200×630 social-card
|
| 319 |
+
ratio (the size Facebook, Twitter / X, LinkedIn, Slack, Discord and
|
| 320 |
+
iMessage all crop to). A screenshot of the stage at 100% IS the
|
| 321 |
+
/img/thumb.png replacement: drop the PNG straight into img/ and
|
| 322 |
+
bump the og:image:width/height meta in demo.html accordingly. The inner
|
| 323 |
+
.carbon-banner markup is identical to the main stage; the cqh-based
|
| 324 |
+
font-size rules and the .sb-logo-stage--og selectors above retune
|
| 325 |
+
the hero to the OG ratio automatically — no separate composition. */
|
| 326 |
+
.sb-logo-stage--og {
|
| 327 |
+
--w: 1200px;
|
| 328 |
+
--h: 630px;
|
| 329 |
+
/* No extra padding here: the .banner-inner inside .carbon-banner
|
| 330 |
+
handles its own internal gutters via the shared override above.
|
| 331 |
+
Stage background only shows through the helix overshoot, which
|
| 332 |
+
is the same paper used by the main stage. */
|
| 333 |
+
background: var(--paper, #f7f5ee);
|
| 334 |
+
/* Clip the rotated helix overshoot at the stage edge so the
|
| 335 |
+
screenshot crop is clean. Mirrors .carbon-banner's own
|
| 336 |
+
overflow:hidden which already clips inside the banner, but we
|
| 337 |
+
repeat it here for safety in case the canvas drifts further out
|
| 338 |
+
than the inner banner clip. */
|
| 339 |
+
overflow: hidden;
|
| 340 |
+
}
|
| 341 |
|
| 342 |
.sb-logo-meta {
|
| 343 |
font-family: "JetBrains Mono", ui-monospace, monospace;
|
|
|
|
| 524 |
|
| 525 |
<!-- ------------------------------------------------------------------ -->
|
| 526 |
<!-- SEO / social-share thumbnail. -->
|
| 527 |
+
<!-- Composed in HTML so the lockup tracks edits to logo-rectangle.svg -->
|
| 528 |
+
<!-- automatically: screenshot the stage at 100% and drop the PNG into -->
|
| 529 |
+
<!-- img/thumb.png. The stage is sized at the canonical 1200×630 -->
|
| 530 |
+
<!-- social-card ratio so the export drops straight into demo.html's -->
|
| 531 |
+
<!-- og:image + twitter:image meta tags. Marked data-static so the helix-->
|
| 532 |
+
<!-- renders a single frozen frame instead of animating — keeps the -->
|
| 533 |
+
<!-- screenshot deterministic and frees the rAF loop. -->
|
| 534 |
<!-- ------------------------------------------------------------------ -->
|
| 535 |
<div class="sb-section-label">
|
| 536 |
<span>seo · share thumbnail</span>
|
| 537 |
+
<span class="sb-section-label__hint">1200×630 · screenshot at 100% and drop into img/thumb.png</span>
|
| 538 |
</div>
|
| 539 |
|
| 540 |
<div class="sb-thumbs" id="sb-thumbs">
|
| 541 |
|
| 542 |
<figure class="sb-logo-card">
|
| 543 |
<div class="sb-logo-stage sb-logo-stage--og">
|
| 544 |
+
<header class="carbon-banner" data-static aria-label="Carbon OG share thumbnail">
|
| 545 |
+
<div class="banner-inner">
|
| 546 |
+
<div class="banner-left">
|
| 547 |
+
|
| 548 |
+
<div class="banner-identity">
|
| 549 |
+
<a class="logo-card" href="#" aria-label="Carbon, go to top">
|
| 550 |
+
<img class="logo-img" src="/img/logo.svg" alt="" width="44" height="44">
|
| 551 |
+
</a>
|
| 552 |
+
<div class="banner-breadcrumb">
|
| 553 |
+
<div class="banner-title">CARBON</div>
|
| 554 |
+
<div class="banner-path">huggingfacebio/carbon-3b</div>
|
| 555 |
+
</div>
|
| 556 |
+
</div>
|
| 557 |
+
|
| 558 |
+
<div class="banner-headline">
|
| 559 |
+
<h1 class="banner-wordmark"><span>CARBON</span><span class="banner-cursor" aria-hidden="true"></span></h1>
|
| 560 |
+
<p class="banner-subtitle">Autoregressive Genomic Foundation Model</p>
|
| 561 |
+
<ul class="banner-specs" aria-label="Model specs">
|
| 562 |
+
<li class="banner-spec"><strong>49,152</strong> bp context</li>
|
| 563 |
+
<li class="banner-spec"><strong>6-mer</strong> tokenizer</li>
|
| 564 |
+
<li class="banner-spec"><strong>1T</strong> train tokens</li>
|
| 565 |
+
</ul>
|
| 566 |
+
</div>
|
| 567 |
+
|
| 568 |
+
</div>
|
| 569 |
+
|
| 570 |
+
<div class="banner-helix" aria-hidden="true">
|
| 571 |
+
<canvas class="cb-helix-canvas"></canvas>
|
| 572 |
+
</div>
|
| 573 |
+
</div>
|
| 574 |
+
</header>
|
| 575 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
| 576 |
</figure>
|
| 577 |
|
| 578 |
</div>
|