Skip to content

Commit ca9d721

Browse files
committed
feat(ui): complete visual redesign with Dead Frequency theme
- Replace dark glassmorphism with warm parchment industrial aesthetic - New color palette: amber TX (#C85A00), teal RX (#007A6B), parchment bg (#F2EDE4) - Typography: DM Serif Display (headings) + IBM Plex Mono (readouts) - Custom CSS design system: .panel, .btn, .badge, .stat-tile, .console-area - Replace Aurora WebGL bg with grid-texture + SVG arc corner accents - Remove 60/80-bar animated visualizers, replace with elegant 7-bar SoundWave - Add pulsing concentric rings around TX/RX icon when audio is active - Redesign home page: accent-strip cards, serif masthead, DecryptedText - Redesign footer as instrument status bar (ADL-8FSK / SYS OK) - Update APIOverrideModal to match new design system - Fix Framer Motion onHoverStart null currentTarget crash (Home.tsx)
1 parent 4fbdbba commit ca9d721

8 files changed

Lines changed: 928 additions & 611 deletions

File tree

index.html

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@
55
<meta charset="UTF-8" />
66
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
77
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
8-
<title>Transmit via Sound</title>
8+
<title>Acoustic Data Link — Transmit via Sound</title>
9+
<meta name="description" content="Air-gapped peer-to-peer acoustic data transmission using FSK audio signals." />
10+
<!-- Distinctive font pairing: DM Serif Display (editorial heading) + IBM Plex Mono (technical readouts) -->
11+
<link rel="preconnect" href="https://fonts.googleapis.com" />
12+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
13+
<link href="https://fonts.googleapis.com/css2?family=DM+Serif+Display:ital@0;1&family=IBM+Plex+Mono:ital,wght@0,300;0,400;0,500;0,600;1,400&family=Barlow+Condensed:wght@300;400;500;600;700&display=swap" rel="stylesheet" />
914
</head>
1015

1116
<body>

src/components/Layout/APIOverrideModal.tsx

Lines changed: 47 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -19,62 +19,75 @@ export const APIOverrideModal: React.FC = () => {
1919
initial={{ opacity: 0 }}
2020
animate={{ opacity: 1 }}
2121
exit={{ opacity: 0 }}
22-
className="fixed inset-0 z-[100] flex items-center justify-center p-4 bg-background/80 backdrop-blur-md"
22+
className="fixed inset-0 z-[100] flex items-center justify-center p-4"
23+
style={{ background: 'rgba(242, 237, 228, 0.85)', backdropFilter: 'blur(6px)' }}
2324
>
2425
<motion.div
25-
initial={{ scale: 0.95, y: 20 }}
26+
initial={{ scale: 0.95, y: 16 }}
2627
animate={{ scale: 1, y: 0 }}
27-
exit={{ scale: 0.95, y: 20 }}
28-
className="w-full max-w-md glass-panel overflow-hidden border border-white/10 shadow-2xl relative"
28+
exit={{ scale: 0.95, y: 16 }}
29+
className="panel w-full max-w-md relative overflow-hidden"
2930
>
31+
{/* Accent strip */}
32+
<div style={{ position: 'absolute', top: 0, left: 0, right: 0, height: 3, background: 'var(--color-warning)' }} />
33+
3034
<button
3135
onClick={() => setApiOverrideModalOpen(false)}
32-
className="absolute top-4 right-4 text-textMuted hover:text-white transition-colors"
36+
style={{ position: 'absolute', top: 14, right: 14, color: 'var(--color-text-muted)', background: 'none', border: 'none', cursor: 'pointer', padding: 4 }}
3337
>
34-
<X size={20} />
38+
<X size={18} />
3539
</button>
36-
<div className="p-6 border-b border-white/5 space-y-2">
40+
41+
<div className="p-6 flex flex-col gap-5" style={{ paddingTop: '1.75rem' }}>
3742
<div className="flex items-center gap-3">
38-
<div className="w-10 h-10 rounded-full bg-warning/20 text-warning flex items-center justify-center">
39-
<AlertTriangle size={20} />
43+
<div className="flex items-center justify-center rounded-full"
44+
style={{ width: 40, height: 40, background: 'rgba(230, 81, 0, 0.12)', color: 'var(--color-warning)' }}>
45+
<AlertTriangle size={18} />
46+
</div>
47+
<div>
48+
<h2 style={{ fontFamily: "'DM Serif Display', serif", fontSize: '1.25rem', fontWeight: 400, color: 'var(--color-text)' }}>
49+
System Limit Reached
50+
</h2>
4051
</div>
41-
<h2 className="text-xl font-bold tracking-tight">System Limit Reached</h2>
4252
</div>
43-
<p className="text-sm text-textMuted leading-relaxed pt-2">
44-
The system API key has expired or reached its limit. Please enter your own Google API Key to continue.
53+
54+
<p style={{ fontFamily: "'IBM Plex Mono', monospace", fontSize: '0.68rem', color: 'var(--color-text-muted)', lineHeight: 1.7 }}>
55+
The system API key has expired or reached its limit.
56+
Enter your own Google API Key to continue.
4557
</p>
46-
</div>
4758

48-
<div className="p-6 space-y-4">
49-
<div className="space-y-2">
50-
<label className="text-xs font-mono text-textMuted flex items-center gap-2">
51-
<Key size={12} />
52-
GOOGLE GEMINI API KEY
59+
<div className="flex flex-col gap-2">
60+
<label className="label" style={{ fontFamily: "'IBM Plex Mono', monospace" }}>
61+
<Key size={11} /> Google Gemini API Key
5362
</label>
5463
<input
5564
type="password"
5665
value={inputValue}
57-
onChange={(e) => setInputValue(e.target.value)}
66+
onChange={e => setInputValue(e.target.value)}
5867
placeholder="AIzaSy..."
59-
className="glass-input font-mono text-sm tracking-widest placeholder:opacity-50"
68+
className="field"
69+
style={{ fontFamily: "'IBM Plex Mono', monospace", letterSpacing: '0.08em' }}
6070
autoFocus
6171
/>
6272
</div>
63-
</div>
6473

65-
<div className="p-6 pt-0 flex justify-end gap-3">
66-
<button
67-
onClick={() => setApiOverrideModalOpen(false)}
68-
className="px-4 py-2 rounded-lg text-sm text-textMuted hover:text-white transition-colors"
69-
>
70-
Cancel
71-
</button>
72-
<button
73-
onClick={handleSave}
74-
className="px-6 py-2 rounded-lg text-sm font-medium bg-primary text-black hover:bg-primary/90 transition-colors shadow-[0_0_15px_rgba(124,255,103,0.3)] hover:shadow-[0_0_25px_rgba(124,255,103,0.5)]"
75-
>
76-
Override System
77-
</button>
74+
<div style={{ paddingTop: '0.5rem', borderTop: '1px solid var(--color-border)', display: 'flex', justifyContent: 'flex-end', gap: 8 }}>
75+
<button onClick={() => setApiOverrideModalOpen(false)} className="btn btn-ghost"
76+
style={{ fontFamily: "'IBM Plex Mono', monospace" }}>
77+
Cancel
78+
</button>
79+
<button onClick={handleSave} className="btn btn-primary"
80+
style={{ fontFamily: "'IBM Plex Mono', monospace" }}>
81+
Override System
82+
</button>
83+
</div>
84+
85+
<p style={{ fontFamily: "'IBM Plex Mono', monospace", fontSize: '0.6rem', color: 'var(--color-text-faint)', textAlign: 'center' }}>
86+
System Error? Contact Asmith —{' '}
87+
<a href="mailto:asmyth@duck.com" style={{ color: 'var(--color-primary)', textDecoration: 'none' }}>
88+
asmyth@duck.com
89+
</a>
90+
</p>
7891
</div>
7992
</motion.div>
8093
</motion.div>

src/components/Layout/Footer.tsx

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,27 @@
11
import React from 'react';
2-
import { Mail } from 'lucide-react';
32

43
export const Footer: React.FC = () => {
54
return (
6-
<footer className="fixed bottom-0 left-0 w-full z-50 p-6 flex justify-between items-center pointer-events-none">
7-
<div className="flex-1"></div>
8-
<div className="pointer-events-auto bg-surface/30 backdrop-blur-sm border border-white/5 rounded-full px-4 py-2 flex items-center gap-2 transition-all hover:bg-surface/50 hover:border-white/10">
9-
<a
10-
href="mailto:asmyth@duck.com"
11-
className="text-xs text-textMuted hover:text-white transition-colors flex items-center gap-2 group"
12-
>
13-
<span>Developed by Asmith</span>
14-
<span className="opacity-50 group-hover:opacity-100 transition-opacity"></span>
15-
<Mail className="w-3 h-3 group-hover:text-primary transition-colors" />
16-
<span className="group-hover:text-primary transition-colors">asmyth@duck.com</span>
17-
</a>
18-
</div>
5+
<footer className="relative z-20 w-full border-t flex items-center justify-between px-6 md:px-10 py-3" style={{ borderColor: 'var(--color-border)', background: 'var(--color-surface)' }}>
6+
{/* Left — system tag */}
7+
<span className="label text-[10px]" style={{ fontFamily: "'IBM Plex Mono', monospace", color: 'var(--color-text-faint)' }}>
8+
ADL-8FSK / v1.0
9+
</span>
10+
11+
{/* Centre — attribution */}
12+
<a
13+
href="mailto:asmyth@duck.com"
14+
className="label hover:opacity-80 transition-opacity"
15+
style={{ fontFamily: "'IBM Plex Mono', monospace", fontSize: '0.62rem', color: 'var(--color-text-muted)', textDecoration: 'none' }}
16+
>
17+
Developed by Asmith&nbsp;—&nbsp;asmyth@duck.com
18+
</a>
19+
20+
{/* Right — status dot */}
21+
<span className="flex items-center gap-1.5 label" style={{ fontFamily: "'IBM Plex Mono', monospace", fontSize: '0.58rem', color: 'var(--color-text-faint)' }}>
22+
<span className="inline-block w-1.5 h-1.5 rounded-full" style={{ background: 'var(--color-success)' }} />
23+
SYS OK
24+
</span>
1925
</footer>
2026
);
2127
};

src/components/Layout/Layout.tsx

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import React from 'react';
22
import { Outlet } from 'react-router-dom';
3-
import Aurora from '../Background/Aurora';
43
import { Footer } from './Footer';
54
import { APIOverrideModal } from './APIOverrideModal';
65
import { useAppStore } from '../../hooks/useAppStore';
@@ -9,25 +8,42 @@ export const Layout: React.FC = () => {
98
const { reducedMotion } = useAppStore();
109

1110
return (
12-
<div className="relative min-h-screen w-full overflow-hidden bg-background text-text flex flex-col items-center">
13-
{/* Immersive Background Layer */}
14-
<div className="fixed inset-0 z-0 pointer-events-none opacity-60">
15-
{!reducedMotion ? (
16-
<Aurora colorStops={['#5227FF', '#2A1A5E', '#1D0F3F']} amplitude={0.8} blend={0.6} />
17-
) : (
18-
<div className="absolute inset-0 bg-gradient-to-br from-[#121216] to-[#0a0a0c]" />
19-
)}
20-
</div>
11+
<div className="relative min-h-screen w-full overflow-hidden flex flex-col" style={{ background: 'var(--color-background)' }}>
2112

22-
{/* Subtle Noise Texture Overlay */}
23-
<div className="fixed inset-0 z-[1] pointer-events-none opacity-[0.03]" style={{ backgroundImage: 'url("data:image/svg+xml,%3Csvg viewBox=%220 0 200 200%22 xmlns=%22http://www.w3.org/2000/svg%22%3E%3Cfilter id=%22noiseFilter%22%3E%3CfeTurbulence type=%22fractalNoise%22 baseFrequency=%220.65%22 numOctaves=%223%22 stitchTiles=%22stitch%22/%3E%3C/filter%3E%3Crect width=%22100%25%22 height=%22100%25%22 filter=%22url(%23noiseFilter)%22/%3E%3C/svg%3E")' }}></div>
13+
{/* Grid texture pattern — fills the page with a subtle ruled-paper feel */}
14+
<div
15+
className="fixed inset-0 z-0 pointer-events-none grid-texture"
16+
aria-hidden="true"
17+
/>
2418

25-
{/* Main Content Render */}
26-
<main className="relative z-10 w-full max-w-7xl mx-auto px-4 md:px-8 py-10 md:py-20 flex-grow flex flex-col h-full items-center justify-center">
19+
{/* Top-left corner accent — decorative signal mark */}
20+
{!reducedMotion && (
21+
<div className="fixed top-0 left-0 z-0 pointer-events-none" aria-hidden="true">
22+
<svg width="320" height="320" viewBox="0 0 320 320" fill="none" xmlns="http://www.w3.org/2000/svg" opacity="0.07">
23+
{/* Concentric quarter-circles — signal antenna motif */}
24+
{[60, 110, 160, 210, 260].map((r, i) => (
25+
<path key={i} d={`M 0 0 A ${r} ${r} 0 0 1 ${r} 0`} stroke="var(--color-primary)" strokeWidth="1" fill="none" />
26+
))}
27+
</svg>
28+
</div>
29+
)}
30+
31+
{/* Bottom-right mirror accent */}
32+
{!reducedMotion && (
33+
<div className="fixed bottom-0 right-0 z-0 pointer-events-none rotate-180" aria-hidden="true">
34+
<svg width="240" height="240" viewBox="0 0 240 240" fill="none" xmlns="http://www.w3.org/2000/svg" opacity="0.05">
35+
{[50, 90, 130, 170, 210].map((r, i) => (
36+
<path key={i} d={`M 0 0 A ${r} ${r} 0 0 1 ${r} 0`} stroke="var(--color-accent)" strokeWidth="1" fill="none" />
37+
))}
38+
</svg>
39+
</div>
40+
)}
41+
42+
{/* Main content */}
43+
<main className="relative z-10 w-full max-w-7xl mx-auto px-4 md:px-8 py-10 md:py-16 flex-grow flex flex-col items-center justify-center">
2744
<Outlet />
2845
</main>
2946

30-
{/* Global Elements */}
3147
<Footer />
3248
<APIOverrideModal />
3349
</div>

0 commit comments

Comments
 (0)