diff --git a/VERSION b/VERSION
index 08e9158..64e9c64 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1217
\ No newline at end of file
+1219
\ No newline at end of file
diff --git a/backend/static/css/components.css b/backend/static/css/components.css
index 77b70ec..87dea9c 100644
--- a/backend/static/css/components.css
+++ b/backend/static/css/components.css
@@ -3053,17 +3053,18 @@ html.modal-open {
.map-legend::-webkit-scrollbar { display: none; }
/* Regenradar-Zeitleiste (RainViewer: ~2h Vergangenheit + ~30min Nowcast, Play/Pause + Slider) */
-/* Optik wie die Status-Pill darunter (hell/cremefarben, Blur, Border), direkt darüber gesetzt. */
+/* Optik + Maße wie die Status-Pill darunter: gleiche linke Kante (var(--space-3)); die Breite wird
+ per JS an die Pill angeglichen (gleiche rechte Kante). Höhe wie die Pill. */
.map-radar-timeline {
position: absolute;
left: var(--space-3);
- right: 88px; /* Platz für die Ecken-FABs (Speed-Dial / Zurück) rechts */
- bottom: calc(var(--space-3) + 40px); /* unmittelbar über der Status-Pill */
+ width: min(320px, calc(100% - 100px)); /* Fallback; JS setzt = Pill-Breite */
+ bottom: calc(var(--space-3) + 34px); /* unmittelbar über der Status-Pill */
z-index: 900;
display: flex;
align-items:center;
- gap: 8px;
- padding: 4px 12px 4px 5px;
+ gap: 7px;
+ padding: 3px 12px 3px 4px;
border-radius: var(--radius-full);
background: rgba(255, 255, 255, 0.88);
backdrop-filter: blur(4px);
@@ -3071,6 +3072,7 @@ html.modal-open {
border: 1px solid var(--c-border-light);
color: var(--c-text);
pointer-events: auto;
+ box-sizing: border-box;
}
:root[data-theme="dark"] .map-radar-timeline {
background: rgba(24, 20, 16, 0.92);
@@ -3078,19 +3080,20 @@ html.modal-open {
}
.rdr-play {
flex-shrink: 0;
- width: 30px; height: 30px;
+ width: 24px; height: 24px;
border: none; border-radius: 50%;
background: var(--c-surface-2);
color: var(--c-text); cursor: pointer;
display: flex; align-items: center; justify-content: center;
}
+.rdr-play svg { width: 14px; height: 14px; }
.rdr-play:active { background: var(--c-border); }
.rdr-slider { flex: 1; min-width: 0; height: 4px; accent-color: var(--c-primary); cursor: pointer; }
.rdr-time {
flex-shrink: 0;
font-size: 11px; font-weight: 600;
font-variant-numeric: tabular-nums;
- min-width: 78px; text-align: right; color: var(--c-text-secondary);
+ min-width: 74px; text-align: right; color: var(--c-text-secondary);
}
.rdr-time.is-forecast { color: var(--c-primary); } /* Nowcast/Vorhersage-Frames hervorgehoben */
diff --git a/backend/static/index.html b/backend/static/index.html
index 60bf077..1770205 100644
--- a/backend/static/index.html
+++ b/backend/static/index.html
@@ -86,14 +86,14 @@
Ban Yaro
-
+
-
-
-
-
-
+
+
+
+
+
@@ -617,11 +617,11 @@
-
-
-
-
-
+
+
+
+
+
@@ -631,7 +631,7 @@
-
+
diff --git a/backend/static/js/app.js b/backend/static/js/app.js
index 1433eb5..6d91f3c 100644
--- a/backend/static/js/app.js
+++ b/backend/static/js/app.js
@@ -3,7 +3,7 @@
Router, State-Management, Navigation, Initialisierung.
============================================================ */
-const APP_VER = '1217'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
+const APP_VER = '1219'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
const APP_VERSION = '1.6.0'; // ← semantische Version, wird bei make release gesetzt
window.APP_VER = APP_VER; // global verfügbar für andere Module (z.B. offline-indicator)
window.APP_VERSION = APP_VERSION;
diff --git a/backend/static/js/pages/map.js b/backend/static/js/pages/map.js
index 29bff06..568f5d3 100644
--- a/backend/static/js/pages/map.js
+++ b/backend/static/js/pages/map.js
@@ -621,12 +621,16 @@ window.Page_map = (() => {
document.getElementById('central-map')?.appendChild(el);
el.querySelector('#rdr-play').addEventListener('click', _toggleRadarPlay);
el.querySelector('#rdr-slider').addEventListener('input', e => {
+ const idx = parseInt(e.target.value, 10); // ZUERST lesen: _radarPause() setzt slider.value zurück
_radarPause();
- _showRadarFrame(parseInt(e.target.value, 10));
+ _showRadarFrame(idx);
});
} else {
el.querySelector('#rdr-slider').max = _radarFrames.length - 1;
}
+ // Breite an die Status-Pill angleichen → gleiche linke + rechte Kante.
+ const pill = document.querySelector('.map-statusbar');
+ if (pill && pill.offsetWidth > 60) el.style.width = pill.offsetWidth + 'px';
_updateRadarTimelineUI();
}
diff --git a/backend/static/landing.html b/backend/static/landing.html
index 0b01da6..9eef0c0 100644
--- a/backend/static/landing.html
+++ b/backend/static/landing.html
@@ -4,7 +4,7 @@
-
+
Ban Yaro — Die Hunde-App für Deutschland, Österreich & Schweiz
diff --git a/backend/static/sw.js b/backend/static/sw.js
index 1affc8c..b3e17b8 100644
--- a/backend/static/sw.js
+++ b/backend/static/sw.js
@@ -4,7 +4,7 @@
============================================================ */
// ← EINZIGE Stelle für die Version — STATIC_ASSETS und CACHE_VERSION leiten sich ab
-const VER = '1217';
+const VER = '1219';
const CACHE_VERSION = `by-v${VER}`;
const CACHE_STATIC = `${CACHE_VERSION}-static`;
const CACHE_TILES = 'ban-yaro-tiles-v1'; // bleibt über SW-Updates erhalten
diff --git a/docs/DWD_RAIN_FORECAST_PLAN.md b/docs/DWD_RAIN_FORECAST_PLAN.md
new file mode 100644
index 0000000..4c84e5d
--- /dev/null
+++ b/docs/DWD_RAIN_FORECAST_PLAN.md
@@ -0,0 +1,56 @@
+# DWD Regen-Vorhersage (Radar-Nowcast) — Scoping-Plan
+
+**Status:** gescoppt + Datenformat verifiziert (2026-06-05). Umsetzung offen.
+**Ziel:** Verlässliche, längere Regen-**Vorhersage** als animiertes Karten-Overlay (bis +2 h) statt RainViewers
+unzuverlässigem 30-Min-Nowcast (der oft leer ist). Self-hosted wie die Basemap — passt zur Tile-Server-Philosophie.
+
+## Quelle: DWD RV (Composite RV) — kostenlos, kein API-Key
+- `https://opendata.dwd.de/weather/radar/composite/rv/DE1200_RV.tar.bz2`
+- **Alle 5 Min** publiziert. Jedes Archiv = ein Vorhersage-Lauf mit **25 Frames** `_000`…`_120`
+ (**0 bis +120 Min**, 5-Min-Schritte), je ~2,5 MB unkomprimiert (~1 MB als .tar.bz2).
+- **Format (verifiziert):** RADOLAN-Binär. 194-Byte-ASCII-Header bis `ETX (0x03)`, dann **1200×1100 uint16
+ little-endian** (= 2.640.000 Byte). Header-Felder: `PR E-02` (0,01 mm), `INT 5` (5-Min-Summe),
+ `GP1200x1100`, `VV` (Lead-Time). **Wert = `raw & 0x0FFF` × 0,01 mm/5min; `raw & 0x2000` = kein Daten.**
+ → Decode trivial, **kein wradlib nötig** (PoC: 1,32 Mio Zellen geparst, Regen korrekt erkannt).
+- **Gitter/Projektion:** DE1200 (1 km), polar-stereografisch, fest georeferenziert (Eckkoordinaten dokumentiert;
+ wradlib `get_radolan_grid` ODER GDAL mit dem bekannten RADOLAN-PROJ-String).
+- **Abdeckung:** Deutschland + Randbereiche (reicht etwas nach AT/CH/Nachbarn, aber DE-zentriert).
+ Voll-AT/CH bräuchte ACG/MeteoSwiss → out of scope.
+
+## Pipeline (Server-seitig, Cron alle 5 Min — analog zum OSM-POI-Job)
+1. **Fetch** neueste `DE1200_RV