Initial commit: SREBOT website (Express/EJS + i18n) - extracted from SREBOT monorepo

This commit is contained in:
clxud
2026-07-02 02:35:56 +00:00
commit 7f2ab08adc
145 changed files with 148257 additions and 0 deletions
+266
View File
@@ -0,0 +1,266 @@
<style>
#langDropdown .hidden-dropdown { display: none; }
#langDropdown.open .hidden-dropdown { display: block; }
/* Bot product switcher — horizontal slider */
#botSwitcher .switcher-panel {
opacity: 0;
width: 0;
max-width: 0;
overflow: hidden;
pointer-events: none;
transition: width 320ms cubic-bezier(.2,.9,.25,1), max-width 320ms cubic-bezier(.2,.9,.25,1), opacity 220ms ease 40ms;
}
#botSwitcher.open .switcher-panel {
opacity: 1;
width: 440px;
max-width: 440px;
pointer-events: auto;
}
#botSwitcher .switcher-chevron { transition: transform 280ms cubic-bezier(.2,.9,.25,1); color: rgba(255,255,255,0.35); }
#botSwitcher.open .switcher-chevron { transform: rotate(-90deg); color: #90EE90; }
#botSwitcher .switcher-trigger:hover .switcher-chevron { color: #90EE90; }
.switcher-card {
position: relative;
flex: 1 1 0;
min-width: 0;
height: 88px;
display: flex;
align-items: stretch;
text-decoration: none;
overflow: visible;
transform: translateX(0);
opacity: 0;
transition: opacity 380ms ease 120ms, transform 380ms cubic-bezier(.2,.9,.25,1) 120ms, filter 220ms ease;
}
#botSwitcher .switcher-card.card-tss { transform: translateX(-14px); }
#botSwitcher .switcher-card.card-sre { transform: translateX(14px); }
#botSwitcher.open .switcher-card { opacity: 1; transform: translateX(0); }
.switcher-card-inner {
flex: 1;
display: flex;
align-items: center;
gap: 12px;
transition: background-color 200ms ease;
}
.switcher-card.card-tss .switcher-card-inner { flex-direction: row; padding: 10px 0 10px 26px; }
.switcher-card.card-sre .switcher-card-inner { flex-direction: row-reverse; padding: 10px 26px 10px 0; }
.switcher-card:hover .switcher-card-inner { background: rgba(255,255,255,0.04); }
.switcher-pfp {
flex: 0 0 auto;
width: 56px;
height: 56px;
border-radius: 14px;
border: 1px solid transparent;
object-fit: cover;
transition: transform 320ms cubic-bezier(.2,.9,.25,1), box-shadow 320ms ease;
}
.switcher-card.card-tss .switcher-pfp {
margin-right: -1px;
border-color: rgba(255,157,0,0.35);
border-right: 0;
border-radius: 14px 0 0 14px;
box-shadow: 0 0 18px -4px rgba(255,157,0,0.45);
}
.switcher-card.card-sre .switcher-pfp {
margin-left: -1px;
border-color: rgba(144,238,144,0.35);
border-left: 0;
border-radius: 0 14px 14px 0;
box-shadow: none;
}
.switcher-text {
flex: 1 1 auto;
min-width: 0;
display: flex;
flex-direction: column;
line-height: 1.1;
}
.switcher-card.card-tss .switcher-text { text-align: left; }
.switcher-card.card-sre .switcher-text { text-align: right; }
.switcher-card.card-tss .switcher-title,
.switcher-card.card-tss .switcher-sub { padding-left: 4px; }
.switcher-card.card-sre .switcher-title,
.switcher-card.card-sre .switcher-sub { padding-right: 4px; }
.switcher-title {
font-family: 'JetBrains Mono', ui-monospace, 'SFMono-Regular', Menlo, monospace;
font-size: 22px;
font-weight: 800;
letter-spacing: 0.08em;
color: #fff;
line-height: 1;
}
.switcher-card.card-tss .switcher-title {
background: linear-gradient(95deg,#fff7e8,#ffdca3 58%,#fffdf8);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
}
.switcher-card.card-sre .switcher-title {
background: linear-gradient(265deg,#90EE90,#d8ffd8 70%);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
}
.switcher-sub {
margin-top: 6px;
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.18em;
color: rgba(255,255,255,0.4);
}
.switcher-card.card-tss .switcher-pip,
.switcher-card.card-sre .switcher-pip {
display: inline-block;
width: 5px; height: 5px;
border-radius: 999px;
vertical-align: middle;
margin: 0 6px;
}
.switcher-card.card-tss .switcher-pip { background: #ff9d00; box-shadow: 0 0 6px #ff9d00; }
.switcher-card.card-sre .switcher-pip { background: #90EE90; box-shadow: 0 0 6px #90EE90; }
</style>
<!-- Navigation Bar -->
<nav class="fixed top-0 left-0 right-0 bg-[#1E1E1E]/98 backdrop-blur-md border-b border-white/5" style="z-index: 1000;">
<div class="w-full px-6 lg:px-8">
<div class="flex items-center h-16">
<!-- Left: Product switcher -->
<div class="relative flex-shrink-0" id="botSwitcher">
<button type="button" onclick="document.getElementById('botSwitcher').classList.toggle('open')" class="switcher-trigger flex items-center space-x-3 focus:outline-none focus-visible:ring-2 focus-visible:ring-[#90EE90]/40 rounded-md -ml-1 pl-1 pr-2 py-1" aria-haspopup="menu" aria-label="Switch bot">
<img src="/images/toothless_server.gif" alt="<%= botName %>" class="h-8 w-auto" width="32" height="32">
<span class="text-lg font-semibold whitespace-nowrap"><span class="text-[#90EE90]">Toothless</span> <span class="text-accent">SREBOT</span></span>
<i class="fas fa-chevron-down switcher-chevron text-[10px] ml-0.5"></i>
</button>
<div class="switcher-panel absolute left-0 top-full mt-2 bg-[#141414] border border-white/10 rounded-2xl shadow-2xl shadow-black/70" style="z-index: 200;" role="menu" aria-label="Bot switcher">
<div class="flex items-stretch h-[88px] w-[440px]">
<a href="https://tss.pawjob.us" class="switcher-card card-tss" role="menuitem" aria-label="Switch to Toothless TSS Bot">
<div class="switcher-card-inner">
<div class="switcher-text">
<span class="switcher-title">TSS</span>
<span class="switcher-sub"><span class="switcher-pip"></span>tssbot</span>
</div>
<img src="/images/light_fury_match.jpg" alt="Light Fury" class="switcher-pfp" width="56" height="56">
</div>
</a>
<a href="/" class="switcher-card card-sre" role="menuitem" aria-current="page" aria-label="Toothless SREBOT (current)">
<div class="switcher-card-inner">
<div class="switcher-text">
<span class="switcher-title">SRE</span>
<span class="switcher-sub">srebot<span class="switcher-pip"></span></span>
</div>
<img src="/images/toothless_match.jpg" alt="Toothless" class="switcher-pfp" width="56" height="56">
</div>
</a>
</div>
</div>
</div>
<!-- Center: Nav links -->
<div class="hidden lg:flex items-center justify-center flex-1 space-x-6">
<% const navLinks = [
{ href: '/', key: 'home' },
{ href: '/squadrons', key: 'squadrons' },
{ href: '/leaderboard/players', key: 'leaderboards' },
{ href: '/analytics', key: 'analytics' },
{ href: '/timeline', key: 'timeline' },
{ href: '/docs', key: 'docs' },
]; %>
<% navLinks.forEach(link => { %>
<% if (typeof activePage !== 'undefined' && activePage === link.key) { %>
<a href="<%= link.href %>" class="text-accent transition-colors text-sm font-medium border-b-2 border-accent pb-1"><%= t('nav.' + link.key) %></a>
<% } else { %>
<a href="<%= link.href %>" class="text-muted hover:text-accent transition-colors text-sm font-medium"><%= t('nav.' + link.key) %></a>
<% } %>
<% }); %>
<a href="/premium" class="<%= typeof activePage !== 'undefined' && activePage === 'premium' ? 'nav-premium transition-colors text-sm font-medium border-b-2 border-[#ffd700] pb-1' : 'nav-premium transition-colors text-sm font-medium' %>"><%= t('nav.premium') %></a>
<a href="/support" class="nav-rainbow transition-colors text-sm font-medium flex items-center">
<i class="fas fa-life-ring mr-1.5 text-xs"></i>
<%= t('nav.support') %>
</a>
<a href="https://ko-fi.com/notsotoothless" target="_blank" rel="noopener noreferrer" class="nav-donate transition-colors text-sm font-medium flex items-center">
<i class="fas fa-heart mr-1.5 text-xs"></i>
<%= t('nav.donate') %>
</a>
</div>
<!-- Right: Language toggle + Discord -->
<div class="hidden lg:flex items-center space-x-6 flex-shrink-0">
<div class="relative" id="langDropdown">
<button onclick="document.getElementById('langDropdown').classList.toggle('open')" class="flex items-center gap-3 px-3 py-1.5 text-sm font-medium rounded-md border transition-colors" style="border-color: rgba(144,238,144,0.2); color: #90EE90;">
<span id="langCurrent"><%= lang === 'en' ? 'ENG' : lang === 'ru' ? 'РУС' : lang === 'fr' ? 'FRA' : lang === 'it' ? 'ITA' : lang === 'uk' ? 'УКР' : lang === 'de' ? 'DEU' : lang === 'es' ? 'ESP' : lang === 'pl' ? 'POL' : lang === 'cs' ? 'CES' : '简中' %></span>
<i class="fas fa-chevron-down text-[10px] opacity-60"></i>
</button>
<div class="absolute right-0 top-full mt-1 min-w-[170px] bg-[#2A2A2A] border border-white/10 rounded-lg shadow-xl overflow-hidden hidden-dropdown" style="z-index: 100;">
<button onclick="switchLanguage('en')" class="lang-option w-full text-left px-3 py-2 text-sm hover:bg-white/5 transition-colors <%= lang === 'en' ? 'text-[#90EE90]' : 'text-white/70' %>">ENG <span class="text-white/30 ml-1">English</span></button>
<button onclick="switchLanguage('ru')" class="lang-option w-full text-left px-3 py-2 text-sm hover:bg-white/5 transition-colors <%= lang === 'ru' ? 'text-[#90EE90]' : 'text-white/70' %>">РУС <span class="text-white/30 ml-1">Русский</span></button>
<button onclick="switchLanguage('fr')" class="lang-option w-full text-left px-3 py-2 text-sm hover:bg-white/5 transition-colors <%= lang === 'fr' ? 'text-[#90EE90]' : 'text-white/70' %>">FRA <span class="text-white/30 ml-1">Français</span></button>
<button onclick="switchLanguage('it')" class="lang-option w-full text-left px-3 py-2 text-sm hover:bg-white/5 transition-colors <%= lang === 'it' ? 'text-[#90EE90]' : 'text-white/70' %>">ITA <span class="text-white/30 ml-1">Italiano</span></button>
<button onclick="switchLanguage('uk')" class="lang-option w-full text-left px-3 py-2 text-sm hover:bg-white/5 transition-colors <%= lang === 'uk' ? 'text-[#90EE90]' : 'text-white/70' %>">УКР <span class="text-white/30 ml-1">Українська</span></button>
<button onclick="switchLanguage('de')" class="lang-option w-full text-left px-3 py-2 text-sm hover:bg-white/5 transition-colors <%= lang === 'de' ? 'text-[#90EE90]' : 'text-white/70' %>">DEU <span class="text-white/30 ml-1">Deutsch</span></button>
<button onclick="switchLanguage('es')" class="lang-option w-full text-left px-3 py-2 text-sm hover:bg-white/5 transition-colors <%= lang === 'es' ? 'text-[#90EE90]' : 'text-white/70' %>">ESP <span class="text-white/30 ml-1">Español</span></button>
<button onclick="switchLanguage('pl')" class="lang-option w-full text-left px-3 py-2 text-sm hover:bg-white/5 transition-colors <%= lang === 'pl' ? 'text-[#90EE90]' : 'text-white/70' %>">POL <span class="text-white/30 ml-1">Polski</span></button>
<button onclick="switchLanguage('cs')" class="lang-option w-full text-left px-3 py-2 text-sm hover:bg-white/5 transition-colors <%= lang === 'cs' ? 'text-[#90EE90]' : 'text-white/70' %>">CES <span class="text-white/30 ml-1">Čeština</span></button>
<button onclick="switchLanguage('zh-CN')" class="lang-option w-full text-left px-3 py-2 text-sm hover:bg-white/5 transition-colors <%= lang === 'zh-CN' ? 'text-[#90EE90]' : 'text-white/70' %>">简中 <span class="text-white/30 ml-1">简体中文</span></button>
</div>
</div>
<button class="btn-primary px-4 py-2 rounded-lg text-sm font-bold inline-flex items-center" id="inviteBtn">
<i class="fab fa-discord mr-2"></i><%= t('nav.addToDiscord') %>
</button>
</div>
<button class="lg:hidden text-accent" id="mobileMenuBtn">
<i class="fas fa-bars text-xl"></i>
</button>
</div>
</div>
<div class="hidden lg:hidden border-t border-white/5 bg-[#1E1E1E]/98" id="mobileMenu">
<div class="px-6 py-4 space-y-2">
<% navLinks.forEach(link => { %>
<% if (typeof activePage !== 'undefined' && activePage === link.key) { %>
<a href="<%= link.href %>" class="block px-4 py-2 text-accent bg-white/5 rounded-md"><%= t('nav.' + link.key) %></a>
<% } else { %>
<a href="<%= link.href %>" class="block px-4 py-2 text-muted hover:bg-white/5 rounded-md"><%= t('nav.' + link.key) %></a>
<% } %>
<% }); %>
<a href="/premium" class="block px-4 py-2 nav-premium <%= typeof activePage !== 'undefined' && activePage === 'premium' ? 'bg-white/5' : 'hover:bg-white/5' %> rounded-md"><%= t('nav.premium') %></a>
<a href="/support" class="block px-4 py-2 nav-rainbow hover:bg-white/5 rounded-md">
<i class="fas fa-life-ring mr-2"></i><%= t('nav.support') %>
</a>
<a href="https://ko-fi.com/notsotoothless" target="_blank" rel="noopener noreferrer" class="block px-4 py-2 nav-donate hover:bg-white/5 rounded-md">
<i class="fas fa-heart mr-2"></i><%= t('nav.donate') %>
</a>
<button class="block w-full px-4 py-2 btn-primary font-semibold rounded-md text-center" id="inviteBtnMobile">
<i class="fab fa-discord mr-2"></i><%= t('nav.addToDiscord') %>
</button>
<div class="border border-white/10 rounded-md overflow-hidden">
<button onclick="switchLanguage('en')" class="block w-full text-left px-4 py-2 text-sm transition-colors <%= lang === 'en' ? 'bg-[rgba(144,238,144,0.15)] text-[#90EE90]' : 'text-white/50 hover:bg-white/5' %>">ENG — English</button>
<button onclick="switchLanguage('ru')" class="block w-full text-left px-4 py-2 text-sm transition-colors <%= lang === 'ru' ? 'bg-[rgba(144,238,144,0.15)] text-[#90EE90]' : 'text-white/50 hover:bg-white/5' %>">РУС — Русский</button>
<button onclick="switchLanguage('fr')" class="block w-full text-left px-4 py-2 text-sm transition-colors <%= lang === 'fr' ? 'bg-[rgba(144,238,144,0.15)] text-[#90EE90]' : 'text-white/50 hover:bg-white/5' %>">FRA — Français</button>
<button onclick="switchLanguage('it')" class="block w-full text-left px-4 py-2 text-sm transition-colors <%= lang === 'it' ? 'bg-[rgba(144,238,144,0.15)] text-[#90EE90]' : 'text-white/50 hover:bg-white/5' %>">ITA — Italiano</button>
<button onclick="switchLanguage('uk')" class="block w-full text-left px-4 py-2 text-sm transition-colors <%= lang === 'uk' ? 'bg-[rgba(144,238,144,0.15)] text-[#90EE90]' : 'text-white/50 hover:bg-white/5' %>">УКР — Українська</button>
<button onclick="switchLanguage('de')" class="block w-full text-left px-4 py-2 text-sm transition-colors <%= lang === 'de' ? 'bg-[rgba(144,238,144,0.15)] text-[#90EE90]' : 'text-white/50 hover:bg-white/5' %>">DEU — Deutsch</button>
<button onclick="switchLanguage('es')" class="block w-full text-left px-4 py-2 text-sm transition-colors <%= lang === 'es' ? 'bg-[rgba(144,238,144,0.15)] text-[#90EE90]' : 'text-white/50 hover:bg-white/5' %>">ESP — Español</button>
<button onclick="switchLanguage('pl')" class="block w-full text-left px-4 py-2 text-sm transition-colors <%= lang === 'pl' ? 'bg-[rgba(144,238,144,0.15)] text-[#90EE90]' : 'text-white/50 hover:bg-white/5' %>">POL — Polski</button>
<button onclick="switchLanguage('cs')" class="block w-full text-left px-4 py-2 text-sm transition-colors <%= lang === 'cs' ? 'bg-[rgba(144,238,144,0.15)] text-[#90EE90]' : 'text-white/50 hover:bg-white/5' %>">CES — Čeština</button>
<button onclick="switchLanguage('zh-CN')" class="block w-full text-left px-4 py-2 text-sm transition-colors <%= lang === 'zh-CN' ? 'bg-[rgba(144,238,144,0.15)] text-[#90EE90]' : 'text-white/50 hover:bg-white/5' %>">简中 — 简体中文</button>
</div>
</div>
</div>
</nav>
<script>
(function(){
var sw = document.getElementById('botSwitcher');
if (!sw) return;
document.addEventListener('click', function(e){
if (sw.classList.contains('open') && !sw.contains(e.target)) {
sw.classList.remove('open');
}
});
document.addEventListener('keydown', function(e){
if (e.key === 'Escape' && sw.classList.contains('open')) {
sw.classList.remove('open');
}
});
})();
</script>