refactor(cuprate-ui): align dashboard with bitcoin UI style

This commit is contained in:
archipelago
2026-09-12 16:14:55 -04:00
parent 86052d9552
commit ee11863ada
+27 -15
View File
@@ -56,6 +56,15 @@
.wrap { max-width: 1100px; margin: 0 auto; padding: 2rem 1rem 3rem; }
/* Match the Bitcoin dashboard's app-header rhythm: identity on the
left, compact live status cards on the right. */
.app-header { display:flex; align-items:center; justify-content:space-between; gap:1.5rem; flex-wrap:wrap; }
.app-header-id { display:flex; align-items:center; gap:1rem; min-width:0; }
.app-header-actions { display:flex; align-items:center; gap:.75rem; flex-wrap:wrap; }
.info-card { background:rgba(0,0,0,.6); backdrop-filter:blur(24px); border-radius:.75rem; padding:.65rem .85rem; box-shadow:inset 0 1px 0 rgba(255,255,255,.16); }
.node-mark { width:3.25rem; height:3.25rem; border-radius:.85rem; display:grid; place-items:center; background:linear-gradient(135deg,rgba(247,147,26,.35),rgba(247,147,26,.08)); border:1px solid rgba(247,147,26,.45); color:#f7931a; font-size:1.45rem; font-weight:800; }
@media (max-width:700px) { .app-header, .app-header-id, .app-header-actions { justify-content:center; } .app-header-text { text-align:center; } .app-header-actions > .info-card { flex:1 1 8rem; } }
header { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; margin-bottom: 1.5rem; }
header h1 { font-size: 1.6rem; font-weight: 700; letter-spacing: -0.02em; }
header h1 .accent { color: #f7931a; }
@@ -122,19 +131,26 @@
<body>
<div class="bg-layer"></div>
<div class="wrap">
<header>
<div>
<h1><span class="accent">Cuprate</span> Monero Node</h1>
<div class="sub">Rust implementation of the Monero protocol, on Archipelago</div>
<header class="glass-card" style="padding:1.5rem;">
<div class="app-header">
<div class="app-header-id">
<div class="node-mark" aria-hidden="true">C</div>
<div class="app-header-text">
<h1><span class="accent">Cuprate</span> Monero Node</h1>
<div class="sub">Rust implementation of the Monero protocol, on Archipelago</div>
</div>
</div>
<div class="app-header-actions">
<div class="info-card"><div class="sub">Status</div><span id="statusPill" class="pill"><span class="dot"></span><span id="statusText">Connecting…</span></span></div>
<div class="info-card"><div class="sub">Network</div><strong id="headerNetwork">—</strong></div>
<div class="info-card"><div class="sub">Height</div><strong id="headerHeight">—</strong></div>
</div>
</div>
<span id="statusPill" class="pill"><span class="dot"></span><span id="statusText">Connecting…</span></span>
</header>
<div id="offlineNotice" class="notice error" style="display:none;">
<b>Cuprate is not reachable.</b> The node is stopped, still installing, or was refused
by the disk-space gate — a Monero node cannot run pruned, so Archipelago keeps it off
disks too small to hold the full chain (~250&nbsp;GB and growing) rather than let it fill
the drive. Attach a larger disk and start it again.
<b>Cuprate is not reachable.</b> The node may be stopped, still installing, or syncing.
Check the service status and try again shortly.
</div>
<div class="grid" style="margin-top:1rem;">
@@ -167,12 +183,6 @@
<div class="stat"><span class="label">Difficulty</span><span class="value" id="difficulty">—</span></div>
<div class="stat"><span class="label">Chain size</span><span class="value" id="chainSize">—</span></div>
<div class="stat"><span class="label">Free disk</span><span class="value" id="freeSpace">—</span></div>
<div class="notice">
<b>Monero has no pruned mode.</b> Unlike the Bitcoin apps on this node — which
drop old block data automatically when disk is scarce — a cuprate node stores the
full chain. Archipelago therefore only runs it on disks of 450&nbsp;GB or more and
refuses it (with this explanation) anywhere smaller.
</div>
</div>
<div class="glass-card">
@@ -279,6 +289,8 @@
: info.stagenet ? 'Stagenet'
: (info.net || info.nettype || '—');
setStat('nettype', nettype);
document.getElementById('headerNetwork').textContent = nettype;
document.getElementById('headerHeight').textContent = tabular(height);
const nowSecs = info.time ?? info.adjusted_time ?? Math.floor(Date.now() / 1000);
const started = info.start_time ?? info.startup_time;