website: fix HTML issues, mobile nav, i18n, and SEO

Bug Fixes:
- index.html: remove duplicate <title> tags (invalid HTML), use single
  title + JS swap; fix og:image relative→absolute URL (logo.png)
- join.html: fix hardcoded lang=de, add language detection IIFE,
  add lang toggle to nav, make badge/title/desc/actions bilingual,
  add missing </head> closing tag, add noindex meta
- app.js: join status handler was German-only; now fully bilingual
  (Success/Error titles, countdown, close/retry button labels)

Improvements:
- Add Firefox 'Add to Firefox' button to hero CTA (placeholder href=#)
- impressum.html / datenschutz.html: add noindex meta to keep legal
  pages out of search results
- robots.txt: add Sitemap directive for SEO crawlability
- sitemap.xml: new file listing main page + legal pages with priorities
- style.css: mobile nav hamburger menu (☰) replaces display:none
  blackout; nav-links drop down on mobile with backdrop blur
- style.css: cta-group flex-wrap for narrow screens
- Hamburger button added to all 4 page navs
This commit is contained in:
MacBook
2026-05-04 05:49:16 +02:00
parent 90882f91ef
commit 1e3bb94660
8 changed files with 114 additions and 25 deletions
+14 -7
View File
@@ -161,14 +161,18 @@ document.addEventListener('DOMContentLoaded', () => {
if (success) {
if (icon) icon.textContent = '✅';
title.textContent = 'Erfolgreich!';
const isDE = document.documentElement.classList.contains('lang-de');
title.textContent = isDE ? 'Erfolgreich!' : 'Success!';
let count = 3;
const updateCountdown = () => {
desc.innerHTML = `Du bist dem Raum beigetreten. <br><span style="color:var(--accent); font-weight:bold;">Dieser Tab schließt sich in ${count} Sekunden...</span>`;
const closingMsg = isDE
? `Du bist dem Raum beigetreten. <br><span style="color:var(--accent); font-weight:bold;">Dieser Tab schließt sich in ${count} Sekunden...</span>`
: `You joined the room. <br><span style="color:var(--accent); font-weight:bold;">This tab will close in ${count} seconds...</span>`;
desc.innerHTML = closingMsg;
if (count <= 0) {
window.close();
desc.textContent = 'Beitritt erfolgreich! Du kannst diesen Tab jetzt manuell schließen.';
desc.textContent = isDE ? 'Beitritt erfolgreich! Du kannst diesen Tab jetzt manuell schließen.' : 'Joined successfully! You can close this tab manually.';
} else {
count--;
setTimeout(updateCountdown, 1000);
@@ -176,12 +180,15 @@ document.addEventListener('DOMContentLoaded', () => {
};
updateCountdown();
actions.innerHTML = '<button class="primary" onclick="window.close()" style="background:var(--success); width: 100%;">TAB JETZT SCHLIESSEN</button>';
const closeLabel = isDE ? 'TAB JETZT SCHLIESSEN' : 'CLOSE TAB NOW';
actions.innerHTML = `<button class="primary" onclick="window.close()" style="background:var(--success); width: 100%;">${closeLabel}</button>`;
} else {
if (icon) icon.textContent = '❌';
title.textContent = 'Fehler';
desc.textContent = `Beitritt fehlgeschlagen: ${message}`;
actions.innerHTML = '<button class="primary" onclick="location.reload()" style="width: 100%;">ERNEUT VERSUCHEN</button>';
const isDE = document.documentElement.classList.contains('lang-de');
title.textContent = isDE ? 'Fehler' : 'Error';
desc.textContent = isDE ? `Beitritt fehlgeschlagen: ${message}` : `Join failed: ${message}`;
const retryLabel = isDE ? 'ERNEUT VERSUCHEN' : 'TRY AGAIN';
actions.innerHTML = `<button class="primary" onclick="location.reload()" style="width: 100%;">${retryLabel}</button>`;
}
} else {
const banner = document.getElementById('koala-banner');
+2
View File
@@ -6,6 +6,7 @@
<title>Datenschutz / Privacy Policy | KoalaSync</title>
<link rel="stylesheet" href="style.css">
<link rel="icon" type="image/png" href="assets/logo.png">
<meta name="robots" content="noindex">
<script>
(function() {
var savedLang = localStorage.getItem('koala_lang');
@@ -40,6 +41,7 @@
<img src="assets/logo.png" alt="KoalaSync Logo">
<span>KoalaSync</span>
</a>
<button class="hamburger" onclick="document.querySelector('.nav-links').classList.toggle('open')" aria-label="Menu"></button>
<div class="nav-links">
<a href="index.html"><span lang="de">Startseite</span><span lang="en">Home</span></a>
<a href="https://github.com/shik3i/KoalaSync" target="_blank">GitHub</a>
+2
View File
@@ -6,6 +6,7 @@
<title>Impressum / Legal Notice | KoalaSync</title>
<link rel="stylesheet" href="style.css">
<link rel="icon" type="image/png" href="assets/logo.png">
<meta name="robots" content="noindex">
<script>
(function() {
var savedLang = localStorage.getItem('koala_lang');
@@ -40,6 +41,7 @@
<img src="assets/logo.png" alt="KoalaSync Logo">
<span>KoalaSync</span>
</a>
<button class="hamburger" onclick="document.querySelector('.nav-links').classList.toggle('open')" aria-label="Menu"></button>
<div class="nav-links">
<a href="index.html"><span lang="de">Startseite</span><span lang="en">Home</span></a>
<a href="https://github.com/shik3i/KoalaSync" target="_blank">GitHub</a>
+11 -12
View File
@@ -3,15 +3,14 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title lang="en">KoalaSync | Real-time Video Synchronization for Friends</title>
<title lang="de">KoalaSync | Echtzeit-Video-Synchronisation für Freunde</title>
<title>KoalaSync | Real-time Video Synchronization for Friends</title>
<meta name="description" content="Watch YouTube, Twitch, and HTML5 videos perfectly synchronized with friends. KoalaSync is a privacy-first, open-source Chrome extension.">
<link rel="stylesheet" href="style.css">
<link rel="icon" type="image/png" href="assets/logo.png">
<meta property="og:title" content="KoalaSync | Sync your videos">
<meta property="og:description" content="Watch together, stay in sync. Privacy-first video synchronization.">
<meta property="og:image" content="assets/hero.png">
<meta property="og:image" content="https://koalasync.shik3i.net/assets/logo.png">
<meta property="og:type" content="website">
<script>
@@ -21,6 +20,8 @@
var activeLang = savedLang || browserLang;
document.documentElement.classList.add('lang-' + activeLang);
document.documentElement.lang = activeLang;
var titles = { en: 'KoalaSync | Real-time Video Synchronization for Friends', de: 'KoalaSync | Echtzeit-Video-Synchronisation für Freunde' };
document.title = titles[activeLang] || titles.en;
})();
function toggleLanguage(e) {
@@ -32,15 +33,8 @@
html.classList.add('lang-' + newLang);
html.lang = newLang;
localStorage.setItem('koala_lang', newLang);
// Toggle title tags
var titleEn = document.querySelector('title[lang="en"]');
var titleDe = document.querySelector('title[lang="de"]');
if (newLang === 'de') {
document.title = titleDe ? titleDe.textContent : 'KoalaSync';
} else {
document.title = titleEn ? titleEn.textContent : 'KoalaSync';
}
var titles = { en: 'KoalaSync | Real-time Video Synchronization for Friends', de: 'KoalaSync | Echtzeit-Video-Synchronisation für Freunde' };
document.title = titles[newLang] || titles.en;
}
</script>
</head>
@@ -58,6 +52,7 @@
<img src="assets/logo.png" alt="KoalaSync Logo">
<span>KoalaSync</span>
</div>
<button class="hamburger" onclick="document.querySelector('.nav-links').classList.toggle('open')" aria-label="Menu"></button>
<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>
@@ -84,6 +79,10 @@
<img src="assets/chrome.svg" width="20" style="filter: brightness(100)">
<span lang="en">Add to Chrome</span><span lang="de">Zu Chrome hinzufügen</span>
</a>
<a href="#" class="btn btn-primary" style="background: #e66000;">
🦊
<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">
GitHub Repo
</a>
+34 -6
View File
@@ -1,11 +1,36 @@
<!DOCTYPE html>
<html lang="de">
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Beitreten | KoalaSync</title>
<title>Join Room | KoalaSync</title>
<link rel="stylesheet" href="style.css">
<link rel="icon" type="image/png" href="assets/logo.png">
<meta name="robots" content="noindex">
<script>
(function() {
var savedLang = localStorage.getItem('koala_lang');
var browserLang = navigator.language.startsWith('de') ? 'de' : 'en';
var activeLang = savedLang || browserLang;
document.documentElement.classList.add('lang-' + activeLang);
document.documentElement.lang = activeLang;
var titles = { en: 'Join Room | KoalaSync', de: 'Raum beitreten | KoalaSync' };
document.title = titles[activeLang] || titles.en;
})();
function toggleLanguage(e) {
if(e) e.preventDefault();
var html = document.documentElement;
var currentIsEnglish = html.classList.contains('lang-en');
var newLang = currentIsEnglish ? 'de' : 'en';
html.classList.remove('lang-en', 'lang-de');
html.classList.add('lang-' + newLang);
html.lang = newLang;
localStorage.setItem('koala_lang', newLang);
var titles = { en: 'Join Room | KoalaSync', de: 'Raum beitreten | KoalaSync' };
document.title = titles[newLang] || titles.en;
}
</script>
</head>
<body>
<div class="bg-blobs">
@@ -20,19 +45,22 @@
<img src="assets/logo.png" alt="KoalaSync Logo">
<span>KoalaSync</span>
</a>
<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>
</div>
</div>
</nav>
<main class="legal-content join-card">
<div class="legal-card" id="join-container" data-reveal style="padding: 2.5rem;">
<div class="room-badge">INVITATION DETECTED</div>
<h1 id="join-title" style="font-size: 2rem; margin-bottom: 1rem;">Ready to sync?</h1>
<div class="room-badge"><span lang="en">INVITATION DETECTED</span><span lang="de">EINLADUNG ERKANNT</span></div>
<h1 id="join-title" style="font-size: 2rem; margin-bottom: 1rem;"><span lang="en">Ready to sync?</span><span lang="de">Bereit zum Synchronisieren?</span></h1>
<p id="join-desc" style="text-align: center; color: var(--text-muted); margin-bottom: 2rem; font-size: 0.9rem;">
You've been invited to join a synchronized session.
<span lang="en">You've been invited to join a synchronized session.</span>
<span lang="de">Du wurdest eingeladen, einer synchronisierten Sitzung beizutreten.</span>
</p>
<div id="room-info-box" style="background: rgba(255,255,255,0.03); padding: 2rem; border-radius: 20px; margin-bottom: 2rem; border: 1px solid var(--glass-border); text-align: center; position: relative; overflow: hidden;">
@@ -41,7 +69,7 @@
</div>
<div id="join-actions" style="display: flex; flex-direction: column; gap: 1rem;">
<div style="text-align: center; color: var(--text-muted); font-size: 0.8rem;">Detecting extension...</div>
<div style="text-align: center; color: var(--text-muted); font-size: 0.8rem;"><span lang="en">Detecting extension...</span><span lang="de">Erweiterung wird erkannt...</span></div>
</div>
</div>
</main>
+2
View File
@@ -1,2 +1,4 @@
User-agent: *
Allow: /
Sitemap: https://koalasync.shik3i.net/sitemap.xml
+18
View File
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://koalasync.shik3i.net/</loc>
<changefreq>monthly</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>https://koalasync.shik3i.net/impressum.html</loc>
<changefreq>yearly</changefreq>
<priority>0.3</priority>
</url>
<url>
<loc>https://koalasync.shik3i.net/datenschutz.html</loc>
<changefreq>yearly</changefreq>
<priority>0.3</priority>
</url>
</urlset>
+31
View File
@@ -399,9 +399,26 @@ footer {
}
.cta-group {
justify-content: center;
flex-wrap: wrap;
}
.nav-links {
display: none;
position: absolute;
top: 100%;
left: 0;
right: 0;
flex-direction: column;
background: rgba(15, 23, 42, 0.95);
backdrop-filter: blur(12px);
padding: 1rem 2rem;
gap: 1rem;
border-bottom: 1px solid var(--glass-border);
}
.nav-links.open {
display: flex;
}
.hamburger {
display: flex;
}
.legal-card {
padding: 1.5rem;
@@ -425,3 +442,17 @@ html.lang-de [lang="en"] {
.lang-toggle:hover {
color: var(--accent);
}
/* --- Hamburger Menu --- */
.hamburger {
display: none;
align-items: center;
justify-content: center;
background: none;
border: none;
color: var(--text);
font-size: 1.5rem;
cursor: pointer;
padding: 0.25rem;
line-height: 1;
}