mirror of
https://github.com/Shik3i/KoalaSync.git
synced 2026-07-26 12:08:15 +00:00
feat(website): fully redesign website and invitation page with premium responsive layouts, inline SVG icons, and a sleek vector Globe language selector
This commit is contained in:
+86
-6
@@ -74,8 +74,14 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
const isFirefox = navigator.userAgent.includes('Firefox');
|
||||
if (isFirefox) {
|
||||
actions.innerHTML = `
|
||||
<a href="https://addons.mozilla.org/de/firefox/addon/koalasync/" class="primary btn-firefox" style="text-align:center; text-decoration:none; display:block; padding: 1.2rem; border-radius: 12px; font-weight: 700;">GET IT ON MOZILLA ADD-ONS</a>
|
||||
<a href="https://github.com/shik3i/KoalaSync" style="text-align:center; color:#e66000; text-decoration:underline; font-size:0.85rem; margin-top:0.8rem; display:block; font-weight: 600;">Download via GitHub</a>
|
||||
<a href="https://addons.mozilla.org/de/firefox/addon/koalasync/" class="primary btn-firefox" style="text-align:center; text-decoration:none; display:flex; align-items:center; justify-content:center; gap: 8px; padding: 1.2rem; border-radius: 12px; font-weight: 700;">
|
||||
<span>🦊</span>
|
||||
<span lang="en">GET IT ON MOZILLA ADD-ONS</span><span lang="de">IM FIREFOX ADD-ON STORE HERUNTERLADEN</span>
|
||||
</a>
|
||||
<a href="https://github.com/shik3i/KoalaSync" style="text-align:center; text-decoration:none; display:flex; align-items:center; justify-content:center; gap: 8px; padding: 0.8rem; background: rgba(255, 255, 255, 0.04); border: 1px solid var(--glass-border); color: #e66000; border-radius: 12px; font-weight: 700; font-size: 0.85rem; margin-top: 0.5rem; transition: background 0.2s;">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" width="16" height="16" style="display: block;"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg>
|
||||
<span lang="en">Download via GitHub</span><span lang="de">Über GitHub herunterladen</span>
|
||||
</a>
|
||||
<p style="text-align:center; font-size:0.8rem; opacity:0.7; margin-top: 1.2rem; color: var(--text-muted);">
|
||||
<span lang="en">The extension is required to join and sync videos.</span>
|
||||
<span lang="de">Die Erweiterung ist erforderlich, um beizutreten und Videos zu synchronisieren.</span>
|
||||
@@ -83,8 +89,14 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
`;
|
||||
} else {
|
||||
actions.innerHTML = `
|
||||
<a href="#" class="primary" style="text-align:center; text-decoration:none; display:block; padding: 1.2rem; background: var(--accent); color: white; border-radius: 12px; font-weight: 700;">GET IT ON CHROME WEBSTORE</a>
|
||||
<a href="https://github.com/shik3i/KoalaSync" style="text-align:center; color:var(--accent); text-decoration:underline; font-size:0.85rem; margin-top:0.8rem; display:block; font-weight: 600;">Download via GitHub</a>
|
||||
<a href="#" class="primary" style="text-align:center; text-decoration:none; display:flex; align-items:center; justify-content:center; gap: 8px; padding: 1.2rem; background: var(--accent); color: white; border-radius: 12px; font-weight: 700;">
|
||||
<img src="assets/chrome.svg" width="20" style="display: block;">
|
||||
<span lang="en">GET IT ON CHROME WEBSTORE</span><span lang="de">IM CHROME WEB STORE HERUNTERLADEN</span>
|
||||
</a>
|
||||
<a href="https://github.com/shik3i/KoalaSync" style="text-align:center; text-decoration:none; display:flex; align-items:center; justify-content:center; gap: 8px; padding: 0.8rem; background: rgba(255, 255, 255, 0.04); border: 1px solid var(--glass-border); color: var(--accent); border-radius: 12px; font-weight: 700; font-size: 0.85rem; margin-top: 0.5rem; transition: background 0.2s;">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" width="16" height="16" style="display: block;"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg>
|
||||
<span lang="en">Download via GitHub</span><span lang="de">Über GitHub herunterladen</span>
|
||||
</a>
|
||||
<p style="text-align:center; font-size:0.8rem; opacity:0.7; margin-top: 1.2rem; color: var(--text-muted);">
|
||||
<span lang="en">The extension is required to join and sync videos.</span>
|
||||
<span lang="de">Die Erweiterung ist erforderlich, um beizutreten und Videos zu synchronisieren.</span>
|
||||
@@ -95,8 +107,12 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
actions.innerHTML = `
|
||||
<div class="joining-spinner" style="text-align:center; padding: 1rem;">
|
||||
<div style="font-size: 1.2rem; margin-bottom: 0.5rem;">🚀</div>
|
||||
<div style="font-weight: 600; color: var(--accent);">Joining room automatically...</div>
|
||||
<p style="font-size: 0.75rem; color: var(--text-muted); margin-top: 0.5rem;">Your extension is taking care of it.</p>
|
||||
<div style="font-weight: 600; color: var(--accent);">
|
||||
<span lang="en">Joining room automatically...</span><span lang="de">Raum wird automatisch betreten...</span>
|
||||
</div>
|
||||
<p style="font-size: 0.75rem; color: var(--text-muted); margin-top: 0.5rem;">
|
||||
<span lang="en">Your extension is taking care of it.</span><span lang="de">Deine Erweiterung kümmert sich darum.</span>
|
||||
</p>
|
||||
</div>
|
||||
`;
|
||||
|
||||
@@ -270,6 +286,70 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
}
|
||||
};
|
||||
|
||||
// Extension Mockup Tab Switcher
|
||||
const mockTabs = document.querySelectorAll('.mock-tab');
|
||||
const mockScreens = document.querySelectorAll('.mock-screen');
|
||||
|
||||
mockTabs.forEach(tab => {
|
||||
tab.addEventListener('click', () => {
|
||||
mockTabs.forEach(t => t.classList.remove('active'));
|
||||
mockScreens.forEach(s => s.classList.remove('active'));
|
||||
|
||||
tab.classList.add('active');
|
||||
const targetId = tab.getAttribute('data-target');
|
||||
const targetScreen = document.getElementById(targetId);
|
||||
if (targetScreen) {
|
||||
targetScreen.classList.add('active');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Terminal Tab Switcher
|
||||
const termTabBtns = document.querySelectorAll('.terminal-tab-btn');
|
||||
const termPanes = document.querySelectorAll('.terminal-pane');
|
||||
|
||||
termTabBtns.forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
termTabBtns.forEach(b => b.classList.remove('active'));
|
||||
termPanes.forEach(p => p.classList.remove('active'));
|
||||
|
||||
btn.classList.add('active');
|
||||
const targetPaneId = btn.getAttribute('data-tab');
|
||||
const targetPane = document.getElementById(targetPaneId);
|
||||
if (targetPane) {
|
||||
targetPane.classList.add('active');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Terminal Clipboard Copy
|
||||
const copyBtn = document.querySelector('.terminal-copy-btn');
|
||||
if (copyBtn) {
|
||||
copyBtn.addEventListener('click', () => {
|
||||
const activePane = document.querySelector('.terminal-pane.active');
|
||||
if (!activePane) return;
|
||||
const codeElement = activePane.querySelector('code');
|
||||
if (!codeElement) return;
|
||||
|
||||
const textToCopy = codeElement.innerText || codeElement.textContent;
|
||||
|
||||
navigator.clipboard.writeText(textToCopy).then(() => {
|
||||
const isDE = document.documentElement.classList.contains('lang-de');
|
||||
const originalHTML = copyBtn.innerHTML;
|
||||
|
||||
copyBtn.innerHTML = isDE ? '✅ Kopiert!' : '✅ Copied!';
|
||||
copyBtn.disabled = true;
|
||||
|
||||
setTimeout(() => {
|
||||
copyBtn.innerHTML = originalHTML;
|
||||
copyBtn.disabled = false;
|
||||
}, 2000);
|
||||
}).catch(err => {
|
||||
console.error('Failed to copy text: ', err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
checkInvite();
|
||||
updateDynamicVersion();
|
||||
});
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" width="24" height="24"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg>
|
||||
|
After Width: | Height: | Size: 835 B |
+308
-22
@@ -56,8 +56,14 @@
|
||||
<div class="nav-links">
|
||||
<a href="#features"><span lang="en">Features</span><span lang="de">Funktionen</span></a>
|
||||
<a href="#how-it-works"><span lang="en">How it works</span><span lang="de">So funktioniert's</span></a>
|
||||
<a href="https://github.com/Shik3i/KoalaSync" target="_blank">GitHub</a>
|
||||
<a class="lang-toggle" onclick="toggleLanguage(event)">🌍 EN/DE</a>
|
||||
<a href="https://github.com/Shik3i/KoalaSync" target="_blank" style="display: inline-flex; align-items: center; gap: 6px;">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" width="16" height="16" style="display: block;"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg>
|
||||
GitHub
|
||||
</a>
|
||||
<a class="lang-toggle" onclick="toggleLanguage(event)" style="display: inline-flex; align-items: center; gap: 6px;">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width: 16px; height: 16px; display: block;"><circle cx="12" cy="12" r="10"></circle><line x1="2" y1="12" x2="22" y2="12"></line><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"></path></svg>
|
||||
EN/DE
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
@@ -71,8 +77,8 @@
|
||||
<span lang="de">Gemeinsam schauen.<br>Perfekt synchron.</span>
|
||||
</h1>
|
||||
<h2 class="hero-subtitle" data-reveal>
|
||||
<span lang="en">The ultimate free watch party extension for YouTube, Twitch, and local MP4s.</span>
|
||||
<span lang="de">Die ultimative, kostenlose Watch-Party-Erweiterung für YouTube, Twitch und lokale MP4s.</span>
|
||||
<span lang="en">The ultimate free watch party extension for YouTube, Twitch, and local MP4s. Built for extreme precision and data sovereignty.</span>
|
||||
<span lang="de">Die ultimative, kostenlose Watch-Party-Erweiterung für YouTube, Twitch und lokale MP4s. Entwickelt für extreme Präzision und Datenhoheit.</span>
|
||||
</h2>
|
||||
<div class="cta-group" data-reveal>
|
||||
<a href="#" class="btn btn-primary">
|
||||
@@ -83,11 +89,151 @@
|
||||
🦊
|
||||
<span lang="en">Add to Firefox</span><span lang="de">Zu Firefox hinzufügen</span>
|
||||
</a>
|
||||
<a href="https://github.com/Shik3i/KoalaSync" class="btn btn-secondary">
|
||||
<a href="https://github.com/Shik3i/KoalaSync" class="btn btn-secondary" style="display: inline-flex; align-items: center; gap: 8px;">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" width="20" height="20" style="display: block;"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg>
|
||||
GitHub Repo
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Interactive CSS Extension Mockup -->
|
||||
<div class="hero-mockup-wrapper" data-reveal>
|
||||
<div class="extension-mockup">
|
||||
<div class="mock-header">
|
||||
<img src="assets/logo.png" alt="KoalaSync">
|
||||
<span>KOALASYNC</span>
|
||||
</div>
|
||||
<div class="mock-tabs">
|
||||
<button class="mock-tab active" data-target="mock-room">Room</button>
|
||||
<button class="mock-tab" data-target="mock-sync">Sync</button>
|
||||
<button class="mock-tab" data-target="mock-settings">Settings</button>
|
||||
<button class="mock-tab" data-target="mock-dev">Dev</button>
|
||||
</div>
|
||||
<div class="mock-body">
|
||||
<!-- ROOM TAB -->
|
||||
<div id="mock-room" class="mock-screen active">
|
||||
<div class="mock-joined-room">
|
||||
<span class="mock-room-name">brave-eagle-80</span>
|
||||
<span class="mock-server-badge">Official Server</span>
|
||||
</div>
|
||||
<div class="mock-card">
|
||||
<div class="mock-label">Invite Link</div>
|
||||
<div class="mock-invite-box">
|
||||
<input type="text" class="mock-input" value="https://sync.koalastuff.net/join.html#join:brave-eagle-80:pass" readonly>
|
||||
<button class="mock-btn" style="padding: 0.35rem 0.5rem;" onclick="navigator.clipboard.writeText('https://sync.koalastuff.net/join.html#join:brave-eagle-80:pass')">Copy</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mock-card" style="flex: 1; display: flex; flex-direction: column; overflow: hidden;">
|
||||
<div class="mock-label">Peers in Room</div>
|
||||
<div class="mock-peer-list">
|
||||
<div class="mock-peer-item">
|
||||
<div class="mock-peer-header">
|
||||
<span class="mock-peer-name">CoolUsername</span>
|
||||
<span class="mock-peer-meta">YOU</span>
|
||||
</div>
|
||||
<div class="mock-peer-tab">🎬 Germany's Next Flopmodel - S21E12</div>
|
||||
<div class="mock-peer-status"><span style="color:#22c55e;">●</span> 0:55 • Playing</div>
|
||||
</div>
|
||||
<div class="mock-peer-item">
|
||||
<div class="mock-peer-header">
|
||||
<span class="mock-peer-name">KoalaPC</span>
|
||||
<span class="mock-peer-meta">Peer</span>
|
||||
</div>
|
||||
<div class="mock-peer-tab">🎬 Germany's Next Flopmodel - S21E12</div>
|
||||
<div class="mock-peer-status"><span style="color:#22c55e;">●</span> 0:55 • Playing</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="mock-btn" style="background:#ef4444; width:100%; margin-top:auto;">Leave Room</button>
|
||||
</div>
|
||||
|
||||
<!-- SYNC TAB -->
|
||||
<div id="mock-sync" class="mock-screen">
|
||||
<div class="mock-target-box">
|
||||
⭐ MATCH: Germany's Next Flopmodel - S21E12
|
||||
</div>
|
||||
<div class="mock-card">
|
||||
<div class="mock-label">Remote Control</div>
|
||||
<div class="mock-ctrl-buttons">
|
||||
<button class="mock-btn mock-btn-play">▶ Play</button>
|
||||
<button class="mock-btn mock-btn-pause">⏸ Pause</button>
|
||||
<button class="mock-btn mock-btn-force">⚡ Force Sync Everyone</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mock-card">
|
||||
<div class="mock-label">Last Activity Status</div>
|
||||
<div class="mock-status-display">
|
||||
<span style="font-weight: 700;">PAUSE</span>
|
||||
<span class="mock-status-pill">● In Sync</span>
|
||||
</div>
|
||||
<div class="mock-log-item">
|
||||
Pause triggered by CoolUsername
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- SETTINGS TAB -->
|
||||
<div id="mock-settings" class="mock-screen">
|
||||
<div class="mock-card">
|
||||
<div class="mock-label">Your Username</div>
|
||||
<input type="text" class="mock-input" value="CoolUsername" readonly>
|
||||
</div>
|
||||
<div class="mock-card" style="flex: 1;">
|
||||
<div class="mock-label">Preferences</div>
|
||||
<div class="mock-settings-row">
|
||||
<input type="checkbox" id="chk-noise" checked disabled>
|
||||
<div>
|
||||
<label for="chk-noise">Filter Noise Tabs</label>
|
||||
<p>Hide common non-video websites from the target selector.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mock-settings-row">
|
||||
<input type="checkbox" id="chk-binge" checked disabled>
|
||||
<div>
|
||||
<label for="chk-binge">Auto-Sync Next Episode</label>
|
||||
<p>Automatically sync transitions between series episodes.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="mock-btn" style="background:#4b5563; width:100%;">Regenerate Peer ID</button>
|
||||
</div>
|
||||
|
||||
<!-- DEV TAB -->
|
||||
<div id="mock-dev" class="mock-screen">
|
||||
<div class="mock-card">
|
||||
<div class="mock-label">Diagnostics</div>
|
||||
<div class="mock-diagnostic-grid">
|
||||
<div class="mock-diag-box">
|
||||
<div class="mock-label" style="margin-bottom:0.1rem; font-size:0.55rem;">Ready State</div>
|
||||
<span class="diag-val">HAVE_ENOUGH_DATA</span>
|
||||
</div>
|
||||
<div class="mock-diag-box">
|
||||
<div class="mock-label" style="margin-bottom:0.1rem; font-size:0.55rem;">Seek Delta</div>
|
||||
<span class="diag-val">0.05s</span>
|
||||
</div>
|
||||
<div class="mock-diag-box">
|
||||
<div class="mock-label" style="margin-bottom:0.1rem; font-size:0.55rem;">Buffered</div>
|
||||
<span class="diag-val">300.2s</span>
|
||||
</div>
|
||||
<div class="mock-diag-box">
|
||||
<div class="mock-label" style="margin-bottom:0.1rem; font-size:0.55rem;">Engine State</div>
|
||||
<span class="diag-val" style="color:#22c55e;">SYNCED</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mock-card" style="flex: 1; overflow: hidden;">
|
||||
<div class="mock-label">Event Stream</div>
|
||||
<div style="font-family:monospace; font-size:0.65rem; color:#10b981; line-height:1.4;">
|
||||
<div>[18:37:32] EVENT: PLAY -> ACK</div>
|
||||
<div>[18:37:32] FORCE_SYNC -> 0.05s diff</div>
|
||||
<div>[18:37:38] EVENT: PAUSE -> BROADCAST</div>
|
||||
<div style="color:var(--text-muted);">[18:37:42] content_heartbeat: active</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
@@ -97,33 +243,46 @@
|
||||
<span lang="en">Why KoalaSync?</span><span lang="de">Warum KoalaSync?</span>
|
||||
</h2>
|
||||
<p style="text-align: center; color: var(--text-muted); margin-bottom: 4rem;">
|
||||
<span lang="en">Built for performance, privacy, and simplicity.</span><span lang="de">Entwickelt für Leistung, Privatsphäre und Einfachheit.</span>
|
||||
<span lang="en">Built for frame-perfect performance, absolute privacy, and total simplicity.</span>
|
||||
<span lang="de">Entwickelt für bildgenaue Leistung, absolute Privatsphäre und totale Einfachheit.</span>
|
||||
</p>
|
||||
|
||||
<div class="features-grid">
|
||||
<div class="feature-card" data-reveal>
|
||||
<div class="feature-icon">⚡</div>
|
||||
<h3><span lang="en">Real-time Sync</span><span lang="de">Echtzeit-Synchronisation</span></h3>
|
||||
<p lang="en">Proprietary two-phase synchronization protocol ensures sub-millisecond precision across all peers.</p>
|
||||
<p lang="de">Das proprietäre Zwei-Phasen-Synchronisationsprotokoll gewährleistet Sub-Millisekunden-Präzision für alle Teilnehmer.</p>
|
||||
<h3>
|
||||
<span lang="en">Full Control / Instant Sync</span>
|
||||
<span lang="de">Volle Kontrolle & Echtzeit</span>
|
||||
</h3>
|
||||
<p lang="en">One pauses, everyone pauses. One seeks, everyone follows. Our custom two-phase sync protocol coordinates playback with sub-millisecond precision across all participants.</p>
|
||||
<p lang="de">Einer pausiert, alle pausieren. Einer spult, alle folgen. Unser Zwei-Phasen-Synchronisationsprotokoll koordiniert die Wiedergabe in Echtzeit mit Sub-Millisekunden-Präzision.</p>
|
||||
</div>
|
||||
<div class="feature-card" data-reveal>
|
||||
<div class="feature-icon">🎬</div>
|
||||
<h3><span lang="en">Episode Auto-Sync</span><span lang="de">Automatische Episoden-Synchronisation</span></h3>
|
||||
<p lang="en">Perfectly sync series binges. All peers wait until everyone has loaded the next episode.</p>
|
||||
<p lang="de">Perfekt synchronisiertes Serien-Bingeing. Alle warten, bis jeder die nächste Episode geladen hat.</p>
|
||||
<h3>
|
||||
<span lang="en">Endless Binge-Watching</span>
|
||||
<span lang="de">Grenzenloses Bingen</span>
|
||||
</h3>
|
||||
<p lang="en">Autoplay perfectly in sync. KoalaSync automatically detects episode transitions and holds playback until all peers have successfully loaded the next video.</p>
|
||||
<p lang="de">Nächste Episode startet für jeden zeitgleich. KoalaSync erkennt den Episodenwechsel und pausiert, bis jeder Teilnehmer das neue Video fertig geladen hat.</p>
|
||||
</div>
|
||||
<div class="feature-card" data-reveal>
|
||||
<div class="feature-icon">🛡️</div>
|
||||
<h3><span lang="en">Privacy First</span><span lang="de">Privatsphäre zuerst</span></h3>
|
||||
<p lang="en">Zero data persistence. Our relay server runs entirely in RAM and collects no telemetry or logs.</p>
|
||||
<p lang="de">Keine Datenspeicherung. Unser Relay-Server läuft komplett im RAM und sammelt weder Telemetrie noch Logs.</p>
|
||||
<h3>
|
||||
<span lang="en">Zero Accounts / Pure Privacy</span>
|
||||
<span lang="de">Keine Accounts / Datenschutz</span>
|
||||
</h3>
|
||||
<p lang="en">No registration, no tracking, and no database persistence. The server runs entirely in RAM, collects no telemetry or logs, and completely forgets your room when you leave.</p>
|
||||
<p lang="de">Keine Registrierung, kein Tracking und keine Datenspeicherung. Der Server läuft flüchtig im RAM, sammelt keine Logs und vergisst deinen Raum sofort nach dem Verlassen.</p>
|
||||
</div>
|
||||
<div class="feature-card" data-reveal>
|
||||
<div class="feature-icon">⭐</div>
|
||||
<h3><span lang="en">Smart Match</span><span lang="de">Intelligente Zuordnung</span></h3>
|
||||
<p lang="en">Find the right tab instantly. KoalaSync highlights and sorts matching video tabs for you.</p>
|
||||
<p lang="de">Finden Sie sofort den richtigen Tab. KoalaSync markiert und sortiert passende Video-Tabs für Sie.</p>
|
||||
<div class="feature-icon">🌐</div>
|
||||
<h3>
|
||||
<span lang="en">Universal HTML5 Support</span>
|
||||
<span lang="de">Universeller HTML5-Support</span>
|
||||
</h3>
|
||||
<p lang="en">Works on YouTube, Twitch, Netflix, Disney+, Jellyfin, Emby, and any standard webpage containing a HTML5 video element. Perfect for custom self-hosted setups.</p>
|
||||
<p lang="de">Unterstützt YouTube, Twitch, Netflix, Disney+, Jellyfin, Emby und jede beliebige Webseite mit einem HTML5-Video-Tag. Ideal auch für eigene Medienbibliotheken.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -144,7 +303,25 @@
|
||||
<p lang="en">Add KoalaSync to your browser from the Chrome Web Store, Firefox Add-ons, or download the latest developer ZIP from GitHub.</p>
|
||||
<p lang="de">Füge KoalaSync aus dem Chrome Web Store, den Firefox Add-ons oder über die Entwickler-ZIP von GitHub zu deinem Browser hinzu.</p>
|
||||
</div>
|
||||
<div style="background: var(--card); height: 200px; border-radius: 20px; border: 1px solid var(--glass-border);"></div>
|
||||
<!-- Custom Step 1 Illustration -->
|
||||
<div class="step-illustration-1" data-reveal>
|
||||
<div class="illus-browser-bar">
|
||||
<div class="illus-browser-header">
|
||||
<div class="illus-dots">
|
||||
<span class="illus-dot"></span>
|
||||
<span class="illus-dot"></span>
|
||||
<span class="illus-dot"></span>
|
||||
</div>
|
||||
<div class="illus-address-bar"></div>
|
||||
<div class="illus-extension-icon">🐨</div>
|
||||
</div>
|
||||
<div class="illus-browser-body">
|
||||
<div class="illus-line-placeholder" style="width: 80%;"></div>
|
||||
<div class="illus-line-placeholder" style="width: 50%;"></div>
|
||||
<div class="illus-line-placeholder" style="width: 90%;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="step">
|
||||
<div class="step-text" data-reveal>
|
||||
@@ -153,7 +330,20 @@
|
||||
<p lang="en">Open the extension, enter a Room ID and Password, and hit Join. Your secure synchronization space is ready.</p>
|
||||
<p lang="de">Öffnen Sie die Erweiterung, geben Sie eine Raum-ID und ein Passwort ein und klicken Sie auf Beitreten. Ihr sicherer Synchronisationsraum ist bereit.</p>
|
||||
</div>
|
||||
<div style="background: var(--card); height: 200px; border-radius: 20px; border: 1px solid var(--glass-border);"></div>
|
||||
<!-- Custom Step 2 Illustration -->
|
||||
<div class="step-illustration-2" data-reveal>
|
||||
<div class="illus-form-box">
|
||||
<div class="illus-form-field">
|
||||
<div class="illus-line-placeholder" style="width: 30%; height: 6px;"></div>
|
||||
<div class="illus-form-input">
|
||||
<div class="illus-typing-text">brave-eagle-80</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="illus-form-btn">
|
||||
<span lang="en">CREATE ROOM</span><span lang="de">RAUM ERSTELLEN</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="step">
|
||||
<div class="step-text" data-reveal>
|
||||
@@ -162,7 +352,103 @@
|
||||
<p lang="en">Send the invite link to your friends. Once they join, select your video tab and enjoy perfectly synced playback.</p>
|
||||
<p lang="de">Senden Sie den Einladungslink an Ihre Freunde. Sobald sie beitreten, wählen Sie Ihren Video-Tab aus und genießen Sie die perfekt synchronisierte Wiedergabe.</p>
|
||||
</div>
|
||||
<div style="background: var(--card); height: 200px; border-radius: 20px; border: 1px solid var(--glass-border);"></div>
|
||||
<!-- Custom Step 3 Illustration -->
|
||||
<div class="step-illustration-3" data-reveal>
|
||||
<div class="illus-players-container">
|
||||
<div class="illus-mini-player">
|
||||
<div class="illus-video-screen">
|
||||
<div class="illus-play-icon">▶</div>
|
||||
</div>
|
||||
<div class="illus-player-timeline">
|
||||
<div class="illus-timeline-bar">
|
||||
<div class="illus-timeline-progress"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="illus-sync-connection">
|
||||
<div class="illus-sync-line">
|
||||
<div class="illus-sync-pulse"></div>
|
||||
</div>
|
||||
<span class="illus-sync-label">IN SYNC</span>
|
||||
</div>
|
||||
<div class="illus-mini-player">
|
||||
<div class="illus-video-screen">
|
||||
<div class="illus-play-icon">▶</div>
|
||||
</div>
|
||||
<div class="illus-player-timeline">
|
||||
<div class="illus-timeline-bar">
|
||||
<div class="illus-timeline-progress"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Self Hosters Paradise Section -->
|
||||
<section id="self-hosting" style="background: rgba(15, 23, 42, 0.4); border-top: 1px solid var(--glass-border); border-bottom: 1px solid var(--glass-border);">
|
||||
<div class="container">
|
||||
<h2 style="font-size: 2.5rem; text-align: center; margin-bottom: 1rem;">
|
||||
<span lang="en">Self-Hosters Paradise</span><span lang="de">Das Paradies für Self-Hoster</span>
|
||||
</h2>
|
||||
<p style="text-align: center; color: var(--text-muted); margin-bottom: 3rem; max-width: 600px; margin-left: auto; margin-right: auto;">
|
||||
<span lang="en">Maintain absolute data sovereignty. Deploy your own private high-performance relay server in under 60 seconds.</span>
|
||||
<span lang="de">Behalte die absolute Datenhoheit. Richte deinen eigenen privaten Hochleistungs-Relay-Server in unter 60 Sekunden ein.</span>
|
||||
</p>
|
||||
|
||||
<div class="terminal-container" data-reveal>
|
||||
<div class="terminal-header">
|
||||
<div class="terminal-dots">
|
||||
<span class="terminal-dot red"></span>
|
||||
<span class="terminal-dot yellow"></span>
|
||||
<span class="terminal-dot green"></span>
|
||||
</div>
|
||||
<div class="terminal-tabs">
|
||||
<button class="terminal-tab-btn active" data-tab="pane-docker">docker-compose.yml</button>
|
||||
<button class="terminal-tab-btn" data-tab="pane-caddy">Caddyfile</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="terminal-body">
|
||||
<button class="terminal-copy-btn">
|
||||
📋 <span lang="en">Copy Code</span><span lang="de">Code kopieren</span>
|
||||
</button>
|
||||
|
||||
<div id="pane-docker" class="terminal-pane active">
|
||||
<pre><code><span class="t-key">version:</span> <span class="t-str">"3.8"</span>
|
||||
|
||||
<span class="t-key">services:</span>
|
||||
<span class="t-key">koalasync:</span>
|
||||
<span class="t-key">image:</span> <span class="t-str">ghcr.io/shik3i/koalasync:latest</span>
|
||||
<span class="t-key">container_name:</span> <span class="t-str">koalasync-relay</span>
|
||||
<span class="t-key">ports:</span>
|
||||
<span class="t-key">-</span> <span class="t-str">"3000:3000"</span>
|
||||
<span class="t-key">environment:</span>
|
||||
<span class="t-key">-</span> <span class="t-str">NODE_ENV=production</span>
|
||||
<span class="t-key">-</span> <span class="t-str">PORT=3000</span>
|
||||
<span class="t-key">restart:</span> <span class="t-str">always</span>
|
||||
<span class="t-key">logging:</span>
|
||||
<span class="t-key">driver:</span> <span class="t-str">"json-file"</span>
|
||||
<span class="t-key">options:</span>
|
||||
<span class="t-key">max-size:</span> <span class="t-str">"10m"</span></code></pre>
|
||||
</div>
|
||||
|
||||
<div id="pane-caddy" class="terminal-pane">
|
||||
<pre><code><span class="t-comment"># Reverse proxy for your secure WebSocket relay server</span>
|
||||
<span class="t-key">sync.yourdomain.com</span> {
|
||||
<span class="t-key">reverse_proxy</span> <span class="t-val">localhost:3000</span>
|
||||
|
||||
<span class="t-key">header</span> {
|
||||
<span class="t-comment"># Security policies</span>
|
||||
<span class="t-key">Permissions-Policy</span> <span class="t-str">"interest-cohort=()"</span>
|
||||
<span class="t-key">Strict-Transport-Security</span> <span class="t-str">"max-age=31536000; includeSubDomains; preload"</span>
|
||||
<span class="t-key">X-Content-Type-Options</span> <span class="t-str">"nosniff"</span>
|
||||
<span class="t-key">X-Frame-Options</span> <span class="t-str">"DENY"</span>
|
||||
}
|
||||
}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+8
-2
@@ -48,8 +48,14 @@
|
||||
<button class="hamburger" onclick="document.querySelector('.nav-links').classList.toggle('open')" aria-label="Menu">☰</button>
|
||||
<div class="nav-links">
|
||||
<a href="index.html">Home</a>
|
||||
<a href="https://github.com/shik3i/KoalaSync" target="_blank">GitHub</a>
|
||||
<a class="lang-toggle" onclick="toggleLanguage(event)">🌍 EN/DE</a>
|
||||
<a href="https://github.com/shik3i/KoalaSync" target="_blank" style="display: inline-flex; align-items: center; gap: 6px;">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" width="16" height="16" style="display: block;"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg>
|
||||
GitHub
|
||||
</a>
|
||||
<a class="lang-toggle" onclick="toggleLanguage(event)" style="display: inline-flex; align-items: center; gap: 6px;">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width: 16px; height: 16px; display: block;"><circle cx="12" cy="12" r="10"></circle><line x1="2" y1="12" x2="22" y2="12"></line><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"></path></svg>
|
||||
EN/DE
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
+771
-27
@@ -156,43 +156,45 @@ nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-top: 8rem;
|
||||
text-align: center;
|
||||
padding-bottom: 4rem;
|
||||
}
|
||||
|
||||
.hero-grid {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
display: grid;
|
||||
grid-template-columns: 1.2fr 1fr;
|
||||
align-items: center;
|
||||
gap: 2rem;
|
||||
gap: 4rem;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.hero-text h1 {
|
||||
font-size: 5rem;
|
||||
font-size: 4.5rem;
|
||||
font-weight: 800;
|
||||
line-height: 1;
|
||||
line-height: 1.1;
|
||||
margin-bottom: 1.5rem;
|
||||
background: linear-gradient(to bottom, #fff 30%, #6366f1);
|
||||
background: linear-gradient(to bottom, #fff 40%, #6366f1);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
|
||||
.hero-text p, .hero-subtitle {
|
||||
font-size: 1.5rem;
|
||||
font-size: 1.25rem;
|
||||
color: var(--text-muted);
|
||||
margin-bottom: 3rem;
|
||||
max-width: 700px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
margin-bottom: 2.5rem;
|
||||
max-width: 600px;
|
||||
font-weight: 400;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.cta-group {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: 1rem 2rem;
|
||||
padding: 0.85rem 1.75rem;
|
||||
border-radius: 12px;
|
||||
font-weight: 600;
|
||||
text-decoration: none;
|
||||
@@ -200,6 +202,7 @@ nav {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
@@ -240,9 +243,9 @@ nav {
|
||||
display: inline-block;
|
||||
background: rgba(99, 102, 241, 0.1);
|
||||
color: var(--accent);
|
||||
padding: 0.5rem 1.25rem;
|
||||
padding: 0.4rem 1rem;
|
||||
border-radius: 99px;
|
||||
font-size: 0.85rem;
|
||||
font-size: 0.8rem;
|
||||
font-weight: 700;
|
||||
margin-bottom: 1.5rem;
|
||||
border: 1px solid rgba(99, 102, 241, 0.3);
|
||||
@@ -250,15 +253,334 @@ nav {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
/* --- Interactive CSS Extension Mockup --- */
|
||||
.hero-mockup-wrapper {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.hero-image {
|
||||
.extension-mockup {
|
||||
width: 320px;
|
||||
height: 490px;
|
||||
background: #0f172a;
|
||||
border-radius: 20px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.4), 0 0 20px rgba(99, 102, 241, 0.15);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.mock-header {
|
||||
background: #1e293b;
|
||||
padding: 0.85rem 1rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
.mock-header img {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.mock-header span {
|
||||
font-weight: 800;
|
||||
font-size: 0.95rem;
|
||||
letter-spacing: 0.5px;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.mock-tabs {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
background: #1e293b;
|
||||
padding: 0.25rem;
|
||||
gap: 0.25rem;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
.mock-tab {
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--text-muted);
|
||||
font-size: 0.75rem;
|
||||
font-weight: 600;
|
||||
padding: 0.4rem 0;
|
||||
cursor: pointer;
|
||||
border-radius: 6px;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.mock-tab:hover {
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.mock-tab.active {
|
||||
background: var(--accent);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.mock-body {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 0.95rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.85rem;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.mock-screen {
|
||||
display: none;
|
||||
flex-direction: column;
|
||||
gap: 0.85rem;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.mock-screen.active {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
/* Common Mockup Components */
|
||||
.mock-card {
|
||||
background: #1e293b;
|
||||
border: 1px solid rgba(255, 255, 255, 0.05);
|
||||
border-radius: 10px;
|
||||
padding: 0.75rem;
|
||||
}
|
||||
|
||||
.mock-label {
|
||||
font-size: 0.65rem;
|
||||
font-weight: 700;
|
||||
color: var(--text-muted);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
margin-bottom: 0.4rem;
|
||||
}
|
||||
|
||||
.mock-input {
|
||||
background: #0f172a;
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
border-radius: 6px;
|
||||
color: white;
|
||||
padding: 0.45rem;
|
||||
font-size: 0.75rem;
|
||||
width: 100%;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.mock-btn {
|
||||
background: var(--accent);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
padding: 0.5rem;
|
||||
font-weight: 600;
|
||||
font-size: 0.75rem;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.mock-btn:hover {
|
||||
background: #4f46e5;
|
||||
}
|
||||
|
||||
/* Room Tab Details */
|
||||
.mock-joined-room {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
background: rgba(99, 102, 241, 0.1);
|
||||
border: 1px solid rgba(99, 102, 241, 0.2);
|
||||
border-radius: 8px;
|
||||
padding: 0.6rem 0.75rem;
|
||||
}
|
||||
|
||||
.mock-room-name {
|
||||
font-weight: 700;
|
||||
color: var(--accent);
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.mock-server-badge {
|
||||
background: rgba(99, 102, 241, 0.2);
|
||||
color: var(--accent);
|
||||
font-size: 0.6rem;
|
||||
font-weight: 700;
|
||||
padding: 2px 6px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.mock-invite-box {
|
||||
display: flex;
|
||||
gap: 0.4rem;
|
||||
}
|
||||
|
||||
.mock-invite-box input {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.mock-peer-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.mock-peer-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: rgba(255, 255, 255, 0.02);
|
||||
border: 1px solid rgba(255, 255, 255, 0.03);
|
||||
border-radius: 8px;
|
||||
padding: 0.5rem 0.6rem;
|
||||
}
|
||||
|
||||
.mock-peer-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.mock-peer-name {
|
||||
font-weight: 700;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.mock-peer-meta {
|
||||
font-size: 0.65rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.mock-peer-tab {
|
||||
font-size: 0.7rem;
|
||||
color: var(--accent);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.mock-peer-status {
|
||||
font-size: 0.65rem;
|
||||
color: var(--text-muted);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
/* Sync Tab Details */
|
||||
.mock-target-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.4rem;
|
||||
background: rgba(234, 179, 8, 0.1);
|
||||
border: 1px solid rgba(234, 179, 8, 0.2);
|
||||
color: #facc15;
|
||||
padding: 0.5rem 0.6rem;
|
||||
border-radius: 8px;
|
||||
font-weight: 600;
|
||||
font-size: 0.7rem;
|
||||
}
|
||||
|
||||
.mock-ctrl-buttons {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.mock-btn-play { background: #22c55e; }
|
||||
.mock-btn-play:hover { background: #16a34a; }
|
||||
.mock-btn-pause { background: #ef4444; }
|
||||
.mock-btn-pause:hover { background: #dc2626; }
|
||||
.mock-btn-force { background: var(--accent); grid-column: span 2; }
|
||||
|
||||
.mock-status-display {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.mock-status-pill {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.3rem;
|
||||
background: rgba(34, 197, 94, 0.1);
|
||||
border: 1px solid rgba(34, 197, 94, 0.2);
|
||||
color: #22c55e;
|
||||
padding: 2px 8px;
|
||||
border-radius: 99px;
|
||||
font-size: 0.65rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.mock-log-item {
|
||||
font-size: 0.7rem;
|
||||
color: var(--text-muted);
|
||||
border-left: 2px solid var(--accent);
|
||||
padding-left: 0.4rem;
|
||||
margin-top: 0.4rem;
|
||||
}
|
||||
|
||||
/* Settings Tab Details */
|
||||
.mock-settings-row {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 0.5rem;
|
||||
margin-bottom: 0.6rem;
|
||||
}
|
||||
|
||||
.mock-settings-row input[type="checkbox"] {
|
||||
margin-top: 0.2rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mock-settings-row label {
|
||||
cursor: pointer;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.mock-settings-row p {
|
||||
font-size: 0.65rem;
|
||||
color: var(--text-muted);
|
||||
margin-top: 0.1rem;
|
||||
}
|
||||
|
||||
/* Dev Tab Details */
|
||||
.mock-diagnostic-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 0.4rem;
|
||||
}
|
||||
|
||||
.mock-diag-box {
|
||||
background: rgba(255, 255, 255, 0.02);
|
||||
border: 1px solid rgba(255, 255, 255, 0.04);
|
||||
border-radius: 6px;
|
||||
padding: 0.4rem;
|
||||
}
|
||||
|
||||
.mock-diag-box .diag-val {
|
||||
font-family: monospace;
|
||||
font-weight: 700;
|
||||
color: var(--accent);
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
/* --- Features --- */
|
||||
.features-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
|
||||
gap: 2rem;
|
||||
margin-top: 4rem;
|
||||
}
|
||||
@@ -268,17 +590,33 @@ nav {
|
||||
padding: 2.5rem;
|
||||
border-radius: 24px;
|
||||
border: 1px solid var(--glass-border);
|
||||
transition: transform 0.3s;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.feature-card::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0; left: 0; right: 0; bottom: 0;
|
||||
border-radius: 24px;
|
||||
padding: 1px;
|
||||
background: linear-gradient(to bottom right, rgba(99, 102, 241, 0.25), 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;
|
||||
}
|
||||
|
||||
.feature-card:hover {
|
||||
transform: translateY(-10px);
|
||||
transform: translateY(-5px);
|
||||
box-shadow: 0 15px 30px rgba(99, 102, 241, 0.15);
|
||||
border-color: rgba(99, 102, 241, 0.2);
|
||||
}
|
||||
|
||||
.feature-icon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
background: var(--accent-glow);
|
||||
background: rgba(99, 102, 241, 0.1);
|
||||
color: var(--accent);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -286,28 +624,32 @@ nav {
|
||||
border-radius: 12px;
|
||||
margin-bottom: 1.5rem;
|
||||
font-size: 1.5rem;
|
||||
border: 1px solid rgba(99, 102, 241, 0.2);
|
||||
}
|
||||
|
||||
.feature-card h3 {
|
||||
margin-bottom: 1rem;
|
||||
font-size: 1.5rem;
|
||||
margin-bottom: 0.75rem;
|
||||
font-size: 1.35rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.feature-card p {
|
||||
color: var(--text-muted);
|
||||
font-size: 0.95rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* --- How it works --- */
|
||||
.steps {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4rem;
|
||||
gap: 6rem;
|
||||
}
|
||||
|
||||
.step {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 4rem;
|
||||
grid-template-columns: 1fr 1.1fr;
|
||||
gap: 6rem;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
@@ -316,11 +658,412 @@ nav {
|
||||
}
|
||||
|
||||
.step-num {
|
||||
font-size: 5rem;
|
||||
font-size: 4rem;
|
||||
font-weight: 800;
|
||||
color: var(--accent-glow);
|
||||
color: rgba(99, 102, 241, 0.15);
|
||||
line-height: 1;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.step-text h3 {
|
||||
font-size: 1.85rem;
|
||||
margin-bottom: 1rem;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.step-text p {
|
||||
color: var(--text-muted);
|
||||
font-size: 1.05rem;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* Custom CSS Mockups for step illustrations */
|
||||
.step-illustration-1, .step-illustration-2, .step-illustration-3 {
|
||||
background: #1e293b;
|
||||
height: 240px;
|
||||
border-radius: 20px;
|
||||
border: 1px solid var(--glass-border);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 15px 30px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
/* Step 1 Illustration: Browser & Extension icon trigger */
|
||||
.illus-browser-bar {
|
||||
width: 85%;
|
||||
background: #0f172a;
|
||||
border: 1px solid rgba(255,255,255,0.05);
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 10px 20px rgba(0,0,0,0.4);
|
||||
}
|
||||
|
||||
.illus-browser-header {
|
||||
background: #1e293b;
|
||||
padding: 0.5rem 0.75rem;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid rgba(255,255,255,0.05);
|
||||
}
|
||||
|
||||
.illus-dots {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.illus-dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
background: rgba(255,255,255,0.2);
|
||||
}
|
||||
|
||||
.illus-address-bar {
|
||||
background: #0f172a;
|
||||
border: 1px solid rgba(255,255,255,0.05);
|
||||
padding: 2px 10px;
|
||||
border-radius: 4px;
|
||||
width: 60%;
|
||||
height: 14px;
|
||||
}
|
||||
|
||||
.illus-extension-icon {
|
||||
position: relative;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: rgba(99, 102, 241, 0.2);
|
||||
border: 1px solid var(--accent);
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
animation: pulse-border 2s infinite alternate;
|
||||
}
|
||||
|
||||
@keyframes pulse-border {
|
||||
0% { box-shadow: 0 0 0 rgba(99, 102, 241, 0); border-color: rgba(99, 102, 241, 0.4); }
|
||||
100% { box-shadow: 0 0 8px rgba(99, 102, 241, 0.6); border-color: var(--accent); }
|
||||
}
|
||||
|
||||
.illus-browser-body {
|
||||
padding: 1.5rem;
|
||||
height: 80px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.illus-line-placeholder {
|
||||
height: 8px;
|
||||
background: rgba(255,255,255,0.05);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
/* Step 2 Illustration: Typing in Form Fields */
|
||||
.illus-form-box {
|
||||
width: 70%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.75rem;
|
||||
background: rgba(15, 23, 42, 0.6);
|
||||
border: 1px solid rgba(255, 255, 255, 0.05);
|
||||
border-radius: 12px;
|
||||
padding: 1rem;
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.illus-form-field {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.35rem;
|
||||
}
|
||||
|
||||
.illus-form-input {
|
||||
background: #0f172a;
|
||||
border: 1px solid rgba(99, 102, 241, 0.3);
|
||||
padding: 0.45rem;
|
||||
border-radius: 6px;
|
||||
height: 28px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.illus-typing-text {
|
||||
font-family: monospace;
|
||||
font-weight: 700;
|
||||
color: var(--text);
|
||||
font-size: 0.8rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.illus-typing-text::after {
|
||||
content: '|';
|
||||
animation: blink-cursor 0.8s infinite;
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
@keyframes blink-cursor {
|
||||
50% { opacity: 0; }
|
||||
}
|
||||
|
||||
.illus-form-btn {
|
||||
background: var(--accent);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
padding: 0.45rem;
|
||||
font-weight: 700;
|
||||
font-size: 0.75rem;
|
||||
text-align: center;
|
||||
box-shadow: 0 4px 10px rgba(99, 102, 241, 0.3);
|
||||
}
|
||||
|
||||
/* Step 3 Illustration: Multi-player Sync simulation */
|
||||
.illus-players-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1.5rem;
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
.illus-mini-player {
|
||||
flex: 1;
|
||||
background: #0f172a;
|
||||
border: 1px solid rgba(255,255,255,0.05);
|
||||
border-radius: 10px;
|
||||
height: 120px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.illus-video-screen {
|
||||
width: 100%;
|
||||
height: 100px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: radial-gradient(circle, rgba(99,102,241,0.15) 0%, transparent 80%);
|
||||
}
|
||||
|
||||
.illus-play-icon {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
background: rgba(99, 102, 241, 0.9);
|
||||
color: white;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 0.85rem;
|
||||
box-shadow: 0 0 12px rgba(99, 102, 241, 0.5);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.illus-player-timeline {
|
||||
height: 20px;
|
||||
background: #1e293b;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 0.5rem;
|
||||
border-top: 1px solid rgba(255,255,255,0.05);
|
||||
}
|
||||
|
||||
.illus-timeline-bar {
|
||||
flex: 1;
|
||||
height: 3px;
|
||||
background: rgba(255,255,255,0.1);
|
||||
position: relative;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.illus-timeline-progress {
|
||||
position: absolute;
|
||||
top: 0; left: 0;
|
||||
width: 60%;
|
||||
height: 100%;
|
||||
background: var(--accent);
|
||||
border-radius: 2px;
|
||||
animation: timeline-grow 4s infinite linear;
|
||||
}
|
||||
|
||||
@keyframes timeline-grow {
|
||||
0% { width: 0%; }
|
||||
100% { width: 100%; }
|
||||
}
|
||||
|
||||
.illus-sync-connection {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0.25rem;
|
||||
color: var(--accent);
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
.illus-sync-line {
|
||||
width: 40px;
|
||||
height: 2px;
|
||||
background: linear-gradient(to right, var(--accent), var(--success));
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.illus-sync-pulse {
|
||||
position: absolute;
|
||||
top: -3px;
|
||||
left: 0;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
background: #fff;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 0 8px #fff;
|
||||
animation: slide-pulse 2s infinite linear;
|
||||
}
|
||||
|
||||
@keyframes slide-pulse {
|
||||
0% { left: 0%; }
|
||||
100% { left: 100%; }
|
||||
}
|
||||
|
||||
.illus-sync-label {
|
||||
font-size: 0.55rem;
|
||||
font-weight: 700;
|
||||
background: rgba(34, 197, 94, 0.15);
|
||||
color: #22c55e;
|
||||
padding: 1px 6px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid rgba(34, 197, 94, 0.25);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* --- Self Hosters Terminal --- */
|
||||
.terminal-container {
|
||||
max-width: 850px;
|
||||
margin: 3rem auto 0 auto;
|
||||
background: #0f172a;
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
border-radius: 16px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 20px 45px rgba(0,0,0,0.5);
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.terminal-header {
|
||||
background: #1e293b;
|
||||
padding: 0.85rem 1.25rem;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid rgba(255,255,255,0.06);
|
||||
}
|
||||
|
||||
.terminal-dots {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.terminal-dot {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.terminal-dot.red { background: #ef4444; }
|
||||
.terminal-dot.yellow { background: #f59e0b; }
|
||||
.terminal-dot.green { background: #10b981; }
|
||||
|
||||
.terminal-tabs {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.terminal-tab-btn {
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--text-muted);
|
||||
font-weight: 600;
|
||||
font-size: 0.8rem;
|
||||
padding: 0.35rem 0.75rem;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.terminal-tab-btn:hover {
|
||||
color: var(--text);
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
}
|
||||
|
||||
.terminal-tab-btn.active {
|
||||
color: var(--accent);
|
||||
background: rgba(99, 102, 241, 0.1);
|
||||
border: 1px solid rgba(99, 102, 241, 0.2);
|
||||
}
|
||||
|
||||
.terminal-body {
|
||||
position: relative;
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.terminal-pane {
|
||||
display: none;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.terminal-pane.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.terminal-pane pre {
|
||||
margin: 0;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.terminal-pane code {
|
||||
font-family: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace;
|
||||
font-size: 0.85rem;
|
||||
line-height: 1.6;
|
||||
color: #e2e8f0;
|
||||
}
|
||||
|
||||
/* Syntax Highlighting */
|
||||
.t-comment { color: #64748b; font-style: italic; }
|
||||
.t-key { color: #f472b6; }
|
||||
.t-val { color: #38bdf8; }
|
||||
.t-str { color: #34d399; }
|
||||
.t-num { color: #fbbf24; }
|
||||
|
||||
.terminal-copy-btn {
|
||||
position: absolute;
|
||||
top: 1rem;
|
||||
right: 1.5rem;
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
color: var(--text-muted);
|
||||
padding: 0.35rem 0.75rem;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 600;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.3rem;
|
||||
}
|
||||
|
||||
.terminal-copy-btn:hover {
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
color: var(--text);
|
||||
border-color: rgba(255, 255, 255, 0.15);
|
||||
}
|
||||
|
||||
.terminal-copy-btn:active {
|
||||
transform: scale(0.97);
|
||||
}
|
||||
|
||||
/* --- Footer --- */
|
||||
@@ -343,6 +1086,7 @@ footer {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
|
||||
/* --- Legal Pages --- */
|
||||
.legal-content {
|
||||
max-width: 800px;
|
||||
|
||||
Reference in New Issue
Block a user