Terminology (user-facing labels now match the product/registry distinction): - BCDN = Bitcoin Cash Domain Names (the product — what you view) - BCNR = Bitcoin Cash Name Registry (the on-chain system that backs it) Chrome badge, popover, Settings section and 'Open with…' prompt all show BCDN for a resolved name. BCNR stays only where the registry itself is the subject. 'Open with…' prompt (collision.html): - Larger window (640x520, was 480x340) - Radio-select pattern with explicit Open / Cancel buttons (was auto-fire on click) - Enter = Open, Esc = Cancel, keyboard-first - Body copy per operator spec (no product-name-in-parens; blockchain-generic) - Card titles kept short: 'BCNR / BCDN' + 'ICANN / IANA' Address-bar chip: - Says BCDN (not BCNR) for on-chain names; ICANN for web - Dropped the '·.tld' suffix — TLD is already in the URL bar - On collision candidates: shows BOTH chips (BCDN | ICANN) with active highlighted; clicking the inactive one flips the tab (via collision-switch) Settings section renamed Naming → Registries. Copy rewritten in the same BCDN/BCNR frame; policy labels are now 'BCDN first' / 'ICANN first' / 'Ask each time'. Passive 'also on BCNR' bar copy updated to BCDN. Verified: all preload/settings/main/chrome JS + HTML parse; no secrets in staging.
116 lines
6.7 KiB
HTML
116 lines
6.7 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%; 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; }
|
|
.host { color:var(--fg); font-weight:600; }
|
|
.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; }
|
|
.choice:hover { background:var(--btn-hover); }
|
|
.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; }
|
|
</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" 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>
|
|
<div class="desc">DNS service coordinated by the ICANN. The registry served by the incumbent root.</div>
|
|
</div>
|
|
</div>
|
|
|
|
<fieldset>
|
|
<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>
|
|
</fieldset>
|
|
|
|
<div class="actions">
|
|
<button class="act" id="cancel">Cancel<kbd>Esc</kbd></button>
|
|
<button class="act primary" id="confirm">Open<kbd>Enter</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.title = "Open " + host + " with…";
|
|
|
|
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");
|
|
}
|
|
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); } });
|
|
}
|
|
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);
|
|
document.addEventListener("keydown", (e) => {
|
|
if (e.key === "Escape") cancel();
|
|
if (e.key === "Enter" && e.target.tagName !== "BUTTON") confirm();
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|