theseus/collision.html
Local Dev d0db4ac495 Collision modes (BCNR/ICANN) + root TLD cert + VPS electrum-source indexer
Theseus soft-mode UX: 'Open with...' modal on collision, per-name/per-TLD
overrides, live per-tab switcher in the site-info popover, and a Naming section
in Settings for policy + reset. Backed by an on-chain root TLD certificate
(tlds.bch) that resolver-web.js discovers via fetchBcnrTlds()/isBcnrNativeTld().

Companion pieces:
- Argus/src/indexer/ELECTRUM-SOURCE-README.md — the featherweight VPS variant
  (no BCHN node, no Fulcrum) now live as bns-indexer.service.
- Argus/DESIGN-root-tld-cert.md — clarified: NOT a governance workflow, just
  ordinary key management (single wallet MVP -> 2-of-3 multisig). List gates
  registration / surgical NRPT / soft-mode classifier — never resolution.
- ROADMAP-IDEAS.md — recorded SiaGit/GitHub.sia + user-friendly Sia UI ideas.

Full spec: Argus/DESIGN-collision-modes.md (already tracked).
2026-08-02 11:39:00 +02:00

94 lines
4.8 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Open with…</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style>
:root {
color-scheme: dark light;
--bg:#0f1116; --fg:#e5e7eb; --muted:#9ca3af; --border:#2a2f3a;
--btn:#1f2430; --btn-hover:#2a3040; --accent:#f5c518; --icann:#4c9eff;
}
@media (prefers-color-scheme: light) {
:root { --bg:#f7f7f8; --fg:#111827; --muted:#6b7280; --border:#e5e7eb; --btn:#fff; --btn-hover:#f0f2f5; }
}
* { box-sizing: border-box; }
html, body { margin:0; height:100%; }
body { background:var(--bg); color:var(--fg); font:14px/1.4 system-ui,-apple-system,Segoe UI,Roboto,sans-serif; display:flex; flex-direction:column; padding:16px 18px; }
h1 { margin:0 0 4px; font-size:15px; font-weight:600; }
.sub { color:var(--muted); font-size:12.5px; margin-bottom:14px; }
.host { color:var(--fg); font-weight:600; }
.choices { display:grid; grid-template-columns:1fr 1fr; gap:10px; margin-bottom:12px; }
.choice { border:1px solid var(--border); border-radius:8px; padding:12px; cursor:pointer; background:var(--btn); text-align:left; color:var(--fg); }
.choice:hover { background:var(--btn-hover); }
.choice .icon { font-size:20px; }
.choice .title { font-weight:600; margin:6px 0 2px; }
.choice .desc { font-size:11.5px; color:var(--muted); }
.choice.bcnr .icon, .choice.bcnr .title { color:var(--accent); }
.choice.icann .icon, .choice.icann .title { color:var(--icann); }
fieldset { border:0; padding:0; margin:0 0 10px; }
fieldset .row { display:flex; align-items:center; gap:8px; padding:4px 0; font-size:12.5px; color:var(--muted); }
fieldset .row input { accent-color:var(--accent); }
.actions { display:flex; justify-content:flex-end; gap:8px; margin-top:auto; }
button.cancel { background:transparent; color:var(--muted); border:0; padding:8px 12px; cursor:pointer; }
button.cancel:hover { color:var(--fg); }
kbd { border:1px solid var(--border); border-radius:3px; padding:0 4px; font:11px monospace; color:var(--muted); }
</style>
</head>
<body>
<h1><span class="host" id="host"></span> exists in two registries</h1>
<div class="sub">Choose which one to open. You can change this later in Settings.</div>
<div class="choices">
<button class="choice bcnr" data-choice="bcnr" title="Open the on-chain name">
<div class="icon"></div>
<div class="title">Bitcoin Cash Name Registry</div>
<div class="desc">On-chain registration (BCNR). Owned by the holder of a name certificate on the Bitcoin Cash Blockchain.</div>
</button>
<button class="choice icann" data-choice="icann" title="Open the ICANN-served address">
<div class="icon">🌐</div>
<div class="title">ICANN / IANA</div>
<div class="desc">DNS service coordinated by the ICANN. The registry served by the incumbent root.</div>
</button>
</div>
<fieldset>
<div class="row"><input type="radio" name="remember" id="rem-no" value="no" checked><label for="rem-no">Ask again</label></div>
<div class="row"><input type="radio" name="remember" id="rem-name" value="name"><label for="rem-name">Always use this choice for <span class="host" id="host2"></span></label></div>
<div class="row"><input type="radio" name="remember" id="rem-tld" value="tld"><label for="rem-tld">Always use this choice for all <span id="tld2"></span> names</label></div>
</fieldset>
<div class="actions">
<button class="cancel" id="cancel">Cancel <kbd>Esc</kbd></button>
</div>
<script>
const qs = new URLSearchParams(location.search);
const host = qs.get("host") || ""; const tld = qs.get("tld") || "";
document.getElementById("host").textContent = host;
document.getElementById("host2").textContent = host;
document.getElementById("tld").textContent = "." + tld;
document.getElementById("tld2").textContent = "." + tld;
document.title = "Open " + host + " with…";
function remember() {
const r = document.querySelector('input[name="remember"]:checked');
return r ? r.value : "no";
}
for (const btn of document.querySelectorAll(".choice")) {
btn.addEventListener("click", () => {
window.collisionApi.choose(host, { choice: btn.dataset.choice, remember: remember() });
});
}
document.getElementById("cancel").addEventListener("click", () => {
window.collisionApi.choose(host, { choice: "cancel", remember: "no" });
});
document.addEventListener("keydown", (e) => {
if (e.key === "Escape") window.collisionApi.choose(host, { choice: "cancel", remember: "no" });
if (e.key === "1") window.collisionApi.choose(host, { choice: "bcnr", remember: remember() });
if (e.key === "2") window.collisionApi.choose(host, { choice: "icann", remember: remember() });
});
</script>
</body>
</html>