v0.3.3 -- Living design reference for all UI elements
CSS custom properties defined in src/app.css on :root and [data-theme='dark'].
--color-bg Primary background--color-bg-secondary Secondary background--color-bg-alt Alternate background (panels, info boxes)--color-hover-bg Hover state background--color-text Primary text--color-text-muted Secondary / muted text--color-border Default border--color-border-light Light border--color-border-dark Strong border (buttons, inputs focused)--color-link Hyperlinks--color-success Success states--color-warning Warning states--color-error Error states--color-info Informational--color-accent Accent / primary action--color-crypto-bg Crypto-themed background--color-crypto-text Crypto-themed text--spacing-xs 0.5rem--spacing-sm 0.75rem--spacing-md 1rem--spacing-lg 1.5rem--spacing-xl 2rem--font-mono ui-monospace, 'Cascadia Code', 'Source Code Pro', Menlo, Consolas, monospace:root {
--color-bg: #ffffff;
--color-text: #111111;
--color-border: #e5e5e5;
--color-accent: #5c6bc0;
--font-mono: ui-monospace, 'Cascadia Code', ...;
--spacing-md: 1rem;
}
[data-theme='dark'] {
--color-bg: #002b36;
--color-text: #93a1a1;
--color-border: #586e75;
--color-accent: #6c71c4;
}Top-level layout elements from src/routes/+page.svelte and src/components/ThemeToggle.svelte.
Outer wrapper. Starts with margin-top: 25vh (centered on home), transitions to margin-top: 0 when .active (navigated to a section).
.app-wrapper {
margin-top: 25vh;
transition: margin-top 0.3s ease;
}
.app-wrapper.active {
margin-top: 0;
} Horizontal bar shown when navigated away from home. Contains back button, section title, and spacer.
.nav-bar {
display: flex;
justify-content: space-between;
align-items: center;
padding: var(--spacing-sm) var(--spacing-lg);
border-bottom: 1px solid var(--color-border);
} Ghost button for back navigation. No background, border, or shadow.
.nav-btn {
background: none; border: none; box-shadow: none;
padding: 0.3rem 0.5rem; font-size: 0.8rem;
color: var(--color-text-muted);
} Section name label centered in nav bar.
.nav-title {
font-size: 0.8rem; font-weight: 600;
text-transform: uppercase; letter-spacing: 0.05em;
} Fixed-position button (top-right) to toggle light/dark theme. From ThemeToggle.svelte.
.theme-toggle {
position: fixed; top: var(--spacing-md); right: var(--spacing-md);
z-index: 200; font-size: 1.1rem;
} Content container. Max 900px, centered with horizontal padding.
.container {
max-width: 900px;
margin: 0 auto;
padding: 0 var(--spacing-lg);
} Footer with version string. Centered text at page bottom.
.app-footer {
text-align: center;
padding: var(--spacing-lg) 0;
margin-top: var(--spacing-xl);
}Buttons, inputs, badges, tables, and utility classes from src/app.css.
Default: bordered with shadow. .primary: accent background, white text. :disabled: faded, no shadow.
button, .btn {
font-family: var(--font-mono); font-size: 0.8rem; font-weight: 600;
padding: 0.4rem 1rem; border: 1px solid var(--color-border-dark);
border-radius: 0; background: var(--color-bg); color: var(--color-text);
text-transform: uppercase; letter-spacing: 0.05em;
box-shadow: 2px 2px 0px var(--color-shadow);
}
button.primary {
background: var(--color-accent); color: #fff;
}
button:disabled {
opacity: 0.4; cursor: not-allowed; box-shadow: none;
} input, textarea, select {
font-family: var(--font-mono); font-size: 0.9rem;
padding: 0.5rem 0.75rem; border: 1px solid var(--color-border);
border-radius: 0; background: var(--color-bg); color: var(--color-text);
}
input:focus, textarea:focus, select:focus {
border-color: var(--color-border-dark);
box-shadow: 2px 2px 0px var(--color-shadow);
} Inline status labels with semantic color variants.
.badge {
display: inline-block; font-size: 0.7rem; font-weight: 600;
padding: 0.15rem 0.4rem; border: 1px solid;
text-transform: uppercase; letter-spacing: 0.03em;
}
.badge-success { background: rgba(40,167,69,0.15); border-color: #28a745; color: #28a745; }
.badge-warning { background: rgba(255,193,7,0.15); border-color: #ffc107; color: #92400e; }
.badge-error { background: rgba(220,53,69,0.15); border-color: #dc3545; color: #dc3545; }
.badge-info { background: rgba(92,107,192,0.15); border-color: var(--color-accent); color: var(--color-accent); } Minimal data table with hover highlight.
| Index | Address | Balance |
|---|---|---|
| 0 | 0xAb5801a7...93Fd | 1.234 ETH |
| 1 | 0x1234abcd...5678 | 0.500 ETH |
.data-table {
width: 100%; border-collapse: collapse; font-size: 0.85rem;
}
.data-table th {
font-weight: 600; text-transform: uppercase; font-size: 0.75rem;
letter-spacing: 0.05em; color: var(--color-text-muted);
}
.data-table th, .data-table td {
padding: 0.4rem 0.75rem; text-align: left;
border-bottom: 1px solid var(--color-border);
}
.data-table tr:hover { background: var(--color-hover-bg); } Scrollable log output with colored line types. From src/app.css.
.terminal-log {
background: var(--color-bg-alt); border: 1px solid var(--color-border-light);
font-size: 13px; padding: var(--spacing-md);
max-height: 400px; overflow-y: auto;
box-shadow: 2px 2px 0px var(--color-shadow);
}
.log-line::before { content: '> '; color: var(--color-text-muted); }
.log-line.fetch { color: var(--color-link); }
.log-line.found { color: var(--color-success); }
.log-line.match { color: var(--color-error); font-weight: 600; }
.log-line.clear { color: var(--color-text-muted); }
.log-line.error { color: var(--color-error); } Floating ephemeral toast that animates upward and fades out (1s). Position set via JS at click coordinates.
.copy-toast {
position: fixed; pointer-events: none;
font-size: 0.7rem; font-weight: 600; text-transform: uppercase;
padding: 0.2rem 0.5rem; background: var(--color-text); color: var(--color-bg);
border: 1px solid var(--color-border-dark); z-index: 9999;
animation: copyToast 1s ease forwards;
} .text-muted Muted text color .text-sm 0.85rem font size .text-xs 0.75rem font size .mt-xs / .mt-sm / .mt-md / .mt-lg Margin-top utilities .mb-sm / .mb-md / .mb-lg Margin-bottom utilities .gap-sm / .gap-md Gap utilitiesLanding page elements from src/components/Hero.svelte. Centered layout, max-width 600px.
Centered container for the home screen. Contains title, subtitle, action buttons, and the explainer accordion.
Shamir's Secret Sharing for Seed Phrases
Split. Print. Recover.
.hero { text-align: center; max-width: 600px; margin: 0 auto; }
.hero-title { font-size: 2.5rem; letter-spacing: 0.1em; text-transform: lowercase; }
.hero-subtitle { font-size: 0.9rem; margin-top: var(--spacing-xs); }
.hero-tagline { letter-spacing: 0.15em; text-transform: uppercase; font-size: 0.75rem; } Flex row of navigation buttons. Wraps and stacks vertically on mobile.
.hero-actions {
display: flex; gap: var(--spacing-sm);
justify-content: center; flex-wrap: wrap;
}
.hero-actions button { min-width: 120px; } Accordion section explaining Shamir's algorithm. Uses .explainer-section, .explainer-heading, and .math-block for formulas.
For each byte s of the secret, a random polynomial is constructed:
.explainer {
text-align: left; max-width: 520px; margin: 0 auto;
border: 1px solid var(--color-border); background: var(--color-bg-alt);
padding: var(--spacing-md);
}
.math-block {
font-family: var(--font-mono); font-size: 0.75rem;
background: var(--color-hover-bg); border: 1px solid var(--color-border);
padding: 0.5rem 0.75rem; margin: 0.4rem 0; text-align: center;
}Reusable container from src/components/Panel.svelte. Uses global .panel / .panel-header from src/app.css.
Panel body content goes here. This is the default content area with padding: var(--spacing-md).
.panel {
background: var(--color-bg); border: 1px solid var(--color-border);
border-radius: 0; box-shadow: 2px 2px 0px var(--color-shadow);
}
.panel-header {
padding: var(--spacing-sm) var(--spacing-md);
border-bottom: 1px solid var(--color-border);
font-weight: 600; font-size: 0.85rem;
text-transform: uppercase; letter-spacing: 0.05em;
}
.panel-body {
padding: var(--spacing-md);
}Multi-step wizard from src/components/GenerateFlow.svelte and its sub-components.
Horizontal step tracker from StepIndicator.svelte. Badges show active, completed, or default state.
.step-indicator { display: flex; flex-wrap: wrap; gap: 0.35rem; }
.step-badge {
display: inline-flex; align-items: center; gap: 0.35rem;
padding: 0.2rem 0.5rem; font-size: 0.7rem; font-weight: 600;
text-transform: uppercase; border: 1px solid var(--color-border);
color: var(--color-text-muted);
}
.step-badge.active {
background: rgba(92,107,192,0.15); border-color: var(--color-accent);
color: var(--color-accent);
}
.step-badge.completed {
background: rgba(40,167,69,0.15); border-color: var(--color-success);
color: var(--color-success);
} Row of word count options (12, 15, 18, 21, 24). Selected button uses .primary.
Canvas from EntropyCanvas.svelte for mouse/touch entropy collection. Dark background, crosshair cursor, progress bar below.
.entropy-canvas {
width: 100%; height: 200px;
border: 1px solid var(--color-border-dark);
box-shadow: 2px 2px 0px var(--color-shadow);
cursor: crosshair; touch-action: none;
} 4-column grid of word cells from MnemonicGrid.svelte. Each cell has a small index number and centered word text.
.mnemonic-grid {
display: grid; grid-template-columns: repeat(4, 1fr); gap: 0.5rem;
}
.word-cell {
border: 1px solid var(--color-border-dark);
box-shadow: 2px 2px 0px var(--color-shadow);
padding: 0.5rem; position: relative;
display: flex; align-items: center; justify-content: center;
min-height: 2.8rem;
}
.word-index { position: absolute; top: 2px; left: 4px; font-size: 0.6rem; }
.word-text { font-size: 0.85rem; font-weight: 600; text-align: center; } Derivation path selector from PathEditor.svelte. Toggle buttons for MetaMask / Ledger / Custom, with path display below.
m/44'/60'/0'/0/{index}Threshold (N) and total shares (M) inputs side by side.
Color picker for card highlight. 32x32 buttons in a flex row.
.color-swatch {
width: 32px; height: 32px;
border: 2px solid var(--color-border);
padding: 0; min-width: 0;
box-shadow: 1px 1px 0px var(--color-shadow);
}
.color-swatch.selected {
border-color: var(--color-border-dark);
box-shadow: 3px 3px 0px var(--color-shadow);
transform: translate(-1px, -1px);
} Modal overlay (fixed, full-screen dim) and centered confirmation dialog. Used for PIN and passphrase confirmation.
.popup-overlay {
position: fixed; inset: 0; background: rgba(0,0,0,0.3);
z-index: 100;
}
.confirm-popup {
position: fixed; top: 50%; left: 50%;
transform: translate(-50%, -50%); z-index: 101;
background: var(--color-bg); border: 2px solid var(--color-border-dark);
box-shadow: 6px 6px 0px var(--color-shadow);
padding: var(--spacing-lg); min-width: 320px;
} Large centered password input for 6-digit PIN entry from PinInput.svelte.
.pin-input {
font-size: 1.5rem; letter-spacing: 0.5em;
text-align: center; padding: 0.75rem; max-width: 300px;
}QR scanning and file import UI from src/components/ScanFlow.svelte.
Camera viewport container. 4:3 aspect ratio, max 500px wide, dark border with shadow.
Camera not active
.camera-area {
position: relative; width: 100%; max-width: 500px;
margin: 0 auto; aspect-ratio: 4/3;
background: var(--color-bg-alt);
border: 1px solid var(--color-border-dark);
box-shadow: 2px 2px 0px var(--color-shadow);
} AR-style scanning overlay with corner brackets and guidance pill.
Progress indicator showing scanned shares vs. threshold. Boxes fill green as shares are found.
.threshold-box {
width: 20px; height: 20px;
border: 2px solid var(--color-border-dark); background: var(--color-bg);
}
.threshold-box.filled { background: var(--color-success); }
.slot-box {
width: 24px; height: 24px; border: 1px solid var(--color-border);
font-size: 0.6rem; color: var(--color-text-muted);
}
.slot-box.scanned {
background: var(--color-success-bg); border-color: var(--color-success);
color: var(--color-success); font-weight: 600;
} Status bar shown during file imports. Braille spinner + striped progress fill.
Scanning page 3/7 -- Found 2 QR codes
Accepted file formats info card with icon list and warning footer.
Password input for encrypted JSON import. Horizontal input + button layout.
Secret management list from src/components/VaultPanel.svelte. Expandable items with export options.
Vertical list of saved secrets. Each item expands to show details on click.
Expanded detail content area
Export/share dialog with multiple download options (Print, HTML, PDF, Image, JSON).
Action buttons at the bottom of an expanded vault item (Reprint, Export, Delete).
Table listing share indices, share data preview, and actions within the vault detail view.
| Share | Data | Status |
|---|---|---|
| 1/5 | a1b2c3d4e5f6... | OK |
| 2/5 | f6e5d4c3b2a1... | OK |
| 3/5 | 1a2b3c4d5e6f... | OK |
App configuration from src/components/SettingsPanel.svelte. Stacked panels for each setting group.
Vertical stack of Panel components with gap: var(--spacing-md).
Layout selector row: button + description + download icon.
Key-value rows showing storage info (localStorage, IndexedDB, encryption method).
Expandable cryptographic details section. Lists algorithm names and descriptions.
Shamir's Secret Sharing over GF(2^8). Information-theoretically secure.
AES-256-GCM with authenticated encryption.
Linked badges for third-party libraries used in the project.
Platform-specific PWA install instructions. Key-value rows.