fix(rwallet): use CSS variable theming + soften global light mode

Replace ~30 hardcoded dark hex colors in folk-wallet-viewer with --rs-*
CSS variables so rWallet adapts to both light and dark themes. Warm up
the global light palette from pure white to off-white tones.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jeff Emmett 2026-03-09 15:27:07 -07:00
parent f2ce77321f
commit 93b6b2eb2c
3 changed files with 55 additions and 55 deletions

View File

@ -234,13 +234,13 @@ class FolkWalletViewer extends HTMLElement {
private renderStyles(): string { private renderStyles(): string {
return ` return `
<style> <style>
:host { display: block; font-family: system-ui, -apple-system, sans-serif; color: #e0e0e0; } :host { display: block; font-family: system-ui, -apple-system, sans-serif; color: var(--rs-text-primary); }
* { box-sizing: border-box; } * { box-sizing: border-box; }
/* ── Hero ── */ /* ── Hero ── */
.hero { .hero {
text-align: center; padding: 32px 16px 24px; text-align: center; padding: 32px 16px 24px;
border-bottom: 1px solid #2a2a3e; margin-bottom: 24px; border-bottom: 1px solid var(--rs-border-subtle); margin-bottom: 24px;
} }
.hero-title { .hero-title {
font-size: 28px; font-weight: 700; margin: 0 0 6px; font-size: 28px; font-weight: 700; margin: 0 0 6px;
@ -248,13 +248,13 @@ class FolkWalletViewer extends HTMLElement {
-webkit-background-clip: text; -webkit-text-fill-color: transparent; -webkit-background-clip: text; -webkit-text-fill-color: transparent;
background-clip: text; background-clip: text;
} }
.hero-subtitle { font-size: 14px; color: #888; margin: 0 0 20px; } .hero-subtitle { font-size: 14px; color: var(--rs-text-secondary); margin: 0 0 20px; }
/* ── Address bar ── */ /* ── Address bar ── */
.address-bar { display: flex; gap: 8px; margin-bottom: 12px; max-width: 640px; margin-left: auto; margin-right: auto; } .address-bar { display: flex; gap: 8px; margin-bottom: 12px; max-width: 640px; margin-left: auto; margin-right: auto; }
.address-bar input { .address-bar input {
flex: 1; padding: 12px 16px; border-radius: 10px; flex: 1; padding: 12px 16px; border-radius: 10px;
border: 1px solid #444; background: #1e1e2e; color: #e0e0e0; border: 1px solid var(--rs-input-border); background: var(--rs-bg-surface); color: var(--rs-text-primary);
font-family: monospace; font-size: 14px; font-family: monospace; font-size: 14px;
} }
.address-bar input:focus { border-color: #00d4ff; outline: none; box-shadow: 0 0 0 2px rgba(0,212,255,0.15); } .address-bar input:focus { border-color: #00d4ff; outline: none; box-shadow: 0 0 0 2px rgba(0,212,255,0.15); }
@ -272,16 +272,16 @@ class FolkWalletViewer extends HTMLElement {
} }
.testnet-toggle { .testnet-toggle {
display: flex; align-items: center; gap: 8px; display: flex; align-items: center; gap: 8px;
cursor: pointer; user-select: none; font-size: 13px; color: #888; cursor: pointer; user-select: none; font-size: 13px; color: var(--rs-text-secondary);
} }
.testnet-toggle:hover { color: #bbb; } .testnet-toggle:hover { color: var(--rs-text-primary); }
.toggle-track { .toggle-track {
width: 34px; height: 18px; border-radius: 9px; background: #333; width: 34px; height: 18px; border-radius: 9px; background: var(--rs-border);
position: relative; transition: background 0.2s; position: relative; transition: background 0.2s;
} }
.testnet-toggle.active .toggle-track { background: #f59e0b; } .testnet-toggle.active .toggle-track { background: #f59e0b; }
.toggle-thumb { .toggle-thumb {
width: 14px; height: 14px; border-radius: 50%; background: #666; width: 14px; height: 14px; border-radius: 50%; background: var(--rs-text-muted);
position: absolute; top: 2px; left: 2px; transition: all 0.2s; position: absolute; top: 2px; left: 2px; transition: all 0.2s;
} }
.testnet-toggle.active .toggle-thumb { left: 18px; background: #fff; } .testnet-toggle.active .toggle-thumb { left: 18px; background: #fff; }
@ -300,8 +300,8 @@ class FolkWalletViewer extends HTMLElement {
} }
.supported-chain { .supported-chain {
display: flex; align-items: center; gap: 5px; display: flex; align-items: center; gap: 5px;
padding: 4px 10px; border-radius: 6px; background: #1e1e2e; padding: 4px 10px; border-radius: 6px; background: var(--rs-bg-surface);
border: 1px solid #2a2a3e; font-size: 12px; color: #999; border: 1px solid var(--rs-border-subtle); font-size: 12px; color: var(--rs-text-secondary);
} }
.supported-chain .dot { width: 6px; height: 6px; border-radius: 50%; } .supported-chain .dot { width: 6px; height: 6px; border-radius: 50%; }
@ -311,28 +311,28 @@ class FolkWalletViewer extends HTMLElement {
gap: 16px; margin-bottom: 28px; gap: 16px; margin-bottom: 28px;
} }
.feature-card { .feature-card {
background: #1e1e2e; border: 1px solid #2a2a3e; border-radius: 12px; background: var(--rs-bg-surface); border: 1px solid var(--rs-border-subtle); border-radius: 12px;
padding: 20px; text-align: center; transition: border-color 0.2s; padding: 20px; text-align: center; transition: border-color 0.2s;
} }
.feature-card:hover { border-color: #444; } .feature-card:hover { border-color: var(--rs-border-strong); }
.feature-icon { font-size: 28px; margin-bottom: 10px; } .feature-icon { font-size: 28px; margin-bottom: 10px; }
.feature-card h3 { font-size: 14px; font-weight: 600; margin: 0 0 6px; color: #e0e0e0; } .feature-card h3 { font-size: 14px; font-weight: 600; margin: 0 0 6px; color: var(--rs-text-primary); }
.feature-card p { font-size: 12px; color: #888; margin: 0; line-height: 1.5; } .feature-card p { font-size: 12px; color: var(--rs-text-secondary); margin: 0; line-height: 1.5; }
/* ── Example wallets ── */ /* ── Example wallets ── */
.examples { .examples {
max-width: 640px; margin: 0 auto 20px; max-width: 640px; margin: 0 auto 20px;
} }
.examples-label { font-size: 11px; color: #666; text-transform: uppercase; letter-spacing: 1px; margin-bottom: 10px; } .examples-label { font-size: 11px; color: var(--rs-text-muted); text-transform: uppercase; letter-spacing: 1px; margin-bottom: 10px; }
.example-list { display: flex; flex-direction: column; gap: 6px; } .example-list { display: flex; flex-direction: column; gap: 6px; }
.example-item { .example-item {
display: flex; align-items: center; gap: 10px; padding: 10px 14px; display: flex; align-items: center; gap: 10px; padding: 10px 14px;
background: #1e1e2e; border: 1px solid #2a2a3e; border-radius: 10px; background: var(--rs-bg-surface); border: 1px solid var(--rs-border-subtle); border-radius: 10px;
cursor: pointer; transition: all 0.2s; cursor: pointer; transition: all 0.2s;
} }
.example-item:hover { border-color: #00d4ff; background: #252540; } .example-item:hover { border-color: #00d4ff; background: var(--rs-bg-hover); }
.example-name { font-size: 13px; font-weight: 500; color: #e0e0e0; } .example-name { font-size: 13px; font-weight: 500; color: var(--rs-text-primary); }
.example-addr { font-size: 11px; color: #666; font-family: monospace; } .example-addr { font-size: 11px; color: var(--rs-text-muted); font-family: monospace; }
.example-type { .example-type {
margin-left: auto; font-size: 10px; font-weight: 600; margin-left: auto; font-size: 10px; font-weight: 600;
padding: 2px 8px; border-radius: 4px; text-transform: uppercase; padding: 2px 8px; border-radius: 4px; text-transform: uppercase;
@ -343,47 +343,47 @@ class FolkWalletViewer extends HTMLElement {
/* ── Dashboard: chains ── */ /* ── Dashboard: chains ── */
.chains { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 20px; } .chains { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 20px; }
.chain-btn { .chain-btn {
padding: 6px 14px; border-radius: 8px; border: 2px solid #333; padding: 6px 14px; border-radius: 8px; border: 2px solid var(--rs-border);
background: #1e1e2e; color: #ccc; cursor: pointer; font-size: 13px; background: var(--rs-bg-surface); color: var(--rs-text-secondary); cursor: pointer; font-size: 13px;
display: flex; align-items: center; gap: 6px; transition: all 0.2s; display: flex; align-items: center; gap: 6px; transition: all 0.2s;
} }
.chain-btn:hover { border-color: #555; } .chain-btn:hover { border-color: var(--rs-border-strong); }
.chain-btn.active { border-color: var(--chain-color); background: rgba(255,255,255,0.05); } .chain-btn.active { border-color: var(--chain-color); background: var(--rs-bg-hover); }
.chain-dot { width: 8px; height: 8px; border-radius: 50%; } .chain-dot { width: 8px; height: 8px; border-radius: 50%; }
/* ── Dashboard: stats ── */ /* ── Dashboard: stats ── */
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 12px; margin-bottom: 24px; } .stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 12px; margin-bottom: 24px; }
.stat-card { .stat-card {
background: #1e1e2e; border: 1px solid #333; border-radius: 10px; background: var(--rs-bg-surface); border: 1px solid var(--rs-border); border-radius: 10px;
padding: 14px; text-align: center; padding: 14px; text-align: center;
} }
.stat-label { font-size: 11px; color: #888; text-transform: uppercase; margin-bottom: 6px; } .stat-label { font-size: 11px; color: var(--rs-text-secondary); text-transform: uppercase; margin-bottom: 6px; }
.stat-value { font-size: 20px; font-weight: 700; color: #00d4ff; } .stat-value { font-size: 20px; font-weight: 700; color: #00d4ff; }
/* ── Dashboard: balance table ── */ /* ── Dashboard: balance table ── */
.balance-table { width: 100%; border-collapse: collapse; } .balance-table { width: 100%; border-collapse: collapse; }
.balance-table th { .balance-table th {
text-align: left; padding: 10px 8px; border-bottom: 2px solid #333; text-align: left; padding: 10px 8px; border-bottom: 2px solid var(--rs-border);
color: #888; font-size: 11px; text-transform: uppercase; color: var(--rs-text-secondary); font-size: 11px; text-transform: uppercase;
} }
.balance-table td { padding: 10px 8px; border-bottom: 1px solid #2a2a3e; } .balance-table td { padding: 10px 8px; border-bottom: 1px solid var(--rs-border-subtle); }
.balance-table tr:hover td { background: rgba(255,255,255,0.02); } .balance-table tr:hover td { background: var(--rs-bg-hover); }
.token-symbol { font-weight: 600; color: #e0e0e0; } .token-symbol { font-weight: 600; color: var(--rs-text-primary); }
.token-name { font-size: 12px; color: #888; } .token-name { font-size: 12px; color: var(--rs-text-secondary); }
.amount-cell { text-align: right; font-family: monospace; } .amount-cell { text-align: right; font-family: monospace; }
.fiat { color: #4ade80; } .fiat { color: var(--rs-success); }
/* ── States ── */ /* ── States ── */
.empty { text-align: center; color: #666; padding: 40px; } .empty { text-align: center; color: var(--rs-text-muted); padding: 40px; }
.loading { text-align: center; color: #888; padding: 40px; } .loading { text-align: center; color: var(--rs-text-secondary); padding: 40px; }
.loading .spinner { .loading .spinner {
display: inline-block; width: 20px; height: 20px; display: inline-block; width: 20px; height: 20px;
border: 2px solid #333; border-top-color: #00d4ff; border-radius: 50%; border: 2px solid var(--rs-border); border-top-color: #00d4ff; border-radius: 50%;
animation: spin 0.8s linear infinite; margin-right: 8px; vertical-align: middle; animation: spin 0.8s linear infinite; margin-right: 8px; vertical-align: middle;
} }
@keyframes spin { to { transform: rotate(360deg); } } @keyframes spin { to { transform: rotate(360deg); } }
.error { .error {
text-align: center; color: #ef5350; padding: 16px; text-align: center; color: var(--rs-error); padding: 16px;
background: rgba(239,83,80,0.08); border: 1px solid rgba(239,83,80,0.2); background: rgba(239,83,80,0.08); border: 1px solid rgba(239,83,80,0.2);
border-radius: 10px; margin-bottom: 16px; border-radius: 10px; margin-bottom: 16px;
} }

View File

@ -422,7 +422,7 @@ routes.get("/", (c) => {
modules: getModuleInfoList(), modules: getModuleInfoList(),
theme: "dark", theme: "dark",
body: `<folk-wallet-viewer></folk-wallet-viewer>`, body: `<folk-wallet-viewer></folk-wallet-viewer>`,
scripts: `<script type="module" src="/modules/rwallet/folk-wallet-viewer.js?v=3"></script>`, scripts: `<script type="module" src="/modules/rwallet/folk-wallet-viewer.js?v=4"></script>`,
styles: `<link rel="stylesheet" href="/modules/rwallet/wallet.css">`, styles: `<link rel="stylesheet" href="/modules/rwallet/wallet.css">`,
})); }));
}); });

View File

@ -84,10 +84,10 @@
color-scheme: light; color-scheme: light;
/* Surface */ /* Surface */
--rs-bg-page: #f8fafc; --rs-bg-page: #f5f5f0;
--rs-bg-surface: #ffffff; --rs-bg-surface: #fafaf7;
--rs-bg-surface-raised: #f1f5f9; --rs-bg-surface-raised: #f0efe9;
--rs-bg-surface-sunken: #f8fafc; --rs-bg-surface-sunken: #eeedea;
--rs-bg-overlay: rgba(255, 255, 255, 0.9); --rs-bg-overlay: rgba(255, 255, 255, 0.9);
--rs-bg-hover: rgba(0, 0, 0, 0.04); --rs-bg-hover: rgba(0, 0, 0, 0.04);
--rs-bg-active: #e0f2fe; --rs-bg-active: #e0f2fe;
@ -117,7 +117,7 @@
--rs-spinner-head: #14b8a6; --rs-spinner-head: #14b8a6;
/* Component-specific tokens */ /* Component-specific tokens */
--rs-input-bg: #f8fafc; --rs-input-bg: #f5f5f0;
--rs-input-border: #e2e8f0; --rs-input-border: #e2e8f0;
--rs-input-text: #334155; --rs-input-text: #334155;
--rs-btn-secondary-bg: rgba(0, 0, 0, 0.05); --rs-btn-secondary-bg: rgba(0, 0, 0, 0.05);
@ -126,16 +126,16 @@
--rs-card-border: rgba(0, 0, 0, 0.06); --rs-card-border: rgba(0, 0, 0, 0.06);
/* Canvas */ /* Canvas */
--rs-canvas-bg: #ffffff; --rs-canvas-bg: #fafaf7;
--rs-canvas-grid: #f1f5f9; --rs-canvas-grid: #f1f5f9;
/* Toolbar */ /* Toolbar */
--rs-toolbar-bg: #ffffff; --rs-toolbar-bg: #fafaf7;
--rs-toolbar-btn-bg: #f1f5f9; --rs-toolbar-btn-bg: #f0efe9;
--rs-toolbar-btn-hover: #e2e8f0; --rs-toolbar-btn-hover: #e2e8f0;
--rs-toolbar-btn-text: #0f172a; --rs-toolbar-btn-text: #0f172a;
--rs-toolbar-sep: #e2e8f0; --rs-toolbar-sep: #e2e8f0;
--rs-toolbar-panel-bg: #ffffff; --rs-toolbar-panel-bg: #fafaf7;
--rs-toolbar-panel-border: #e2e8f0; --rs-toolbar-panel-border: #e2e8f0;
} }
@ -144,10 +144,10 @@
:root:not([data-theme]) { :root:not([data-theme]) {
color-scheme: light; color-scheme: light;
--rs-bg-page: #f8fafc; --rs-bg-page: #f5f5f0;
--rs-bg-surface: #ffffff; --rs-bg-surface: #fafaf7;
--rs-bg-surface-raised: #f1f5f9; --rs-bg-surface-raised: #f0efe9;
--rs-bg-surface-sunken: #f8fafc; --rs-bg-surface-sunken: #eeedea;
--rs-bg-overlay: rgba(255, 255, 255, 0.9); --rs-bg-overlay: rgba(255, 255, 255, 0.9);
--rs-bg-hover: rgba(0, 0, 0, 0.04); --rs-bg-hover: rgba(0, 0, 0, 0.04);
--rs-bg-active: #e0f2fe; --rs-bg-active: #e0f2fe;
@ -171,7 +171,7 @@
--rs-spinner-track: rgba(0, 0, 0, 0.08); --rs-spinner-track: rgba(0, 0, 0, 0.08);
--rs-spinner-head: #14b8a6; --rs-spinner-head: #14b8a6;
--rs-input-bg: #f8fafc; --rs-input-bg: #f5f5f0;
--rs-input-border: #e2e8f0; --rs-input-border: #e2e8f0;
--rs-input-text: #334155; --rs-input-text: #334155;
--rs-btn-secondary-bg: rgba(0, 0, 0, 0.05); --rs-btn-secondary-bg: rgba(0, 0, 0, 0.05);
@ -179,15 +179,15 @@
--rs-card-bg: rgba(0, 0, 0, 0.02); --rs-card-bg: rgba(0, 0, 0, 0.02);
--rs-card-border: rgba(0, 0, 0, 0.06); --rs-card-border: rgba(0, 0, 0, 0.06);
--rs-canvas-bg: #ffffff; --rs-canvas-bg: #fafaf7;
--rs-canvas-grid: #f1f5f9; --rs-canvas-grid: #f1f5f9;
--rs-toolbar-bg: #ffffff; --rs-toolbar-bg: #fafaf7;
--rs-toolbar-btn-bg: #f1f5f9; --rs-toolbar-btn-bg: #f0efe9;
--rs-toolbar-btn-hover: #e2e8f0; --rs-toolbar-btn-hover: #e2e8f0;
--rs-toolbar-btn-text: #0f172a; --rs-toolbar-btn-text: #0f172a;
--rs-toolbar-sep: #e2e8f0; --rs-toolbar-sep: #e2e8f0;
--rs-toolbar-panel-bg: #ffffff; --rs-toolbar-panel-bg: #fafaf7;
--rs-toolbar-panel-border: #e2e8f0; --rs-toolbar-panel-border: #e2e8f0;
} }
} }