mirror of
https://github.com/luxfi/financial.git
synced 2026-10-30 16:55:56 +00:00
The demo tenant conceit is gone: mockups and the six animated screens brand as Lux with the triangle mark. The site drops Zen for the brand faces — Lux Sans for text, Lux Display for the hero, both vendored until @luxfi/font is on the registry. Screens record on pure black, and the showcase leads with a full-width frame. Co-authored-by: Hanzo Dev <[email protected]>
95 lines
6.9 KiB
HTML
95 lines
6.9 KiB
HTML
<!doctype html>
|
|
<html><head><meta charset="utf-8"><link rel="stylesheet" href="lib.css">
|
|
<style>
|
|
.cust-grid { display: grid; grid-template-columns: 1.4fr 1fr; gap: 20px; flex: 1; min-height: 0; }
|
|
.ceremony { display: flex; flex-direction: column; gap: 16px; justify-content: space-evenly; }
|
|
.shares { display: flex; justify-content: space-around; padding: 18px 0 6px; }
|
|
.share { display: flex; flex-direction: column; align-items: center; gap: 10px; }
|
|
.share .node {
|
|
width: 96px; height: 96px; border-radius: 24px;
|
|
background: var(--panel2); border: 1.5px solid var(--line2);
|
|
display: flex; align-items: center; justify-content: center;
|
|
font-size: 24px; transition: all 0.5s ease; position: relative;
|
|
}
|
|
.share .node svg { width: 38px; height: 38px; stroke: var(--ink3); fill: none; stroke-width: 1.6; transition: stroke 0.5s ease; }
|
|
.share.lit .node { border-color: var(--gold); box-shadow: 0 0 26px rgba(212, 175, 55, 0.35); }
|
|
.share.lit .node svg { stroke: var(--gold); }
|
|
.share .nm { font-size: 12px; font-weight: 600; color: var(--ink2); }
|
|
.share .loc { font-size: 10.5px; color: var(--ink3); }
|
|
.sigbar { height: 8px; border-radius: 99px; background: var(--panel2); border: 1px solid var(--line); overflow: hidden; }
|
|
.sigbar > div { height: 100%; width: 0; border-radius: 99px; background: linear-gradient(90deg, #8a6d1f, #e8cd6a); transition: width 1.2s cubic-bezier(0.4, 0, 0.2, 1); }
|
|
.sigrow { display: flex; justify-content: space-between; align-items: center; font-size: 12.5px; color: var(--ink2); }
|
|
.req { display: flex; justify-content: space-between; align-items: center; background: var(--panel2); border: 1px solid var(--line2); border-radius: 12px; padding: 14px 16px; }
|
|
.req .what { font-weight: 650; font-size: 13.5px; }
|
|
.req .sub { color: var(--ink3); font-size: 11.5px; margin-top: 3px; }
|
|
.row { grid-template-columns: 1.7fr 1fr 1fr 0.9fr; }
|
|
.thead { grid-template-columns: 1.7fr 1fr 1fr 0.9fr; }
|
|
.keyfact { display: flex; gap: 8px; align-items: baseline; font-size: 12px; color: var(--ink3); padding: 2px 4px; }
|
|
.keyfact b { color: var(--ink2); font-weight: 650; }
|
|
</style></head>
|
|
<body><div class="app">
|
|
<aside class="side">
|
|
<div class="brand"><div class="brand-mark">▼</div><div class="brand-name">Lux</div></div>
|
|
<div class="nav-item"><svg viewBox="0 0 24 24"><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/></svg>Dashboard</div>
|
|
<div class="nav-item active"><svg viewBox="0 0 24 24"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>Custody</div>
|
|
<div class="nav-item"><svg viewBox="0 0 24 24"><path d="M21 8v10a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8m18 0V6a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v2m18 0H3"/></svg>Wallets</div>
|
|
<div class="nav-item"><svg viewBox="0 0 24 24"><path d="M3 3v18h18"/><path d="M7 14l4-4 4 4 5-6"/></svg>Audit</div>
|
|
<div class="foot"><span class="env-dot"></span>MPC · 2-of-3 threshold</div>
|
|
</aside>
|
|
<main class="main">
|
|
<div class="topbar fx"><h1>MPC custody</h1><div class="who"><span class="pill"><span class="env-dot"></span>Signer set healthy</span><div class="avatar">LX</div></div></div>
|
|
<div class="cust-grid">
|
|
<div class="card ceremony fx">
|
|
<div class="label">Signing ceremony</div>
|
|
<div class="req">
|
|
<div><div class="what" id="reqw">Withdraw 12.5 BTC → cold vault</div><div class="sub">Policy: 2-of-3 shares · velocity limit OK · destination allowlisted</div></div>
|
|
<span class="tag wait" id="reqtag">Awaiting shares</span>
|
|
</div>
|
|
<div class="shares">
|
|
<div class="share" id="sh1"><div class="node"><svg viewBox="0 0 24 24"><path d="M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4"/></svg></div><span class="nm">Share A</span><span class="loc">HSM · NY4</span></div>
|
|
<div class="share" id="sh2"><div class="node"><svg viewBox="0 0 24 24"><path d="M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4"/></svg></div><span class="nm">Share B</span><span class="loc">KMS · Zurich</span></div>
|
|
<div class="share" id="sh3"><div class="node"><svg viewBox="0 0 24 24"><path d="M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4"/></svg></div><span class="nm">Share C</span><span class="loc">Mobile · client</span></div>
|
|
</div>
|
|
<div class="sigrow"><span>Threshold signature — CGGMP21</span><span class="mono" id="sigpct">0%</span></div>
|
|
<div class="sigbar"><div id="sig"></div></div>
|
|
<div class="keyfact"><b>The full private key never exists.</b><span>Shares compute the signature together; no machine ever holds the key.</span></div>
|
|
</div>
|
|
<div class="table fx" style="flex:none;">
|
|
<div class="thead"><span>Event</span><span>Asset</span><span>Policy</span><span>Result</span></div>
|
|
<div id="audit"></div>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
</div>
|
|
<script>
|
|
const $ = (id) => document.getElementById(id);
|
|
const audit = [
|
|
['Withdraw → cold vault', '12.5 BTC', '2-of-3', 'ok', 'Signed'],
|
|
['Bridge transfer', '250K USDC', '2-of-3', 'ok', 'Signed'],
|
|
['Key rotation', 'Vault #4', 'quorum', 'ok', 'Rotated'],
|
|
['Withdraw attempt', '80 ETH', 'velocity', 'bad', 'Blocked'],
|
|
['Staking delegation', '10K LUX', '2-of-3', 'ok', 'Signed'],
|
|
];
|
|
function addAudit([ev, asset, pol, cls, res], flash) {
|
|
const d = document.createElement('div');
|
|
d.className = 'row' + (flash ? ' flash' : '');
|
|
d.style.gridTemplateColumns = '1.7fr 1fr 1fr 0.9fr';
|
|
d.innerHTML = `<span>${ev}</span><span class="mono" style="color:var(--ink2)">${asset}</span><span style="color:var(--ink3);font-size:12px;">${pol}</span><span class="tag ${cls}">${res}</span>`;
|
|
$('audit').prepend(d);
|
|
while ($('audit').children.length > 6) $('audit').lastChild.remove();
|
|
}
|
|
function cycle() {
|
|
document.querySelectorAll('.fx').forEach((el, i) => { el.classList.remove('in'); setTimeout(() => el.classList.add('in'), 80 + i * 110); });
|
|
['sh1','sh2','sh3'].forEach(id => $(id).classList.remove('lit'));
|
|
$('sig').style.width = '0%'; $('sigpct').textContent = '0%';
|
|
$('reqtag').className = 'tag wait'; $('reqtag').textContent = 'Awaiting shares';
|
|
$('audit').innerHTML = '';
|
|
audit.slice(1).reverse().forEach(r => addAudit(r, false));
|
|
setTimeout(() => $('sh1').classList.add('lit'), 1800);
|
|
setTimeout(() => { $('sh3').classList.add('lit'); $('sig').style.width = '55%'; $('sigpct').textContent = '55%'; }, 2900);
|
|
setTimeout(() => { $('sig').style.width = '100%'; $('sigpct').textContent = '100%'; }, 4100);
|
|
setTimeout(() => { $('reqtag').className = 'tag ok'; $('reqtag').textContent = 'Signed ✓'; addAudit(audit[0], true); }, 5400);
|
|
}
|
|
cycle(); setInterval(cycle, 8000);
|
|
</script></body></html>
|