2026-08-02 11:39:00 +02:00
<!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; }
2026-08-02 13:02:47 +02:00
html, body { margin:0; height:100%; overflow:hidden; }
body { background:var(--bg); color:var(--fg); font:15px/1.45 system-ui,-apple-system,Segoe UI,Roboto,sans-serif; display:flex; flex-direction:column; padding:26px 34px; }
h1 { margin:0 0 6px; font-size:18px; font-weight:600; }
.sub { color:var(--muted); font-size:13.5px; margin-bottom:22px; }
2026-08-02 11:39:00 +02:00
.host { color:var(--fg); font-weight:600; }
2026-08-02 13:02:47 +02:00
.choices { display:grid; grid-template-columns:1fr 1fr; gap:14px; margin-bottom:22px; }
.choice { border:2px solid var(--border); border-radius:10px; padding:18px; background:var(--btn); text-align:left; color:var(--fg); cursor:pointer; transition: border-color .12s, background .12s; }
2026-08-02 11:39:00 +02:00
.choice:hover { background:var(--btn-hover); }
2026-08-02 13:02:47 +02:00
.choice.sel.bcdn { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, var(--btn)); }
.choice.sel.icann { border-color: var(--icann); background: color-mix(in srgb, var(--icann) 12%, var(--btn)); }
.choice .head { display:flex; align-items:center; gap:10px; margin-bottom:8px; }
.choice .radio { flex:none; width:16px; height:16px; border-radius:50%; border:2px solid var(--border); position:relative; }
.choice.sel.bcdn .radio { border-color: var(--accent); background: radial-gradient(circle, var(--accent) 40%, transparent 42%); }
.choice.sel.icann .radio { border-color: var(--icann); background: radial-gradient(circle, var(--icann) 40%, transparent 42%); }
.choice .icon { font-size:20px; line-height:1; }
.choice .title { font-weight:600; font-size:15px; }
.choice.bcdn .title { color: var(--accent); }
.choice.icann .title { color: var(--icann); }
.choice .desc { font-size:13px; color:var(--muted); }
fieldset { border:0; padding:0; margin:0 0 22px; display:flex; flex-direction:column; gap:8px; }
fieldset legend { color:var(--muted); font-size:12.5px; padding:0; margin-bottom:6px; text-transform:uppercase; letter-spacing:.03em; }
fieldset .row { display:flex; align-items:center; gap:9px; font-size:13.5px; padding:2px 0; }
fieldset .row input { accent-color:var(--accent); width:15px; height:15px; }
fieldset .row label { color:var(--fg); cursor:pointer; }
.actions { display:flex; justify-content:flex-end; gap:10px; margin-top:auto; }
button.act { border:1px solid var(--border); background:var(--btn); color:var(--fg); padding:10px 20px; border-radius:8px; font-size:14px; cursor:pointer; }
button.act:hover { background: var(--btn-hover); }
button.act.primary { background:var(--accent); color:#111; border-color:var(--accent); font-weight:600; }
button.act.primary:hover { filter:brightness(1.05); }
kbd { border:1px solid var(--border); border-radius:3px; padding:0 5px; font:11px monospace; color:var(--muted); margin-left:6px; }
2026-08-02 11:39:00 +02:00
< / 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 >
2026-08-02 13:02:47 +02:00
< div class = "choices" id = "choices" >
< div class = "choice bcdn sel" data-choice = "bcdn" tabindex = "0" >
< div class = "head" >
< span class = "radio" > < / span > < span class = "icon" > ⛓< / span >
< span class = "title" > BCNR / BCDN< / span >
< / div >
< div class = "desc" > On-chain registration. Owned by the holder of a digital name certificate. The registry served by the blockchain root.< / div >
< / div >
< div class = "choice icann" data-choice = "icann" tabindex = "0" >
< div class = "head" >
< span class = "radio" > < / span > < span class = "icon" > 🌐< / span >
< span class = "title" > ICANN / IANA< / span >
< / div >
2026-08-02 11:39:00 +02:00
< div class = "desc" > DNS service coordinated by the ICANN. The registry served by the incumbent root.< / div >
2026-08-02 13:02:47 +02:00
< / div >
2026-08-02 11:39:00 +02:00
< / div >
< fieldset >
2026-08-02 13:02:47 +02:00
< legend > Remember this choice< / legend >
< div class = "row" > < input type = "radio" name = "remember" id = "rem-no" value = "no" checked > < label for = "rem-no" > Ask again next time< / label > < / div >
< div class = "row" > < input type = "radio" name = "remember" id = "rem-name" value = "name" > < label for = "rem-name" > Always use 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 for all < span id = "tld" > < / span > names< / label > < / div >
2026-08-02 11:39:00 +02:00
< / fieldset >
< div class = "actions" >
2026-08-02 13:02:47 +02:00
< button class = "act" id = "cancel" > Cancel< kbd > Esc< / kbd > < / button >
< button class = "act primary" id = "confirm" > Open< kbd > Enter< / kbd > < / button >
2026-08-02 11:39:00 +02:00
< / 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.title = "Open " + host + " with…";
2026-08-02 13:02:47 +02:00
let choice = "bcdn"; // default preselected
const bcdnEl = document.querySelector('.choice[data-choice="bcdn"]');
const icannEl = document.querySelector('.choice[data-choice="icann"]');
function select(c) {
choice = c;
bcdnEl.classList.toggle("sel", c === "bcdn");
icannEl.classList.toggle("sel", c === "icann");
2026-08-02 11:39:00 +02:00
}
2026-08-02 13:02:47 +02:00
for (const el of [bcdnEl, icannEl]) {
el.addEventListener("click", () => select(el.dataset.choice));
el.addEventListener("keydown", (e) => { if (e.key === " " || e.key === "Enter") { e.preventDefault(); select(el.dataset.choice); } });
2026-08-02 11:39:00 +02:00
}
2026-08-02 13:02:47 +02:00
function remember() { return document.querySelector('input[name="remember"]:checked')?.value || "no"; }
function confirm() {
// Map "bcdn" (user-facing) -> "bcnr" (internal key used by main.js/collisions.json)
window.collisionApi.choose(host, { choice: choice === "bcdn" ? "bcnr" : "icann", remember: remember() });
}
function cancel() { window.collisionApi.choose(host, { choice: "cancel", remember: "no" }); }
document.getElementById("confirm").addEventListener("click", confirm);
document.getElementById("cancel").addEventListener("click", cancel);
2026-08-02 11:39:00 +02:00
document.addEventListener("keydown", (e) => {
2026-08-02 13:02:47 +02:00
if (e.key === "Escape") cancel();
if (e.key === "Enter" & & e.target.tagName !== "BUTTON") confirm();
2026-08-02 11:39:00 +02:00
});
< / script >
< / body >
< / html >