site/hephaestus.x/silentmode/index.html
Local Dev 941851ea0e feat(hephaestus.x): per-repo detail pages under /silentmode/*
Adds live pages for each repo without leaving hephaestus.x:

  hephaestus.x/silentmode/            → index of all silentmode/* repos
  hephaestus.x/silentmode/theseus/    → README + recent commits + clone URLs
  hephaestus.x/silentmode/sirius/     → same
  hephaestus.x/silentmode/ariadne/    → same, gated ("private, sign in to browse")
  hephaestus.x/silentmode/hephaestus/ → same, gated

Single _template.html hardcoded per repo via sed; each detail page pulls
metadata + README + last 8 commits from code.silentmode.st via the
CORS-enabled Forgejo API on load, renders README with a minimal
markdown-to-HTML pass, and gracefully falls back to a "sign in to browse"
note when the API returns 401/404 (private repo).

The URL stays on hephaestus.x while browsing — user only leaves when they
click "Browse full source →" or a specific commit link.
2026-08-31 15:29:49 +02:00

127 lines
5.3 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>
</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>