The dashboard was capped at 1200px with single-column lists, so a 1920px display showed a narrow strip of cards. Above 1280px it now widens to 1720px with a 260px sidebar, name/TLD lists become card grids (auto-fill, 360-400px columns), and Settings and TLD detail lay their cards out in two or three columns. Narrow screens are unchanged. The header Dashboard button was hidden until sign-in, which left new visitors with no obvious way in; it is now always shown and lands on the portal's sign-in when signed out. Also closes a Settings-pane markup bug: the Wallet card ended one div early, which pushed the "Reading, language & help" and "This device" cards outside the pane so they appeared under every other pane.
669 lines
43 KiB
HTML
669 lines
43 KiB
HTML
<!doctype html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<title>Dashboard — your names on Sirius.X</title>
|
||
<meta name="description" content="Manage every BCNR name and TLD your wallet holds: DNS records, content, redirects, transfers, TLD pricing. Your keys never leave the browser.">
|
||
<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="Sirius.X">
|
||
<meta property="og:title" content="Sirius.X dashboard — your BCNR names">
|
||
<meta property="og:description" content="Manage DNS, content, redirects and TLD policy for every name your wallet holds. Keys never leave the browser.">
|
||
<meta property="og:url" content="https://silentmode.st/sirius-x/portal.html">
|
||
<meta property="og:image" content="https://silentmode.st/sirius-x/brand/banner.svg">
|
||
<meta name="twitter:card" content="summary">
|
||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||
<link href="https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,300;9..144,400;9..144,500;9..144,600;9..144,700&family=DM+Sans:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&family=Ubuntu:wght@400;500;700&display=swap" rel="stylesheet">
|
||
<style>
|
||
:root{
|
||
--bg:#050810; --panel:#141a24; --panel2:#0a0f1c; --line:rgba(255,255,255,.06);
|
||
--sky-mid:#0a0f1c; --sky-rim:#131a2a;
|
||
--ink:#f1f4fa; --mut:#b8c2d4; --dim:#6a7488; --acid:#d6ff3d;
|
||
--chain-native:#0AC18E;
|
||
--ok:#4fd1a5; --taken:#f6768a; --warn:#ffc75f;
|
||
--serif:'Fraunces',Georgia,serif;
|
||
--sans:'DM Sans','Inter',system-ui,sans-serif;
|
||
--mono:'JetBrains Mono',ui-monospace,monospace;
|
||
}
|
||
*{box-sizing:border-box}
|
||
body{margin:0;
|
||
background:radial-gradient(ellipse 1200px 600px at 50% -5%,var(--sky-rim) 0%,transparent 60%),
|
||
radial-gradient(ellipse 900px 500px at 100% 100%,var(--sky-mid) 0%,transparent 55%),
|
||
radial-gradient(ellipse 900px 500px at 0% 100%,#0c1424 0%,transparent 55%),
|
||
var(--bg);
|
||
background-attachment:fixed;
|
||
color:var(--ink);font:15px/1.55 var(--sans);min-height:100vh;font-feature-settings:"ss01","ss02"}
|
||
h1,h2,h3{font-family:var(--serif);font-feature-settings:"ss01","ss02"}
|
||
code,.mono{font-family:var(--mono)}
|
||
html[data-font-cmp="ubuntu"] body,
|
||
html[data-font-cmp="ubuntu"] h1, html[data-font-cmp="ubuntu"] h2, html[data-font-cmp="ubuntu"] h3,
|
||
html[data-font-cmp="ubuntu"] p, html[data-font-cmp="ubuntu"] a, html[data-font-cmp="ubuntu"] button,
|
||
html[data-font-cmp="ubuntu"] span, html[data-font-cmp="ubuntu"] div,
|
||
html[data-font-cmp="ubuntu"] label, html[data-font-cmp="ubuntu"] input, html[data-font-cmp="ubuntu"] li{
|
||
font-family:'Ubuntu',system-ui,sans-serif !important
|
||
}
|
||
html[data-font-cmp="ubuntu"] code, html[data-font-cmp="ubuntu"] .mono{font-family:var(--mono) !important}
|
||
.font-picker{display:inline-flex;align-items:center;gap:2px;padding:2px;margin:0 10px;
|
||
background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.08);border-radius:999px;
|
||
font-family:var(--mono);font-size:10px;letter-spacing:.12em;text-transform:uppercase}
|
||
.font-picker button{background:transparent;border:none;color:var(--dim);
|
||
padding:4px 10px;border-radius:999px;cursor:pointer;font-family:inherit;font-size:inherit;
|
||
letter-spacing:inherit;text-transform:inherit;transition:color .12s}
|
||
.font-picker button:hover{color:var(--ink)}
|
||
.font-picker button.active{background:var(--acid);color:var(--bg);font-weight:600}
|
||
a{color:var(--acid)}
|
||
.wrap{max-width:820px;margin:0 auto;padding:0 1.2rem}
|
||
.topnav{position:sticky;top:0;z-index:20;display:flex;gap:2px;align-items:center;flex-wrap:wrap;
|
||
padding:10px 1.2rem;background:rgba(11,14,20,.82);backdrop-filter:blur(10px);border-bottom:1px solid var(--line)}
|
||
.topnav .brand{font-weight:600;color:var(--ink);text-decoration:none;margin-right:14px;font-size:15px;letter-spacing:.2px}
|
||
.topnav .brand .g{color:var(--acid)}
|
||
.topnav a{color:var(--mut);text-decoration:none;padding:6px 12px;border-radius:8px;font-size:14px}
|
||
.topnav a:hover{color:var(--ink);background:var(--panel)}
|
||
.topnav a.here{color:var(--acid);background:rgba(214,255,61,.08)}
|
||
.topnav a.portal{margin-left:auto;background:rgba(214,255,61,.10);color:var(--acid);font-weight:500}
|
||
.topnav a.portal:hover{background:rgba(214,255,61,.18)}
|
||
header.hero{text-align:center;padding:3rem 1.2rem 1rem}
|
||
.mark{font-size:44px;line-height:1}
|
||
h1{font-size:clamp(1.6rem,4.5vw,2.2rem);margin:.3rem 0 .3rem}
|
||
h1 .g{color:var(--acid)}
|
||
.tag{color:var(--mut);font-size:1rem;max-width:580px;margin:0 auto}
|
||
h2{font-size:1.35rem;margin:0 0 .3rem}
|
||
h3{font-size:1.05rem;margin:0 0 .3rem}
|
||
section{padding:2rem 0;border-top:1px solid var(--line);margin-top:2rem}
|
||
section:first-of-type{border-top:none;margin-top:1rem}
|
||
.card{background:var(--panel);border:1px solid var(--line);border-radius:14px;padding:20px 22px;margin-top:1rem}
|
||
label{display:block;font-size:13px;color:var(--mut);margin:14px 0 5px}
|
||
textarea,input[type=password],input[type=text],input[type=number],select{
|
||
width:100%;padding:10px 12px;border-radius:10px;border:1px solid #ffffff22;background:#0e131b;
|
||
color:var(--ink);font-size:14px;font-family:inherit;outline:none
|
||
}
|
||
select{appearance:auto}
|
||
textarea{min-height:74px;resize:vertical;font-family:var(--mono);font-size:13px}
|
||
textarea:focus,input:focus,select:focus{border-color:#4b7bec}
|
||
.btn{display:inline-flex;align-items:center;gap:6px;text-decoration:none;padding:9px 16px;border-radius:10px;background:#4b7bec;color:#fff;font-size:14px;border:none;cursor:pointer;font-family:inherit;line-height:1.2}
|
||
.btn.ghost{background:transparent;border:1px solid var(--line);color:var(--ink)}
|
||
.btn.acid{background:var(--acid);color:#0b0e14;font-weight:600}
|
||
.btn.danger{background:rgba(246,118,138,.14);color:var(--taken);border:1px solid rgba(246,118,138,.35)}
|
||
.btn.small{padding:6px 11px;font-size:12.5px}
|
||
.btn:hover{filter:brightness(1.12)}
|
||
.btn:disabled{opacity:.45;cursor:not-allowed;filter:none}
|
||
.row{display:flex;gap:10px;flex-wrap:wrap;margin-top:14px;align-items:center}
|
||
.row.end{justify-content:flex-end}
|
||
.row.between{justify-content:space-between}
|
||
.muted{color:var(--mut);font-size:13px}
|
||
.dim{color:var(--dim);font-size:12.5px}
|
||
code,.mono{background:#0e131b;border:1px solid var(--line);border-radius:6px;padding:1px 6px;font-family:var(--mono);font-size:12.5px;word-break:break-all}
|
||
.badge{display:inline-block;font-size:11px;padding:2px 9px;border-radius:999px;font-weight:600;line-height:1.6}
|
||
.b-x{background:rgba(214,255,61,.14);color:var(--acid)}
|
||
.b-warn{background:rgba(255,199,95,.14);color:var(--warn)}
|
||
.b-ok{background:rgba(79,209,165,.14);color:var(--ok)}
|
||
.b-off{background:rgba(246,118,138,.14);color:var(--taken)}
|
||
.b-dim{background:rgba(255,255,255,.06);color:var(--mut)}
|
||
.err{color:var(--taken);font-size:13.5px;margin-top:10px}
|
||
.status{background:var(--panel2);border:1px solid var(--line);border-radius:10px;padding:10px 14px;font-size:13px;color:var(--mut);margin-top:12px}
|
||
.status.ok{border-left:3px solid var(--ok)}
|
||
.status.err{border-left:3px solid var(--taken);color:var(--taken)}
|
||
.hidden{display:none !important}
|
||
|
||
/* ---------- dashboard shell ---------- */
|
||
.dash{display:grid;grid-template-columns:236px minmax(0,1fr);gap:26px;max-width:1200px;margin:0 auto;padding:1.4rem 1.2rem 3rem}
|
||
/* wide screens: let the dashboard use the width — wider sidebar, card
|
||
grids for the lists, two-column settings / TLD detail. Text blocks keep
|
||
a readable measure via .ph p max-width. */
|
||
@media (min-width:1280px){
|
||
.dash{max-width:1720px;grid-template-columns:260px minmax(0,1fr);gap:34px;padding:1.6rem 2rem 3rem}
|
||
.list.cols{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:10px;margin-top:8px}
|
||
.list.cols .drow{margin-top:0;align-content:start}
|
||
.list.cols > .empty,.list.cols > .status{grid-column:1/-1}
|
||
.grid2{grid-template-columns:repeat(auto-fit,minmax(340px,1fr))}
|
||
.pane[data-pane="settings"]:not([hidden]),.pane[data-pane="tld"]:not([hidden]){display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px;align-content:start}
|
||
.pane[data-pane="settings"] > .ph,.pane[data-pane="tld"] > .crumbs,.pane[data-pane="tld"] > .dhead,.pane[data-pane="tld"] > .msg,.pane[data-pane="tld"] > .grid2{grid-column:1/-1}
|
||
.pane[data-pane="settings"] > .card,.pane[data-pane="tld"] > .card{margin-top:0}
|
||
.pane[data-pane="tld"] > .msg:empty{display:none}
|
||
.pane[data-pane="domain"] .sub[data-sub="summary"] > .grid2{grid-template-columns:repeat(2,minmax(0,1fr))}
|
||
.pane[data-pane="newtld"] .card{max-width:760px !important}
|
||
}
|
||
@media (min-width:1700px){
|
||
.list.cols{grid-template-columns:repeat(auto-fill,minmax(400px,1fr))}
|
||
.pane[data-pane="settings"]:not([hidden]){grid-template-columns:repeat(3,minmax(0,1fr))}
|
||
}
|
||
.side{position:sticky;top:68px;align-self:start;display:flex;flex-direction:column;gap:4px}
|
||
.side .who{padding:12px 14px;border-radius:12px;background:var(--panel);border:1px solid var(--line);margin-bottom:8px}
|
||
.side .who .lbl{font-family:var(--mono);font-size:10px;letter-spacing:.2em;text-transform:uppercase;color:var(--dim)}
|
||
.side .who .addr{font-family:var(--mono);font-size:12px;color:var(--ink);word-break:break-all;margin-top:4px}
|
||
.side .who .net{font-size:11.5px;color:var(--dim);margin-top:4px}
|
||
.side .grp{font-family:var(--mono);font-size:10px;letter-spacing:.2em;text-transform:uppercase;color:var(--dim);padding:12px 14px 4px}
|
||
.side button.item,.side a.item{display:flex;align-items:center;gap:10px;width:100%;text-align:left;padding:9px 12px;border-radius:10px;
|
||
background:transparent;border:1px solid transparent;color:var(--mut);font:inherit;font-size:14px;cursor:pointer;text-decoration:none;transition:all .12s}
|
||
.side .item .ic{width:20px;text-align:center;flex:none;opacity:.9}
|
||
.side .item .cnt{margin-left:auto;font-family:var(--mono);font-size:11px;padding:1px 7px;border-radius:999px;background:rgba(255,255,255,.08);color:var(--ink)}
|
||
.side .item:hover{color:var(--ink);background:rgba(255,255,255,.04)}
|
||
.side .item.active{color:var(--acid);background:rgba(214,255,61,.08);border-color:rgba(214,255,61,.18)}
|
||
.side .item.active .cnt{background:rgba(214,255,61,.2);color:var(--acid)}
|
||
.side .sep{height:1px;background:var(--line);margin:8px 0}
|
||
.content{min-width:0}
|
||
.pane{animation:paneIn .18s ease-out}
|
||
.pane[hidden]{display:none}
|
||
@keyframes paneIn{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}
|
||
.ph{display:flex;align-items:flex-end;justify-content:space-between;gap:12px;flex-wrap:wrap;margin-bottom:.6rem}
|
||
.ph p{margin:.2rem 0 0;color:var(--mut);font-size:13.5px;max-width:720px}
|
||
.crumbs{font-size:13px;color:var(--dim);margin-bottom:8px}
|
||
.crumbs a{color:var(--mut);text-decoration:none}
|
||
.crumbs a:hover{color:var(--ink)}
|
||
|
||
/* stats */
|
||
.stat-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:12px;margin-top:1rem}
|
||
.stat{background:var(--panel);border:1px solid var(--line);border-radius:14px;padding:16px 18px}
|
||
.stat .lbl{font-family:var(--mono);font-size:10.5px;letter-spacing:.22em;text-transform:uppercase;color:var(--dim);margin-bottom:8px;display:flex;align-items:center;gap:6px}
|
||
.stat .lbl:before{content:"";width:5px;height:5px;background:var(--acid);border-radius:50%}
|
||
.stat .val{font-family:var(--serif);font-size:30px;font-weight:600;color:var(--ink);letter-spacing:-.01em;line-height:1}
|
||
.stat .sub{color:var(--mut);font-size:12.5px;margin-top:4px}
|
||
|
||
/* toolbar + lists */
|
||
.toolbar{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin:10px 0 6px}
|
||
.toolbar input[type=text]{max-width:320px}
|
||
.toolbar select{width:auto;padding:8px 30px 8px 10px;font-size:13px}
|
||
.list{margin-top:6px}
|
||
.drow{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:8px 14px;align-items:center;padding:13px 16px;
|
||
background:var(--panel2);border:1px solid var(--line);border-radius:12px;margin-top:8px;cursor:pointer;transition:border-color .12s,background .12s}
|
||
.drow:hover{border-color:rgba(214,255,61,.3);background:#0c1220}
|
||
.drow .n{font-family:var(--mono);font-size:15px;color:var(--ink);display:flex;align-items:center;gap:8px;flex-wrap:wrap}
|
||
.drow .n .tld{color:var(--acid)}
|
||
.drow .meta{grid-column:1/-1;display:flex;gap:6px;flex-wrap:wrap;align-items:center;color:var(--mut);font-size:12px}
|
||
.drow .acts{display:flex;gap:6px;flex-wrap:wrap;justify-content:flex-end}
|
||
.empty{padding:26px 20px;text-align:center;color:var(--mut);border:1px dashed var(--line);border-radius:12px;margin-top:10px}
|
||
|
||
/* detail */
|
||
.dhead{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
|
||
.dhead h2{font-family:var(--mono);font-size:1.5rem;margin:0}
|
||
.subtabs{display:flex;gap:4px;flex-wrap:wrap;border-bottom:1px solid var(--line);margin:14px 0 16px}
|
||
.subtabs button{background:transparent;border:0;border-bottom:2px solid transparent;color:var(--mut);padding:9px 12px;font:inherit;font-size:13.5px;cursor:pointer;margin-bottom:-1px}
|
||
.subtabs button:hover{color:var(--ink)}
|
||
.subtabs button.active{color:var(--acid);border-bottom-color:var(--acid)}
|
||
.kv{display:grid;grid-template-columns:160px minmax(0,1fr);gap:8px 14px;font-size:13.5px;margin-top:10px}
|
||
.kv .k{color:var(--dim)}
|
||
.kv .v{word-break:break-all}
|
||
.kv .v code{font-size:12px}
|
||
.grid2{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px}
|
||
.card h3{margin-top:0}
|
||
.card .hint{color:var(--dim);font-size:12.5px;margin:2px 0 0}
|
||
.field-hint{color:var(--dim);font-size:11.5px;margin-left:8px;text-transform:none;letter-spacing:0}
|
||
.budget{display:flex;justify-content:space-between;align-items:center;font-size:12px;color:var(--mut);margin-top:14px;padding:8px 12px;background:var(--panel2);border-radius:8px}
|
||
.budget.over{background:rgba(246,118,138,.15);color:var(--taken)}
|
||
.steps-log{margin-top:12px;font-family:var(--mono);font-size:12px;color:var(--mut);background:#0e131b;border:1px solid var(--line);border-radius:8px;padding:10px 12px;max-height:140px;overflow-y:auto;display:none}
|
||
.steps-log.on{display:block}
|
||
.steps-log div::before{content:"› ";color:var(--acid)}
|
||
.msg{font-size:13px;margin-top:12px}
|
||
.msg.err{color:var(--taken)} .msg.ok{color:var(--ok)}
|
||
|
||
/* DNS table */
|
||
.tbl{width:100%;border-collapse:separate;border-spacing:0;margin-top:10px;font-size:13px}
|
||
.tbl th{font-family:var(--mono);font-size:10.5px;letter-spacing:.18em;text-transform:uppercase;color:var(--dim);text-align:left;padding:8px 10px;border-bottom:1px solid var(--line)}
|
||
.tbl td{padding:9px 10px;border-bottom:1px solid var(--line);vertical-align:middle}
|
||
.tbl td.t{font-family:var(--mono);color:var(--acid);width:80px}
|
||
.tbl td.v{font-family:var(--mono);word-break:break-all}
|
||
.tbl td.p{color:var(--mut);white-space:nowrap}
|
||
.tbl td.a{text-align:right;white-space:nowrap}
|
||
.tbl .x{background:none;border:0;color:var(--dim);cursor:pointer;font-size:16px;padding:2px 6px}
|
||
.tbl .x:hover{color:var(--taken)}
|
||
.addrow{display:grid;grid-template-columns:110px minmax(0,1fr) 90px 90px 90px auto;gap:8px;align-items:end;margin-top:12px;padding:12px;background:var(--panel2);border:1px solid var(--line);border-radius:10px}
|
||
.addrow label{margin:0 0 4px;font-size:11px;text-transform:uppercase;letter-spacing:.08em}
|
||
.addrow input,.addrow select{padding:8px 10px;font-size:13px}
|
||
.addrow .opt[hidden]{display:none}
|
||
.toggle{display:flex;align-items:flex-start;gap:12px;padding:12px 0;border-bottom:1px solid var(--line)}
|
||
.toggle:last-child{border-bottom:0}
|
||
.toggle .txt b{display:block;font-weight:600;font-size:14px}
|
||
.toggle .txt span{color:var(--mut);font-size:12.5px}
|
||
.toggle input[type=checkbox]{width:18px;height:18px;margin-top:3px;accent-color:var(--acid);flex:none}
|
||
.pill{display:inline-block;font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;padding:2px 8px;border-radius:999px;background:rgba(255,255,255,.06);color:var(--dim);margin-left:8px;vertical-align:middle}
|
||
|
||
/* modals kept for policy editing */
|
||
.modal{position:fixed;inset:0;background:rgba(6,9,14,.82);backdrop-filter:blur(3px);
|
||
display:none;align-items:flex-start;justify-content:center;padding:3vh 1rem;overflow-y:auto;z-index:50}
|
||
.modal.open{display:flex}
|
||
.sheet{background:var(--panel);border:1px solid var(--line);border-radius:16px;max-width:620px;width:100%;padding:24px 26px;position:relative}
|
||
.sheet h3{margin:0 0 .3rem;font-size:1.15rem;font-family:var(--mono)}
|
||
.sheet .sub{color:var(--mut);font-size:13px;margin:0 0 1.2rem}
|
||
.sheet .x{position:absolute;top:14px;right:16px;background:none;border:none;color:var(--dim);font-size:22px;cursor:pointer;line-height:1}
|
||
.sheet label{display:block;font-size:12px;color:var(--mut);margin:12px 0 4px;text-transform:uppercase;letter-spacing:.4px}
|
||
.sheet input[type=text],.sheet textarea,.sheet select{width:100%;padding:9px 12px;border-radius:8px;border:1px solid #ffffff22;background:#0e131b;color:var(--ink);font-size:13px;font-family:var(--mono);outline:none}
|
||
.sheet textarea{min-height:60px;resize:vertical}
|
||
.sheet .actions{display:flex;gap:10px;justify-content:flex-end;margin-top:16px}
|
||
footer{border-top:1px solid var(--line);padding:2rem 0 3rem;color:var(--dim);font-size:13px;text-align:center;margin-top:2.5rem}
|
||
@media (max-width:900px){
|
||
.dash{grid-template-columns:1fr;gap:14px}
|
||
.side{position:static;flex-direction:row;flex-wrap:wrap;gap:6px}
|
||
.side .who,.side .grp,.side .sep{display:none}
|
||
.side .item{width:auto;padding:7px 11px;font-size:13px}
|
||
.kv{grid-template-columns:1fr}
|
||
.addrow{grid-template-columns:1fr 1fr}
|
||
}
|
||
</style>
|
||
<script src="./js/i18n.js?v=20260917h"></script>
|
||
</head>
|
||
<body>
|
||
|
||
<nav class="topnav">
|
||
<a class="brand" href="./">⭐ <span class="g">Sirius.X</span></a>
|
||
<a href="./#try">Try it</a>
|
||
<a href="./#search-input">✏️ Register</a>
|
||
<a href="./tld.html">🌐 TLD</a>
|
||
<a href="./market.html">🛒 Market</a>
|
||
<a href="./theseus/"><svg width="14" height="14" viewBox="0 0 64 64" style="vertical-align:-2px;margin-right:4px" 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"/><circle cx="32" cy="32" r="3" fill="#0b0e14"/></svg>Theseus</a>
|
||
<a href="./portal.html" class="portal here">🔑 Sign in</a>
|
||
</nav>
|
||
|
||
<!-- ============ signed-out: hero + inline sign-in ============ -->
|
||
<div id="signed-out">
|
||
<header class="hero">
|
||
<div class="mark">🔑</div>
|
||
<h1>Your <span class="g">names</span> dashboard</h1>
|
||
<p class="tag">Sign in once with your Bitcoin Cash seed phrase or connect an external wallet. This device
|
||
stays signed in until you sign out — no passwords on every visit. Your keys never leave this browser.</p>
|
||
</header>
|
||
<div class="wrap">
|
||
<section id="signin">
|
||
<h2>Sign in or create a wallet</h2>
|
||
<p class="muted">The same wallet that will hold your names does the signing. Pick a tab —
|
||
everything happens on this page; keys never leave your browser.</p>
|
||
<div id="signin-inline" style="margin-top:1rem"></div>
|
||
<div id="signin-err" class="err hidden"></div>
|
||
</section>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ============ signed-in: dashboard ============ -->
|
||
<div id="me" class="dash hidden">
|
||
<aside class="side" aria-label="Dashboard menu">
|
||
<div class="who">
|
||
<div class="lbl">Signed in</div>
|
||
<div class="addr" id="side-addr">—</div>
|
||
<div class="net">chipnet · <span id="side-balance">—</span> sat</div>
|
||
</div>
|
||
<button class="item" data-go="studio"><span class="ic">🎨</span>Web-Builder</button>
|
||
<button class="item active" data-go="domains"><span class="ic">🌐</span>Domain names<span class="cnt" id="cnt-names">0</span></button>
|
||
<button class="item" data-go="tlds"><span class="ic">🏷</span>My TLDs<span class="cnt" id="cnt-tlds">0</span></button>
|
||
<div class="sep"></div>
|
||
<button class="item" data-go="settings"><span class="ic">⚙</span>Settings</button>
|
||
<a class="item hidden" id="side-admin" href="./admin/"><span class="ic">🛠</span>Admin panel</a>
|
||
<button class="item" id="side-signout"><span class="ic">🚪</span>Sign out</button>
|
||
</aside>
|
||
|
||
<main class="content">
|
||
|
||
<!-- WEB-BUILDER -->
|
||
<div class="pane" data-pane="studio" hidden>
|
||
<div class="ph"><div><h2>Web-Builder</h2><p>Sirius Studio builds a site for any name you hold: drag blocks, edit text, publish. Pages live in the name's own folder on Sia and the name points at them — no host, no renewal.</p></div>
|
||
<div class="row" style="margin:0"><button class="btn ghost small" id="refresh-btn">↻ Refresh</button></div></div>
|
||
<div class="status" id="studio-status">Loading names from the chain…</div>
|
||
<div id="studio-list" class="list cols"></div>
|
||
</div>
|
||
|
||
<!-- DOMAINS -->
|
||
<div class="pane" data-pane="domains">
|
||
<div class="ph"><div><h2>Domain names</h2><p>Every BCNR name this wallet holds. Open one to manage DNS, content, redirects or transfer it.</p></div>
|
||
<a class="btn acid small" href="./#search-input">+ Register a name</a></div>
|
||
<div id="ov-attention" class="list" style="margin-bottom:6px"></div>
|
||
<div class="toolbar">
|
||
<input type="text" id="dom-search" placeholder="Filter names…" autocomplete="off">
|
||
<select id="dom-sort"><option value="name">Sort: name</option><option value="tld">Sort: TLD</option><option value="height">Sort: newest</option></select>
|
||
<select id="dom-tld"><option value="">All TLDs</option></select>
|
||
<span class="dim" id="dom-count"></span>
|
||
</div>
|
||
<div class="status" id="names-status">Loading names from the chain…</div>
|
||
<div id="names-list" class="list cols"></div>
|
||
</div>
|
||
|
||
<!-- DOMAIN DETAIL -->
|
||
<div class="pane" data-pane="domain" hidden>
|
||
<div class="crumbs"><a href="#domains" data-go="domains">Domain names</a> › <span id="dd-crumb">—</span></div>
|
||
<div class="dhead">
|
||
<h2 id="dd-name">—</h2>
|
||
<span class="badge b-x">on chain</span>
|
||
<span class="badge b-dim" id="dd-dnsbadge">no DNS</span>
|
||
<span style="margin-left:auto" class="row" style="margin:0">
|
||
<a class="btn ghost small" id="dd-view" href="#" target="_blank" rel="noopener">Open site →</a>
|
||
</span>
|
||
</div>
|
||
<div class="subtabs" role="tablist">
|
||
<button data-sub="summary" class="active">Summary</button>
|
||
<button data-sub="dns">DNS records</button>
|
||
<button data-sub="content">Content & hosting</button>
|
||
<button data-sub="redirect">Redirect</button>
|
||
<button data-sub="transfer">Transfer</button>
|
||
<button data-sub="sell">Sell</button>
|
||
<button data-sub="export">Export</button>
|
||
</div>
|
||
|
||
<div class="sub" data-sub="sell" hidden>
|
||
<div class="card" style="margin-top:0">
|
||
<h3>Sell this name</h3>
|
||
<p class="hint">You sign an offer once: "whoever pays me this price gets the certificate". The offer is stored by the gateway and shown on the <a href="./market.html" target="_blank" rel="noopener">market</a>. A buyer completes it in one transaction — you are paid in the same transaction that moves the name, or not at all. No escrow, nothing to trust.</p>
|
||
<div class="status" id="sell-status">Checking the market…</div>
|
||
<div id="sell-form">
|
||
<div class="row" style="align-items:flex-end">
|
||
<div><label style="margin-top:0">Price (USD)</label><input type="text" id="sell-usd" placeholder="25" inputmode="decimal" style="max-width:160px"></div>
|
||
<div><label style="margin-top:0">Price (sat)</label><input type="text" id="sell-sats" placeholder="6250000" inputmode="numeric" style="max-width:200px"></div>
|
||
<span class="dim" id="sell-rate"></span>
|
||
</div>
|
||
<div class="row end"><button class="btn acid" id="sell-list">List for sale →</button></div>
|
||
</div>
|
||
<div id="sell-active" class="hidden">
|
||
<div class="kv" id="sell-kv"></div>
|
||
<div class="row end">
|
||
<button class="btn danger" id="sell-cancel">Cancel listing →</button>
|
||
</div>
|
||
<p class="hint">Cancelling removes the offer from the market and moves your certificate once (a no-op update, a few cents), so the signed offer can never be completed later.</p>
|
||
</div>
|
||
<div class="steps-log" id="sell-log"></div>
|
||
<div class="msg" id="sell-msg"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="sub" data-sub="summary">
|
||
<div class="grid2">
|
||
<div class="card" style="margin-top:0">
|
||
<h3>Certificate</h3>
|
||
<div class="kv" id="dd-kv"></div>
|
||
</div>
|
||
<div class="card" style="margin-top:0">
|
||
<h3>Where it points</h3>
|
||
<p class="hint">On-chain records decide what a resolver serves. Change them under Content & hosting.</p>
|
||
<div class="kv" id="dd-records"></div>
|
||
</div>
|
||
</div>
|
||
<div class="card">
|
||
<h3>DNS at a glance</h3>
|
||
<p class="hint">Signed off-chain records for mail, verification and classic DNS interop.</p>
|
||
<div id="dd-dns-summary" class="muted" style="margin-top:8px">—</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="sub" data-sub="dns" hidden>
|
||
<div class="card" style="margin-top:0">
|
||
<div class="row between" style="margin:0">
|
||
<div><h3 style="margin:0">DNS records</h3>
|
||
<p class="hint">Standard records, signed by your key and stored in a manifest on Sia. Free to edit, no chain transaction. Resolvers and the gateway verify the signature against the current NFT holder.</p></div>
|
||
<span class="badge b-dim" id="dns-seq">seq —</span>
|
||
</div>
|
||
<table class="tbl" id="dns-table">
|
||
<thead><tr><th>Type</th><th>Value</th><th>Priority / extra</th><th></th></tr></thead>
|
||
<tbody></tbody>
|
||
</table>
|
||
<div class="empty hidden" id="dns-empty">No DNS records yet. Add the first one below.</div>
|
||
<div class="addrow">
|
||
<div><label>Type</label>
|
||
<select id="dns-type">
|
||
<option>A</option><option>AAAA</option><option>CNAME</option><option>MX</option>
|
||
<option>TXT</option><option>NS</option><option>SRV</option><option>CAA</option>
|
||
</select></div>
|
||
<div><label id="dns-value-label">Value</label><input type="text" id="dns-value" placeholder="1.2.3.4" autocomplete="off" spellcheck="false"></div>
|
||
<div class="opt" data-for="MX SRV"><label>Priority</label><input type="number" id="dns-prio" min="0" placeholder="10"></div>
|
||
<div class="opt" data-for="SRV"><label>Weight</label><input type="number" id="dns-weight" min="0" placeholder="0"></div>
|
||
<div class="opt" data-for="SRV"><label>Port</label><input type="number" id="dns-port" min="0" placeholder="443"></div>
|
||
<div class="opt" data-for="CAA"><label>Tag</label><select id="dns-tag"><option>issue</option><option>issuewild</option><option>iodef</option></select></div>
|
||
<div><label> </label><button class="btn small" id="dns-add">+ Add</button></div>
|
||
</div>
|
||
<div class="dim" id="dns-help" style="margin-top:8px"></div>
|
||
<div class="steps-log" id="dns-log"></div>
|
||
<div class="msg" id="dns-msg"></div>
|
||
<div class="row end">
|
||
<button class="btn ghost" id="dns-reload">Discard changes</button>
|
||
<button class="btn acid" id="dns-publish">Sign & publish →</button>
|
||
</div>
|
||
</div>
|
||
<div class="card">
|
||
<h3>Nameservers</h3>
|
||
<p class="hint">BCNR names do not need nameservers — resolvers read the chain and this manifest directly. Add NS records above only if you also delegate this name in classic DNS.</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="sub" data-sub="content" hidden>
|
||
<div class="card" style="margin-top:0">
|
||
<h3>Content & hosting</h3>
|
||
<p class="hint">On-chain records, published as one signed UPD transaction (a few cents of chain dust). Leave a field blank to drop that record. Precedence for resolvers: h, then s3, then p, then ip.</p>
|
||
<label>h <span class="field-hint">inline HTML — served as-is at the site root (~150 bytes)</span></label>
|
||
<textarea id="ct-h" placeholder="<h1>My site</h1>"></textarea>
|
||
<label>s3 <span class="field-hint">Sia bucket key, trailing slash for directories — also where DNS manifests live</span></label>
|
||
<input type="text" id="ct-s3" placeholder="bns/myname/">
|
||
<label>p <span class="field-hint">reverse proxy: full upstream URL the gateway mirrors</span></label>
|
||
<input type="text" id="ct-p" placeholder="https://origin.example.com">
|
||
<label>ip <span class="field-hint">IPv4 that serves this name over Host header</span></label>
|
||
<input type="text" id="ct-ip" placeholder="1.2.3.4">
|
||
<label>tls <span class="field-hint">SHA-256 of your leaf cert — chain-pinned TLS trust</span></label>
|
||
<input type="text" id="ct-tls" placeholder="hex — 64 chars, no separators">
|
||
<div class="budget" id="ct-budget">payload: <b><span id="ct-budget-used">0</span></b> / <span id="ct-budget-max">?</span> bytes</div>
|
||
<div class="steps-log" id="ct-log"></div>
|
||
<div class="msg" id="ct-msg"></div>
|
||
<div class="row end">
|
||
<button class="btn ghost" id="ct-reset">Reset</button>
|
||
<button class="btn acid" id="ct-save">Save records →</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="sub" data-sub="redirect" hidden>
|
||
<div class="card" style="margin-top:0">
|
||
<h3>Redirect</h3>
|
||
<p class="hint">Forward this name to any web address. Stored on chain as the <b>u</b> record; resolvers and the gateway issue the redirect. Clear it to stop forwarding.</p>
|
||
<label>Destination URL</label>
|
||
<input type="text" id="rd-url" placeholder="https://example.com/">
|
||
<div class="steps-log" id="rd-log"></div>
|
||
<div class="msg" id="rd-msg"></div>
|
||
<div class="row end">
|
||
<button class="btn ghost" id="rd-clear">Remove redirect</button>
|
||
<button class="btn acid" id="rd-save">Save redirect →</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="sub" data-sub="transfer" hidden>
|
||
<div class="card" style="margin-top:0">
|
||
<h3>Transfer ownership</h3>
|
||
<p class="hint">Moves the name's certificate to another Bitcoin Cash address in one transaction. Records stay as they are. The new holder controls the name from that moment — this cannot be undone from here.</p>
|
||
<label>Recipient address <span class="field-hint">bchtest:… (chipnet)</span></label>
|
||
<input type="text" id="tr-addr" placeholder="bchtest:q…" autocomplete="off" spellcheck="false">
|
||
<label style="display:flex;align-items:center;gap:8px;margin-top:12px"><input type="checkbox" id="tr-ack" style="width:16px;height:16px;accent-color:var(--acid)"> I understand this hands the name to that address permanently.</label>
|
||
<div class="steps-log" id="tr-log"></div>
|
||
<div class="msg" id="tr-msg"></div>
|
||
<div class="row end"><button class="btn danger" id="tr-send" disabled>Transfer name →</button></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="sub" data-sub="export" hidden>
|
||
<div class="card" style="margin-top:0">
|
||
<h3>Export</h3>
|
||
<p class="hint">Download this name's DNS as a BIND-style zone file, or its full record set as JSON, for backups or importing elsewhere.</p>
|
||
<div class="row">
|
||
<button class="btn ghost small" id="ex-zone">⬇ Zone file (.txt)</button>
|
||
<button class="btn ghost small" id="ex-json">⬇ Records (.json)</button>
|
||
<button class="btn ghost small" id="ex-copy">Copy DNS manifest</button>
|
||
</div>
|
||
<pre class="mono" id="ex-preview" style="margin-top:12px;padding:12px;white-space:pre-wrap;font-size:12px;max-height:280px;overflow:auto"></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- TLDs -->
|
||
<div class="pane" data-pane="tlds" hidden>
|
||
<div class="ph"><div><h2>My TLDs</h2><p>Every per-TLD registry NFT this wallet holds. Set the price every name under a TLD sells for, switch it on or off (off = private: only you can register under it), and tune policy. Each change is one signed TUPD on chain; you receive 90% of every sale.</p></div>
|
||
<button class="btn acid small" data-go="newtld">+ Register a TLD</button></div>
|
||
<div class="status" id="tlds-status">Loading TLDs from the chain…</div>
|
||
<div id="tlds-list" class="list cols"></div>
|
||
</div>
|
||
|
||
<!-- TLD DETAIL -->
|
||
<div class="pane" data-pane="tld" hidden>
|
||
<div class="crumbs"><a href="#tlds" data-go="tlds">My TLDs</a> › <span id="td-crumb">—</span></div>
|
||
<div class="dhead">
|
||
<h2 id="td-name">.—</h2>
|
||
<span class="badge" id="td-state">on</span>
|
||
<span class="badge b-x" id="td-price">tier pricing</span>
|
||
<span style="margin-left:auto"></span>
|
||
<button class="btn ghost small" id="td-toggle">Switch off</button>
|
||
<button class="btn acid small" id="td-policy">Price & policy</button>
|
||
</div>
|
||
<div class="msg" id="td-msg"></div>
|
||
<div class="grid2" style="margin-top:14px">
|
||
<div class="card" style="margin-top:0">
|
||
<h3>Registry</h3>
|
||
<div class="kv" id="td-kv"></div>
|
||
</div>
|
||
<div class="card" style="margin-top:0">
|
||
<h3>Register a name under this TLD</h3>
|
||
<p class="hint">Works whether the TLD is on or off. As the owner you pay only the platform's 10% share.</p>
|
||
<div class="row" style="margin-top:10px">
|
||
<input type="text" id="td-label" placeholder="label" maxlength="32" autocomplete="off" spellcheck="false" style="max-width:220px">
|
||
<span class="mono" id="td-suffix">.—</span>
|
||
<button class="btn small acid" id="td-register">Register →</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="card" id="td-cosign-card">
|
||
<h3>Pending approvals</h3>
|
||
<p class="hint">Registrations under this TLD that wait for your co-signature. Approving signs your TLD certificate into the buyer's transaction and broadcasts it; the certificate returns to you in the same transaction. Nothing can be registered under a co-sign or private TLD without this step.</p>
|
||
<div id="td-cosign" class="list"></div>
|
||
<div class="msg" id="td-cosign-msg"></div>
|
||
</div>
|
||
<div class="card">
|
||
<h3>Names registered under this TLD</h3>
|
||
<p class="hint">Everyone's registrations, from the public registry.</p>
|
||
<div id="td-names" class="list cols"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- NEW TLD -->
|
||
<div class="pane" data-pane="newtld" hidden>
|
||
<div class="ph"><div><h2>Register a TLD</h2><p>TLDs are per-registry NFTs on the chipnet TLD beacon. Public mints pay a service fee that funds the registry. Chipnet uses a placeholder rate; mainnet prices by label length via a real oracle.</p></div></div>
|
||
<div class="card" id="tld-register-card" style="margin-top:0;max-width:640px">
|
||
<label>Label <span class="dim" style="margin-left:6px">1–16 chars, [a-z0-9-]</span></label>
|
||
<input type="text" id="tld-label" placeholder="myregistry" autocomplete="off" spellcheck="false" maxlength="16">
|
||
<label style="margin-top:12px">Service fee (USD) <span class="dim" style="margin-left:6px">chipnet test rate</span></label>
|
||
<input type="text" id="tld-usd" value="5">
|
||
<div class="status" id="tld-price">= <b>0</b> sats · rate <b>0</b> sats/USD</div>
|
||
<div class="row">
|
||
<button class="btn ghost small" id="tld-check" disabled>Check availability</button>
|
||
<button class="btn acid small" id="tld-submit" disabled>Register (~0 sats)</button>
|
||
</div>
|
||
<div id="tld-log" class="status" style="display:none;font-family:var(--mono);font-size:12.5px;margin-top:12px"></div>
|
||
<div id="tld-msg" style="margin-top:10px;font-size:13.5px"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- SETTINGS -->
|
||
<div class="pane" data-pane="settings" hidden>
|
||
<div class="ph"><div><h2>Settings</h2><p>Session, security and wallet details for this browser. Nothing here changes what is on chain.</p></div></div>
|
||
<div class="card" style="margin-top:0">
|
||
<h3>Session</h3>
|
||
<div class="toggle"><input type="checkbox" id="set-stay"><div class="txt"><b>Stay signed in on this device</b><span>Your recovery phrase is kept encrypted under a key this browser holds and cannot export. Next visits open the dashboard straight away. Turn off to be asked for your password or PIN every time.</span></div></div>
|
||
<div class="toggle"><input type="checkbox" id="set-pinpay"><div class="txt"><b>Ask for PIN before payments</b><span>Adds a PIN prompt when registering a name or TLD. Off by default so signed-in sessions run uninterrupted.</span></div></div>
|
||
<div class="row">
|
||
<button class="btn ghost small" id="set-setpin">Set / change PIN</button>
|
||
<button class="btn ghost small" id="set-clearpin">Remove PIN</button>
|
||
<span class="dim" id="set-pinstate"></span>
|
||
</div>
|
||
</div>
|
||
<div class="card">
|
||
<h3>Wallet</h3>
|
||
<p class="hint">Your addresses and current balance. Keys stay in this browser.</p>
|
||
<label>Receive address <span class="dim" style="margin-left:6px">chipnet</span></label>
|
||
<div><code id="me-addr">—</code> <button class="btn ghost small" data-copy="me-addr">Copy</button></div>
|
||
<label style="margin-top:14px">Token address <span class="dim" style="margin-left:6px">holds your name certificates</span></label>
|
||
<div><code id="me-taddr">—</code> <button class="btn ghost small" data-copy="me-taddr">Copy</button></div>
|
||
<div class="row between">
|
||
<span class="dim" id="me-info">—</span>
|
||
<span class="row" style="margin:0">
|
||
<a class="btn ghost small" href="https://tbch.googol.cash/" target="_blank" rel="noopener">Faucet →</a>
|
||
<a class="btn ghost small" href="https://chipnet.imaginary.cash/faucet" target="_blank" rel="noopener">Faucet 2 →</a>
|
||
</span>
|
||
</div>
|
||
<div class="kv" style="margin-top:14px"><div class="k">Spendable</div><div class="v" id="w-sats">—</div><div class="k">UTXOs</div><div class="v" id="w-utxos">—</div><div class="k">Watched addresses</div><div class="v" id="w-watched">—</div><div class="k">Chain height</div><div class="v" id="stat-height">—</div></div>
|
||
</div>
|
||
<div class="card">
|
||
<h3>Reading, language & help</h3>
|
||
<p class="hint">Font pill and language picker live in the top bar; both are remembered per browser. The technical documentation is at <a href="./docs/" target="_blank" rel="noopener">sirius-x/docs</a>.</p>
|
||
</div>
|
||
<div class="card">
|
||
<h3>This device</h3>
|
||
<p class="hint">Sign out keeps the encrypted wallet on this device so you can unlock it later. Forget removes it entirely — you will need your recovery phrase to come back.</p>
|
||
<div class="row">
|
||
<button class="btn ghost small" id="set-signout">Sign out</button>
|
||
<button class="btn danger small" id="set-forget">Forget wallet on this device</button>
|
||
</div>
|
||
<div class="msg" id="set-msg"></div>
|
||
</div>
|
||
</div>
|
||
|
||
</main>
|
||
</div>
|
||
|
||
<!-- TLD-policy editor modal — signs a TUPD against the TREG NFT. -->
|
||
<div class="modal" id="tld-editor">
|
||
<div class="sheet">
|
||
<button class="x" id="tld-ed-close" title="close">×</button>
|
||
<h3>Policy for <span id="tld-ed-name" style="color:var(--acid);font-family:var(--mono)">.—</span></h3>
|
||
<p class="sub">Set policy for names registered under this TLD. Only your key can sign this TUPD;
|
||
the transaction fee is a few cents in chain dust. Leave a field blank to omit that policy
|
||
(defaults apply — open policy, tier pricing).</p>
|
||
<label>price <span class="field-hint">USD per name — flat, shown to every buyer; blank = length tiers. You receive 90% of each sale.</span></label>
|
||
<input type="text" id="tld-ed-price" placeholder="7" inputmode="decimal">
|
||
<label>listing <span class="field-hint">off hides the TLD from search and blocks new registrations until you switch it back on</span></label>
|
||
<select id="tld-ed-hidden">
|
||
<option value="">On — listed, names for sale</option>
|
||
<option value="1">Off — hidden, not for sale</option>
|
||
</select>
|
||
<label>min_len <span class="field-hint">reject names shorter than N chars</span></label>
|
||
<input type="text" id="tld-ed-minlen" placeholder="1">
|
||
<label>fee_bps <span class="field-hint">service fee owner takes, in basis points (500 = 5%)</span></label>
|
||
<input type="text" id="tld-ed-feebps" placeholder="500">
|
||
<label>policy <span class="field-hint">open · frozen · reserved-only</span></label>
|
||
<input type="text" id="tld-ed-policy" placeholder="open">
|
||
<label>reserved <span class="field-hint">space-separated labels only owner can mint</span></label>
|
||
<input type="text" id="tld-ed-reserved" placeholder="admin root bank">
|
||
<label>renewal_period <span class="field-hint">days between renewals, 0 = never expire</span></label>
|
||
<input type="text" id="tld-ed-renewal" placeholder="0">
|
||
<label>renewal_fee <span class="field-hint">renewal price in sats, 0 = free</span></label>
|
||
<input type="text" id="tld-ed-renewalfee" placeholder="0">
|
||
<label>site <span class="field-hint">where the TLD's own landing lives</span></label>
|
||
<input type="text" id="tld-ed-site" placeholder="https://silentmode.st/…">
|
||
<div class="budget" id="tld-ed-budget">payload: <b><span id="tld-ed-budget-used">0</span></b> / <span id="tld-ed-budget-max">?</span> bytes</div>
|
||
<div class="steps-log" id="tld-ed-log"></div>
|
||
<div class="msg" id="tld-ed-msg"></div>
|
||
<div class="actions">
|
||
<button class="btn ghost" id="tld-ed-cancel">Cancel</button>
|
||
<button class="btn acid" id="tld-ed-save">Save policy →</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- PIN setup modal (Settings) -->
|
||
<div class="modal" id="pin-modal">
|
||
<div class="sheet" style="max-width:440px">
|
||
<button class="x" id="pin-close" title="close">×</button>
|
||
<h3>Set a PIN</h3>
|
||
<p class="sub">4–6 digits. Encrypts your recovery phrase under this PIN on this device. Three wrong PINs clear it and fall back to your password.</p>
|
||
<label>PIN</label><input type="text" id="pin-1" inputmode="numeric" pattern="[0-9]*" maxlength="6" autocomplete="off">
|
||
<label>Repeat PIN</label><input type="text" id="pin-2" inputmode="numeric" pattern="[0-9]*" maxlength="6" autocomplete="off">
|
||
<div class="msg" id="pin-msg"></div>
|
||
<div class="actions"><button class="btn ghost" id="pin-cancel">Cancel</button><button class="btn acid" id="pin-save">Save PIN →</button></div>
|
||
</div>
|
||
</div>
|
||
|
||
<footer id="site-footer"></footer>
|
||
|
||
<script type="importmap">
|
||
{ "imports": { "@bitauth/libauth": "https://silentmode.st/js/libauth.js" } }
|
||
</script>
|
||
<script src="./js/session.js?v=20260917dash"></script>
|
||
<script src="./js/pin-escrow.js?v=20260909pin"></script>
|
||
<script src="./js/pricing.js?v=20260917market"></script>
|
||
<script type="module" src="./js/dashboard.js?v=20260917market"></script>
|
||
<script defer src="./js/theme.js?v=20260910font"></script>
|
||
<script defer src="./js/site-footer.js?v=20260917market"></script>
|
||
<script type="module" src="./js/register-flow.js?v=20260917market"></script>
|
||
<script defer src="./js/profile-menu.js?v=20260917wide"></script>
|
||
</body>
|
||
</html>
|