From 8e0830f0462570934c9b406a745fcaa6d614698e Mon Sep 17 00:00:00 2001 From: Local Dev Date: Thu, 22 Oct 2026 21:30:13 +0300 Subject: [PATCH] prometheus: SVG icons for the 8 categories MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces the emoji glyphs (๐Ÿ’ฌ๐Ÿ›ก๏ธ๐Ÿ’ธ๐ŸŽฎ๐Ÿงฐ๐ŸŽงโš™๏ธโœจ) in the category grid with dedicated SVG icons under /static/icons/cat-.svg, following the same visual family as the sibling .x marks (theseus, sirius, ariadne, pithos, aegis): 12-radius dark square + acid-green mark, legible at 16 px tab-icon size and 40 px grid size. Designs chosen to not blur with the Silent Mode product icons also rendered on the site: cat-communication speech bubble + three dots (not an envelope โ€” too close to the Hephaestus letter imagery elsewhere) cat-privacy shield + checkmark (DISTINCT from aegis.svg's shield+chevron, so category + listing don't collide) cat-wallets stacked coins + B serif (hints at the BCH coin) cat-games stylised controller (d-pad + two action buttons) cat-devtools code brackets < / > (reads as "code" at 16 px where a wrench/hammer blurs with the Utilities gear) cat-media play triangle in a circle (equally "player" and "publish/broadcast") cat-utilities gear with hollow centre (less visual weight than the Media circle; the two side-by-side don't crowd each other) cat-other sparkle burst + two smaller sparkles (sibling of sirius.svg's 4-point mark, extras so the two don't look identical) pages-browse.js: CATEGORIES[].icon is now the path to the SVG, not an emoji string. The three places the icon rendered โ€” grid card, category hero, and the inline chip on listing detail โ€” all now use at the size they need (40, 56, 14 respectively). The CSS entry `.cat .ico` loses the font-size + grayscale (text styling) and gains width/height for the image plus a tiny hover rotation that matches the existing lift transform. Also: when a listing has no `icon` of its own, the detail page's icon slot now falls back to the category's SVG (centered + padded) instead of a plain ๐Ÿ“ฆ emoji, so the detail hero always has a vector icon. --- public/icons/cat-communication.svg | 8 ++++++++ public/icons/cat-devtools.svg | 8 ++++++++ public/icons/cat-games.svg | 9 +++++++++ public/icons/cat-media.svg | 7 +++++++ public/icons/cat-other.svg | 8 ++++++++ public/icons/cat-privacy.svg | 7 +++++++ public/icons/cat-utilities.svg | 8 ++++++++ public/icons/cat-wallets.svg | 9 +++++++++ public/style.css | 4 +++- service/pages-browse.js | 31 ++++++++++++++++++------------ 10 files changed, 86 insertions(+), 13 deletions(-) create mode 100644 public/icons/cat-communication.svg create mode 100644 public/icons/cat-devtools.svg create mode 100644 public/icons/cat-games.svg create mode 100644 public/icons/cat-media.svg create mode 100644 public/icons/cat-other.svg create mode 100644 public/icons/cat-privacy.svg create mode 100644 public/icons/cat-utilities.svg create mode 100644 public/icons/cat-wallets.svg diff --git a/public/icons/cat-communication.svg b/public/icons/cat-communication.svg new file mode 100644 index 0000000..e4cbe2b --- /dev/null +++ b/public/icons/cat-communication.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/public/icons/cat-devtools.svg b/public/icons/cat-devtools.svg new file mode 100644 index 0000000..fa66a19 --- /dev/null +++ b/public/icons/cat-devtools.svg @@ -0,0 +1,8 @@ + + + + + + + diff --git a/public/icons/cat-games.svg b/public/icons/cat-games.svg new file mode 100644 index 0000000..a06eaaf --- /dev/null +++ b/public/icons/cat-games.svg @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/public/icons/cat-media.svg b/public/icons/cat-media.svg new file mode 100644 index 0000000..d933510 --- /dev/null +++ b/public/icons/cat-media.svg @@ -0,0 +1,7 @@ + + + + + + diff --git a/public/icons/cat-other.svg b/public/icons/cat-other.svg new file mode 100644 index 0000000..fffaf5c --- /dev/null +++ b/public/icons/cat-other.svg @@ -0,0 +1,8 @@ + + + + + + + diff --git a/public/icons/cat-privacy.svg b/public/icons/cat-privacy.svg new file mode 100644 index 0000000..7ed4970 --- /dev/null +++ b/public/icons/cat-privacy.svg @@ -0,0 +1,7 @@ + + + + + + diff --git a/public/icons/cat-utilities.svg b/public/icons/cat-utilities.svg new file mode 100644 index 0000000..b79d22d --- /dev/null +++ b/public/icons/cat-utilities.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/public/icons/cat-wallets.svg b/public/icons/cat-wallets.svg new file mode 100644 index 0000000..35f95ee --- /dev/null +++ b/public/icons/cat-wallets.svg @@ -0,0 +1,9 @@ + + + + + + + + B + diff --git a/public/style.css b/public/style.css index 9e53bb5..14e1dc4 100644 --- a/public/style.css +++ b/public/style.css @@ -168,7 +168,9 @@ footer .fine{max-width:660px;margin:.8rem auto 0;line-height:1.7} display:flex;flex-direction:column;gap:.6rem; } .cat:hover{transform:translateY(-3px);border-color:rgba(214,255,61,.35);background:var(--panel2)} -.cat .ico{font-size:26px;line-height:1;filter:grayscale(.2)} +.cat .ico{width:40px;height:40px;display:block;transition:transform .18s ease} +.cat:hover .ico{transform:rotate(-3deg)} +.cat.empty .ico{opacity:.75} .cat h3{margin:.1rem 0 0;font-size:1.02rem} .cat .count{color:var(--dim);font-size:12px;letter-spacing:.02em;margin-top:auto;padding-top:.4rem} .cat.empty .count::before{content:"โ€” ";color:var(--dim)} diff --git a/service/pages-browse.js b/service/pages-browse.js index 1e06f38..98ed9a8 100644 --- a/service/pages-browse.js +++ b/service/pages-browse.js @@ -30,22 +30,26 @@ import { softwareApplicationLd } from './seo.js'; * allow-list in listings.js. The browse grid picks up the new row * automatically. */ +// `icon` is a path to an SVG under /static/icons/. Rendered via at the +// three sizes the templates use (26 px in the grid, 40 px in the category +// hero, 1em in the inline chip on listing detail pages). The icons share a +// family with the sibling .x marks: 12-radius dark square + acid-green mark. export const CATEGORIES = [ - { slug: 'communication', icon: '๐Ÿ’ฌ', title: 'Communication', + { slug: 'communication', icon: '/static/icons/cat-communication.svg', title: 'Communication', blurb: `Messengers, voice, boards, group chats. Clients that route through peers rather than someone else's server.` }, - { slug: 'privacy', icon: '๐Ÿ›ก๏ธ', title: 'Privacy & security', + { slug: 'privacy', icon: '/static/icons/cat-privacy.svg', title: 'Privacy & security', blurb: `Tor and mix-net tooling, key and vault managers, disk crypto. The things a conventional store delists first when a government writes.` }, - { slug: 'wallets', icon: '๐Ÿ’ธ', title: 'Wallets & payments', + { slug: 'wallets', icon: '/static/icons/cat-wallets.svg', title: 'Wallets & payments', blurb: `BCH wallets, cross-chain bridges, point-of-sale terminals. The chain publishes the listing and the chain settles the payment.` }, - { slug: 'games', icon: '๐ŸŽฎ', title: 'Games', + { slug: 'games', icon: '/static/icons/cat-games.svg', title: 'Games', blurb: `Standalone titles, on-chain leaderboards, in-app purchases that reach the publisher instead of a 30% toll.` }, - { slug: 'devtools', icon: '๐Ÿงฐ', title: 'Developer tools', + { slug: 'devtools', icon: '/static/icons/cat-devtools.svg', title: 'Developer tools', blurb: `SDKs, libraries, indexers, faucets, protocol utilities. The pieces other apps on this list are built out of.` }, - { slug: 'media', icon: '๐ŸŽง', title: 'Media & publishing', + { slug: 'media', icon: '/static/icons/cat-media.svg', title: 'Media & publishing', blurb: `Readers, players, one-file blogs, podcast hosts. Clients that find their audience without going through an aggregator.` }, - { slug: 'utilities', icon: 'โš™๏ธ', title: 'Utilities', + { slug: 'utilities', icon: '/static/icons/cat-utilities.svg', title: 'Utilities', blurb: `File tools, format converters, backup, calculators. The small sharp things that solve one problem and do not ask for an account first.` }, - { slug: 'other', icon: 'โœจ', title: 'Everything else', + { slug: 'other', icon: '/static/icons/cat-other.svg', title: 'Everything else', blurb: `Anything that does not fit above. New categories are proposed in-band โ€” any listing can declare one and clients will offer to add it.` }, ]; @@ -77,7 +81,7 @@ export function renderCategoriesGrid({ verbose = true } = {}) { const emptyCls = n === 0 ? ' empty' : ''; const countLabel = `${n} ${n === 1 ? 'listing' : 'listings'}`; return ` -
${c.icon}
+

${escapeHtml(c.title)}

${verbose ? `

${escapeHtml(c.blurb)}

` : ''} ${countLabel} @@ -102,7 +106,7 @@ export function categoryPage(req, slug) { here, body: `
-
${cat.icon}
+

${escapeHtml(title)}

${escapeHtml(cat.blurb)}

@@ -136,7 +140,7 @@ export function appPage(req, publisher, slug) { const cat = CATEGORY_BY_SLUG[row.category]; const catChip = cat - ? `
${cat.icon} ${escapeHtml(cat.title)}` + ? ` ${escapeHtml(cat.title)}` : ''; const scanReport = safeParse(row.scan_report); @@ -150,7 +154,10 @@ export function appPage(req, publisher, slug) { const iconHtml = row.icon ? `` - : `
${cat?.icon || '๐Ÿ“ฆ'}
`; + : cat?.icon + ? `` + : `
๐Ÿ“ฆ
`; return { title: `${row.name} by ${row.publisher}`,