diff --git a/public/index.html b/public/index.html index a5a1441..e4a50ca 100644 --- a/public/index.html +++ b/public/index.html @@ -38,8 +38,6 @@ - - @@ -62,6 +60,22 @@ Zum Hauptinhalt springen + + +
diff --git a/public/locales/ar.json b/public/locales/ar.json index e965958..35e3ed1 100644 --- a/public/locales/ar.json +++ b/public/locales/ar.json @@ -868,5 +868,8 @@ "next": "Next", "done": "Get started", "skip": "Skip" + }, + "offline": { + "banner": "Offline – reconnecting…" } -} +} \ No newline at end of file diff --git a/public/locales/de.json b/public/locales/de.json index c7ab779..9f07956 100644 --- a/public/locales/de.json +++ b/public/locales/de.json @@ -888,5 +888,8 @@ "next": "Weiter", "done": "Loslegen", "skip": "Überspringen" + }, + "offline": { + "banner": "Offline – Verbindung wird wiederhergestellt…" } } diff --git a/public/locales/el.json b/public/locales/el.json index 320751b..f61fb32 100644 --- a/public/locales/el.json +++ b/public/locales/el.json @@ -868,5 +868,8 @@ "next": "Next", "done": "Get started", "skip": "Skip" + }, + "offline": { + "banner": "Offline – reconnecting…" } -} +} \ No newline at end of file diff --git a/public/locales/en.json b/public/locales/en.json index d258257..58e04be 100644 --- a/public/locales/en.json +++ b/public/locales/en.json @@ -869,5 +869,8 @@ "next": "Next", "done": "Get started", "skip": "Skip" + }, + "offline": { + "banner": "Offline – reconnecting…" } -} +} \ No newline at end of file diff --git a/public/locales/es.json b/public/locales/es.json index 550dead..c5adbf3 100644 --- a/public/locales/es.json +++ b/public/locales/es.json @@ -868,5 +868,8 @@ "next": "Next", "done": "Get started", "skip": "Skip" + }, + "offline": { + "banner": "Offline – reconnecting…" } -} +} \ No newline at end of file diff --git a/public/locales/fr.json b/public/locales/fr.json index eda86aa..52f6f5d 100644 --- a/public/locales/fr.json +++ b/public/locales/fr.json @@ -868,5 +868,8 @@ "next": "Next", "done": "Get started", "skip": "Skip" + }, + "offline": { + "banner": "Offline – reconnecting…" } -} +} \ No newline at end of file diff --git a/public/locales/hi.json b/public/locales/hi.json index 9581739..3652c2d 100644 --- a/public/locales/hi.json +++ b/public/locales/hi.json @@ -868,5 +868,8 @@ "next": "Next", "done": "Get started", "skip": "Skip" + }, + "offline": { + "banner": "Offline – reconnecting…" } -} +} \ No newline at end of file diff --git a/public/locales/it.json b/public/locales/it.json index 045e49e..e823a10 100644 --- a/public/locales/it.json +++ b/public/locales/it.json @@ -868,5 +868,8 @@ "next": "Next", "done": "Get started", "skip": "Skip" + }, + "offline": { + "banner": "Offline – reconnecting…" } -} +} \ No newline at end of file diff --git a/public/locales/ja.json b/public/locales/ja.json index 64aabbe..99532e5 100644 --- a/public/locales/ja.json +++ b/public/locales/ja.json @@ -868,5 +868,8 @@ "next": "Next", "done": "Get started", "skip": "Skip" + }, + "offline": { + "banner": "Offline – reconnecting…" } -} +} \ No newline at end of file diff --git a/public/locales/pt.json b/public/locales/pt.json index f41b9d7..63f71a7 100644 --- a/public/locales/pt.json +++ b/public/locales/pt.json @@ -869,5 +869,8 @@ "next": "Next", "done": "Get started", "skip": "Skip" + }, + "offline": { + "banner": "Offline – reconnecting…" } -} +} \ No newline at end of file diff --git a/public/locales/ru.json b/public/locales/ru.json index bba83d1..354d8d4 100644 --- a/public/locales/ru.json +++ b/public/locales/ru.json @@ -868,5 +868,8 @@ "next": "Next", "done": "Get started", "skip": "Skip" + }, + "offline": { + "banner": "Offline – reconnecting…" } -} +} \ No newline at end of file diff --git a/public/locales/sv.json b/public/locales/sv.json index 6c351c9..b3871f1 100644 --- a/public/locales/sv.json +++ b/public/locales/sv.json @@ -868,5 +868,8 @@ "next": "Next", "done": "Get started", "skip": "Skip" + }, + "offline": { + "banner": "Offline – reconnecting…" } -} +} \ No newline at end of file diff --git a/public/locales/tr.json b/public/locales/tr.json index 7b817f2..b6d8720 100644 --- a/public/locales/tr.json +++ b/public/locales/tr.json @@ -868,5 +868,8 @@ "next": "Next", "done": "Get started", "skip": "Skip" + }, + "offline": { + "banner": "Offline – reconnecting…" } -} +} \ No newline at end of file diff --git a/public/locales/uk.json b/public/locales/uk.json index 755fa6d..b7caa69 100644 --- a/public/locales/uk.json +++ b/public/locales/uk.json @@ -868,5 +868,8 @@ "next": "Next", "done": "Get started", "skip": "Skip" + }, + "offline": { + "banner": "Offline – reconnecting…" } -} +} \ No newline at end of file diff --git a/public/locales/zh.json b/public/locales/zh.json index 0daccb1..abfb61a 100644 --- a/public/locales/zh.json +++ b/public/locales/zh.json @@ -868,5 +868,8 @@ "next": "Next", "done": "Get started", "skip": "Skip" + }, + "offline": { + "banner": "Offline – reconnecting…" } -} +} \ No newline at end of file diff --git a/public/router.js b/public/router.js index d72dc6c..6934195 100644 --- a/public/router.js +++ b/public/router.js @@ -541,6 +541,20 @@ function renderAppShell(container) { initMoreSheet(container); initNavHideOnScroll(container); initSearch(container); + initOfflineBanner(); +} + +function initOfflineBanner() { + const banner = document.getElementById('offline-banner'); + if (!banner) return; + const i18nSpan = banner.querySelector('[data-i18n]'); + function update() { + banner.hidden = navigator.onLine; + if (i18nSpan) i18nSpan.textContent = t('offline.banner'); + } + window.addEventListener('online', update); + window.addEventListener('offline', update); + update(); } /** diff --git a/public/styles/layout.css b/public/styles/layout.css index 3f94ef8..9a5c4ea 100755 --- a/public/styles/layout.css +++ b/public/styles/layout.css @@ -1897,6 +1897,40 @@ } } +/* -------------------------------------------------------- + * Offline-Banner + * -------------------------------------------------------- */ +.offline-banner { + position: fixed; + top: 0; + left: 0; + right: 0; + z-index: calc(var(--z-toast) + 1); + display: flex; + align-items: center; + gap: var(--space-2); + padding: var(--space-2) var(--space-4); + background-color: var(--color-warning-light); + color: var(--color-warning); + font-size: var(--text-sm); + font-weight: var(--font-weight-medium); + border-bottom: 1px solid color-mix(in srgb, var(--color-warning) 20%, transparent); + animation: offline-banner-in 0.2s var(--ease-out); +} + +.offline-banner[hidden] { + display: none; +} + +@keyframes offline-banner-in { + from { opacity: 0; transform: translateY(-100%); } + to { opacity: 1; transform: translateY(0); } +} + +@media (prefers-reduced-motion: reduce) { + .offline-banner { animation: none; } +} + /* -------------------------------------------------------- * Print-Styles * -------------------------------------------------------- */