diff --git a/frontend/src/App.vue b/frontend/src/App.vue
index 6c5b9ae..60774fa 100644
--- a/frontend/src/App.vue
+++ b/frontend/src/App.vue
@@ -225,6 +225,32 @@ const tabs = computed(() => [
const rad = ref(null)
+// Bei 2500 Karten kommt man sonst nicht mehr nach oben
+const obenKnopf = ref(false)
+
+function beimScrollen() {
+ obenKnopf.value = window.scrollY > 800
+}
+
+// Eigene Animation statt behavior: 'smooth'. Das rechnet mit fester
+// Geschwindigkeit und bräuchte über 300.000 Pixel Seitenhöhe Minuten.
+const OBEN_DAUER = 450
+
+function nachOben() {
+ const start = window.scrollY
+ const beginn = performance.now()
+
+ function schritt(jetzt) {
+ const t = Math.min(1, (jetzt - beginn) / OBEN_DAUER)
+ // Sanft an- und auslaufend
+ const p = t < 0.5 ? 2 * t * t : 1 - (-2 * t + 2) ** 2 / 2
+ window.scrollTo(0, start * (1 - p))
+ if (t < 1) requestAnimationFrame(schritt)
+ }
+
+ requestAnimationFrame(schritt)
+}
+
// Die movie_ids der geschauten Filme — die Detailansicht zeigt damit an,
// ob der Film schon lief
const gesehen = ref([])
@@ -476,10 +502,12 @@ onMounted(() => {
else if (nachricht.type === 'features') ladeWuensche()
})
window.addEventListener('keydown', tastatur)
+ window.addEventListener('scroll', beimScrollen, { passive: true })
})
onUnmounted(() => {
window.removeEventListener('keydown', tastatur)
+ window.removeEventListener('scroll', beimScrollen)
abbestellen?.()
})
@@ -594,6 +622,10 @@ onUnmounted(() => {
/>
+
+
{
}
.tabs {
+ position: sticky;
+ top: 0;
+ z-index: 10;
display: flex;
gap: 0.35rem;
- margin-bottom: 1.25rem;
+ /* Der negative Rand deckt das Polster der Seite ab, sonst scrollen
+ Karten oberhalb der Leiste durchs Bild */
+ margin: -1.5rem -1.25rem 1.25rem;
+ padding: 0.7rem 1.25rem 0;
+ background: var(--bg);
border-bottom: 1px solid var(--line);
}
+.nach-oben {
+ position: fixed;
+ right: calc(var(--sidebar) + 1.25rem);
+ bottom: 1.5rem;
+ z-index: 15;
+ width: 3rem;
+ height: 3rem;
+ color: #fff;
+ font-size: 1.35rem;
+ line-height: 1;
+ background: var(--accent);
+ border: 0;
+ border-radius: 50%;
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.6);
+}
+
+.nach-oben:hover {
+ filter: brightness(1.15);
+}
+
.tabs button {
display: flex;
align-items: center;