diff --git a/VERSION b/VERSION
index 364aacb..1f5e025 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1292
\ No newline at end of file
+1295
\ No newline at end of file
diff --git a/backend/database.py b/backend/database.py
index 4f3ce10..a26bd07 100644
--- a/backend/database.py
+++ b/backend/database.py
@@ -605,6 +605,7 @@ def _migrate(conn_factory):
("notes", "location_name", "TEXT"),
("notes", "parent_label", "TEXT"),
("users", "notes_ki_enabled", "INTEGER NOT NULL DEFAULT 1"),
+ ("users", "anthem_heard", "INTEGER NOT NULL DEFAULT 0"),
# Züchter-Rolle
("users", "breeder_status", "TEXT"),
# Würfe: Verknüpfung mit Zuchtkartei-Hunden + Welfare
diff --git a/backend/routes/auth.py b/backend/routes/auth.py
index 403eae8..771f735 100644
--- a/backend/routes/auth.py
+++ b/backend/routes/auth.py
@@ -398,7 +398,7 @@ async def me(user=Depends(get_current_user)):
bio, wohnort, erfahrung, social_link,
profil_sichtbarkeit, avatar_url, created_at,
is_founder, is_partner, founder_number, is_founder_pending,
- notes_ki_enabled, gassi_stunde_push,
+ notes_ki_enabled, gassi_stunde_push, anthem_heard,
preferred_theme, subscription_tier,
subscription_expires_at, subscription_cancelled_at, needs_dog_selection,
billing_address, geburtstag
diff --git a/backend/routes/profile.py b/backend/routes/profile.py
index bf16ce0..17cc159 100644
--- a/backend/routes/profile.py
+++ b/backend/routes/profile.py
@@ -50,6 +50,16 @@ def _load_user(user_id: int) -> dict:
return data
+@router.post("/anthem-heard", status_code=204)
+async def mark_anthem_heard(user=Depends(get_current_user)):
+ """Merkt server-seitig, dass die Hymne gehört wurde — geräteübergreifend und
+ übersteht Cache-Clear bzw. die iOS-Trennung von PWA- und Safari-localStorage,
+ damit der Banner nach einem Deploy nicht erneut auftaucht."""
+ with db() as conn:
+ conn.execute("UPDATE users SET anthem_heard=1 WHERE id=?", (user["id"],))
+ return None
+
+
@router.patch("")
async def update_profile(data: ProfileUpdate, user=Depends(get_current_user)):
fields = data.model_dump(exclude_none=True)
diff --git a/backend/static/css/components.css b/backend/static/css/components.css
index a96b2ab..cad9fcd 100644
--- a/backend/static/css/components.css
+++ b/backend/static/css/components.css
@@ -8267,6 +8267,29 @@ svg.empty-state-icon {
}
#worlds-fab:active { transform: scale(0.92); box-shadow: 0 2px 10px rgba(196,132,58,0.3); }
+/* Hymne-Button — Gegenspieler zum FAB, unten links, nur WELT + nach erstem Hören */
+#worlds-anthem {
+ position: fixed;
+ bottom: calc(env(safe-area-inset-bottom, 16px) + 16px);
+ left: 20px;
+ width: 54px; height: 54px;
+ border-radius: 50%;
+ background: rgba(22,26,30,0.66);
+ -webkit-backdrop-filter: blur(8px);
+ backdrop-filter: blur(8px);
+ color: #fff;
+ border: 1px solid rgba(255,255,255,0.20);
+ cursor: pointer;
+ z-index: 60;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ box-shadow: 0 4px 18px rgba(0,0,0,0.40);
+ transition: transform 0.12s, background 0.2s;
+}
+#worlds-anthem:active { transform: scale(0.92); }
+#worlds-anthem.playing { background: var(--c-primary); border-color: transparent; }
+
/* Header + Bottom-Nav: vollständig entfernt — Welten übernehmen Navigation */
#app-header { display: none !important; }
#bottom-nav { display: none !important; }
diff --git a/backend/static/index.html b/backend/static/index.html
index 830ff54..58232ad 100644
--- a/backend/static/index.html
+++ b/backend/static/index.html
@@ -86,14 +86,14 @@
Ban Yaro
-
+
-
-
-
-
-
+
+
+
+
+
@@ -596,6 +596,10 @@
+
+