feat: add DeepVoidBackground and update UI theme across pages

- Add DeepVoidBackground component with animated gradient effects
- Apply nofx theme classes to StrategyStudioPage, AITradersPage, etc.
- Update styling for consistent dark theme with gold accents
- Add PageNotFound and TraderDashboardPage components
This commit is contained in:
tinkle-community
2026-01-04 17:49:59 +08:00
parent bdfd8dc0d0
commit 50923f6a2e
22 changed files with 3493 additions and 3960 deletions

View File

@@ -85,10 +85,7 @@ export default function HeaderBar({
className="flex items-center gap-2 hover:opacity-80 transition-opacity cursor-pointer"
>
<img src="/icons/nofx.svg" alt="NOFX Logo" className="w-7 h-7" />
<span
className="text-lg font-bold"
style={{ color: 'var(--brand-yellow)' }}
>
<span className="text-lg font-bold text-nofx-gold">
NOFX
</span>
</div>
@@ -128,28 +125,12 @@ export default function HeaderBar({
<button
key={tab.page}
onClick={() => handleNavClick(tab)}
className="text-sm font-bold transition-all duration-300 relative focus:outline-2 focus:outline-yellow-500"
style={{
color: currentPage === tab.page ? 'var(--brand-yellow)' : 'var(--brand-light-gray)',
padding: '8px 12px',
borderRadius: '8px',
position: 'relative',
}}
onMouseEnter={(e) => {
if (currentPage !== tab.page) {
e.currentTarget.style.color = 'var(--brand-yellow)'
}
}}
onMouseLeave={(e) => {
if (currentPage !== tab.page) {
e.currentTarget.style.color = 'var(--brand-light-gray)'
}
}}
className={`text-sm font-bold transition-all duration-300 relative focus:outline-2 focus:outline-yellow-500 px-3 py-2 rounded-lg
${currentPage === tab.page ? 'text-nofx-gold' : 'text-nofx-text-muted hover:text-nofx-gold'}`}
>
{currentPage === tab.page && (
<span
className="absolute inset-0 rounded-lg"
style={{ background: 'rgba(240, 185, 11, 0.15)', zIndex: -1 }}
className="absolute inset-0 rounded-lg bg-nofx-gold/15 -z-10"
/>
)}
{tab.label}
@@ -167,16 +148,7 @@ export default function HeaderBar({
href={OFFICIAL_LINKS.github}
target="_blank"
rel="noopener noreferrer"
className="p-2 rounded-lg transition-all hover:scale-110"
style={{ color: '#848E9C' }}
onMouseEnter={(e) => {
e.currentTarget.style.color = '#EAECEF'
e.currentTarget.style.background = 'rgba(255, 255, 255, 0.05)'
}}
onMouseLeave={(e) => {
e.currentTarget.style.color = '#848E9C'
e.currentTarget.style.background = 'transparent'
}}
className="p-2 rounded-lg transition-all hover:scale-110 text-nofx-text-muted hover:text-white hover:bg-white/5"
title="GitHub"
>
<svg width="18" height="18" viewBox="0 0 16 16" fill="currentColor">
@@ -188,16 +160,7 @@ export default function HeaderBar({
href={OFFICIAL_LINKS.twitter}
target="_blank"
rel="noopener noreferrer"
className="p-2 rounded-lg transition-all hover:scale-110"
style={{ color: '#848E9C' }}
onMouseEnter={(e) => {
e.currentTarget.style.color = '#1DA1F2'
e.currentTarget.style.background = 'rgba(29, 161, 242, 0.1)'
}}
onMouseLeave={(e) => {
e.currentTarget.style.color = '#848E9C'
e.currentTarget.style.background = 'transparent'
}}
className="p-2 rounded-lg transition-all hover:scale-110 text-nofx-text-muted hover:text-[#1DA1F2] hover:bg-[#1DA1F2]/10"
title="Twitter"
>
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
@@ -209,16 +172,7 @@ export default function HeaderBar({
href={OFFICIAL_LINKS.telegram}
target="_blank"
rel="noopener noreferrer"
className="p-2 rounded-lg transition-all hover:scale-110"
style={{ color: '#848E9C' }}
onMouseEnter={(e) => {
e.currentTarget.style.color = '#0088cc'
e.currentTarget.style.background = 'rgba(0, 136, 204, 0.1)'
}}
onMouseLeave={(e) => {
e.currentTarget.style.color = '#848E9C'
e.currentTarget.style.background = 'transparent'
}}
className="p-2 rounded-lg transition-all hover:scale-110 text-nofx-text-muted hover:text-[#0088cc] hover:bg-[#0088cc]/10"
title="Telegram"
>
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
@@ -237,62 +191,24 @@ export default function HeaderBar({
<div className="relative" ref={userDropdownRef}>
<button
onClick={() => setUserDropdownOpen(!userDropdownOpen)}
className="flex items-center gap-2 px-3 py-2 rounded transition-colors"
style={{
background: 'var(--panel-bg)',
border: '1px solid var(--panel-border)',
}}
onMouseEnter={(e) =>
(e.currentTarget.style.background =
'rgba(255, 255, 255, 0.05)')
}
onMouseLeave={(e) =>
(e.currentTarget.style.background = 'var(--panel-bg)')
}
className="flex items-center gap-2 px-3 py-2 rounded transition-colors bg-nofx-bg-lighter border border-nofx-gold/20 hover:bg-white/5"
>
<div
className="w-6 h-6 rounded-full flex items-center justify-center text-xs font-bold"
style={{
background: 'var(--brand-yellow)',
color: 'var(--brand-black)',
}}
>
<div className="w-6 h-6 rounded-full flex items-center justify-center text-xs font-bold bg-nofx-gold text-black">
{user.email[0].toUpperCase()}
</div>
<span
className="text-sm"
style={{ color: 'var(--brand-light-gray)' }}
>
<span className="text-sm text-nofx-text-muted">
{user.email}
</span>
<ChevronDown
className="w-4 h-4"
style={{ color: 'var(--brand-light-gray)' }}
/>
<ChevronDown className="w-4 h-4 text-nofx-text-muted" />
</button>
{userDropdownOpen && (
<div
className="absolute right-0 top-full mt-2 w-48 rounded-lg shadow-lg overflow-hidden z-50"
style={{
background: 'var(--brand-dark-gray)',
border: '1px solid var(--panel-border)',
}}
>
<div
className="px-3 py-2 border-b"
style={{ borderColor: 'var(--panel-border)' }}
>
<div
className="text-xs"
style={{ color: 'var(--text-secondary)' }}
>
<div className="absolute right-0 top-full mt-2 w-48 rounded-lg shadow-lg overflow-hidden z-50 bg-nofx-bg-lighter border border-nofx-gold/20">
<div className="px-3 py-2 border-b border-nofx-gold/20">
<div className="text-xs text-nofx-text-muted">
{t('loggedInAs', language)}
</div>
<div
className="text-sm font-medium"
style={{ color: 'var(--brand-light-gray)' }}
>
<div className="text-sm font-medium text-nofx-text-muted">
{user.email}
</div>
</div>
@@ -302,11 +218,7 @@ export default function HeaderBar({
onLogout()
setUserDropdownOpen(false)
}}
className="w-full px-3 py-2 text-sm font-semibold transition-colors hover:opacity-80 text-center"
style={{
background: 'var(--binance-red-bg)',
color: 'var(--binance-red)',
}}
className="w-full px-3 py-2 text-sm font-semibold transition-colors hover:opacity-80 text-center bg-nofx-danger/20 text-nofx-danger"
>
{t('exitLogin', language)}
</button>
@@ -322,19 +234,14 @@ export default function HeaderBar({
<div className="flex items-center gap-3">
<a
href="/login"
className="px-3 py-2 text-sm font-medium transition-colors rounded"
style={{ color: 'var(--brand-light-gray)' }}
className="px-3 py-2 text-sm font-medium transition-colors rounded text-nofx-text-muted hover:text-white"
>
{t('signIn', language)}
</a>
{registrationEnabled && (
<a
href="/register"
className="px-4 py-2 rounded font-semibold text-sm transition-colors hover:opacity-90"
style={{
background: 'var(--brand-yellow)',
color: 'var(--brand-black)',
}}
className="px-4 py-2 rounded font-semibold text-sm transition-colors hover:opacity-90 bg-nofx-gold text-black"
>
{t('signUp', language)}
</a>
@@ -347,15 +254,7 @@ export default function HeaderBar({
<div className="relative" ref={dropdownRef}>
<button
onClick={() => setLanguageDropdownOpen(!languageDropdownOpen)}
className="flex items-center gap-2 px-3 py-2 rounded transition-colors"
style={{ color: 'var(--brand-light-gray)' }}
onMouseEnter={(e) =>
(e.currentTarget.style.background =
'rgba(255, 255, 255, 0.05)')
}
onMouseLeave={(e) =>
(e.currentTarget.style.background = 'transparent')
}
className="flex items-center gap-2 px-3 py-2 rounded transition-colors text-nofx-text-muted hover:bg-white/5"
>
<span className="text-lg">
{language === 'zh' ? '🇨🇳' : '🇺🇸'}
@@ -364,28 +263,14 @@ export default function HeaderBar({
</button>
{languageDropdownOpen && (
<div
className="absolute right-0 top-full mt-2 w-32 rounded-lg shadow-lg overflow-hidden z-50"
style={{
background: 'var(--brand-dark-gray)',
border: '1px solid var(--panel-border)',
}}
>
<div className="absolute right-0 top-full mt-2 w-32 rounded-lg shadow-lg overflow-hidden z-50 bg-nofx-bg-lighter border border-nofx-gold/20">
<button
onClick={() => {
onLanguageChange?.('zh')
setLanguageDropdownOpen(false)
}}
className={`w-full flex items-center gap-2 px-3 py-2 transition-colors ${
language === 'zh' ? '' : 'hover:opacity-80'
}`}
style={{
color: 'var(--brand-light-gray)',
background:
language === 'zh'
? 'rgba(240, 185, 11, 0.1)'
: 'transparent',
}}
className={`w-full flex items-center gap-2 px-3 py-2 transition-colors text-nofx-text-muted hover:text-white
${language === 'zh' ? 'bg-nofx-gold/10' : 'hover:bg-white/5'}`}
>
<span className="text-base">🇨🇳</span>
<span className="text-sm"></span>
@@ -395,16 +280,8 @@ export default function HeaderBar({
onLanguageChange?.('en')
setLanguageDropdownOpen(false)
}}
className={`w-full flex items-center gap-2 px-3 py-2 transition-colors ${
language === 'en' ? '' : 'hover:opacity-80'
}`}
style={{
color: 'var(--brand-light-gray)',
background:
language === 'en'
? 'rgba(240, 185, 11, 0.1)'
: 'transparent',
}}
className={`w-full flex items-center gap-2 px-3 py-2 transition-colors text-nofx-text-muted hover:text-white
${language === 'en' ? 'bg-nofx-gold/10' : 'hover:bg-white/5'}`}
>
<span className="text-base">🇺🇸</span>
<span className="text-sm">English</span>
@@ -418,8 +295,7 @@ export default function HeaderBar({
{/* Mobile Menu Button */}
<motion.button
onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
className="md:hidden"
style={{ color: 'var(--brand-light-gray)' }}
className="md:hidden text-nofx-text-muted hover:text-white"
whileTap={{ scale: 0.9 }}
>
{mobileMenuOpen ? (
@@ -439,11 +315,7 @@ export default function HeaderBar({
: { height: 0, opacity: 0 }
}
transition={{ duration: 0.3 }}
className="md:hidden overflow-hidden"
style={{
background: 'var(--brand-dark-gray)',
borderTop: '1px solid rgba(240, 185, 11, 0.1)',
}}
className="md:hidden overflow-hidden bg-nofx-bg-lighter border-t border-nofx-gold/10"
>
<div className="px-4 py-4 space-y-2">
{/* Mobile Navigation Tabs - Show all tabs */}
@@ -476,25 +348,17 @@ export default function HeaderBar({
<button
key={tab.page}
onClick={() => handleMobileNavClick(tab)}
className="block text-sm font-bold transition-all duration-300 relative focus:outline-2 focus:outline-yellow-500"
style={{
color: currentPage === tab.page ? 'var(--brand-yellow)' : 'var(--brand-light-gray)',
padding: '12px 16px',
borderRadius: '8px',
position: 'relative',
width: '100%',
textAlign: 'left',
}}
className={`block text-sm font-bold transition-all duration-300 relative focus:outline-2 focus:outline-yellow-500 w-full text-left px-4 py-3 rounded-lg
${currentPage === tab.page ? 'text-nofx-gold' : 'text-nofx-text-muted hover:text-white hover:bg-white/5'}`}
>
{currentPage === tab.page && (
<span
className="absolute inset-0 rounded-lg"
style={{ background: 'rgba(240, 185, 11, 0.15)', zIndex: -1 }}
className="absolute inset-0 rounded-lg bg-nofx-gold/15 -z-10"
/>
)}
{tab.label}
{tab.requiresAuth && !isLoggedIn && (
<span className="ml-2 text-[10px] px-1.5 py-0.5 rounded" style={{ background: 'rgba(240, 185, 11, 0.2)', color: '#F0B90B' }}>
<span className="ml-2 text-[10px] px-1.5 py-0.5 rounded bg-nofx-gold/20 text-nofx-gold">
{language === 'zh' ? '需登录' : 'Login'}
</span>
)}
@@ -511,21 +375,19 @@ export default function HeaderBar({
<a
key={item.key}
href={`#${item.key === 'features' ? 'features' : 'how-it-works'}`}
className="block text-sm py-2"
style={{ color: 'var(--brand-light-gray)' }}
className="block text-sm py-2 text-nofx-text-muted hover:text-white"
>
{item.label}
</a>
))}
{/* Social Links - Mobile */}
<div className="py-3 flex items-center gap-3" style={{ borderTop: '1px solid #2B3139' }}>
<div className="py-3 flex items-center gap-3 border-t border-nofx-gold/20">
<a
href={OFFICIAL_LINKS.github}
target="_blank"
rel="noopener noreferrer"
className="p-2 rounded-lg"
style={{ color: '#848E9C', background: 'rgba(255, 255, 255, 0.05)' }}
className="p-2 rounded-lg text-nofx-text-muted bg-white/5 hover:text-white"
>
<svg width="20" height="20" viewBox="0 0 16 16" fill="currentColor">
<path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z" />
@@ -535,8 +397,7 @@ export default function HeaderBar({
href={OFFICIAL_LINKS.twitter}
target="_blank"
rel="noopener noreferrer"
className="p-2 rounded-lg"
style={{ color: '#848E9C', background: 'rgba(255, 255, 255, 0.05)' }}
className="p-2 rounded-lg text-nofx-text-muted bg-white/5 hover:text-[#1DA1F2]"
>
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor">
<path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z" />
@@ -546,8 +407,7 @@ export default function HeaderBar({
href={OFFICIAL_LINKS.telegram}
target="_blank"
rel="noopener noreferrer"
className="p-2 rounded-lg"
style={{ color: '#848E9C', background: 'rgba(255, 255, 255, 0.05)' }}
className="p-2 rounded-lg text-nofx-text-muted bg-white/5 hover:text-[#0088cc]"
>
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor">
<path d="M11.944 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0a12 12 0 0 0-.056 0zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472-.18 1.898-.962 6.502-1.36 8.627-.168.9-.499 1.201-.82 1.23-.696.065-1.225-.46-1.9-.902-1.056-.693-1.653-1.124-2.678-1.8-1.185-.78-.417-1.21.258-1.91.177-.184 3.247-2.977 3.307-3.23.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345-.48.33-.913.49-1.302.48-.428-.008-1.252-.241-1.865-.44-.752-.245-1.349-.374-1.297-.789.027-.216.325-.437.893-.663 3.498-1.524 5.83-2.529 6.998-3.014 3.332-1.386 4.025-1.627 4.476-1.635z" />
@@ -558,10 +418,7 @@ export default function HeaderBar({
{/* Language Toggle */}
<div className="py-2">
<div className="flex items-center gap-2 mb-2">
<span
className="text-xs"
style={{ color: 'var(--brand-light-gray)' }}
>
<span className="text-xs text-nofx-text-muted">
{t('language', language)}:
</span>
</div>
@@ -571,11 +428,10 @@ export default function HeaderBar({
onLanguageChange?.('zh')
setMobileMenuOpen(false)
}}
className={`w-full flex items-center gap-3 px-3 py-2 rounded transition-colors ${
language === 'zh'
? 'bg-yellow-500 text-black'
: 'text-gray-400 hover:text-white'
}`}
className={`w-full flex items-center gap-3 px-3 py-2 rounded transition-colors ${language === 'zh'
? 'bg-yellow-500 text-black'
: 'text-gray-400 hover:text-white'
}`}
>
<span className="text-lg">🇨🇳</span>
<span className="text-sm"></span>
@@ -585,11 +441,10 @@ export default function HeaderBar({
onLanguageChange?.('en')
setMobileMenuOpen(false)
}}
className={`w-full flex items-center gap-3 px-3 py-2 rounded transition-colors ${
language === 'en'
? 'bg-yellow-500 text-black'
: 'text-gray-400 hover:text-white'
}`}
className={`w-full flex items-center gap-3 px-3 py-2 rounded transition-colors ${language === 'en'
? 'bg-yellow-500 text-black'
: 'text-gray-400 hover:text-white'
}`}
>
<span className="text-lg">🇺🇸</span>
<span className="text-sm">English</span>
@@ -600,33 +455,17 @@ export default function HeaderBar({
{/* User info and logout for mobile when logged in */}
{isLoggedIn && user && (
<div
className="mt-4 pt-4"
style={{ borderTop: '1px solid var(--panel-border)' }}
className="mt-4 pt-4 border-t border-nofx-gold/20"
>
<div
className="flex items-center gap-2 px-3 py-2 mb-2 rounded"
style={{ background: 'var(--panel-bg)' }}
>
<div
className="w-6 h-6 rounded-full flex items-center justify-center text-xs font-bold"
style={{
background: 'var(--brand-yellow)',
color: 'var(--brand-black)',
}}
>
<div className="flex items-center gap-2 px-3 py-2 mb-2 rounded bg-nofx-bg-lighter">
<div className="w-6 h-6 rounded-full flex items-center justify-center text-xs font-bold bg-nofx-gold text-black">
{user.email[0].toUpperCase()}
</div>
<div>
<div
className="text-xs"
style={{ color: 'var(--text-secondary)' }}
>
<div className="text-xs text-nofx-text-muted">
{t('loggedInAs', language)}
</div>
<div
className="text-sm"
style={{ color: 'var(--brand-light-gray)' }}
>
<div className="text-sm text-nofx-text-muted">
{user.email}
</div>
</div>
@@ -637,11 +476,7 @@ export default function HeaderBar({
onLogout()
setMobileMenuOpen(false)
}}
className="w-full px-4 py-2 rounded text-sm font-semibold transition-colors text-center"
style={{
background: 'var(--binance-red-bg)',
color: 'var(--binance-red)',
}}
className="w-full px-4 py-2 rounded text-sm font-semibold transition-colors text-center bg-nofx-danger/20 text-nofx-danger"
>
{t('exitLogin', language)}
</button>
@@ -656,11 +491,7 @@ export default function HeaderBar({
<div className="space-y-2 mt-2">
<a
href="/login"
className="block w-full px-4 py-2 rounded text-sm font-medium text-center transition-colors"
style={{
color: 'var(--brand-light-gray)',
border: '1px solid var(--brand-light-gray)',
}}
className="block w-full px-4 py-2 rounded text-sm font-medium text-center transition-colors text-nofx-text-muted border border-nofx-text-muted hover:text-white hover:border-white"
onClick={() => setMobileMenuOpen(false)}
>
{t('signIn', language)}
@@ -668,11 +499,7 @@ export default function HeaderBar({
{registrationEnabled && (
<a
href="/register"
className="block w-full px-4 py-2 rounded font-semibold text-sm text-center transition-colors"
style={{
background: 'var(--brand-yellow)',
color: 'var(--brand-black)',
}}
className="block w-full px-4 py-2 rounded font-semibold text-sm text-center transition-colors bg-nofx-gold text-black hover:opacity-90"
onClick={() => setMobileMenuOpen(false)}
>
{t('signUp', language)}