diff --git a/website/app.js b/website/app.js index ea25d0a..40040c3 100644 --- a/website/app.js +++ b/website/app.js @@ -1,26 +1,22 @@ // KoalaSync Landing Page Logic document.addEventListener('DOMContentLoaded', () => { - // Scroll Reveal Logic + // Scroll Reveal Logic (IntersectionObserver for performance) const revealElements = document.querySelectorAll('[data-reveal]'); - const revealOnScroll = () => { - const windowHeight = window.innerHeight; - revealElements.forEach(el => { - const elementTop = el.getBoundingClientRect().top; - const revealPoint = 150; - - if (elementTop < windowHeight - revealPoint) { - el.classList.add('revealed'); + const revealObserver = new IntersectionObserver((entries) => { + entries.forEach(entry => { + if (entry.isIntersecting) { + entry.target.classList.add('revealed'); + revealObserver.unobserve(entry.target); } }); - }; + }, { + rootMargin: '0px 0px -150px 0px', + threshold: 0.1 + }); - // Initial check - revealOnScroll(); - - // Scroll listener - window.addEventListener('scroll', revealOnScroll); + revealElements.forEach(el => revealObserver.observe(el)); // Navbar scroll effect const nav = document.querySelector('nav'); @@ -75,11 +71,11 @@ document.addEventListener('DOMContentLoaded', () => { if (isFirefox) { actions.innerHTML = ` - 🦊 + Firefox GET IT ON MOZILLA ADD-ONSIM FIREFOX ADD-ON STORE HERUNTERLADEN - + Download via GitHubÜber GitHub herunterladen

@@ -90,11 +86,11 @@ document.addEventListener('DOMContentLoaded', () => { } else { actions.innerHTML = ` - + Chrome GET IT ON CHROME WEBSTOREIM CHROME WEB STORE HERUNTERLADEN - + Download via GitHubÜber GitHub herunterladen

@@ -106,7 +102,7 @@ document.addEventListener('DOMContentLoaded', () => { } else { actions.innerHTML = `

-
🚀
+
Joining room automatically...Raum wird automatisch betreten...
@@ -194,22 +190,21 @@ document.addEventListener('DOMContentLoaded', () => { if (icon) icon.textContent = '✅'; const isDE = document.documentElement.classList.contains('lang-de'); title.textContent = isDE ? 'Erfolgreich!' : 'Success!'; + desc.innerHTML = isDE + ? 'Verbunden!
W\u00e4hle jetzt einen Video-Tab in der Erweiterung aus.' + : 'Connected!
Now select a video tab in the extension.'; - let count = 2; + let count = 3; const updateCountdown = () => { - const closingMsg = isDE - ? `Du bist dem Raum beigetreten.
Dieser Tab schließt sich in ${count} Sekunden...` - : `You joined the room.
This tab will close in ${count} seconds...`; - desc.innerHTML = closingMsg; if (count <= 0) { window.close(); - desc.textContent = isDE ? 'Beitritt erfolgreich! Du kannst diesen Tab jetzt manuell schließen.' : 'Joined successfully! You can close this tab manually.'; + desc.textContent = isDE ? 'Beitritt erfolgreich! Du kannst diesen Tab jetzt manuell schlie\u00dfen.' : 'Joined successfully! You can close this tab manually.'; } else { count--; setTimeout(updateCountdown, 1000); } }; - updateCountdown(); + setTimeout(updateCountdown, 1000); const closeLabel = isDE ? 'TAB JETZT SCHLIESSEN' : 'CLOSE TAB NOW'; actions.innerHTML = ``; @@ -405,6 +400,47 @@ document.addEventListener('DOMContentLoaded', () => { }); }); + // Automated Store/Local Badge Linking based on User-Agent + const detectBrowserAndElevateBadge = () => { + const isFirefox = navigator.userAgent.includes('Firefox'); + const isChrome = navigator.userAgent.includes('Chrome') || navigator.userAgent.includes('Chromium'); + const chromeBtns = document.querySelectorAll('.btn-primary'); + const firefoxBtns = document.querySelectorAll('.btn-firefox'); + + if (isFirefox && chromeBtns.length > 0 && firefoxBtns.length > 0) { + // User is on Firefox: Elevate Firefox button to primary, make Chrome secondary + chromeBtns.forEach(btn => { + btn.classList.remove('btn-primary'); + btn.classList.add('btn-secondary'); + }); + + firefoxBtns.forEach(btn => { + // Put Firefox first in visual order + btn.style.order = '-1'; + + // Add subtle focus scale effect + btn.style.transform = 'scale(1.05)'; + btn.addEventListener('mouseleave', () => { + btn.style.transform = 'scale(1)'; + }); + btn.addEventListener('mouseenter', () => { + btn.style.transform = 'scale(1.05) translateY(-2px)'; + }); + }); + } else if (isChrome && chromeBtns.length > 0 && firefoxBtns.length > 0) { + // User is on Chrome: Make Firefox secondary + firefoxBtns.forEach(btn => { + btn.classList.remove('btn-firefox'); + btn.classList.add('btn-secondary'); + btn.style.color = 'var(--text)'; + btn.style.background = 'var(--card)'; + btn.style.border = '1px solid var(--glass-border)'; + btn.style.boxShadow = 'none'; + }); + } + }; + + detectBrowserAndElevateBadge(); checkInvite(); updateDynamicVersion(); }); diff --git a/website/assets/emby.svg b/website/assets/emby.svg new file mode 100644 index 0000000..2b54f92 --- /dev/null +++ b/website/assets/emby.svg @@ -0,0 +1,3 @@ + + + diff --git a/website/assets/firefox.svg b/website/assets/firefox.svg new file mode 100644 index 0000000..8b3b9ab --- /dev/null +++ b/website/assets/firefox.svg @@ -0,0 +1 @@ +Firefox Browser \ No newline at end of file diff --git a/website/assets/jellyfin.svg b/website/assets/jellyfin.svg new file mode 100644 index 0000000..8a26899 --- /dev/null +++ b/website/assets/jellyfin.svg @@ -0,0 +1,3 @@ + + + diff --git a/website/assets/netflix.svg b/website/assets/netflix.svg new file mode 100644 index 0000000..47ab6ac --- /dev/null +++ b/website/assets/netflix.svg @@ -0,0 +1,3 @@ + + + diff --git a/website/assets/primevideo.svg b/website/assets/primevideo.svg new file mode 100644 index 0000000..e0af9a9 --- /dev/null +++ b/website/assets/primevideo.svg @@ -0,0 +1,5 @@ + + prime + video + + \ No newline at end of file diff --git a/website/assets/twitch.svg b/website/assets/twitch.svg new file mode 100644 index 0000000..1d2686f --- /dev/null +++ b/website/assets/twitch.svg @@ -0,0 +1,3 @@ + + + diff --git a/website/assets/youtube.svg b/website/assets/youtube.svg new file mode 100644 index 0000000..a80a93f --- /dev/null +++ b/website/assets/youtube.svg @@ -0,0 +1,3 @@ + + + diff --git a/website/index.html b/website/index.html index 149a064..1a1de60 100644 --- a/website/index.html +++ b/website/index.html @@ -37,11 +37,11 @@ FeaturesFunktionen How it worksSo funktioniert's - + GitHub - + EN/DE
@@ -62,15 +62,15 @@
- + Chrome Add to ChromeZu Chrome hinzufügen - 🦊 + Firefox Add to FirefoxZu Firefox hinzufügen - + GitHub Releases
@@ -114,7 +114,7 @@ CoolUsername YOUICH -
🎬 Germany's Next Flopmodel - S21E12
+
🎬 Stranger Things - S4E1
0:55 • PlayingWiedergabe
@@ -122,7 +122,7 @@ KoalaPC PeerPartner
-
🎬 Germany's Next Flopmodel - S21E12
+
🎬 Stranger Things - S4E1
0:55 • PlayingWiedergabe
@@ -137,7 +137,7 @@ Select VideoVideo auswählen @@ -245,6 +245,91 @@ +
+
+

+ Works on your favorite platforms + Funktioniert auf deinen Lieblingsplattformen +

+
+ + + + + + + +
+
+
+ +
+
+

+ Perfect for Any Occasion + Perfekt für jeden Anlass +

+

+ Whether near or far, KoalaSync brings people together around their favorite videos. + Ob nah oder fern, KoalaSync bringt Menschen bei ihren Lieblingsvideos zusammen. +

+
+
+

+ 🍿 + Movie Night with Friends + Filmabend mit Freunden +

+

Sync your movies in real time and talk via Discord, Zoom, or your favorite voice call application. It feels just like sitting in the same room.

+

Synchronisiere eure Filme in Echtzeit und quatscht nebenbei auf Discord, Zoom oder im Tool eurer Wahl. Es fühlt sich an, als säßet ihr im selben Raum.

+
+
+

+ 🎓 + Remote Learning + Remote Learning +

+

Analyze online tutorials, lectures, or developer training streams together with classmates or colleagues. Pause and discuss complex steps in perfect harmony.

+

Analysiert Online-Tutorials, Vorlesungen oder Streams gemeinsam mit Mitschülern oder Kollegen. Pausiert und besprecht komplizierte Schritte in perfektem Sync.

+
+
+

+ 💖 + Long-Distance Relationships + Paare auf Distanz +

+

Bridge the distance and enjoy date nights. Experience every plot twist, laugh at the same jokes, and share emotional moments at the exact same millisecond.

+

Überbrückt die Distanz und genießt gemeinsame Date-Nächte. Erlebt jeden Plot-Twist, lacht über dieselben Witze und teilt emotionale Momente zur selben Millisekunde.

+
+
+
+
+

@@ -257,8 +342,8 @@
-

+ Full Control / Instant Sync Volle Kontrolle & Echtzeit

@@ -266,8 +351,8 @@

Einer pausiert, alle pausieren. Einer spult, alle folgen. Unser Zwei-Phasen-Synchronisationsprotokoll koordiniert die Wiedergabe aller Teilnehmer in Echtzeit.

-
🎬

+ 🎬 Endless Binge-Watching Grenzenloses Bingen

@@ -275,8 +360,8 @@

Nächste Episode startet für jeden zeitgleich. KoalaSync erkennt den Episodenwechsel und pausiert, bis jeder Teilnehmer das neue Video fertig geladen hat.

-
🛡️

+ 🛡️ Zero Accounts / Pure Privacy Keine Accounts / Datenschutz

@@ -284,8 +369,8 @@

Kein Login. Keine Daten. Einfach Link teilen und schauen. Der Server läuft flüchtig im RAM und löscht deinen Raum komplett nach dem Verlassen.

-
🌐

+ 🌐 Universal HTML5 Support Universeller HTML5-Support

@@ -293,8 +378,8 @@

Unterstützt YouTube, Twitch, Netflix, Jellyfin, Emby und jede beliebige Webseite mit einem HTML5-Video-Tag. Ideal auch für eigene Medienbibliotheken.

-
🐳

+ 🐳 Self-Hostable & Docker-Ready Self-Hostable & Docker-Ready

@@ -302,8 +387,8 @@

Unsere Server sind kostenlos und schnell, aber du kannst auch die volle Kontrolle übernehmen, wenn du willst. Starte dein eigenes privates Relay in Sekunden via Docker.

-
🔗

+ 🔗 Instant Invites / 1-Click Join Direkte Einladungen & 1-Klick Beitritt

@@ -315,6 +400,73 @@

+
+
+

+ KoalaSync vs. Teleparty + KoalaSync vs. Teleparty +

+

+ See why open source, ad-free and privacy-first is the superior way to watch together. + Erfahre, warum Open Source, werbefrei und Datenschutz der bessere Weg zum gemeinsamen Schauen sind. +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureFunktionKoalaSyncTeleparty
+ 100% Free / No Paywalls100% Kostenlos / Keine Paywalls + No premium subscriptions, hidden fees or locked features.Keine Premium-Abos, versteckte Kosten oder gesperrte Funktionen. + 100% Free100% KostenlosPaid Tiers / Premium LocksPremium-Abo / Paywalls
+ Open Source (MIT)Open Source (MIT) + Fully auditable codebase. Anyone can contribute.Vollständig prüfbarer Code. Jeder kann mitwirken. + YesJaProprietaryProprietär
+ Self-HostableSelf-Hostable + Deploy your own private relay server in seconds.Starte deinen eigenen privaten Relay-Server in Sekunden. + Yes (Docker-ready)Ja (Docker-bereit)NoNein
+ Privacy First / Ephemeral RAMDatenschutz / Flüchtiger RAM + No registration, no accounts, no persistent tracking.Keine Registrierung, keine Accounts, kein Tracking. + Zero-PersistenceKeine SpeicherungGoogle Analytics & CookiesGoogle Analytics & Cookies
+ Universal HTML5 SyncUniverseller HTML5-Sync + Works on almost any website with a video element.Funktioniert auf fast jeder Webseite mit einem Video. + Any Video ElementJedes Video-ElementSupported sites only (some Premium-only)Nur unterstützte Seiten (teilweise Premium-Pflicht)
+
+
+
+

@@ -481,15 +633,30 @@

-
+
-

Ready to sync?Bereit zum Synchronisieren?

-

- Start watching together with friends.Schau gemeinsam mit Freunden. +

+ Not convinced? See for yourself. + Noch nicht überzeugt? Überzeug dich selbst. +

+

+ KoalaSync is 100% open source, ad-free and tracking-free. Audit our codebase on GitHub or install the browser extension directly. + KoalaSync ist zu 100 % Open Source, werbefrei und trackingsicher. Überprüfe unseren Code auf GitHub oder installiere direkt die Browser-Erweiterung.

- - View on GitHubAuf GitHub ansehen - +
diff --git a/website/join.html b/website/join.html index 64a2018..3a0283c 100644 --- a/website/join.html +++ b/website/join.html @@ -26,11 +26,11 @@ @@ -52,7 +52,10 @@
-
Detecting extension...Erweiterung wird erkannt...
+
+
+ Detecting extension...Erweiterung wird erkannt... +
diff --git a/website/style.css b/website/style.css index 61d1813..c857221 100644 --- a/website/style.css +++ b/website/style.css @@ -619,17 +619,11 @@ nav { } .feature-icon { - width: 48px; - height: 48px; - background: rgba(99, 102, 241, 0.1); - color: var(--accent); - display: flex; - align-items: center; - justify-content: center; - border-radius: 12px; - margin-bottom: 1.5rem; - font-size: 1.5rem; - border: 1px solid rgba(99, 102, 241, 0.2); + font-size: 1.6rem; + margin-right: 0.6rem; + display: inline-block; + vertical-align: middle; + filter: drop-shadow(0 2px 8px rgba(0,0,0,0.2)); } .feature-card h3 { @@ -1217,3 +1211,329 @@ html.lang-de [lang="en"] { padding: 0.25rem; line-height: 1; } + +/* --- Feature Cards: subtle differentiation --- */ +.feature-card:nth-child(1) { --card-accent: rgba(99, 102, 241, 0.06); } +.feature-card:nth-child(2) { --card-accent: rgba(139, 92, 246, 0.06); } +.feature-card:nth-child(3) { --card-accent: rgba(34, 197, 94, 0.06); } +.feature-card:nth-child(4) { --card-accent: rgba(56, 189, 248, 0.06); } +.feature-card:nth-child(5) { --card-accent: rgba(245, 158, 11, 0.06); } +.feature-card:nth-child(6) { --card-accent: rgba(236, 72, 153, 0.06); } + +.feature-card { + background: linear-gradient(135deg, var(--card-accent, transparent), var(--card)); +} + +/* --- Compatibility Section --- */ +.compat-section { + padding: 4rem 0; + text-align: center; + background: rgba(255,255,255,0.01); + border-bottom: 1px solid var(--glass-border); +} + +.compat-heading { + font-size: 1rem; + font-weight: 600; + color: var(--text-muted); + letter-spacing: 0.08em; + text-transform: uppercase; + margin-bottom: 2rem; +} + +.compat-row { + display: flex; + justify-content: center; + align-items: center; + gap: 3rem; + flex-wrap: wrap; +} + +.compat-logo { + display: flex; + flex-direction: column; + align-items: center; + gap: 0.5rem; + font-size: 0.75rem; + font-weight: 700; + color: var(--text-muted); + transition: opacity 0.3s; + opacity: 0.55; +} + +.compat-logo:hover { + opacity: 0.85; +} + +.compat-logo img { + width: 28px; + height: 28px; + display: block; +} + +.compat-more { + opacity: 0.4; + cursor: help; + flex-direction: row; + gap: 0.35rem; + position: relative; +} + +.compat-more:hover { + opacity: 0.6; +} + +.compat-more-icon { + font-size: 1.1rem; + font-weight: 700; + color: var(--accent); + line-height: 1; +} + +.compat-tooltip { + display: none; + position: absolute; + bottom: calc(100% + 10px); + left: 50%; + transform: translateX(-50%); + background: var(--card); + color: var(--text-muted); + padding: 0.6rem 0.9rem; + border-radius: 8px; + font-size: 0.72rem; + font-weight: 500; + white-space: nowrap; + border: 1px solid var(--glass-border); + box-shadow: 0 8px 20px rgba(0,0,0,0.4); + z-index: 10; + line-height: 1.4; +} + +.compat-tooltip::after { + content: ''; + position: absolute; + top: 100%; + left: 50%; + transform: translateX(-50%); + border: 6px solid transparent; + border-top-color: var(--glass-border); +} + +.compat-more:hover .compat-tooltip { + display: block; +} + +/* --- Join Page Loading Spinner --- */ +.join-spinner { + width: 36px; + height: 36px; + border: 3px solid rgba(99, 102, 241, 0.2); + border-top-color: var(--accent); + border-radius: 50%; + animation: spin 0.8s linear infinite; + margin: 0 auto 0.75rem; +} + +@keyframes spin { + to { transform: rotate(360deg); } +} + +/* --- Reduced Motion --- */ +@media (prefers-reduced-motion: reduce) { + *, *::before, *::after { + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.01ms !important; + } + [data-reveal] { + opacity: 1; + transform: none; + } + .blob { + animation: none; + } + .illus-typing-text::after { + animation: none; + } + .illus-timeline-progress { + animation: none; + width: 60%; + } + .illus-sync-pulse { + animation: none; + } + .illus-extension-icon { + animation: none; + } +} + +/* --- Use Cases / Anwendungsszenarien Section --- */ +.use-cases-section { + padding: 6rem 0; + position: relative; + border-bottom: 1px solid var(--glass-border); +} + +.use-cases-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); + gap: 2rem; + margin-top: 1rem; +} + +.use-case-card { + background: rgba(30, 41, 59, 0.4); + border: 1px solid var(--glass-border); + border-radius: 16px; + padding: 2.2rem 2rem; + text-align: left; + transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.3s ease; + backdrop-filter: blur(8px); + -webkit-backdrop-filter: blur(8px); + display: flex; + flex-direction: column; + gap: 0.8rem; + position: relative; + overflow: hidden; +} + +.use-case-card::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 3px; + background: linear-gradient(90deg, transparent, var(--card-accent-border, var(--accent)), transparent); + opacity: 0; + transition: opacity 0.3s ease; +} + +.use-case-card:nth-child(1) { --card-accent-border: #6366f1; } +.use-case-card:nth-child(2) { --card-accent-border: #38bdf8; } +.use-case-card:nth-child(3) { --card-accent-border: #ec4899; } + + +.use-case-card:hover { + transform: translateY(-5px); + box-shadow: 0 12px 30px rgba(0, 0, 0, 0.35); + border-color: rgba(255, 255, 255, 0.15); +} + +.use-case-card:hover::before { + opacity: 1; +} + +.use-case-icon { + font-size: 1.6rem; + margin-right: 0.6rem; + display: inline-block; + vertical-align: middle; + filter: drop-shadow(0 2px 8px rgba(0,0,0,0.2)); +} + +.use-case-card h3 { + font-size: 1.25rem; + font-weight: 700; + margin: 0; + color: white; +} + +.use-case-card p { + font-size: 0.9rem; + line-height: 1.6; + color: var(--text-muted); + margin: 0; +} + +/* --- Comparison Section --- */ +.comparison-section { + padding: 6rem 0; + background: rgba(255, 255, 255, 0.01); + border-bottom: 1px solid var(--glass-border); +} + +.comparison-table-wrapper { + overflow-x: auto; + background: rgba(30, 41, 59, 0.35); + border: 1px solid var(--glass-border); + border-radius: 16px; + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2); + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); + margin-top: 1rem; +} + +.comparison-table { + width: 100%; + border-collapse: collapse; + text-align: left; + font-size: 0.95rem; +} + +.comparison-table th, +.comparison-table td { + padding: 1.25rem 1.5rem; + border-bottom: 1px solid rgba(255, 255, 255, 0.06); +} + +.comparison-table th { + background: rgba(15, 23, 42, 0.6); + font-weight: 700; + color: white; + text-transform: uppercase; + font-size: 0.8rem; + letter-spacing: 0.08em; +} + +.comparison-table th.highlight, +.comparison-table td.highlight { + background: rgba(99, 102, 241, 0.08); +} + +.comparison-table tbody tr:hover { + background: rgba(255, 255, 255, 0.02); +} + +.comparison-table tbody tr:last-child td { + border-bottom: none; +} + +.feat-name { + display: flex; + flex-direction: column; + gap: 0.25rem; +} + +.feat-name strong { + color: white; + font-weight: 600; +} + +.feat-desc { + font-size: 0.8rem; + color: var(--text-muted); +} + +.check { + color: #22c55e; + font-weight: 700; +} + +.cross { + color: #ef4444; + font-weight: 500; + opacity: 0.8; +} + +@media (max-width: 768px) { + .comparison-table th, + .comparison-table td { + padding: 1rem; + font-size: 0.85rem; + } + .feat-desc { + display: none; + } +} +