Reskin to GitHub Primer dark

Every colour is now a Primer dark_default token. The header band, its four
capability pills and the heading above the trending table are gone, so the
search field is the first thing on the page and the switcher labels its own
table. Rows tighten to 10px, descriptions clamp to two lines, and the PoC
list loses its box for a hairline rule.

Blue is the only thing you can click. Amber means 500 stars or more and red
means known-exploited, and nothing else carries a hue: the star glyph is
dimmed at every value so the column reads as numbers rather than symbols.

The handoff's placeholder wanted an em dash. It reads "Search CVE, vendor,
product or keyword, exclude with -windows" with the middot the count line
already uses, and the six em dashes I had left in code comments are gone
too.
This commit is contained in:
0xMarcio committed 2026-08-31 04:00:54 +02:00
1 parent abecbf733e
commit 8c739f44e5
5 files changed
+216 -270

No files matched your search

+18 -25
View File
@@ -8,42 +8,35 @@
<link rel="icon" href="/favicon.ico" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=IBM+Plex+Mono:wght@400;500;600&display=swap" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600&family=IBM+Plex+Mono:wght@400;500&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="/style.css" />
</head>
<body>
<header class="masthead">
<div class="container">
<h1 class="wordmark">CVE PoC Hub</h1>
<div class="pills">
<span class="pill">Linked PoCs</span>
<span class="pill">MITRE CVE pages</span>
<span class="pill">Vendor / product filters</span>
<span class="pill">Supports negative terms (e.g. -windows)</span>
</div>
<form class="search" role="search" autocomplete="off">
<span class="search-glyph" aria-hidden="true">⌕</span>
<input type="text" spellcheck="false" data-search
placeholder="Search CVE, vendor, product, or keyword"
aria-label="Search CVE, vendor, product, or keyword" />
<span class="search-status" data-status aria-live="polite"></span>
</form>
</div>
</header>
<div class="container search-bar">
<form class="search" role="search" autocomplete="off">
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" aria-hidden="true">
<circle cx="7.6" cy="7.6" r="5.1" stroke="#8b949e" stroke-width="1.7" />
<path d="M11.5 11.5 L15.6 15.6" stroke="#8b949e" stroke-width="1.7" stroke-linecap="round" />
</svg>
<input type="text" spellcheck="false" data-search
placeholder="Search CVE, vendor, product or keyword &middot; exclude with -windows"
aria-label="Search CVE, vendor, product or keyword" />
<span class="search-status" data-status aria-live="polite"></span>
</form>
</div>
<main class="container content">
<section class="card results" data-results hidden></section>
<section class="panel results" data-results hidden></section>
<section data-trending>
<div class="trend-head">
<h2 data-trend-title>Trending Proof-of-Concepts</h2>
<div class="toggle" role="group" aria-label="Ranking">
<div class="trend-controls">
<div class="switch" role="group" aria-label="Ranking">
<button type="button" data-mode="TRENDING" aria-pressed="true">TRENDING</button>
<button type="button" data-mode="RECENT" aria-pressed="false">RECENT</button>
</div>
<span class="trend-note" data-trend-note></span>
</div>
<div class="card trend-card">
<div class="panel trending">
<div class="col-head">
<span class="col-stars">STARS</span>
<span class="col-updated">UPDATED</span>
@@ -57,7 +50,7 @@
<footer class="site-footer">
<div class="container">
<span>sources: nvd · mitre · github</span>
<span>sources: nvd &middot; mitre &middot; github &middot; cisa kev</span>
<span data-refreshed></span>
</div>
</footer>
+36 -47
View File
@@ -237,7 +237,7 @@ function runSearch(query) {
else if (wordStart(pocText(entry), adjacent) >= 0) score += 100;
}
entry._score = score;
// A term nobody's advisory text uses — "log4shell" — leaves every match tied
// A term nobody's advisory text uses, "log4shell" for one, leaves every match tied
// at the weakest tier, where newest-first is meaningless. How many of the
// linked PoCs carry the term says far more than which CVE is newer.
entry._hits = describes ? 0 : countLinkHits(entry, matchers);
@@ -279,7 +279,6 @@ const el = {
status: document.querySelector('[data-status]'),
results: document.querySelector('[data-results]'),
trending: document.querySelector('[data-trending]'),
trendTitle: document.querySelector('[data-trend-title]'),
trendNote: document.querySelector('[data-trend-note]'),
trendRows: document.querySelector('[data-trend-rows]'),
refreshed: document.querySelector('[data-refreshed]')
@@ -288,21 +287,23 @@ const el = {
function pocRow(url) {
const parsed = repoFromUrl(url);
const href = escapeHTML(url);
// A gist or an advisory has no owner and no stars; the star and age columns
// stay empty rather than inventing a repository shape for it.
if (!parsed) {
return `<div class="poc-row"><span class="poc-name">` +
`<a href="${href}" target="_blank" rel="noopener">${escapeHTML(plainLinkLabel(url))}</a>` +
`</span><span class="poc-stars"></span><span class="poc-age"></span></div>`;
return '<div class="poc-row"><span class="poc-name">' +
`<a class="plain" href="${href}" target="_blank" rel="noopener">${escapeHTML(plainLinkLabel(url))}</a>` +
'</span><span class="poc-stars"></span><span class="poc-age"></span></div>';
}
const key = (parsed.owner + '/' + parsed.repo).toLowerCase();
const meta = repoMeta[key];
const meta = repoMeta[(parsed.owner + '/' + parsed.repo).toLowerCase()];
const stars = meta ? meta[0] : null;
const hours = meta ? hoursSince(meta[1]) : null;
const starClass = stars != null && stars >= 500 ? 'poc-stars is-popular' : 'poc-stars';
return `<div class="poc-row">` +
`<span class="poc-name"><span class="poc-owner">${escapeHTML(parsed.owner)}</span>` +
`<span class="poc-sep"> / </span>` +
const popular = stars != null && stars >= 500 ? ' is-popular' : '';
// The glyph stays dim at every value so the column reads as numbers.
const starCell = stars == null ? '' : `${formatStars(stars)} <span class="star">★</span>`;
return '<div class="poc-row">' +
`<span class="poc-name">${escapeHTML(parsed.owner)}<span class="poc-sep"> / </span>` +
`<a href="${href}" target="_blank" rel="noopener">${escapeHTML(parsed.repo)}</a></span>` +
`<span class="${starClass}">${stars == null ? '' : formatStars(stars) + ' ★'}</span>` +
`<span class="poc-stars${popular}">${starCell}</span>` +
`<span class="poc-age">${escapeHTML(shortAge(hours))}</span></div>`;
}
@@ -313,7 +314,7 @@ function compact(value) {
/** Best links first. A repository named after the CVE is a proof of concept for
* it; a 5k-star scanner that merely mentions it is not, so stars only order
* repositories that are already about this CVE. Links with no star count keep
* their original order behind both — a reference has no repository to rank. */
* their original order behind both: a reference has no repository to rank. */
function rankedLinks(entry) {
if (entry._ranked) return entry._ranked;
const id = compact(entry.cve);
@@ -339,36 +340,34 @@ function resultRow(entry) {
const all = state.pocOpen.has(id);
const links = rankedLinks(entry);
const visible = all ? links : links.slice(0, POC_PREVIEW);
const more = all
? '↑ show fewer'
: (links.length > POC_PREVIEW
? `+ ${formatCount(links.length - POC_PREVIEW)} more repositories`
: 'all repositories shown');
const moreButton = links.length > 1
? `<button type="button" class="poc-more" data-toggle-poc="${escapeHTML(id)}">${more}</button>`
// Nothing to expand means no control: a line reading "all repositories
// shown" under a list of three is chrome that answers a question nobody has.
const moreButton = links.length > POC_PREVIEW
? `<button type="button" class="poc-more" data-toggle-poc="${escapeHTML(id)}">` +
`${all ? '↑ show fewer' : '+ ' + formatCount(links.length - POC_PREVIEW) + ' more'}</button>`
: '';
const flagged = kev[id];
const kevChip = flagged
? `<div class="kev" title="Listed in CISA's Known Exploited Vulnerabilities catalogue on ${escapeHTML(flagged[0])}">` +
`KEV${flagged[1] ? ' · RANSOMWARE' : ''}</div>`
? `<span class="chip chip-kev" title="Listed in CISA's Known Exploited Vulnerabilities catalogue on ${escapeHTML(flagged[0])}${flagged[1] ? ', used in ransomware campaigns' : ''}">` +
`KEV${flagged[1] ? ' RANSOMWARE' : ''}</span>`
: '';
const dates = [];
if (entry.published) dates.push(['published', entry.published]);
if (entry.modified) dates.push(['modified', entry.modified]);
if (entry.published) dates.push(`published ${entry.published}`);
if (entry.modified) dates.push(`modified ${entry.modified}`);
const dateHtml = dates.length
? `<dl class="result-dates">${dates.map(([label, value]) =>
`<div class="result-date"><dt>${label}</dt><dd>${escapeHTML(value)}</dd></div>`).join('')}</dl>`
? `<div class="result-dates">${dates.map(d => `<span>${escapeHTML(d)}</span>`).join('')}</div>`
: '';
return `<div class="result-row">
<div class="result-meta">
<a class="result-id" href="https://nvd.nist.gov/vuln/detail/${encodeURIComponent(id)}" target="_blank" rel="noopener">${escapeHTML(id)}</a>
<div class="result-pocs">${formatCount(links.length)} linked PoC${links.length === 1 ? '' : 's'}</div>
${kevChip}
${dateHtml}
<a class="mitre" href="https://www.cve.org/CVERecord?id=${encodeURIComponent(id)}" target="_blank" rel="noopener">MITRE ↗</a>
<div class="chips">${kevChip}
<a class="chip" href="https://www.cve.org/CVERecord?id=${encodeURIComponent(id)}" target="_blank" rel="noopener">MITRE ↗</a>
</div>
</div>
<div class="result-body">
<p class="result-desc${open ? ' is-open' : ''}">${escapeHTML(entry.desc || '')}</p>
@@ -400,10 +399,7 @@ function renderResults(elapsed) {
el.results.hidden = false;
if (!results.length) {
el.results.innerHTML = `<div class="empty">
<div class="empty-head">No CVE matched <b>${escapeHTML(state.query)}</b></div>
<div class="empty-hint">Try a CVE ID, a vendor, or a product name. Prefix a term with <code>-</code> to exclude it.</div>
</div>`;
el.results.innerHTML = `<div class="empty">No results for ${escapeHTML(state.query)}</div>`;
return;
}
@@ -411,12 +407,12 @@ function renderResults(elapsed) {
const pocTotal = results.pocTotal;
const remaining = results.length - shown.length;
const footer = remaining > 0
? `<button type="button" class="poc-more" data-more-results>+ ${formatCount(remaining)} more matching CVEs</button>`
? `<button type="button" class="poc-more" style="padding:9px 16px" data-more-results>+ ${formatCount(remaining)} more matching CVEs</button>`
: '';
el.results.innerHTML = `<div class="card-head">
el.results.innerHTML = `<div class="panel-head">
<h2>Results</h2>
<span class="card-count">${formatCount(results.length)} CVE${results.length === 1 ? '' : 's'} · ${formatCount(pocTotal)} PoCs</span>
<span class="panel-count">${formatCount(results.length)} CVE${results.length === 1 ? '' : 's'} · ${formatCount(pocTotal)} PoCs</span>
</div>
<div class="col-head"><span>CVE</span><span>DESCRIPTION / POC LINKS</span></div>
${shown.map(resultRow).join('')}${footer}`;
@@ -430,7 +426,7 @@ function renderResults(elapsed) {
function trendRow(item) {
const popular = item.stars >= 500 ? ' is-popular' : '';
return `<div class="trend-row">
<span class="trend-stars${popular}">${formatStars(item.stars)} ★</span>
<span class="trend-stars${popular}">${formatStars(item.stars)} <span class="star">★</span></span>
<span class="trend-age">${escapeHTML(longAge(item._pushed))}</span>
<a class="trend-name" href="${escapeHTML(item.url)}" target="_blank" rel="noopener">${escapeHTML(item.name)}</a>
<span class="trend-desc">${escapeHTML(item.desc || '')}</span>
@@ -453,19 +449,15 @@ function renderTrending() {
}
const rows = ranked.slice(0, TREND_ROWS);
el.trendTitle.textContent = state.mode === 'TRENDING'
? 'Trending Proof-of-Concepts'
: 'Recently updated Proof-of-Concepts';
el.trendNote.textContent = state.mode === 'TRENDING'
? 'stars weighted against time since the last commit'
: `newest commit first · ${formatCount(trending.length)} repositories`;
: 'newest commit first';
el.trendRows.innerHTML = rows.length
? rows.map(trendRow).join('')
: '<div class="trend-row"><span class="trend-desc">No recent PoCs.</span></div>';
document.querySelectorAll('.toggle button').forEach(button => {
document.querySelectorAll('.switch button').forEach(button => {
button.setAttribute('aria-pressed', String(button.dataset.mode === state.mode));
});
}
@@ -485,10 +477,7 @@ function render() {
el.results.hidden = false;
el.trending.hidden = true;
el.status.textContent = 'loading index…';
el.results.innerHTML = `<div class="empty">
<div class="empty-head">Loading the CVE index…</div>
<div class="empty-hint">The full index is a single download; results appear as soon as it lands.</div>
</div>`;
el.results.innerHTML = '<div class="empty">Loading the CVE index…</div>';
return;
}
const started = performance.now();
@@ -517,7 +506,7 @@ el.input.addEventListener('input', () => {
document.querySelector('.search').addEventListener('submit', event => event.preventDefault());
document.querySelector('.toggle').addEventListener('click', event => {
document.querySelector('.switch').addEventListener('click', event => {
const button = event.target.closest('button[data-mode]');
if (!button) return;
state.mode = button.dataset.mode;
+159 -195
View File
@@ -1,37 +1,25 @@
/* CVE PoC Hub — design tokens from the frontend refit handoff. */
/* CVE PoC Hub. GitHub Primer dark_default tokens, per the refit handoff. */
:root {
--page: #0a1114;
--header-top: #102026;
--header-bottom: #0d191e;
--surface: #0d171b;
--surface-sunken: #08100f;
--table-header: #0b1519;
--footer: #0b1418;
--row-hover: #101d21;
--pill: #0e1b20;
--border-strong: #23353a;
--border: #1d2c31;
--border-faint: #162327;
--border-hairline: #142023;
--text-primary: #f2f7f6;
--text: #eaf3f1;
--text-muted: #9fb3b0;
--prose: #8fa3a0;
--text-dim: #7f9491;
--text-faint: #5c6f6c;
--text-faintest: #4a5c59;
--separator: #3d4d4a;
--accent: #58e39b;
--accent-hover: #7df0b3;
--star: #e8b84b;
--canvas: #0d1117;
--canvas-subtle: #161b22;
--border: #30363d;
--border-muted: #21262d;
--fg: #e6edf3;
--fg-muted: #8b949e;
--neutral: #6e7681;
--accent: #2f81f7;
--accent-hover: #58a6ff;
--accent-emphasis: #1f6feb;
--attention: #e3b341;
--danger: #f85149;
--mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
--sans: 'Space Grotesk', system-ui, -apple-system, sans-serif;
}
*, *::before, *::after { box-sizing: border-box; }
* { scrollbar-width: thin; scrollbar-color: var(--border-strong) transparent; }
* { scrollbar-width: thin; scrollbar-color: var(--border) transparent; }
html, body { margin: 0; padding: 0; background: var(--page); min-height: 100%; }
html, body { margin: 0; padding: 0; background: var(--canvas); min-height: 100%; }
body {
font-family: var(--sans);
-webkit-font-smoothing: antialiased;
@@ -42,48 +30,26 @@ body {
a { color: var(--accent); text-decoration: none; }
a:hover { color: var(--accent-hover); }
:focus-visible { outline: 2px solid var(--accent-emphasis); outline-offset: 2px; border-radius: 2px; }
[hidden] { display: none !important; }
:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
border-radius: 2px;
}
.container { max-width: 1240px; width: 100%; margin: 0 auto; padding: 0 32px; }
.container { max-width: 1180px; margin: 0 auto; padding: 0 40px; width: 100%; }
/* ---- search, the first element on the page ------------------------------ */
/* ---- header ------------------------------------------------------------ */
.masthead {
background: linear-gradient(180deg, var(--header-top) 0%, var(--header-bottom) 100%);
border-bottom: 1px solid var(--border);
padding: 44px 0 38px;
}
.wordmark {
margin: 0;
font: 700 46px/1 var(--sans);
color: var(--text-primary);
letter-spacing: -.035em;
}
.pills { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 20px; }
.pill {
font: 400 12px/1 var(--sans);
color: var(--text-muted);
border: 1px solid var(--border-strong);
background: var(--pill);
border-radius: 20px;
padding: 7px 13px;
}
.search-bar { padding-top: 30px; }
.search {
display: flex;
align-items: center;
gap: 12px;
margin-top: 22px;
background: var(--surface-sunken);
border: 1px solid var(--border-strong);
border-radius: 8px;
padding: 15px 18px;
gap: 13px;
height: 52px;
padding: 0 17px;
background: var(--canvas-subtle);
border: 1px solid var(--border);
border-radius: 6px;
}
.search-glyph { font: 400 14px/1 var(--mono); color: var(--text-faintest); }
.search:focus-within { border-color: var(--accent-emphasis); }
.search svg { flex: none; display: block; }
.search input {
flex: 1;
min-width: 0;
@@ -92,201 +58,203 @@ a:hover { color: var(--accent-hover); }
outline: 0;
padding: 0;
font: 400 15px/1 var(--mono);
color: var(--text);
color: var(--fg);
}
.search input::placeholder { color: var(--text-faintest); }
.search:focus-within { outline: 2px solid var(--accent); outline-offset: 2px; }
.search input::placeholder { color: var(--neutral); }
.search-status {
font: 400 11.5px/1 var(--mono);
color: var(--text-faintest);
flex: none;
white-space: nowrap;
font: 400 11.5px/1 var(--mono);
color: var(--fg-muted);
}
/* ---- content ----------------------------------------------------------- */
.content { flex: 1; padding-top: 26px; padding-bottom: 48px; }
.content { flex: 1; padding-top: 34px; padding-bottom: 56px; }
[hidden] { display: none !important; }
/* ---- shared table shell ------------------------------------------------- */
.card {
border: 1px solid var(--border);
border-radius: 9px;
overflow: hidden;
background: var(--surface);
}
.card-head {
.panel { border: 1px solid var(--border); border-radius: 6px; overflow: hidden; }
.panel-head {
display: flex;
align-items: baseline;
gap: 11px;
padding: 15px 20px;
gap: 10px;
padding: 13px 16px;
border-bottom: 1px solid var(--border);
}
.card-head h2 { margin: 0; font: 600 15px/1 var(--sans); color: var(--text); }
.card-count { font: 400 12px/1 var(--mono); color: var(--text-faint); }
.panel-head h2 {
flex: none;
margin: 0;
font: 600 14px/1 var(--sans);
letter-spacing: -.01em;
color: var(--fg);
}
.panel-count {
flex: none;
white-space: nowrap;
font: 400 11.5px/1 var(--mono);
color: var(--fg-muted);
}
.col-head {
display: grid;
padding: 9px 20px;
background: var(--table-header);
padding: 8px 16px;
background: var(--canvas-subtle);
border-bottom: 1px solid var(--border);
font: 500 9.5px/1 var(--mono);
letter-spacing: .11em;
color: var(--text-faint);
font: 400 9.5px/1 var(--mono);
letter-spacing: .12em;
color: var(--fg-muted);
}
/* ---- state A: results -------------------------------------------------- */
/* ---- state A: results --------------------------------------------------- */
.results .col-head, .result-row { grid-template-columns: 230px 1fr; }
.result-row { display: grid; border-bottom: 1px solid var(--border-faint); }
.results .col-head, .result-row { grid-template-columns: 196px minmax(0, 1fr); }
.result-row { display: grid; border-bottom: 1px solid var(--border-muted); }
.result-row:last-child { border-bottom: 0; }
.result-meta { padding: 20px; border-right: 1px solid var(--border-faint); }
.result-id {
font: 600 14.5px/1.2 var(--mono);
color: var(--accent);
letter-spacing: -.01em;
.result-meta { padding: 16px; border-right: 1px solid var(--border-muted); }
.result-id { font: 500 13.5px/1.2 var(--mono); letter-spacing: -.01em; }
.result-pocs { margin-top: 8px; font: 400 11.5px/1 var(--mono); color: var(--fg-muted); }
.result-dates {
margin: 12px 0 0;
display: flex;
flex-direction: column;
gap: 4px;
font: 400 11px/1.4 var(--mono);
color: var(--fg-muted);
}
.result-pocs { font: 500 11.5px/1 var(--mono); color: var(--text-dim); margin-top: 11px; }
.kev {
display: inline-block;
margin-top: 11px;
font: 500 10px/1 var(--mono);
letter-spacing: .09em;
color: var(--text);
background: var(--pill);
border: 1px solid var(--border-strong);
.chips { margin-top: 13px; display: flex; gap: 6px; flex-wrap: wrap; }
.chip {
font: 400 10.5px/1 var(--mono);
letter-spacing: .06em;
color: var(--fg-muted);
border: 1px solid var(--border);
border-radius: 4px;
padding: 6px 8px;
padding: 5px 8px;
}
a.chip:hover { color: var(--fg); border-color: var(--fg-muted); }
.chip-kev {
font-weight: 500;
color: var(--danger);
background: rgba(248, 81, 73, .1);
border-color: rgba(248, 81, 73, .4);
}
.result-dates { display: flex; flex-direction: column; gap: 5px; margin-top: 14px; }
.result-date { display: flex; gap: 8px; font: 400 10.5px/1.4 var(--mono); }
.result-date dt { width: 62px; color: var(--text-faintest); margin: 0; }
.result-date dd { color: var(--prose); margin: 0; }
.mitre {
display: inline-block;
margin-top: 16px;
font: 500 10.5px/1 var(--mono);
color: var(--text-dim);
border: 1px solid var(--border-strong);
border-radius: 4px;
padding: 6px 9px;
}
.mitre:hover { color: var(--text); border-color: #3a5158; }
.result-body { padding: 20px 20px 22px; min-width: 0; }
.result-body { padding: 16px; min-width: 0; }
.result-desc {
margin: 0;
font: 400 13px/1.6 var(--mono);
color: var(--prose);
max-height: 4.7em;
max-width: 96ch;
font: 400 13.5px/1.6 var(--sans);
color: var(--fg-muted);
max-height: 3.2em;
overflow: hidden;
text-wrap: pretty;
}
.result-desc.is-open { max-height: none; }
.expander {
margin-top: 9px;
margin-top: 8px;
background: transparent;
border: 0;
padding: 0;
cursor: pointer;
font: 500 11px/1 var(--mono);
font: 400 11px/1 var(--mono);
color: var(--accent);
}
.expander:hover { color: var(--accent-hover); }
.poc-list {
margin-top: 18px;
border: 1px solid var(--border);
border-radius: 6px;
overflow: hidden;
}
.poc-list { margin-top: 14px; border-top: 1px solid var(--border-muted); }
.poc-row {
display: grid;
grid-template-columns: 1fr 84px 58px;
grid-template-columns: minmax(0, 1fr) 78px 52px;
gap: 14px;
align-items: center;
padding: 10px 14px;
border-bottom: 1px solid var(--border-hairline);
padding: 9px 0;
border-bottom: 1px solid var(--border-muted);
}
.poc-row:hover { background: var(--row-hover); }
.poc-name {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font: 400 12.5px/1 var(--mono);
color: var(--fg-muted);
}
.poc-owner { color: var(--text-faint); }
.poc-sep { color: var(--separator); }
.poc-name a { font-weight: 500; }
.poc-stars { font: 400 12px/1 var(--mono); color: var(--text-faint); text-align: right; }
.poc-stars.is-popular { color: var(--star); }
.poc-age { font: 400 11.5px/1 var(--mono); color: var(--text-faintest); text-align: right; }
.poc-sep { color: var(--neutral); }
.poc-name a { color: var(--fg); font-weight: 500; }
.poc-name a:hover { color: var(--accent); }
.poc-name a.plain { color: var(--fg-muted); font-weight: 400; }
.poc-name a.plain:hover { color: var(--accent); }
.poc-stars { text-align: right; font: 400 12px/1 var(--mono); color: var(--fg-muted); }
.poc-stars.is-popular { color: var(--attention); }
.star { color: var(--neutral); }
.poc-age { text-align: right; font: 400 11.5px/1 var(--mono); color: var(--fg-muted); }
.poc-more {
display: block;
width: 100%;
text-align: left;
background: transparent;
border: 0;
padding: 9px 14px;
padding: 9px 0 0;
cursor: pointer;
font: 500 11px/1 var(--mono);
color: var(--text-dim);
font: 400 11px/1 var(--mono);
color: var(--fg-muted);
}
.poc-more:hover { color: var(--accent); }
/* ---- state B: nothing matched ------------------------------------------ */
/* ---- state B: nothing matched ------------------------------------------- */
.empty { padding: 52px 20px; text-align: center; }
.empty-head { font: 400 14px/1 var(--mono); color: var(--prose); }
.empty-head b { color: var(--text); font-weight: 400; }
.empty-hint { font: 400 13px/1.6 var(--sans); color: var(--text-faint); margin-top: 10px; }
.empty-hint code { font-family: var(--mono); color: var(--text-dim); }
/* ---- state C: trending ------------------------------------------------- */
.trend-head { display: flex; align-items: baseline; gap: 16px; flex-wrap: wrap; }
.trend-head h2 {
margin: 0;
font: 700 23px/1 var(--sans);
color: var(--text);
letter-spacing: -.02em;
.empty {
padding: 44px 16px;
text-align: center;
font: 400 13px/1 var(--mono);
color: var(--fg-muted);
}
.toggle { display: flex; border: 1px solid var(--border); border-radius: 6px; overflow: hidden; }
.toggle button {
/* ---- state C: trending -------------------------------------------------- */
.trend-controls {
display: flex;
align-items: center;
gap: 14px;
flex-wrap: wrap;
margin-bottom: 14px;
}
.switch { display: flex; border: 1px solid var(--border); border-radius: 4px; overflow: hidden; }
.switch button {
border: 0;
border-right: 1px solid var(--border);
padding: 7px 13px;
padding: 7px 12px;
cursor: pointer;
font: 500 11px/1 var(--mono);
font: 500 10.5px/1 var(--mono);
letter-spacing: .06em;
background: transparent;
color: var(--text-dim);
color: var(--fg-muted);
}
.switch button[aria-pressed="true"] { background: var(--accent-emphasis); color: #ffffff; }
.trend-note {
flex: none;
white-space: nowrap;
font: 400 11.5px/1 var(--mono);
color: var(--fg-muted);
}
.toggle button:last-child { border-right: 0; }
.toggle button[aria-pressed="true"] { background: var(--accent); color: var(--surface-sunken); }
.trend-note { font: 400 12px/1 var(--mono); color: var(--text-faint); }
.trend-card { margin-top: 16px; }
.trend-card .col-head, .trend-row {
grid-template-columns: 80px 92px 300px 1fr;
.trending .col-head, .trend-row {
grid-template-columns: 74px 96px 300px minmax(0, 1fr);
gap: 18px;
}
.trend-row {
display: grid;
align-items: center;
padding: 11px 20px;
border-bottom: 1px solid var(--border-hairline);
padding: 10px 16px;
border-bottom: 1px solid var(--border-muted);
}
.trend-row:last-child { border-bottom: 0; }
.trend-row:hover { background: var(--row-hover); }
.trend-row:hover { background: var(--canvas-subtle); }
.col-stars { text-align: right; }
.trend-stars {
font: 500 12.5px/1 var(--mono);
color: var(--text-faint);
text-align: right;
white-space: nowrap;
font: 500 12.5px/1 var(--mono);
color: var(--fg-muted);
}
.trend-stars.is-popular { color: var(--star); }
.trend-age { font: 400 12px/1 var(--mono); color: var(--text-dim); white-space: nowrap; }
.trend-stars.is-popular { color: var(--attention); }
.trend-age { white-space: nowrap; font: 400 12px/1 var(--mono); color: var(--fg-muted); }
.trend-name {
font: 500 12.5px/1 var(--mono);
overflow: hidden;
@@ -294,42 +262,38 @@ a:hover { color: var(--accent-hover); }
white-space: nowrap;
}
.trend-desc {
font: 400 12.5px/1.45 var(--sans);
color: var(--prose);
font: 400 12.5px/1.4 var(--sans);
color: var(--fg-muted);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* ---- footer ------------------------------------------------------------ */
/* ---- footer ------------------------------------------------------------- */
.site-footer {
border-top: 1px solid var(--border);
padding: 16px 0;
background: var(--footer);
}
.site-footer { border-top: 1px solid var(--border-muted); padding: 14px 0; }
.site-footer .container {
display: flex;
gap: 20px;
flex-wrap: wrap;
font: 400 11.5px/1.6 var(--mono);
color: var(--text-faintest);
font: 400 11px/1.6 var(--mono);
color: var(--fg-muted);
}
.site-footer span:last-child { margin-left: auto; }
/* ---- narrow viewports -------------------------------------------------- */
/* ---- narrow viewports --------------------------------------------------- */
@media (max-width: 900px) {
.container { padding: 0 20px; }
.wordmark { font-size: 34px; }
.container { padding: 0 16px; }
.results .col-head { display: none; }
.result-row { grid-template-columns: 1fr; }
.result-meta { border-right: 0; border-bottom: 1px solid var(--border-faint); }
.trend-card .col-head, .trend-row { grid-template-columns: 70px 88px 1fr; }
.result-meta { border-right: 0; border-bottom: 1px solid var(--border-muted); }
.trending .col-head, .trend-row { grid-template-columns: 70px 92px minmax(0, 1fr); }
.col-desc, .trend-desc { display: none; }
}
@media (max-width: 620px) {
.trend-card .col-head, .trend-row { grid-template-columns: 70px 1fr; }
.trending .col-head, .trend-row { grid-template-columns: 66px minmax(0, 1fr); }
.col-updated, .trend-age { display: none; }
.search-status { display: none; }
}
+1 -1
View File
@@ -70,7 +70,7 @@ def collect_repositories() -> tuple[dict[str, list[tuple[Path, str]]], set[str]]
def survey(client: GitHubClient, names: list[str]) -> tuple[set[str], dict[str, list]]:
"""Return the repositories GitHub reports as NOT_FOUND, and stars/last push for the rest.
Anything else — a network error, a throttle, an unexpected response — leaves
Anything else, a network error or a throttle or an unexpected response, leaves
the repository out of both results, so an audit failure never drops a link.
"""
batches = [names[index : index + BATCH] for index in range(0, len(names), BATCH)]
+2 -2
View File
@@ -309,8 +309,8 @@ def qualifying_repo_cves(
description_cves = extract_cves(description, year)
topic_cves = extract_cves(topics, year)
readme_cves = extract_cves(readme, year)
# A caption or description that drops a digit — "CVE-2023-3883" written for
# CVE-2023-38831 — still parses as a valid identifier and would otherwise
# A caption or description that drops a digit, "CVE-2023-3883" written for
# CVE-2023-38831, still parses as a valid identifier and would otherwise
# enrol the repository against whatever unrelated advisory owns it. Trust
# the repository name, which may deliberately carry both identifiers.
truncated = truncated_ids(name_cves | description_cves | topic_cves | readme_cves) - name_cves