site/hephaestus.x/silentmode/index.html
Local Dev 58712e77da site: add favicon link to every silentmode.st HTML page
Bulk-inserts <link rel="icon" type="image/svg+xml" href="/favicon.svg"> before
the </head> tag on every silentmode.st page that was missing it. All 36 site
HTML pages now advertise the chain-links favicon; browsers show it in tabs
and bookmarks across the whole umbrella site.

Pages touched (29): apps/, choose/*, deviant/* (7 pages under the parent
house), hephaestus/, hephaestus.x/* (9 chain-published mirror pages),
nav/ (redirect stub), register.html (redirect stub), sirius/,
sirius/register.html, store/ (redirect stub), tlds/.

Already had favicon from earlier passes (7): index.html, brand/,
tools/, prometheus/, helios/, hermes/, releases/.

Line-ending preservation: choose/index.html and sirius/register.html were
originally stored with CRLF endings; the plain Python read/write path
normalized them to LF and produced a noisy diff. Both files re-serialized as
CRLF before the favicon insert to keep the diff to +1 line each.

Deploy: rsync-equivalent tar-pipe to /opt/silent-mode/site/, plus per-file scp
for the two CRLF-corrected files. Verified live: 7 spot-checked URLs each
report exactly one <link rel="icon"> in served HTML.
2026-08-31 21:43:25 +02:00

128 lines
5.4 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>silentmode/* — Hephaestus</title>
<meta name="description" content="All silentmode/* repos on Hephaestus.">
<style>
:root{
--bg:#0b0e14; --panel:#141a24; --panel2:#18202c; --line:rgba(255,255,255,.09);
--ink:#e7eaf1; --mut:#8b98a9; --dim:#5e6678; --acid:#d6ff3d;
}
*{box-sizing:border-box}
body{margin:0;background:radial-gradient(1100px 560px at 50% -12%,#16202e,var(--bg));
color:var(--ink);font:16px/1.65 system-ui,-apple-system,Segoe UI,Roboto,sans-serif;min-height:100vh;
display:flex;flex-direction:column}
a{color:var(--acid);text-decoration:none}
a:hover{text-decoration:underline}
.wrap{max-width:820px;margin:0 auto;padding:0 1.2rem;width:100%;flex:1}
.top{padding:1.6rem 0;color:var(--dim);font-size:13px}
.top a{color:var(--mut)}
header.hero{text-align:center;padding:3rem 1.2rem 1rem}
.mark{font-size:52px;line-height:1}
h1{font-size:clamp(1.8rem,4.5vw,2.4rem);margin:.4rem 0 .3rem;letter-spacing:-0.01em;font-family:ui-monospace,monospace;font-weight:500}
h1 .g{color:var(--acid)}
.tag{color:var(--mut);font-size:1rem;max-width:560px;margin:0 auto}
section{padding:2rem 0 1rem}
.repo{display:grid;grid-template-columns:1fr auto;gap:16px;align-items:baseline;
background:var(--panel);border:1px solid var(--line);border-radius:12px;
padding:16px 20px;margin-bottom:10px;transition:border-color .1s,background .1s;text-decoration:none}
.repo:hover{border-color:var(--acid);background:var(--panel2);text-decoration:none}
.repo .name{font-family:ui-monospace,monospace;font-size:14.5px;color:var(--ink)}
.repo .name .owner{color:var(--dim)}
.repo .name .sep{color:var(--dim);margin:0 2px}
.repo .name .repo-label{color:var(--acid)}
.repo .desc{color:var(--mut);font-size:13.5px;line-height:1.5;margin:.3rem 0 0;grid-column:1/-1}
.repo .meta{color:var(--dim);font-size:12px;font-family:ui-monospace,monospace;text-align:right;white-space:nowrap}
.repo.priv .name .repo-label{color:var(--mut)}
.empty{color:var(--dim);font-size:14px;text-align:center;padding:2rem}
footer{border-top:1px solid var(--line);padding:2rem 1.2rem 3rem;color:var(--dim);font-size:13px;text-align:center;margin-top:2rem}
footer a{color:var(--mut)} footer a:hover{color:var(--ink)}
</style>
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
</head>
<body>
<div class="wrap">
<div class="top">
<a href="../">hephaestus.x</a> / <strong>silentmode</strong>
</div>
<header class="hero">
<div class="mark">🛠</div>
<h1><span class="g">silentmode</span>/*</h1>
<p class="tag">Public repositories under the <code>silentmode</code> org. Click through for a per-repo overview or straight into the full forge.</p>
</header>
<section>
<div id="repos"><div class="empty">Loading from the forge…</div></div>
</section>
</div>
<footer>
<a href="../">hephaestus.x</a> · Silent Mode's decentralized code host
</footer>
<script type="module">
// Static index: enumerate the known silentmode/* repos. Public ones link to the
// per-repo detail page we generate at hephaestus.x/silentmode/<name>/ ; private
// ones link straight to code.silentmode.st since the detail page shows a
// "sign in to browse" message anyway.
const KNOWN = [
{name: "theseus", private: false},
{name: "sirius", private: false},
{name: "ariadne", private: true},
{name: "hephaestus", private: true},
];
const container = document.getElementById("repos");
function esc(s) {
return String(s ?? "").replace(/[&<>"']/g, c => ({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"}[c]));
}
function fmtDate(iso) {
if (!iso) return "";
const d = new Date(iso);
if (isNaN(d)) return "";
const days = (Date.now() - d.getTime()) / 86400000;
if (days < 1) return "today";
if (days < 30) return `${Math.round(days)}d ago`;
return d.toISOString().slice(0, 10);
}
async function loadRepo(entry) {
const priv = entry.private;
// Public repos: fetch fresh info via CORS. Private: fill in a static line.
if (!priv) {
try {
const info = await fetch(`https://code.silentmode.st/api/v1/repos/silentmode/${entry.name}`).then(r => r.json());
return {...entry, description: info.description, updated_at: info.updated_at, size: info.size};
} catch { return entry; }
}
return entry;
}
Promise.all(KNOWN.map(loadRepo)).then(list => {
container.innerHTML = list.map(r => {
// Public → per-repo detail page on hephaestus.x; private → direct to code.silentmode.st
const href = r.private
? `https://code.silentmode.st/silentmode/${r.name}`
: `./${r.name}/`;
const badge = r.private ? '<span style="color:var(--dim)">private</span>' : "";
const updated = r.updated_at ? `updated ${fmtDate(r.updated_at)}` : "";
const desc = r.description ? `<div class="desc">${esc(r.description)}</div>` : "";
return `
<a class="repo${r.private ? " priv" : ""}" href="${href}">
<div class="name">
<span class="owner">silentmode</span><span class="sep">/</span><span class="repo-label">${esc(r.name)}</span>
${desc}
</div>
<div class="meta">${badge}${badge && updated ? " · " : ""}${updated}</div>
</a>`;
}).join("");
});
</script>
</body>
</html>