feat(ui): overhaul landing page with premium dark theme and dynamic content
This commit introduces a complete redesign of the landing page, shifting from a static layout to a dynamic, configuration-driven interface with a new premium visual theme. Key Changes: - **Visual Redesign**: Implemented a new premium dark theme with a gold and dark blue color palette, updated typography using 'Playfair Display' and 'Inter' fonts, and enhanced visual effects like gradients, shadows, and hover animations. - **Dynamic Content**: The 'Services' and 'Other Links' sections are no longer hardcoded in HTML. They are now dynamically generated from a `siteConfig` JavaScript object, making the content easier to manage and update. - **On-Scroll Animations**: Added fade-in animations for cards and links as they enter the viewport, using the `IntersectionObserver` API for a more engaging user experience. - **Language Switcher Enhancement**: The language switcher now re-renders the dynamic content to display the correct language without a page reload. - **Code Refactoring**: Centralized page content into a single configuration object, improving maintainability and separating data from presentation.
This commit is contained in:
717
index.html
717
index.html
@@ -3,38 +3,35 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Tootaio - 一站式开发者服务平台</title>
|
||||
<title>Tootaio - Premium Developer Services</title>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;700&family=Inter:wght@300;400;500;600&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
:root {
|
||||
--primary: #6366f1;
|
||||
--primary-dark: #4f46e5;
|
||||
--secondary: #8b5cf6;
|
||||
--light: #f8fafc;
|
||||
--dark: #1e293b;
|
||||
--gray: #64748b;
|
||||
--card-bg: #ffffff;
|
||||
}
|
||||
|
||||
.dark-mode {
|
||||
--light: #0f172a;
|
||||
--dark: #f1f5f9;
|
||||
--gray: #cbd5e1;
|
||||
--card-bg: #1e293b;
|
||||
--primary-dark: #0A0E17;
|
||||
--primary: #121826;
|
||||
--secondary: #1C2431;
|
||||
--accent-gold: #D4AF37;
|
||||
--accent-gold-light: #F1E5AC;
|
||||
--accent-blue: #2A4B7C;
|
||||
--text-primary: #FFFFFF;
|
||||
--text-secondary: #B0B7C3;
|
||||
--card-bg: rgba(28, 36, 49, 0.6);
|
||||
--transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
transition: background-color 0.3s, color 0.3s;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background-color: var(--light);
|
||||
color: var(--dark);
|
||||
font-family: 'Inter', sans-serif;
|
||||
background: linear-gradient(135deg, var(--primary-dark), var(--primary));
|
||||
color: var(--text-primary);
|
||||
line-height: 1.6;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.container {
|
||||
@@ -44,13 +41,13 @@
|
||||
}
|
||||
|
||||
header {
|
||||
background: linear-gradient(120deg, var(--primary), var(--secondary));
|
||||
color: white;
|
||||
padding: 1rem 0;
|
||||
background: rgba(10, 14, 23, 0.8);
|
||||
backdrop-filter: blur(10px);
|
||||
padding: 1.2rem 0;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
|
||||
border-bottom: 1px solid rgba(212, 175, 55, 0.2);
|
||||
}
|
||||
|
||||
.nav-container {
|
||||
@@ -60,88 +57,146 @@
|
||||
}
|
||||
|
||||
.logo {
|
||||
font-size: 1.8rem;
|
||||
font-family: 'Playfair Display', serif;
|
||||
font-size: 2rem;
|
||||
font-weight: 700;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: var(--accent-gold);
|
||||
}
|
||||
|
||||
.logo i {
|
||||
margin-right: 10px;
|
||||
color: var(--accent-gold);
|
||||
}
|
||||
|
||||
.nav-links {
|
||||
display: flex;
|
||||
gap: 1.5rem;
|
||||
gap: 2rem;
|
||||
}
|
||||
|
||||
.nav-links a {
|
||||
color: white;
|
||||
color: var(--text-primary);
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
padding: 5px 10px;
|
||||
padding: 8px 16px;
|
||||
border-radius: 4px;
|
||||
transition: var(--transition);
|
||||
}
|
||||
|
||||
.nav-links a:hover {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
color: var(--accent-gold);
|
||||
}
|
||||
|
||||
.language-switcher {
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
border: none;
|
||||
color: white;
|
||||
padding: 5px 10px;
|
||||
background: rgba(212, 175, 55, 0.1);
|
||||
border: 1px solid var(--accent-gold);
|
||||
color: var(--accent-gold);
|
||||
padding: 8px 16px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: var(--transition);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.language-switcher:hover {
|
||||
background: rgba(212, 175, 55, 0.2);
|
||||
}
|
||||
|
||||
.hero {
|
||||
text-align: center;
|
||||
padding: 4rem 1rem;
|
||||
background: linear-gradient(45deg, #4f46e5, #7c3aed);
|
||||
color: white;
|
||||
border-radius: 0 0 20px 20px;
|
||||
margin-bottom: 2rem;
|
||||
padding: 6rem 1rem;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.hero::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: radial-gradient(circle at top right, rgba(212, 175, 55, 0.1), transparent 30%);
|
||||
}
|
||||
|
||||
.hero h1 {
|
||||
font-size: 3rem;
|
||||
margin-bottom: 1rem;
|
||||
font-family: 'Playfair Display', serif;
|
||||
font-size: 3.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
background: linear-gradient(to right, var(--accent-gold), var(--accent-gold-light));
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
|
||||
.hero p {
|
||||
font-size: 1.2rem;
|
||||
max-width: 700px;
|
||||
margin: 0 auto 2rem;
|
||||
margin: 0 auto 3rem;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.cta-button {
|
||||
display: inline-block;
|
||||
background-color: white;
|
||||
color: var(--primary);
|
||||
padding: 12px 30px;
|
||||
background: linear-gradient(135deg, var(--accent-gold), #B8860B);
|
||||
color: var(--primary-dark);
|
||||
padding: 14px 35px;
|
||||
border-radius: 50px;
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||||
transition: transform 0.3s, box-shadow 0.3s;
|
||||
box-shadow: 0 4px 15px rgba(212, 175, 55, 0.3);
|
||||
transition: var(--transition);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.cta-button::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
|
||||
transition: 0.5s;
|
||||
}
|
||||
|
||||
.cta-button:hover {
|
||||
transform: translateY(-3px);
|
||||
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15);
|
||||
box-shadow: 0 6px 20px rgba(212, 175, 55, 0.4);
|
||||
}
|
||||
|
||||
.cta-button:hover::before {
|
||||
left: 100%;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
text-align: center;
|
||||
margin-bottom: 2.5rem;
|
||||
font-size: 2.2rem;
|
||||
color: var(--primary);
|
||||
margin-bottom: 3rem;
|
||||
font-family: 'Playfair Display', serif;
|
||||
font-size: 2.5rem;
|
||||
color: var(--accent-gold);
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
.section-title::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -10px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 60px;
|
||||
height: 3px;
|
||||
background: var(--accent-gold);
|
||||
}
|
||||
|
||||
.services {
|
||||
padding: 3rem 0;
|
||||
padding: 5rem 0;
|
||||
}
|
||||
|
||||
.services-grid {
|
||||
@@ -151,26 +206,33 @@
|
||||
}
|
||||
|
||||
.service-card {
|
||||
background-color: var(--card-bg);
|
||||
background: var(--card-bg);
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
|
||||
transition: transform 0.3s;
|
||||
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2);
|
||||
transition: var(--transition);
|
||||
border: 1px solid rgba(212, 175, 55, 0.1);
|
||||
backdrop-filter: blur(10px);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.service-card:hover {
|
||||
transform: translateY(-5px);
|
||||
transform: translateY(-10px);
|
||||
border-color: rgba(212, 175, 55, 0.3);
|
||||
box-shadow: 0 15px 30px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.card-header {
|
||||
padding: 1.5rem;
|
||||
background: linear-gradient(45deg, var(--primary), var(--secondary));
|
||||
color: white;
|
||||
background: linear-gradient(90deg, var(--accent-blue), var(--secondary));
|
||||
color: var(--text-primary);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.card-header h3 {
|
||||
font-size: 1.4rem;
|
||||
margin-bottom: 0.5rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.card-body {
|
||||
@@ -178,26 +240,39 @@
|
||||
}
|
||||
|
||||
.card-body p {
|
||||
color: var(--gray);
|
||||
color: var(--text-secondary);
|
||||
margin-bottom: 1.5rem;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.card-link {
|
||||
display: inline-block;
|
||||
color: var(--primary);
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
color: var(--accent-gold);
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
font-weight: 500;
|
||||
gap: 8px;
|
||||
transition: var(--transition);
|
||||
}
|
||||
|
||||
.card-link:hover {
|
||||
text-decoration: underline;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.other-links {
|
||||
padding: 3rem 0;
|
||||
background-color: rgba(99, 102, 241, 0.05);
|
||||
border-radius: 20px;
|
||||
margin: 3rem 0;
|
||||
padding: 5rem 0;
|
||||
background: rgba(10, 14, 23, 0.5);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.other-links::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: radial-gradient(circle at bottom left, rgba(42, 75, 124, 0.1), transparent 30%);
|
||||
}
|
||||
|
||||
.links-grid {
|
||||
@@ -209,36 +284,41 @@
|
||||
.link-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 1rem;
|
||||
background-color: var(--card-bg);
|
||||
padding: 1.2rem;
|
||||
background: var(--card-bg);
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
|
||||
text-decoration: none;
|
||||
color: var(--dark);
|
||||
transition: transform 0.3s;
|
||||
color: var(--text-primary);
|
||||
transition: var(--transition);
|
||||
border: 1px solid rgba(212, 175, 55, 0.05);
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.link-item:hover {
|
||||
transform: translateY(-3px);
|
||||
transform: translateY(-5px);
|
||||
border-color: rgba(212, 175, 55, 0.2);
|
||||
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.link-icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
background: linear-gradient(45deg, var(--primary), var(--secondary));
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
background: linear-gradient(135deg, var(--accent-gold), #B8860B);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-right: 1rem;
|
||||
color: white;
|
||||
color: var(--primary-dark);
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
footer {
|
||||
background-color: var(--dark);
|
||||
color: white;
|
||||
padding: 3rem 0 2rem;
|
||||
background-color: var(--primary-dark);
|
||||
padding: 4rem 0 2rem;
|
||||
margin-top: 4rem;
|
||||
border-top: 1px solid rgba(212, 175, 55, 0.1);
|
||||
}
|
||||
|
||||
.footer-content {
|
||||
@@ -257,46 +337,74 @@
|
||||
.footer-column h3 {
|
||||
font-size: 1.2rem;
|
||||
margin-bottom: 1.2rem;
|
||||
color: var(--secondary);
|
||||
color: var(--accent-gold);
|
||||
font-family: 'Playfair Display', serif;
|
||||
}
|
||||
|
||||
.footer-column a {
|
||||
display: block;
|
||||
color: #cbd5e1;
|
||||
color: var(--text-secondary);
|
||||
text-decoration: none;
|
||||
margin-bottom: 0.8rem;
|
||||
transition: var(--transition);
|
||||
}
|
||||
|
||||
.footer-column a:hover {
|
||||
color: white;
|
||||
color: var(--accent-gold);
|
||||
}
|
||||
|
||||
.copyright {
|
||||
text-align: center;
|
||||
padding-top: 2rem;
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.1);
|
||||
color: #94a3b8;
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.05);
|
||||
color: var(--text-secondary);
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
/* Animation for cards when they appear in viewport */
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(30px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.service-card, .link-item {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.animated {
|
||||
animation: fadeInUp 0.6s forwards;
|
||||
}
|
||||
|
||||
/* Responsive design */
|
||||
@media (max-width: 768px) {
|
||||
.nav-links {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.hero h1 {
|
||||
font-size: 2.2rem;
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.hero p {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.services-grid, .links-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
.mobile-menu-btn {
|
||||
display: none;
|
||||
background: none;
|
||||
border: none;
|
||||
color: white;
|
||||
color: var(--accent-gold);
|
||||
font-size: 1.5rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
@@ -306,13 +414,52 @@
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
/* Configuration panel for demo purposes */
|
||||
.config-panel {
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
background: var(--secondary);
|
||||
border: 1px solid var(--accent-gold);
|
||||
border-radius: 8px;
|
||||
padding: 15px;
|
||||
z-index: 1000;
|
||||
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.config-panel h4 {
|
||||
margin-bottom: 10px;
|
||||
color: var(--accent-gold);
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.config-buttons {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.config-btn {
|
||||
padding: 8px 12px;
|
||||
background: var(--accent-blue);
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
transition: var(--transition);
|
||||
}
|
||||
|
||||
.config-btn:hover {
|
||||
background: var(--accent-gold);
|
||||
color: var(--primary-dark);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<div class="container nav-container">
|
||||
<div class="logo">
|
||||
<i class="fas fa-cube"></i>
|
||||
<i class="fas fa-crown"></i>
|
||||
<span data-lang="en">Tootaio</span>
|
||||
<span data-lang="zh" style="display: none;">Tootaio</span>
|
||||
</div>
|
||||
@@ -328,6 +475,7 @@
|
||||
<a href="#" data-lang="zh" style="display: none;">联系</a>
|
||||
</nav>
|
||||
<button class="language-switcher" id="languageSwitcher">
|
||||
<i class="fas fa-globe"></i>
|
||||
<span data-lang="en">中文</span>
|
||||
<span data-lang="zh" style="display: none;">English</span>
|
||||
</button>
|
||||
@@ -339,10 +487,10 @@
|
||||
|
||||
<section class="hero">
|
||||
<div class="container">
|
||||
<h1 data-lang="en">Your All-in-One Developer Platform</h1>
|
||||
<h1 data-lang="zh" style="display: none;">一站式开发者服务平台</h1>
|
||||
<p data-lang="en">Tootaio provides a suite of powerful tools and services for developers, gamers, and creators. Everything you need in one place.</p>
|
||||
<p data-lang="zh" style="display: none;">Tootaio 为开发者、游戏玩家和创作者提供一套强大的工具和服务。您所需的一切,尽在一处。</p>
|
||||
<h1 data-lang="en">Premium Developer Experience</h1>
|
||||
<h1 data-lang="zh" style="display: none;">卓越开发者体验</h1>
|
||||
<p data-lang="en">Tootaio provides a suite of premium tools and services for developers, gamers, and creators. Experience the difference.</p>
|
||||
<p data-lang="zh" style="display: none;">Tootaio 为开发者、游戏玩家和创作者提供一套高级工具和服务。体验与众不同的服务。</p>
|
||||
<a href="#services" class="cta-button" data-lang="en">Explore Services</a>
|
||||
<a href="#services" class="cta-button" data-lang="zh" style="display: none;">探索服务</a>
|
||||
</div>
|
||||
@@ -353,138 +501,8 @@
|
||||
<h2 class="section-title" data-lang="en">Our Services</h2>
|
||||
<h2 class="section-title" data-lang="zh" style="display: none;">我们的服务</h2>
|
||||
|
||||
<div class="services-grid">
|
||||
<!-- Main Site -->
|
||||
<div class="service-card">
|
||||
<div class="card-header">
|
||||
<h3>tootaio.com</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p data-lang="en">The main portal to all Tootaio services and resources.</p>
|
||||
<p data-lang="zh" style="display: none;">通往所有 Tootaio 服务和资源的主门户。</p>
|
||||
<a href="https://tootaio.com" class="card-link" target="_blank">Visit Site</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Gitea -->
|
||||
<div class="service-card">
|
||||
<div class="card-header">
|
||||
<h3>git.tootaio.com</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p data-lang="en">Self-hosted Gitea open source community platform.</p>
|
||||
<p data-lang="zh" style="display: none;">自托管的 Gitea 开源社区平台。</p>
|
||||
<a href="https://git.tootaio.com" class="card-link" target="_blank">Visit Site</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- NAS -->
|
||||
<div class="service-card">
|
||||
<div class="card-header">
|
||||
<h3>nas.tootaio.com</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p data-lang="en">Cloud storage solution for your files and data.</p>
|
||||
<p data-lang="zh" style="display: none;">为您的文件和数据提供的云存储解决方案。</p>
|
||||
<a href="https://nas.tootaio.com" class="card-link" target="_blank">Visit Site</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Torrent -->
|
||||
<div class="service-card">
|
||||
<div class="card-header">
|
||||
<h3>torrent.tootaio.com</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p data-lang="en">Download torrent files to our server with high speed.</p>
|
||||
<p data-lang="zh" style="display: none;">借助服务器高速下载 Torrent 文件。</p>
|
||||
<a href="https://torrent.tootaio.com" class="card-link" target="_blank">Visit Site</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Wiki -->
|
||||
<div class="service-card">
|
||||
<div class="card-header">
|
||||
<h3>wiki.tootaio.com</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p data-lang="en">Wiki for our studio's games and project planning.</p>
|
||||
<p data-lang="zh" style="display: none;">我们工作室游戏和项目策划的维基百科。</p>
|
||||
<a href="https://wiki.tootaio.com" class="card-link" target="_blank">Visit Site</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Kenney Assets -->
|
||||
<div class="service-card">
|
||||
<div class="card-header">
|
||||
<h3>kenney-assets.tootaio.com</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p data-lang="en">Unofficial mirror for Kenney's game assets.</p>
|
||||
<p data-lang="zh" style="display: none;">Kenney 游戏资源的非官方镜像站。</p>
|
||||
<a href="https://kenney-assets.tootaio.com" class="card-link" target="_blank">Visit Site</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Itch.io Godot Downloader -->
|
||||
<div class="service-card">
|
||||
<div class="card-header">
|
||||
<h3>itch-gd-dl.tootaio.com</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p data-lang="en">Itch.io Godot game crawler and downloader.</p>
|
||||
<p data-lang="zh" style="display: none;">Itch.io Godot 游戏爬取和下载工具。</p>
|
||||
<a href="https://itch-gd-dl.tootaio.com" class="card-link" target="_blank">Visit Site</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PDF Tools -->
|
||||
<div class="service-card">
|
||||
<div class="card-header">
|
||||
<h3>pdf.tootaio.com</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p data-lang="en">Online PDF tools for all your document needs.</p>
|
||||
<p data-lang="zh" style="display: none;">满足您所有文档需求的在线 PDF 工具。</p>
|
||||
<a href="https://pdf.tootaio.com" class="card-link" target="_blank">Visit Site</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Life Restart -->
|
||||
<div class="service-card">
|
||||
<div class="card-header">
|
||||
<h3>life-restart.tootaio.com</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p data-lang="en">Mirror site for the Life Restart Simulator game.</p>
|
||||
<p data-lang="zh" style="display: none;">人生重开模拟器游戏的镜像站。</p>
|
||||
<a href="https://life-restart.tootaio.com" class="card-link" target="_blank">Visit Site</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Memos -->
|
||||
<div class="service-card">
|
||||
<div class="card-header">
|
||||
<h3>memos.tootaio.com</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p data-lang="en">Note-taking space for your ideas and thoughts.</p>
|
||||
<p data-lang="zh" style="display: none;">记录您的想法和思考的笔记空间。</p>
|
||||
<a href="https://memos.tootaio.com" class="card-link" target="_blank">Visit Site</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- JSON Hero -->
|
||||
<div class="service-card">
|
||||
<div class="card-header">
|
||||
<h3>json.tootaio.com</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p data-lang="en">JSON Hero viewer for visualizing and editing JSON data.</p>
|
||||
<p data-lang="zh" style="display: none;">用于可视化和编辑 JSON 数据的 JSON Hero 查看器。</p>
|
||||
<a href="https://json.tootaio.com" class="card-link" target="_blank">Visit Site</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="services-grid" id="servicesGrid">
|
||||
<!-- Services will be loaded dynamically from JSON -->
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -494,38 +512,8 @@
|
||||
<h2 class="section-title" data-lang="en">Other Links</h2>
|
||||
<h2 class="section-title" data-lang="zh" style="display: none;">其他链接</h2>
|
||||
|
||||
<div class="links-grid">
|
||||
<a href="https://kingsmai.github.io" class="link-item" target="_blank">
|
||||
<div class="link-icon">
|
||||
<i class="fas fa-blog"></i>
|
||||
</div>
|
||||
<span data-lang="en">Kingsmai's Personal Blog</span>
|
||||
<span data-lang="zh" style="display: none;">Kingsmai 的个人博客</span>
|
||||
</a>
|
||||
|
||||
<a href="https://github.com/kingsmai" class="link-item" target="_blank">
|
||||
<div class="link-icon">
|
||||
<i class="fab fa-github"></i>
|
||||
</div>
|
||||
<span data-lang="en">Kingsmai's GitHub</span>
|
||||
<span data-lang="zh" style="display: none;">Kingsmai 的 GitHub</span>
|
||||
</a>
|
||||
|
||||
<a href="https://discord.com/invite/sJcv7ZM" class="link-item" target="_blank">
|
||||
<div class="link-icon">
|
||||
<i class="fab fa-discord"></i>
|
||||
</div>
|
||||
<span data-lang="en">Studio Discord Community</span>
|
||||
<span data-lang="zh" style="display: none;">工作室 Discord 社区</span>
|
||||
</a>
|
||||
|
||||
<a href="https://space.bilibili.com/670118055" class="link-item" target="_blank">
|
||||
<div class="link-icon">
|
||||
<i class="fas fa-video"></i>
|
||||
</div>
|
||||
<span data-lang="en">Studio BiliBili Space</span>
|
||||
<span data-lang="zh" style="display: none;">工作室 BiliBili 空间</span>
|
||||
</a>
|
||||
<div class="links-grid" id="linksGrid">
|
||||
<!-- Links will be loaded dynamically from JSON -->
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -570,8 +558,116 @@
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<!-- Configuration panel for demo -->
|
||||
<div class="config-panel">
|
||||
<h4>Developer Options</h4>
|
||||
<div class="config-buttons">
|
||||
<button class="config-btn" id="reloadData">Reload Data</button>
|
||||
<button class="config-btn" id="viewConfig">View Config</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Configuration data - in a real scenario, this would be in an external JSON file
|
||||
const siteConfig = {
|
||||
"services": [
|
||||
{
|
||||
"name": "tootaio.com",
|
||||
"url": "https://tootaio.com",
|
||||
"description_en": "The main portal to all Tootaio services and resources.",
|
||||
"description_zh": "通往所有 Tootaio 服务和资源的主门户。"
|
||||
},
|
||||
{
|
||||
"name": "git.tootaio.com",
|
||||
"url": "https://git.tootaio.com",
|
||||
"description_en": "Self-hosted Gitea open source community platform.",
|
||||
"description_zh": "自托管的 Gitea 开源社区平台。"
|
||||
},
|
||||
{
|
||||
"name": "nas.tootaio.com",
|
||||
"url": "https://nas.tootaio.com",
|
||||
"description_en": "Cloud storage solution for your files and data.",
|
||||
"description_zh": "为您的文件和数据提供的云存储解决方案。"
|
||||
},
|
||||
{
|
||||
"name": "torrent.tootaio.com",
|
||||
"url": "https://torrent.tootaio.com",
|
||||
"description_en": "Download torrent files to our server with high speed.",
|
||||
"description_zh": "借助服务器高速下载 Torrent 文件。"
|
||||
},
|
||||
{
|
||||
"name": "wiki.tootaio.com",
|
||||
"url": "https://wiki.tootaio.com",
|
||||
"description_en": "Wiki for our studio's games and project planning.",
|
||||
"description_zh": "我们工作室游戏和项目策划的维基百科。"
|
||||
},
|
||||
{
|
||||
"name": "kenney-assets.tootaio.com",
|
||||
"url": "https://kenney-assets.tootaio.com",
|
||||
"description_en": "Unofficial mirror for Kenney's game assets.",
|
||||
"description_zh": "Kenney 游戏资源的非官方镜像站。"
|
||||
},
|
||||
{
|
||||
"name": "itch-gd-dl.tootaio.com",
|
||||
"url": "https://itch-gd-dl.tootaio.com",
|
||||
"description_en": "Itch.io Godot game crawler and downloader.",
|
||||
"description_zh": "Itch.io Godot 游戏爬取和下载工具。"
|
||||
},
|
||||
{
|
||||
"name": "pdf.tootaio.com",
|
||||
"url": "https://pdf.tootaio.com",
|
||||
"description_en": "Online PDF tools for all your document needs.",
|
||||
"description_zh": "满足您所有文档需求的在线 PDF 工具。"
|
||||
},
|
||||
{
|
||||
"name": "life-restart.tootaio.com",
|
||||
"url": "https://life-restart.tootaio.com",
|
||||
"description_en": "Mirror site for the Life Restart Simulator game.",
|
||||
"description_zh": "人生重开模拟器游戏的镜像站。"
|
||||
},
|
||||
{
|
||||
"name": "memos.tootaio.com",
|
||||
"url": "https://memos.tootaio.com",
|
||||
"description_en": "Note-taking space for your ideas and thoughts.",
|
||||
"description_zh": "记录您的想法和思考的笔记空间。"
|
||||
},
|
||||
{
|
||||
"name": "json.tootaio.com",
|
||||
"url": "https://json.tootaio.com",
|
||||
"description_en": "JSON Hero viewer for visualizing and editing JSON data.",
|
||||
"description_zh": "用于可视化和编辑 JSON 数据的 JSON Hero 查看器。"
|
||||
}
|
||||
],
|
||||
"otherLinks": [
|
||||
{
|
||||
"name_en": "Kingsmai's Personal Blog",
|
||||
"name_zh": "Kingsmai 的个人博客",
|
||||
"url": "https://kingsmai.github.io",
|
||||
"icon": "blog"
|
||||
},
|
||||
{
|
||||
"name_en": "Kingsmai's GitHub",
|
||||
"name_zh": "Kingsmai 的 GitHub",
|
||||
"url": "https://github.com/kingsmai",
|
||||
"icon": "github"
|
||||
},
|
||||
{
|
||||
"name_en": "Studio Discord Community",
|
||||
"name_zh": "工作室 Discord 社区",
|
||||
"url": "https://discord.com/invite/sJcv7ZM",
|
||||
"icon": "discord"
|
||||
},
|
||||
{
|
||||
"name_en": "Studio BiliBili Space",
|
||||
"name_zh": "工作室 BiliBili 空间",
|
||||
"url": "https://space.bilibili.com/670118055",
|
||||
"icon": "video"
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Language switching functionality
|
||||
const languageSwitcher = document.getElementById('languageSwitcher');
|
||||
let currentLang = 'en';
|
||||
|
||||
@@ -591,16 +687,119 @@
|
||||
// Update button text
|
||||
const buttonText = currentLang === 'en' ? '中文' : 'English';
|
||||
languageSwitcher.querySelector('span').textContent = buttonText;
|
||||
|
||||
// Reload content with new language
|
||||
loadServices(currentLang);
|
||||
loadOtherLinks(currentLang);
|
||||
});
|
||||
|
||||
// Mobile menu toggle (optional enhancement)
|
||||
const mobileMenuBtn = document.querySelector('.mobile-menu-btn');
|
||||
const navLinks = document.querySelector('.nav-links');
|
||||
// Load initial content
|
||||
loadServices(currentLang);
|
||||
loadOtherLinks(currentLang);
|
||||
|
||||
mobileMenuBtn.addEventListener('click', function() {
|
||||
navLinks.style.display = navLinks.style.display === 'flex' ? 'none' : 'flex';
|
||||
// Animation on scroll
|
||||
const observerOptions = {
|
||||
threshold: 0.1,
|
||||
rootMargin: '0px 0px -50px 0px'
|
||||
};
|
||||
|
||||
const observer = new IntersectionObserver(function(entries) {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
entry.target.classList.add('animated');
|
||||
}
|
||||
});
|
||||
}, observerOptions);
|
||||
|
||||
// Observe service cards and link items for animation
|
||||
document.querySelectorAll('.service-card, .link-item').forEach(item => {
|
||||
observer.observe(item);
|
||||
});
|
||||
|
||||
// Developer tools
|
||||
document.getElementById('reloadData').addEventListener('click', function() {
|
||||
loadServices(currentLang);
|
||||
loadOtherLinks(currentLang);
|
||||
alert('Data reloaded!');
|
||||
});
|
||||
|
||||
document.getElementById('viewConfig').addEventListener('click', function() {
|
||||
alert('In a real implementation, this would open the external config file.\n\nFor now, check the JavaScript code for the siteConfig object.');
|
||||
});
|
||||
});
|
||||
|
||||
function loadServices(lang) {
|
||||
const servicesGrid = document.getElementById('servicesGrid');
|
||||
servicesGrid.innerHTML = '';
|
||||
|
||||
siteConfig.services.forEach(service => {
|
||||
const card = document.createElement('div');
|
||||
card.className = 'service-card';
|
||||
|
||||
card.innerHTML = `
|
||||
<div class="card-header">
|
||||
<h3>${service.name}</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p>${lang === 'en' ? service.description_en : service.description_zh}</p>
|
||||
<a href="${service.url}" class="card-link" target="_blank">
|
||||
<span data-lang="en">Visit Site</span>
|
||||
<span data-lang="zh" style="display: none;">访问网站</span>
|
||||
<i class="fas fa-arrow-right"></i>
|
||||
</a>
|
||||
</div>
|
||||
`;
|
||||
|
||||
servicesGrid.appendChild(card);
|
||||
|
||||
// Set language-specific visibility
|
||||
card.querySelectorAll('[data-lang]').forEach(element => {
|
||||
if (element.getAttribute('data-lang') === lang) {
|
||||
element.style.display = 'inline';
|
||||
} else {
|
||||
element.style.display = 'none';
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function loadOtherLinks(lang) {
|
||||
const linksGrid = document.getElementById('linksGrid');
|
||||
linksGrid.innerHTML = '';
|
||||
|
||||
siteConfig.otherLinks.forEach(link => {
|
||||
const linkItem = document.createElement('a');
|
||||
linkItem.href = link.url;
|
||||
linkItem.target = '_blank';
|
||||
linkItem.className = 'link-item';
|
||||
|
||||
// Get icon class based on config
|
||||
let iconClass = 'fas fa-link';
|
||||
if (link.icon === 'blog') iconClass = 'fas fa-blog';
|
||||
if (link.icon === 'github') iconClass = 'fab fa-github';
|
||||
if (link.icon === 'discord') iconClass = 'fab fa-discord';
|
||||
if (link.icon === 'video') iconClass = 'fas fa-video';
|
||||
|
||||
linkItem.innerHTML = `
|
||||
<div class="link-icon">
|
||||
<i class="${iconClass}"></i>
|
||||
</div>
|
||||
<span data-lang="en">${link.name_en}</span>
|
||||
<span data-lang="zh" style="display: none;">${link.name_zh}</span>
|
||||
`;
|
||||
|
||||
linksGrid.appendChild(linkItem);
|
||||
|
||||
// Set language-specific visibility
|
||||
linkItem.querySelectorAll('[data-lang]').forEach(element => {
|
||||
if (element.getAttribute('data-lang') === lang) {
|
||||
element.style.display = 'inline';
|
||||
} else {
|
||||
element.style.display = 'none';
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user