The sidebar's body padding-left was pushing the whole page — hero, cards, footer — to the right of centre, off the axis of the hero title. Removed the body reserve; the sidebar is now a pointer-events:none overlay on top of the page. Content wraps back to the middle of the viewport regardless of sidebar width. Links float at opacity 0.35 by default so the sidebar reads as chrome rather than a panel — the section text underneath stays legible. On hover a link snaps to full opacity, picks up an ink colour and a subtle blurred backdrop so it doesn't compete with the content. The active-section link keeps the acid tint at 0.85 and finishes to 1 on hover. Icon rail and mobile bar unchanged. Sirius.X: the Theseus tab link in the topnav now reads Theseus.X with the .X in acid green, matching the naming everywhere else in the ecosystem.
243 lines
15 KiB
HTML
243 lines
15 KiB
HTML
<!doctype html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<title>theseus.x — Plug-ins</title>
|
||
<meta name="description" content="Silent Mode's first-party plug-ins for Theseus Navigator: the Aegis wallet and the Ariadne's Thread system-wide resolver. Current signed versions, hashes, and how they update.">
|
||
<link rel="icon" href="../assets/favicon.svg" type="image/svg+xml">
|
||
<link rel="mask-icon" href="../assets/favicon.svg" color="#d6ff3d">
|
||
<meta property="og:type" content="website">
|
||
<meta property="og:site_name" content="theseus.x">
|
||
<meta property="og:title" content="theseus.x — Plug-ins">
|
||
<meta property="og:description" content="First-party plug-ins for Theseus: Aegis wallet and Ariadne's Thread. Signed, verified on the device.">
|
||
<meta property="og:url" content="https://theseus.x/plug-ins/">
|
||
<style>
|
||
:root{
|
||
--bg:#0b0e14; --panel:#141a24; --panel2:#18202c; --line:rgba(255,255,255,.09);
|
||
--ink:#e7eaf1; --mut:#8b98a9; --dim:#5e6678; --acid:#d6ff3d; --ok:#4fd1a5;
|
||
}
|
||
*{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}
|
||
a{color:var(--acid)}
|
||
.wrap{max-width:900px;margin:0 auto;padding:0 1.2rem}
|
||
.topnav{position:fixed;top:0;left:0;right:0;z-index:20;display:flex;gap:2px;align-items:center;flex-wrap:wrap;
|
||
padding:10px 1.2rem;background:rgba(11,14,20,.88);backdrop-filter:blur(10px)}
|
||
.topnav .brand{font-weight:600;color:var(--ink);text-decoration:none;margin-right:14px;font-size:15px;letter-spacing:.2px;display:flex;align-items:center;gap:8px}
|
||
.topnav .brand .g{color:var(--acid)}
|
||
.topnav .brand svg{width:20px;height:20px}
|
||
.topnav a{color:var(--mut);text-decoration:none;padding:6px 12px;border-radius:8px;font-size:14px;
|
||
display:inline-flex;align-items:center;gap:6px}
|
||
.topnav a:hover{color:var(--ink);background:var(--panel)}
|
||
.topnav a.here{color:var(--acid);background:rgba(214,255,61,.08)}
|
||
.topnav a .g{color:var(--acid)}
|
||
.topnav a svg.tabicon{width:15px;height:15px;flex:none}
|
||
.topnav a.get{margin-left:auto;background:rgba(214,255,61,.10);color:var(--acid);font-weight:500}
|
||
.topnav a.get:hover{background:rgba(214,255,61,.18)}
|
||
|
||
/* Adaptive edge nav: full-width panel at left edge on wide,
|
||
icon rail on medium, bottom bar with icons on mobile. */
|
||
:root{--sn-w:200px;--tn-h:52px}
|
||
body{padding-top:var(--tn-h)}
|
||
.sidenav{position:fixed;top:var(--tn-h);left:0;bottom:0;width:var(--sn-w);z-index:15;
|
||
background:transparent;padding:56px 12px 22px 18px;
|
||
overflow-y:auto;transition:width .15s ease;pointer-events:none}
|
||
.sidenav a{display:flex;align-items:center;gap:14px;color:var(--mut);text-decoration:none;
|
||
padding:9px 12px;border-radius:10px;
|
||
font-size:14.5px;font-weight:500;opacity:.35;pointer-events:auto;
|
||
transition:opacity .12s,color .12s,background .12s,backdrop-filter .12s}
|
||
.sidenav a .ic{flex:none;width:22px;font-size:18px;line-height:1;text-align:center;
|
||
display:none;justify-content:center;align-items:center}
|
||
.sidenav a .lb{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
||
.sidenav a:hover{opacity:1;color:var(--ink);background:rgba(11,14,20,.72);backdrop-filter:blur(8px)}
|
||
.sidenav a.active{opacity:.85;color:var(--acid)}
|
||
.sidenav a.active:hover{opacity:1}
|
||
@media (max-width:1180px){
|
||
:root{--sn-w:64px}
|
||
.sidenav{padding:22px 6px}
|
||
.sidenav .lbl{display:none}
|
||
.sidenav a{justify-content:center;padding:12px 4px;gap:0}
|
||
.sidenav a .ic{display:inline-flex}
|
||
.sidenav a .lb{display:none}
|
||
}
|
||
@media (max-width:720px){
|
||
:root{--sn-w:0px}
|
||
body{padding-left:0;padding-bottom:64px}
|
||
.sidenav{top:auto;bottom:0;left:0;right:0;width:100%;height:auto;
|
||
padding:4px 4px;flex-direction:row;background:rgba(11,14,20,.52);
|
||
display:flex;justify-content:space-around;overflow-x:auto}
|
||
.sidenav .lbl{display:none}
|
||
.sidenav a{flex:1;min-width:56px;padding:10px 6px;justify-content:center;gap:0}
|
||
.sidenav a .ic{display:inline-flex}
|
||
.sidenav a .lb{display:none}
|
||
}
|
||
|
||
header.hero{text-align:center;padding:3.5rem 1.2rem 1rem}
|
||
h1{font-size:clamp(1.8rem,4.5vw,2.4rem);margin:.6rem 0 .3rem;letter-spacing:-.3px}
|
||
h1 .g{color:var(--acid)}
|
||
.tag{color:var(--mut);font-size:1.02rem;max-width:640px;margin:0 auto}
|
||
section{padding:2rem 0;border-top:1px solid var(--line);margin-top:1.6rem;scroll-margin-top:72px}
|
||
section:first-of-type{border-top:none;margin-top:1rem}
|
||
h2{font-size:1.35rem;margin:0 0 .5rem}
|
||
.lede{color:var(--mut);margin:0 0 1.2rem;max-width:720px}
|
||
code{background:#0e131b;border:1px solid var(--line);border-radius:6px;padding:1px 6px;font-family:ui-monospace,monospace;font-size:13px}
|
||
.ext{background:var(--panel);border:1px solid var(--line);border-radius:14px;padding:20px 22px;margin:1rem 0}
|
||
.ext h3{margin:0 0 .3rem;font-size:1.15rem;display:flex;align-items:center;gap:10px;flex-wrap:wrap}
|
||
.ext h3 .icon{font-size:1.4rem}
|
||
.ext .cur{color:var(--acid);font-size:12px;font-weight:600;letter-spacing:.14em;text-transform:uppercase}
|
||
.ext .desc{color:var(--mut);font-size:14px;margin:.3rem 0 .8rem}
|
||
.ext .verifybox{margin-top:.9rem;padding-top:.8rem;border-top:1px solid var(--line);font-size:11.5px;color:var(--dim)}
|
||
.ext .verifybox .lbl{color:var(--mut);font-size:12px;margin-bottom:6px}
|
||
.ext .h{display:flex;gap:8px;flex-wrap:wrap;align-items:baseline;margin-top:4px}
|
||
.ext .h b{color:var(--mut);font-weight:600;min-width:90px}
|
||
.ext .h code{font-family:ui-monospace,monospace;font-size:10.5px;color:#c9d4e3;word-break:break-all;background:transparent;border:none;padding:0}
|
||
.ext .meta{color:var(--dim);font-size:12.5px;margin-top:.4rem}
|
||
.btns{display:flex;gap:8px;flex-wrap:wrap;margin-top:.8rem}
|
||
.btn{display:inline-block;padding:.45rem .9rem;border-radius:9px;background:var(--acid);color:#0b0e14;font-weight:650;text-decoration:none;font-size:14px}
|
||
.btn.ghost{background:transparent;color:var(--ink);border:1px solid var(--line)}
|
||
.note{background:var(--panel);border:1px solid var(--line);border-left:3px solid var(--acid);border-radius:10px;padding:14px 18px;color:var(--mut);font-size:14px;margin:1.4rem 0}
|
||
.note b{color:var(--ink)}
|
||
footer{color:var(--dim);font-size:12.5px;margin:3rem 0 2rem;text-align:center}
|
||
footer a{color:var(--mut)}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<nav class="topnav">
|
||
<a class="brand" href="../">
|
||
<svg viewBox="0 0 64 64" aria-hidden="true">
|
||
<rect width="64" height="64" rx="12" fill="#0b0e14"/>
|
||
<path d="M32 6 L38 32 L26 32 Z" fill="#e04e4e"/>
|
||
<path d="M38 32 L32 58 L26 32 Z" fill="#d6ff3d"/>
|
||
<path d="M6 32 L32 27 L58 32 L32 37 Z" fill="#d6ff3d" opacity=".55"/>
|
||
<circle cx="32" cy="32" r="3" fill="#0b0e14"/>
|
||
</svg>
|
||
<span>Theseus<span class="g">.X</span></span>
|
||
</a>
|
||
<a href="../">Home</a>
|
||
<a class="here" href="./">Plug-ins</a>
|
||
<a href="../extensions/">Extensions</a>
|
||
<a href="https://sirius.x/" title="Register a BCNR name"><svg class="tabicon" viewBox="0 0 64 64" aria-hidden="true"><rect width="64" height="64" rx="12" fill="#0b0e14"/><path d="M32 4 L36.4 27.6 L60 32 L36.4 36.4 L32 60 L27.6 36.4 L4 32 L27.6 27.6 Z" fill="#d6ff3d"/></svg><span>Sirius<span class="g">.X</span></span></a>
|
||
<a class="get" href="../#download">Get Theseus</a>
|
||
</nav>
|
||
|
||
<aside class="sidenav" aria-label="On this page">
|
||
<a href="#aegis-section" title="Aegis wallet" ><span class="ic" aria-hidden="true"><svg viewBox="0 0 32 32" fill="none" width="20" height="20"><polygon points="16,2 28,9 28,23 16,30 4,23 4,9" fill="#0a0a0d" stroke="#D6FF3D" stroke-width="1.6" stroke-linejoin="round"/><circle cx="16" cy="16" r="4.5" fill="none" stroke="#D6FF3D" stroke-width="1.4"/><circle cx="16" cy="16" r="1.6" fill="#D6FF3D"/></svg></span><span class="lb">Aegis wallet</span></a>
|
||
<a href="#ariadne-section" title="Ariadne's Thread" ><span class="ic" aria-hidden="true">🧵</span><span class="lb">Ariadne's Thread</span></a>
|
||
<a href="#line" title="Plug-ins vs extensions"><span class="ic" aria-hidden="true">🧩</span><span class="lb">Plug-ins vs extensions</span></a>
|
||
</aside>
|
||
|
||
<header class="hero">
|
||
<h1>Theseus <span class="g">Plug-ins</span></h1>
|
||
<p class="tag">Silent Mode's own components that ship inside Theseus and appear under
|
||
<b>Settings › Plug-ins</b>: the wallet and the system-wide resolver. Community-made
|
||
add-ons live on the separate <a href="../extensions/">Extensions</a> page.</p>
|
||
</header>
|
||
|
||
<div class="wrap">
|
||
|
||
<section id="aegis-section">
|
||
<h2>Aegis — the wallet</h2>
|
||
<p class="lede">Multi-chain wallet derived from your Theseus vault (BCH, BTC, TRX, ETH, SOL, SC, DGB) with a
|
||
dApp bridge for the pages you visit. Bundled with every Theseus build and updated over a signed channel
|
||
between releases; the panel's own <i>Stage → Restart</i> flow applies an update without reinstalling Theseus.</p>
|
||
<div class="ext" id="aegis" data-channel="../extensions/aegis/updates.json">
|
||
<h3><span class="icon" style="font-size:0;line-height:0"><svg viewBox="0 0 32 32" fill="none" width="26" height="26" style="vertical-align:-6px"><polygon points="16,2 28,9 28,23 16,30 4,23 4,9" fill="#0a0a0d" stroke="#D6FF3D" stroke-width="1.6" stroke-linejoin="round"/><circle cx="16" cy="16" r="4.5" fill="none" stroke="#D6FF3D" stroke-width="1.4"/><circle cx="16" cy="16" r="1.6" fill="#D6FF3D"/></svg></span> Aegis <span class="cur" style="margin-left:auto">current <span data-live="version">0.6.31</span></span></h3>
|
||
<div class="desc">Vault-derived keys, per-chain accounts, imported keys, message signing, dApp permissions per site.</div>
|
||
<div class="meta">Plug-in · Settings › Plug-ins · <span data-live="count">signed versions on the channel</span></div>
|
||
<div class="verifybox">
|
||
<div class="lbl">Signed update manifest — Ed25519 by the Silent Mode operator, SHA-256 verified before install</div>
|
||
<div class="h"><b>updates.json</b><code><a href="../extensions/aegis/updates.json">theseus.x/extensions/aegis/updates.json</a></code></div>
|
||
<div class="h"><b>Tarball</b><code><a data-live="url" href="../extensions/aegis/">…</a></code></div>
|
||
<div class="h"><b>sha256</b><code data-live="sha256">—</code></div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section id="ariadne-section">
|
||
<h2>Ariadne's Thread — the system-wide resolver</h2>
|
||
<p class="lede">Makes BCDN names resolve for <em>every</em> program on the machine, not only Theseus: a local
|
||
DNS resolver plus gateway, installed by Theseus's setup by default (opt-out) and switchable from
|
||
<b>Settings › Plug-ins</b>. The same resolver ships standalone for Windows and as Ariadne for Android.</p>
|
||
<div class="ext" id="ariadne">
|
||
<h3><span class="icon">🧵</span> Ariadne's Thread <span class="cur" style="margin-left:auto">current <span data-live="resolver-version">0.1.3</span></span></h3>
|
||
<div class="desc">Windows service: answers A/AAAA for registered names, forwards everything else to your upstream
|
||
resolver, serves Sia-hosted content through a local gateway with a machine-local CA. Answers MX/TXT/NS from
|
||
owner-signed DNS records.</div>
|
||
<div class="meta">Plug-in · Settings › Plug-ins · Turn on / off · Install / Update / Uninstall from inside Theseus</div>
|
||
<div class="btns">
|
||
<a class="btn" href="https://dl.silentmode.st/latest/AriadneResolver-Setup.exe">Windows installer</a>
|
||
<a class="btn ghost" href="https://dl.silentmode.st/latest/ariadne.apk">Ariadne for Android (APK) · v<span data-live="android-version">0.19</span></a>
|
||
</div>
|
||
<div class="verifybox">
|
||
<div class="lbl">Hashes from the releases manifest — verify before running</div>
|
||
<div class="h"><b>Installer</b><code data-live="resolver-sha">—</code></div>
|
||
<div class="h"><b>APK</b><code data-live="android-sha">—</code></div>
|
||
<div class="h"><b>Manifest</b><code><a href="https://dl.silentmode.st/releases-manifest.json">dl.silentmode.st/releases-manifest.json</a></code></div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section id="line">
|
||
<h2>Where the line is</h2>
|
||
<p class="lede">Plug-ins are first-party: Silent Mode builds them, signs them with the operator key, and Theseus treats
|
||
them as part of itself (own Settings section, own update flow). Extensions are everyone else's: published by
|
||
any BCDN name holder, signed with that name's wallet, listed on <a href="../extensions/">theseus.x/extensions</a>
|
||
and installed from <b>Settings › Extensions</b>. Both are verified on your device before a byte runs.</p>
|
||
<div class="note"><b>Want to build one?</b> Start on the <a href="../extensions/#build">Extensions page</a> — the same add-on
|
||
format powers both, and publishing takes a name and a signature, nothing else.</div>
|
||
</section>
|
||
|
||
<footer>
|
||
Silent Mode · <a href="https://code.silentmode.st/silentmode/theseus/src/branch/master/TheseusNavigator/docs/ADDON-UPDATES.md">how signed updates work</a>
|
||
</footer>
|
||
|
||
</div>
|
||
|
||
<script>
|
||
(async () => {
|
||
const set = (k, f) => document.querySelectorAll('[data-live="' + k + '"]').forEach(f);
|
||
const cmp = (a, b) => { const x = String(a).split(".").map(Number), y = String(b).split(".").map(Number); for (let i = 0; i < Math.max(x.length, y.length); i++) { const d = (x[i] || 0) - (y[i] || 0); if (d) return d; } return 0; };
|
||
try {
|
||
const r = await fetch("../extensions/aegis/updates.json", { cache: "no-store" });
|
||
if (r.ok) {
|
||
const m = await r.json(); const list = (m.addons || []).slice().sort((x, y) => cmp(y.version, x.version)); const top = list[0];
|
||
if (top) {
|
||
set("version", (el) => { el.textContent = top.version; });
|
||
set("sha256", (el) => { el.textContent = top.sha256 || "—"; });
|
||
set("url", (el) => { el.href = top.url; el.textContent = String(top.url).split("/").pop(); });
|
||
set("count", (el) => { el.textContent = list.length + " signed version" + (list.length === 1 ? "" : "s") + " on the channel"; });
|
||
}
|
||
}
|
||
} catch {}
|
||
try {
|
||
const r = await fetch("https://dl.silentmode.st/releases-manifest.json", { cache: "no-store" });
|
||
if (r.ok) {
|
||
const m = await r.json(); const g = (id) => (m.releases || []).find((x) => x.id === id);
|
||
const res = g("ariadne-resolver"), an = g("ariadne-android");
|
||
if (res) { set("resolver-version", (el) => { el.textContent = res.version; }); const f = Object.keys(res.files || {})[0]; set("resolver-sha", (el) => { el.textContent = f ? res.files[f] : "—"; }); }
|
||
if (an) { set("android-version", (el) => { el.textContent = an.version; }); const f = Object.keys(an.files || {})[0]; set("android-sha", (el) => { el.textContent = f ? an.files[f] : "—"; }); }
|
||
}
|
||
} catch {}
|
||
})();
|
||
|
||
// Sidenav scroll-spy: highlight the section currently in view.
|
||
(() => {
|
||
const links = document.querySelectorAll(".sidenav a[href^='#']");
|
||
if (!links.length) return;
|
||
const map = new Map();
|
||
links.forEach((a) => { const el = document.querySelector(a.getAttribute("href")); if (el) map.set(el, a); });
|
||
const io = new IntersectionObserver((entries) => {
|
||
entries.forEach((en) => {
|
||
if (!en.isIntersecting) return;
|
||
const a = map.get(en.target); if (!a) return;
|
||
links.forEach((l) => l.classList.remove("active"));
|
||
a.classList.add("active");
|
||
});
|
||
}, { rootMargin: "-40% 0px -55% 0px", threshold: 0 });
|
||
map.forEach((_, el) => io.observe(el));
|
||
})();
|
||
</script>
|
||
</body>
|
||
</html>
|