Refine branding and default to dark theme

This commit is contained in:
Codex committed 2026-10-05 01:29:49 +00:00
1 parent acd2652046
commit 0405452ab2
5 files changed
+15 -8

No files matched your search

+3 -3
View File
@@ -4,16 +4,16 @@
<meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="theme-color" content="#f7931a">
<meta name="description" content="A private Bitcoin playground. Mine fake coins, inscribe a thought, and follow it into a block.">
<title>Super Testnet — your little Bitcoin universe</title>
<title>Super Testnet — your own little Bitcoin universe</title>
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
</head>
<body>
<header>
<a class="brand" href="#"><span class="mark">S↗</span> SUPER TESTNET <span class="version">v0</span></a>
<a class="brand" href="#"><span class="mark" aria-hidden="true"></span> SUPER TESTNET <span class="version">v0</span></a>
<div class="header-actions"><span class="network"><i></i> PRIVATE LOCAL CHAIN</span><button id="theme-toggle" class="theme-toggle quiet" type="button" aria-label="Toggle color theme">☀ Light</button></div>
</header>
<main>
<section class="hero"><div><p class="eyebrow">BITCOIN, WITH ROOM TO EXPERIMENT</p><h1>Your little<br>Bitcoin universe.</h1><p class="intro">Mine a block. Inscribe a thought. See it land in your wallet.<br>All in your browser, all with pretend money.</p></div><div class="orbit" aria-hidden="true"><div class="cube"><svg viewBox="0 0 100 100" width="82" height="82" fill="none" stroke="currentColor" stroke-width="5" aria-hidden="true"><path d="M35 17v12m12-12v12M35 76v12m12-12v12M24 29h25c22 0 22 23 0 23H24m0 0h28c22 0 22 24 0 24H24m7-47v47"/></svg></div><span>YOUR CHAIN. YOUR PACE.</span></div></section>
<section class="hero"><div><p class="eyebrow">BITCOIN, WITH ROOM TO EXPERIMENT</p><h1>Your own little<br>Bitcoin universe.</h1><p class="intro">Mine a block. Inscribe a thought. See it land in your wallet.<br>All in your browser, all with pretend money.</p></div><div class="orbit" aria-hidden="true"><div class="cube"><svg viewBox="0 0 100 100" width="82" height="82" fill="none" stroke="currentColor" stroke-width="5" aria-hidden="true"><path d="M35 17v12m12-12v12M35 76v12m12-12v12M24 29h25c22 0 22 23 0 23H24m0 0h28c22 0 22 24 0 24H24m7-47v47"/></svg></div><span>YOUR CHAIN. YOUR PACE.</span></div></section>
<aside class="notice"><strong>Test coins only.</strong> This is a private simulation, not Bitcoin testnet or mainnet. Keys stay in this browser, unencrypted. Never load real keys or send real funds here.</aside>
<div id="status" role="status" aria-live="polite">Create a test wallet to start your first loop.</div>
<section class="workspace">
+1 -1
View File
@@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect width="64" height="64" rx="16" fill="#d4ff76"/><text x="13" y="46" font-size="42" font-family="sans-serif" font-weight="bold" fill="#142016">S</text></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 34 34"><rect width="34" height="34" rx="8" fill="#f7931a"/></svg>

Before

Width:  |  Height:  |  Size: 222 B

After

Width:  |  Height:  |  Size: 119 B

+1 -1
View File
@@ -38,7 +38,7 @@ function setTheme(theme, persist = false) {
}
function initTheme() {
const saved = localStorage.getItem(THEME_KEY);
setTheme(saved === 'light' || saved === 'dark' ? saved : (matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark'));
setTheme(saved === 'light' || saved === 'dark' ? saved : 'dark');
}
function download(name, contents) {
const url = URL.createObjectURL(new Blob([contents], { type: 'application/json' }));
+1 -1
View File
@@ -1 +1 @@
:root{font-family:Arial,Helvetica,sans-serif;font-synthesis:none;--orange:#f7931a;--orange-2:#ffad42;--bg:#0f1113;--panel:#171a1e;--panel-2:#20242a;--text:#f3f5f7;--muted:#9ca4ad;--line:#30363d;--soft:#23272e;--danger:#ff9b8d;color:var(--text);background:var(--bg)}:root[data-theme="light"]{--bg:#f5f3ef;--panel:#fffdf9;--panel-2:#f0ece5;--text:#1a1a1a;--muted:#6f6a63;--line:#d8d1c8;--soft:#ece7df;--danger:#a54536}*{box-sizing:border-box}html{background:var(--bg);color-scheme:dark}html[data-theme="light"]{color-scheme:light}body{margin:0;background:var(--bg);color:var(--text);transition:background .18s,color .18s}a{color:var(--orange);text-underline-offset:4px}button,input,textarea{font:inherit}.file-button,button{cursor:pointer}button{border:1px solid var(--line);border-radius:8px;background:var(--panel-2);color:var(--text);padding:12px 17px;font-weight:600;transition:background .15s,border-color .15s,transform .15s}button:hover:not(:disabled){border-color:var(--orange);transform:translateY(-1px)}button:disabled{opacity:.4;cursor:not-allowed;transform:none}button.primary{background:var(--orange);color:#1c1207;border-color:var(--orange)}button.primary:hover:not(:disabled){background:var(--orange-2)}.primary span{float:right;margin-left:20px}.quiet{background:transparent;border-color:var(--line);font-size:13px}button:focus-visible,a:focus-visible,summary:focus-visible,.file-button:focus-visible{outline:3px solid var(--orange-2);outline-offset:4px}header{max-width:1240px;margin:auto;padding:24px 32px;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid var(--line)}.brand{text-decoration:none;color:var(--text);display:flex;align-items:center;gap:10px;font-size:15px;font-weight:800;letter-spacing:1px}.mark{display:inline-grid;place-items:center;background:var(--orange);color:#1c1207;width:34px;height:34px;border-radius:8px;font-size:21px;letter-spacing:-4px;padding-right:4px}.version{font:11px monospace;background:var(--soft);color:var(--orange);border-radius:4px;padding:3px 5px}.header-actions{display:flex;align-items:center;gap:14px}.network{font:11px monospace;color:var(--muted);letter-spacing:1px}.network i{display:inline-block;width:7px;height:7px;border-radius:50%;background:var(--orange);margin-right:6px}.theme-toggle{padding:8px 10px;font:11px monospace}main{max-width:1176px;padding:0 0 10px;margin:auto}.hero{display:flex;justify-content:space-between;align-items:center;padding:53px 0 36px}.eyebrow{font:11px monospace;letter-spacing:1.8px;color:var(--orange);margin:0 0 19px}h1{font-size:clamp(42px,5.5vw,70px);font-weight:500;line-height:1.02;letter-spacing:-3px;margin:0 0 24px}.intro{color:var(--muted);font-size:16px;line-height:1.65}.orbit{width:255px;height:220px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:36px;background:radial-gradient(ellipse,color-mix(in srgb,var(--orange) 16%,transparent),transparent 70%);margin-right:65px}.cube{display:grid;place-items:center;width:110px;height:110px;border:1px solid var(--orange);box-shadow:13px 13px 0 color-mix(in srgb,var(--orange) 18%,var(--panel)),14px 14px 0 color-mix(in srgb,var(--orange) 48%,var(--panel));transform:rotate(-12deg);background:var(--panel-2);color:var(--orange)}.orbit span{font:10px monospace;letter-spacing:2px;color:var(--muted)}.notice{background:color-mix(in srgb,var(--orange) 7%,var(--panel));border:1px solid color-mix(in srgb,var(--orange) 24%,var(--line));border-radius:8px;padding:14px 18px;font-size:12px;color:var(--muted);line-height:1.6}.notice strong{color:var(--text)}#status{min-height:52px;padding:16px 2px;font-size:13px;color:var(--orange)}#status.error{color:var(--danger)}.workspace{display:grid;grid-template-columns:1fr 1fr;gap:18px}.panel{background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:24px;min-width:0}.panel-title{display:flex;align-items:center;gap:10px;margin-bottom:22px}.panel-title h2{font-size:17px;margin:0;font-weight:500;letter-spacing:-.4px}.step{font:11px monospace;color:var(--orange);background:color-mix(in srgb,var(--orange) 10%,var(--panel));border:1px solid color-mix(in srgb,var(--orange) 28%,var(--line));border-radius:6px;padding:7px}.tag{margin-left:auto;font:9px monospace;letter-spacing:1px;color:var(--muted);border:1px solid var(--line);padding:5px;border-radius:4px}.panel p{line-height:1.6;font-size:14px;color:var(--muted)}.label{display:block;font:10px monospace!important;letter-spacing:1.5px;color:var(--muted);margin:0 0 10px}.balance{display:flex;align-items:baseline;gap:12px;font-size:37px;letter-spacing:-1px;font-variant-numeric:tabular-nums}.balance small{color:var(--orange);font-size:13px;letter-spacing:1px}.muted{color:var(--muted)!important;font-size:12px!important;line-height:1.65}label{display:block;font-size:12px;color:var(--muted);margin:14px 0 9px}input,textarea{width:100%;color:var(--text);background:var(--bg);border:1px solid var(--line);border-radius:6px;padding:12px;outline:none}input{fontLine truncated
:root{font-family:Arial,Helvetica,sans-serif;font-synthesis:none;--orange:#f7931a;--orange-2:#ffad42;--bg:#0f1113;--panel:#171a1e;--panel-2:#20242a;--text:#f3f5f7;--muted:#9ca4ad;--line:#30363d;--soft:#23272e;--danger:#ff9b8d;color:var(--text);background:var(--bg)}:root[data-theme="light"]{--bg:#f5f3ef;--panel:#fffdf9;--panel-2:#f0ece5;--text:#1a1a1a;--muted:#6f6a63;--line:#d8d1c8;--soft:#ece7df;--danger:#a54536}*{box-sizing:border-box}html{background:var(--bg);color-scheme:dark}html[data-theme="light"]{color-scheme:light}body{margin:0;background:var(--bg);color:var(--text);transition:background .18s,color .18s}a{color:var(--orange);text-underline-offset:4px}button,input,textarea{font:inherit}.file-button,button{cursor:pointer}button{border:1px solid var(--line);border-radius:8px;background:var(--panel-2);color:var(--text);padding:12px 17px;font-weight:600;transition:background .15s,border-color .15s,transform .15s}button:hover:not(:disabled){border-color:var(--orange);transform:translateY(-1px)}button:disabled{opacity:.4;cursor:not-allowed;transform:none}button.primary{background:var(--orange);color:#1c1207;border-color:var(--orange)}button.primary:hover:not(:disabled){background:var(--orange-2)}.primary span{float:right;margin-left:20px}.quiet{background:transparent;border-color:var(--line);font-size:13px}button:focus-visible,a:focus-visible,summary:focus-visible,.file-button:focus-visible{outline:3px solid var(--orange-2);outline-offset:4px}header{max-width:1240px;margin:auto;padding:24px 32px;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid var(--line)}.brand{text-decoration:none;color:var(--text);display:flex;align-items:center;gap:10px;font-size:15px;font-weight:800;letter-spacing:1px}.mark{display:inline-block;flex-shrink:0;background:var(--orange);width:34px;height:34px;border-radius:8px}.version{font:11px monospace;background:var(--soft);color:var(--orange);border-radius:4px;padding:3px 5px}.header-actions{display:flex;align-items:center;gap:14px}.network{font:11px monospace;color:var(--muted);letter-spacing:1px}.network i{display:inline-block;width:7px;height:7px;border-radius:50%;background:var(--orange);margin-right:6px}.theme-toggle{padding:8px 10px;font:11px monospace}main{max-width:1176px;padding:0 0 10px;margin:auto}.hero{display:flex;justify-content:space-between;align-items:center;padding:53px 0 36px}.eyebrow{font:11px monospace;letter-spacing:1.8px;color:var(--orange);margin:0 0 19px}h1{font-size:clamp(42px,5.5vw,70px);font-weight:500;line-height:1.02;letter-spacing:-3px;margin:0 0 24px}.intro{color:var(--muted);font-size:16px;line-height:1.65}.orbit{width:255px;height:220px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:36px;background:radial-gradient(ellipse,color-mix(in srgb,var(--orange) 16%,transparent),transparent 70%);margin-right:65px}.cube{display:grid;place-items:center;width:110px;height:110px;border:1px solid var(--orange);box-shadow:13px 13px 0 color-mix(in srgb,var(--orange) 18%,var(--panel)),14px 14px 0 color-mix(in srgb,var(--orange) 48%,var(--panel));transform:rotate(-12deg);background:var(--panel-2);color:var(--orange)}.orbit span{font:10px monospace;letter-spacing:2px;color:var(--muted)}.notice{background:color-mix(in srgb,var(--orange) 7%,var(--panel));border:1px solid color-mix(in srgb,var(--orange) 24%,var(--line));border-radius:8px;padding:14px 18px;font-size:12px;color:var(--muted);line-height:1.6}.notice strong{color:var(--text)}#status{min-height:52px;padding:16px 2px;font-size:13px;color:var(--orange)}#status.error{color:var(--danger)}.workspace{display:grid;grid-template-columns:1fr 1fr;gap:18px}.panel{background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:24px;min-width:0}.panel-title{display:flex;align-items:center;gap:10px;margin-bottom:22px}.panel-title h2{font-size:17px;margin:0;font-weight:500;letter-spacing:-.4px}.step{font:11px monospace;color:var(--orange);background:color-mix(in srgb,var(--orange) 10%,var(--panel));border:1px solid color-mix(in srgb,var(--orange) 28%,var(--line));border-radius:6px;padding:7px}.tag{margin-left:auto;font:9px monospace;letter-spacing:1px;color:var(--muted);border:1px solid var(--line);padding:5px;border-radius:4px}.panel p{line-height:1.6;font-size:14px;color:var(--muted)}.label{display:block;font:10px monospace!important;letter-spacing:1.5px;color:var(--muted);margin:0 0 10px}.balance{display:flex;align-items:baseline;gap:12px;font-size:37px;letter-spacing:-1px;font-variant-numeric:tabular-nums}.balance small{color:var(--orange);font-size:13px;letter-spacing:1px}.muted{color:var(--muted)!important;font-size:12px!important;line-height:1.65}label{display:block;font-size:12px;color:var(--muted);margin:14px 0 9px}input,textarea{width:100%;color:var(--text);background:var(--bg);border:1px solid var(--line);border-radius:6px;padding:12px;outline:none}input{font:11px monospace}textarea{resize:vertical;min-height:100px;line-height:1Line truncated
+9 -2
View File
@@ -66,8 +66,9 @@ test('create → mine → mempool → inscription → block/transaction → relo
await page.screenshot({path:`test-results/${test.info().project.name}-complete.png`,fullPage:true});
});
test('theme toggle persists explicit light/dark preference', async ({page}) => {
await page.emulateMedia({colorScheme:'dark'});
for (const colorScheme of ['light', 'dark']) {
test(`dark default and explicit theme persistence with ${colorScheme} system preference`, async ({page}) => {
await page.emulateMedia({colorScheme});
await page.goto('/');
await expect(page.locator('html')).toHaveAttribute('data-theme','dark');
await expect(page.getByRole('button',{name:'Switch to light mode'})).toBeVisible();
@@ -76,7 +77,13 @@ test('theme toggle persists explicit light/dark preference', async ({page}) => {
await page.reload();
await expect(page.locator('html')).toHaveAttribute('data-theme','light');
await expect(page.getByRole('button',{name:'Switch to dark mode'})).toBeVisible();
expect(await page.evaluate(() => localStorage.getItem('super-testnet-theme'))).toBe('light');
await page.getByRole('button',{name:'Switch to dark mode'}).click();
await page.reload();
await expect(page.locator('html')).toHaveAttribute('data-theme','dark');
expect(await page.evaluate(() => localStorage.getItem('super-testnet-theme'))).toBe('dark');
});
}
test('wallet backup reload and rejected oversized or invalid input',async({page})=>{
await page.goto('/'); await page.getByRole('button',{name:'Create test wallet'}).click();