diff --git a/tools/star-tracker/src/pages.ts b/tools/star-tracker/src/pages.ts index bb0fc1a..3f4bc7b 100644 --- a/tools/star-tracker/src/pages.ts +++ b/tools/star-tracker/src/pages.ts @@ -61,6 +61,9 @@ function shell(title: string, user: User | null, body: string): string { dl.embed code { display: inline-block; max-width: 100%; } .embed-row { display: flex; align-items: flex-start; gap: 6px; } .embed-row code { flex: 1; min-width: 0; overflow-x: auto; } + .embed-row pre { flex: 1; min-width: 0; margin: 0; padding: 8px 10px; background: rgba(15,23,42,0.04); border-radius: 4px; overflow-x: auto; } + @media (prefers-color-scheme: dark) { .embed-row pre { background: rgba(255,255,255,0.04); } } + .embed-row pre code { display: block; padding: 0; background: none; white-space: pre; } .embed-row .icon-btn { padding: 0 8px; flex: 0 0 auto; height: 32px; } .secret-row { display: flex; align-items: stretch; gap: 8px; margin: .5rem 0 1rem; } .secret-row .secret { flex: 1; margin: 0; padding: 10px 12px; } @@ -246,11 +249,29 @@ ${body} var base = embed.getAttribute('data-base'); var link = embed.getAttribute('data-link') || ''; var slug = embed.getAttribute('data-slug'); - var url = base + buildQuery(currentTheme(), currentSplit(), currentStyle(), currentRange(), null); + var n = currentSplit(); + var style = currentStyle(); + var range = currentRange(); + var url = base + buildQuery(currentTheme(), n, style, range, null); + // Picture snippet ignores the theme toggle — it serves both + // variants based on the viewer's prefers-color-scheme. + var darkUrl = base + buildQuery('dark', n, style, range, null); + var lightUrl = base + buildQuery('light', n, style, range, 'theme=light'); var md = embed.querySelector('[data-embed-md]'); var html = embed.querySelector('[data-embed-html]'); + var picture = embed.querySelector('[data-embed-picture]'); if (md) md.textContent = '[![' + slug + ' stars](' + url + ')](' + link + ')'; - if (html) html.textContent = '' + slug + ' stars'; + if (html) html.textContent = + '\n' + + ' ' + slug + ' stars\n' + + ''; + if (picture) picture.textContent = + '\n' + + ' \n' + + ' \n' + + ' ' + slug + ' stars\n' + + ' \n' + + ''; } document.querySelectorAll('input[name=chart-split], input[name=chart-theme], input[name=chart-style], input[name=chart-range]').forEach(function (r) { r.addEventListener('change', function () { @@ -424,8 +445,8 @@ function chartBlock( ` : ''; const paramsHint = showSplit - ? `Snippets update as you change the controls above. Params: ?theme=dark, ?split=N (1–8), ?style=step, ?range=30d|90d|1y.` - : `Snippets update as you change the controls above. Params: ?theme=dark, ?style=step, ?range=30d|90d|1y.`; + ? `Snippets update as you change the controls above. Params: ?theme=dark, ?split=N (1–8), ?style=step, ?range=30d|90d|1y. The Auto theme snippet uses <picture> with prefers-color-scheme so GitHub READMEs match the viewer's mode automatically.` + : `Snippets update as you change the controls above. Params: ?theme=dark, ?style=step, ?range=30d|90d|1y. The Auto theme snippet uses <picture> with prefers-color-scheme so GitHub READMEs match the viewer's mode automatically.`; return `
@@ -464,7 +485,16 @@ function chartBlock(
Markdown
[![${altText} stars](${chartSvg})](${linkTarget})${copyBtn('Markdown snippet')}
HTML
-
<a href="${linkTarget}"><img src="${chartSvg}" alt="${altText} stars"></a>${copyBtn('HTML snippet')}
+
<a href="${linkTarget}">
+  <img src="${chartSvg}" alt="${altText} stars">
+</a>
${copyBtn('HTML snippet')}
+
Auto theme 👍
+
<a href="${linkTarget}">
+  <picture>
+    <source media="(prefers-color-scheme: dark)" srcset="${chartSvg}?theme=dark">
+    <img alt="${altText} stars" src="${chartSvg}?theme=light">
+  </picture>
+</a>
${copyBtn('Auto-theme HTML snippet')}

${paramsHint}

`;