feat: complete Phase 1 foundation hardening + three-mode UI design doc

Phase 1a — Gradient Removal:
- Replaced all gradient-button/gradient-card with glass-button/path-option-card
- Removed banned gradient CSS classes

Phase 1b — Security Hardening:
- SecretsManager: AES-256-GCM encryption (core/security)
- electrs_status: credentials from env vars instead of hardcoded
- port_manager: RwLock proper error handling (no unwrap)
- Pinned all 11 :latest manifest images to specific versions
- parmanode converter: pinned inferred image versions

Phase 1c — Code Quality:
- Split rpc.rs (1795 lines) into 6 handler modules (auth, node, container, package, peers)
- Removed sideload code (UI, store, RPC client, 3 doc files)
- Fixed body background flash on logout/refresh
- Replaced 30 TypeScript `any` types with proper types
- Deleted HelloWorld.vue, removed TODO comments
- Added set -euo pipefail to all shell scripts
- Made deploy script verbose with timestamps and elapsed time

Also adds:
- CLAUDE.md project guide
- docs/three-mode-ui-design.md — design spec for Easy/Pro/Chat UI modes
- OnlineStatusPill component

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-03-04 05:23:42 +00:00
parent 62d6c13764
commit 486fc39249
58 changed files with 1902 additions and 2286 deletions

View File

@@ -66,28 +66,56 @@
overflow-x: hidden;
overflow-y: visible;
}
.glass-button {
position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
height: 48px;
min-height: 48px;
padding-block: 0 !important;
line-height: 48px;
background-color: rgba(0, 0, 0, 0.6);
backdrop-filter: blur(18px);
-webkit-backdrop-filter: blur(18px);
border: 1px solid rgba(255, 255, 255, 0.18);
padding-inline: 1.25rem;
background: rgba(0, 0, 0, 0.6);
backdrop-filter: blur(24px);
-webkit-backdrop-filter: blur(24px);
box-shadow:
0 8px 24px rgba(0, 0, 0, 0.45),
inset 0 1px 0 rgba(255, 255, 255, 0.22);
border-radius: 0.75rem;
border: none;
color: rgba(255, 255, 255, 0.9);
transition: all 0.3s ease;
}
.glass-button::before {
content: '';
position: absolute;
inset: 0;
border-radius: inherit;
padding: 2px;
background: linear-gradient(135deg, rgba(0, 0, 0, 0.8), transparent);
-webkit-mask:
linear-gradient(#fff 0 0) content-box,
linear-gradient(#fff 0 0);
-webkit-mask-composite: xor;
mask-composite: exclude;
pointer-events: none;
}
.glass-button:hover {
transform: translateY(-2px);
background: rgba(0, 0, 0, 0.35);
box-shadow:
0 12px 32px rgba(0, 0, 0, 0.6),
inset 0 1px 0 rgba(255, 255, 255, 0.25);
}
.glass-button:hover::before {
background: linear-gradient(135deg, rgba(255, 255, 255, 0.3), transparent);
}
.glass-button-sm {
min-height: 0 !important;
height: auto !important;
line-height: inherit;
padding-block: 0.375rem !important;
padding-block: 0.375rem;
padding-inline: 0.75rem;
font-size: 0.875rem;
}
/* Toast - glassmorphic, top-right */
@@ -111,39 +139,10 @@
transform: translateX(1rem);
}
/* Gradient containers - transparent to black */
.gradient-card {
background: linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, rgba(0, 0, 0, 0.8) 100%);
backdrop-filter: blur(18px);
-webkit-backdrop-filter: blur(18px);
border: 1px solid rgba(255, 255, 255, 0.15);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
border-radius: 1rem;
}
.gradient-card-dark {
background: linear-gradient(180deg, rgba(0, 0, 0, 0.4) 0%, rgba(0, 0, 0, 0.9) 100%);
backdrop-filter: blur(18px);
-webkit-backdrop-filter: blur(18px);
border: 1px solid rgba(255, 255, 255, 0.1);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
border-radius: 1rem;
}
.gradient-button {
background: linear-gradient(135deg, rgba(255, 255, 255, 0.15) 0%, rgba(0, 0, 0, 0.8) 100%);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.2);
color: rgba(255, 255, 255, 0.95);
transition: all 0.3s ease;
}
.gradient-button:hover {
background: linear-gradient(135deg, rgba(255, 255, 255, 0.2) 0%, rgba(0, 0, 0, 0.9) 100%);
border-color: rgba(255, 255, 255, 0.3);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.6);
}
/* BANNED: gradient-card, gradient-card-dark, gradient-button
Use .glass-card or .path-option-card for containers.
Use .glass-button for all buttons.
These gradient styles break the clean glass aesthetic. */
/* Gradient border for logo badge */
.logo-gradient-border {
@@ -198,7 +197,7 @@
-webkit-backdrop-filter: blur(40px);
border-radius: 24px;
border: 1px solid rgba(255, 255, 255, 0.06);
box-shadow:
box-shadow:
0 20px 60px rgba(0, 0, 0, 0.3),
inset 0 1px 0 rgba(255, 255, 255, 0.1);
display: flex;
@@ -236,8 +235,8 @@
border-radius: inherit;
padding: 2px;
background: linear-gradient(135deg, rgba(0, 0, 0, 0.8), transparent);
-webkit-mask:
linear-gradient(#fff 0 0) content-box,
-webkit-mask:
linear-gradient(#fff 0 0) content-box,
linear-gradient(#fff 0 0);
-webkit-mask-composite: xor;
mask-composite: exclude;
@@ -248,7 +247,7 @@
.path-option-card svg {
color: rgba(255, 255, 255, 0.85);
transition: all 0.3s ease;
filter:
filter:
drop-shadow(0 1px 1px rgba(255, 255, 255, 0.3))
drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))
drop-shadow(0 -1px 2px rgba(0, 0, 0, 0.6));
@@ -269,7 +268,7 @@
.path-option-card:hover svg {
color: rgba(255, 255, 255, 1);
filter:
filter:
drop-shadow(0 1px 2px rgba(255, 255, 255, 0.5))
drop-shadow(0 3px 6px rgba(0, 0, 0, 0.9))
drop-shadow(0 -1px 3px rgba(0, 0, 0, 0.7));
@@ -291,7 +290,7 @@
.path-option-card--selected svg {
color: rgba(255, 255, 255, 1);
filter:
filter:
drop-shadow(0 1px 2px rgba(255, 255, 255, 0.6))
drop-shadow(0 3px 8px rgba(0, 0, 0, 1))
drop-shadow(0 0 12px rgba(255, 255, 255, 0.3));
@@ -299,7 +298,7 @@
.path-option-card--selected h3 {
color: rgba(255, 255, 255, 1);
}
}
/* Action Buttons */
.path-action-button {
@@ -415,7 +414,7 @@ body {
font-family: 'Avenir Next', system-ui, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
background: #000 url('/assets/img/bg.jpg') center top / auto 100vh no-repeat fixed;
background: #000;
color: white;
min-height: 100vh;
}