From db70828c82b7535dd2cb1d8bb3e20013f1e011b5 Mon Sep 17 00:00:00 2001
From: KoalaDev <6156589+Shik3i@users.noreply.github.com>
Date: Mon, 6 Jul 2026 16:03:48 +0200
Subject: [PATCH] feat: browser-aware CTAs, tidier hero demo, comparison guides
link
- Hero CTAs: the install buttons are compact (just the browser name) so all
three fit one line; JS detects the visitor's browser and expands that one
to the full "Add to X" call to action. Unknown browsers stay compact.
- Hero demo: caption now sits directly under the two windows (absolutely
positioned to the card cascade) instead of far below the tall scene. The
scene keeps a fixed height that already fits the open popup, so the
vertically centered hero never jumps when the popup toggles.
- The background window now also shows a (non-interactive) extension icon,
making it clear both browsers have KoalaSync installed.
- Escape now also closes the demo popup.
- Added a link from the comparison table to the fuller alternatives/guides
hub, localized in all 15 languages.
Co-Authored-By: Claude Fable 5
---
website/app.js | 26 +++++++++++++++
website/locales/de.json | 3 +-
website/locales/en.json | 3 +-
website/locales/es.json | 3 +-
website/locales/fr.json | 3 +-
website/locales/it.json | 3 +-
website/locales/ja.json | 3 +-
website/locales/ko.json | 3 +-
website/locales/nl.json | 3 +-
website/locales/pl.json | 3 +-
website/locales/pt-BR.json | 3 +-
website/locales/pt.json | 3 +-
website/locales/ru.json | 3 +-
website/locales/tr.json | 3 +-
website/locales/uk.json | 3 +-
website/locales/zh.json | 3 +-
website/style.css | 68 ++++++++++++++++++++++++++++++++++----
website/template.html | 31 +++++++++++------
18 files changed, 139 insertions(+), 31 deletions(-)
diff --git a/website/app.js b/website/app.js
index 49d3391..a13bdc7 100644
--- a/website/app.js
+++ b/website/app.js
@@ -78,6 +78,23 @@ document.addEventListener('DOMContentLoaded', () => {
});
}
+ // Highlight the CTA for the visitor's browser: it expands to the full
+ // "Add to X" label while the others stay compact. Unknown browsers keep
+ // all three compact.
+ try {
+ const ua = navigator.userAgent;
+ let detected = null;
+ if (/Firefox\//.test(ua) && !/Seamonkey\//.test(ua)) {
+ detected = 'firefox';
+ } else if (/Chrome\//.test(ua) || /Chromium\//.test(ua) || /Edg\//.test(ua) || /OPR\//.test(ua)) {
+ detected = 'chrome';
+ }
+ if (detected) {
+ const btn = document.querySelector('.btn-install[data-browser="' + detected + '"]');
+ if (btn) btn.classList.add('is-detected');
+ }
+ } catch (_) { /* leave all buttons compact */ }
+
// Open collapsed section blocks when the URL directly targets them
const hashCollapseMap = { '#faq': 'faq-collapse', '#self-hosting': 'selfhost-collapse' };
const collapseId = hashCollapseMap[window.location.hash];
@@ -809,6 +826,15 @@ document.addEventListener('DOMContentLoaded', () => {
});
}
+ // Escape closes the popup as well
+ document.addEventListener('keydown', (e) => {
+ if (e.key !== 'Escape') return;
+ if (!scene.classList.contains('popup-open')) return;
+ userTookOver = true;
+ finishDemo();
+ setPopupOpen(false);
+ });
+
const runDemo = async () => {
if (demoStarted || userTookOver || reduceMotion) return;
demoStarted = true;
diff --git a/website/locales/de.json b/website/locales/de.json
index 1987871..6393f39 100644
--- a/website/locales/de.json
+++ b/website/locales/de.json
@@ -222,5 +222,6 @@
"FAQ_HIDE_ALL": "Fragen ausblenden",
"SELF_SHOW_SETUP": "Setup-Anleitung anzeigen",
"SELF_HIDE_SETUP": "Setup-Anleitung ausblenden",
- "HERO_TRUST": "Kostenlos · Open Source · Kein Account nötig"
+ "HERO_TRUST": "Kostenlos · Open Source · Kein Account nötig",
+ "COMP_MORE_GUIDES": "Ausführlicher Vergleich und weitere Alternativen"
}
diff --git a/website/locales/en.json b/website/locales/en.json
index 64676a0..4448c46 100644
--- a/website/locales/en.json
+++ b/website/locales/en.json
@@ -222,5 +222,6 @@
"FAQ_HIDE_ALL": "Hide questions",
"SELF_SHOW_SETUP": "Show setup guide",
"SELF_HIDE_SETUP": "Hide setup guide",
- "HERO_TRUST": "Free · Open source · No account needed"
+ "HERO_TRUST": "Free · Open source · No account needed",
+ "COMP_MORE_GUIDES": "Full comparison and more alternatives"
}
diff --git a/website/locales/es.json b/website/locales/es.json
index 11f63be..3032692 100644
--- a/website/locales/es.json
+++ b/website/locales/es.json
@@ -222,5 +222,6 @@
"FAQ_HIDE_ALL": "Ocultar preguntas",
"SELF_SHOW_SETUP": "Mostrar guía de instalación",
"SELF_HIDE_SETUP": "Ocultar guía de instalación",
- "HERO_TRUST": "Gratis · Código abierto · Sin cuenta"
+ "HERO_TRUST": "Gratis · Código abierto · Sin cuenta",
+ "COMP_MORE_GUIDES": "Comparativa completa y más alternativas"
}
diff --git a/website/locales/fr.json b/website/locales/fr.json
index 9409150..4e4ae2c 100644
--- a/website/locales/fr.json
+++ b/website/locales/fr.json
@@ -222,5 +222,6 @@
"FAQ_HIDE_ALL": "Masquer les questions",
"SELF_SHOW_SETUP": "Afficher le guide d'installation",
"SELF_HIDE_SETUP": "Masquer le guide d'installation",
- "HERO_TRUST": "Gratuit · Open source · Sans compte"
+ "HERO_TRUST": "Gratuit · Open source · Sans compte",
+ "COMP_MORE_GUIDES": "Comparatif complet et autres alternatives"
}
diff --git a/website/locales/it.json b/website/locales/it.json
index 9d5f63d..e57f40a 100644
--- a/website/locales/it.json
+++ b/website/locales/it.json
@@ -222,5 +222,6 @@
"FAQ_HIDE_ALL": "Nascondi le domande",
"SELF_SHOW_SETUP": "Mostra la guida all'installazione",
"SELF_HIDE_SETUP": "Nascondi la guida",
- "HERO_TRUST": "Gratuito · Open source · Senza account"
+ "HERO_TRUST": "Gratuito · Open source · Senza account",
+ "COMP_MORE_GUIDES": "Confronto completo e altre alternative"
}
diff --git a/website/locales/ja.json b/website/locales/ja.json
index eabab32..228483c 100644
--- a/website/locales/ja.json
+++ b/website/locales/ja.json
@@ -222,5 +222,6 @@
"FAQ_HIDE_ALL": "質問を隠す",
"SELF_SHOW_SETUP": "セットアップガイドを表示",
"SELF_HIDE_SETUP": "ガイドを隠す",
- "HERO_TRUST": "無料 · オープンソース · アカウント不要"
+ "HERO_TRUST": "無料 · オープンソース · アカウント不要",
+ "COMP_MORE_GUIDES": "詳しい比較とその他の選択肢"
}
diff --git a/website/locales/ko.json b/website/locales/ko.json
index 1383210..3765a6b 100644
--- a/website/locales/ko.json
+++ b/website/locales/ko.json
@@ -222,5 +222,6 @@
"FAQ_HIDE_ALL": "질문 숨기기",
"SELF_SHOW_SETUP": "설치 가이드 보기",
"SELF_HIDE_SETUP": "가이드 숨기기",
- "HERO_TRUST": "무료 · 오픈소스 · 계정 불필요"
+ "HERO_TRUST": "무료 · 오픈소스 · 계정 불필요",
+ "COMP_MORE_GUIDES": "전체 비교 및 다른 대안 보기"
}
diff --git a/website/locales/nl.json b/website/locales/nl.json
index 7581b34..026846c 100644
--- a/website/locales/nl.json
+++ b/website/locales/nl.json
@@ -222,5 +222,6 @@
"FAQ_HIDE_ALL": "Vragen verbergen",
"SELF_SHOW_SETUP": "Installatiehandleiding tonen",
"SELF_HIDE_SETUP": "Handleiding verbergen",
- "HERO_TRUST": "Gratis · Open source · Geen account nodig"
+ "HERO_TRUST": "Gratis · Open source · Geen account nodig",
+ "COMP_MORE_GUIDES": "Volledige vergelijking en meer alternatieven"
}
diff --git a/website/locales/pl.json b/website/locales/pl.json
index c5c6ab6..082fc6a 100644
--- a/website/locales/pl.json
+++ b/website/locales/pl.json
@@ -222,5 +222,6 @@
"FAQ_HIDE_ALL": "Ukryj pytania",
"SELF_SHOW_SETUP": "Pokaż instrukcję instalacji",
"SELF_HIDE_SETUP": "Ukryj instrukcję",
- "HERO_TRUST": "Za darmo · Open source · Bez konta"
+ "HERO_TRUST": "Za darmo · Open source · Bez konta",
+ "COMP_MORE_GUIDES": "Pełne porównanie i więcej alternatyw"
}
diff --git a/website/locales/pt-BR.json b/website/locales/pt-BR.json
index 0c98e7b..3a89210 100644
--- a/website/locales/pt-BR.json
+++ b/website/locales/pt-BR.json
@@ -222,5 +222,6 @@
"FAQ_HIDE_ALL": "Ocultar perguntas",
"SELF_SHOW_SETUP": "Mostrar guia de configuração",
"SELF_HIDE_SETUP": "Ocultar guia",
- "HERO_TRUST": "Grátis · Código aberto · Sem conta"
+ "HERO_TRUST": "Grátis · Código aberto · Sem conta",
+ "COMP_MORE_GUIDES": "Comparação completa e mais alternativas"
}
diff --git a/website/locales/pt.json b/website/locales/pt.json
index 33a75c4..52c3cf6 100644
--- a/website/locales/pt.json
+++ b/website/locales/pt.json
@@ -222,5 +222,6 @@
"FAQ_HIDE_ALL": "Ocultar perguntas",
"SELF_SHOW_SETUP": "Mostrar guia de configuração",
"SELF_HIDE_SETUP": "Ocultar guia",
- "HERO_TRUST": "Grátis · Open source · Sem conta"
+ "HERO_TRUST": "Grátis · Open source · Sem conta",
+ "COMP_MORE_GUIDES": "Comparação completa e mais alternativas"
}
diff --git a/website/locales/ru.json b/website/locales/ru.json
index fb37d7c..d2c72f0 100644
--- a/website/locales/ru.json
+++ b/website/locales/ru.json
@@ -222,5 +222,6 @@
"FAQ_HIDE_ALL": "Скрыть вопросы",
"SELF_SHOW_SETUP": "Показать инструкцию по установке",
"SELF_HIDE_SETUP": "Скрыть инструкцию",
- "HERO_TRUST": "Бесплатно · Открытый код · Без аккаунта"
+ "HERO_TRUST": "Бесплатно · Открытый код · Без аккаунта",
+ "COMP_MORE_GUIDES": "Полное сравнение и другие альтернативы"
}
diff --git a/website/locales/tr.json b/website/locales/tr.json
index 2a3b6ea..fc11c06 100644
--- a/website/locales/tr.json
+++ b/website/locales/tr.json
@@ -222,5 +222,6 @@
"FAQ_HIDE_ALL": "Soruları gizle",
"SELF_SHOW_SETUP": "Kurulum rehberini göster",
"SELF_HIDE_SETUP": "Rehberi gizle",
- "HERO_TRUST": "Ücretsiz · Açık kaynak · Hesap gerekmez"
+ "HERO_TRUST": "Ücretsiz · Açık kaynak · Hesap gerekmez",
+ "COMP_MORE_GUIDES": "Tam karşılaştırma ve diğer alternatifler"
}
diff --git a/website/locales/uk.json b/website/locales/uk.json
index 46d9d39..9fcf09c 100644
--- a/website/locales/uk.json
+++ b/website/locales/uk.json
@@ -222,5 +222,6 @@
"FAQ_HIDE_ALL": "Приховати запитання",
"SELF_SHOW_SETUP": "Показати інструкцію з налаштування",
"SELF_HIDE_SETUP": "Приховати інструкцію",
- "HERO_TRUST": "Безкоштовно · Відкритий код · Без акаунта"
+ "HERO_TRUST": "Безкоштовно · Відкритий код · Без акаунта",
+ "COMP_MORE_GUIDES": "Повне порівняння та інші альтернативи"
}
diff --git a/website/locales/zh.json b/website/locales/zh.json
index 0e5d08a..7c77aea 100644
--- a/website/locales/zh.json
+++ b/website/locales/zh.json
@@ -222,5 +222,6 @@
"FAQ_HIDE_ALL": "收起问题",
"SELF_SHOW_SETUP": "显示部署指南",
"SELF_HIDE_SETUP": "收起指南",
- "HERO_TRUST": "免费 · 开源 · 无需账号"
+ "HERO_TRUST": "免费 · 开源 · 无需账号",
+ "COMP_MORE_GUIDES": "完整对比与更多替代方案"
}
diff --git a/website/style.css b/website/style.css
index 8d7f43e..3948652 100644
--- a/website/style.css
+++ b/website/style.css
@@ -653,6 +653,21 @@ html.theme-light .koala-speech-bubble::after {
transform: translateY(-2px);
}
+/* Install buttons: compact by default (just the browser name) so all three
+ CTAs fit one line; the detected browser expands to the full call to action.
+ The GitHub button stays compact always. */
+.btn-label-full { display: none; }
+
+.btn-install:not(.is-detected),
+.btn-compact {
+ padding: 0.62rem 1.05rem;
+ font-size: 0.9rem;
+ gap: 0.4rem;
+}
+
+.btn-install.is-detected .btn-label-short { display: none; }
+.btn-install.is-detected .btn-label-full { display: inline; }
+
.version-badge {
display: inline-block;
background: rgba(99, 102, 241, 0.1);
@@ -3078,6 +3093,28 @@ html:not(.lang-de) [lang="de"] {
transition: opacity 0.2s ease;
}
+/* Link from the comparison table to the fuller guides/alternatives hub */
+.comparison-guides-link {
+ text-align: center;
+ margin: 2rem 0 0;
+}
+
+.comparison-guides-link a {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.45rem;
+ color: var(--accent);
+ text-decoration: none;
+ font-weight: 600;
+ font-size: 0.95rem;
+ transition: gap 0.2s ease, opacity 0.2s ease;
+}
+
+.comparison-guides-link a:hover {
+ gap: 0.7rem;
+ opacity: 0.85;
+}
+
.table-footnotes:hover {
opacity: 0.95;
}
@@ -3504,14 +3541,14 @@ header[id] {
container-type: inline-size;
}
-/* Fixed scene height: stays below the left hero column's height so it never
- drives the grid row, and never changes when the popup toggles (no vertical
- jumping). The popup is bottom-anchored and simply grows upwards on open. */
+/* Fixed height that already fits the open popup, so toggling it never changes
+ layout (the vertically centered hero never jumps). The caption is absolutely
+ positioned right under the cards instead of after the tall scene, and the
+ empty lower area is the invisible room the popup drops into. */
.hero-demo-scene {
position: relative;
width: 100%;
- height: 500px;
- height: max(calc(66cqw + 78px), 500px);
+ height: max(calc(59cqw + 100px), 548px);
}
/* While initializing, suppress all transitions so the popup can start closed
@@ -3755,11 +3792,23 @@ header[id] {
transition: opacity 0.3s;
}
-.hero-demo-scene:not(.popup-open) .demo-ext-launcher::after {
+.hero-demo-scene:not(.popup-open) .demo-ext-launcher:not(.demo-ext-static)::after {
opacity: 1;
animation: demoBlink 1.4s ease-in-out infinite;
}
+/* Card B shows the same extension icon, purely to signal the friend has it
+ installed too. It is not interactive and does not blink or glow. */
+.demo-ext-static,
+.demo-ext-static:hover {
+ cursor: default;
+ border-color: rgba(255, 255, 255, 0.12);
+ transform: none;
+ box-shadow: none;
+}
+
+.demo-ext-static::after { display: none; }
+
/* Abstract "video" artwork with a slow cinematic pan/zoom while playing */
.demo-video {
position: relative;
@@ -4023,7 +4072,14 @@ header[id] {
}
/* Caption below the scene */
+/* Caption sits absolutely right below the card cascade (matching the cards'
+ bottom edge, which scales with the container width), so the tall scene that
+ reserves popup room does not push it far away. */
.demo-hint {
+ position: absolute;
+ left: 0;
+ right: 0;
+ top: calc(59cqw + 82px);
margin: 0;
text-align: center;
font-size: 0.82rem;
diff --git a/website/template.html b/website/template.html
index 5f834d8..a0af959 100644
--- a/website/template.html
+++ b/website/template.html
@@ -300,17 +300,19 @@
{{HERO_TRUST}}
@@ -387,6 +389,9 @@
Stranger Things - S4E1
🐶 HappyDog
+
+
+
@@ -730,8 +735,8 @@
+
{{DEMO_HINT}}
- {{DEMO_HINT}}
@@ -964,11 +969,17 @@
teleparty.com/privacy
+
+
+ {{COMP_MORE_GUIDES}}
+
+
+