Fix: Dark-Mode Karte + Badge-Farben + --c-bg-secondary

Karte:
- Dark-Mode: CartoDB Dark Matter Tiles statt OSM Standard
- MutationObserver + matchMedia watchee für Live-Theme-Wechsel
- _buildTileLayer() / _applyTileTheme() / _isDarkMode()

Badges litters.js:
- Hardgekodete dunkle Hintergründe → CSS-Klassen (badge-warning/-success/-muted)
- Funktioniert jetzt in Light + Dark Mode korrekt

movies.css:
- .movie-tag-stirbt/.movie-tag-ueberlebt → CSS-Variablen (danger-/success-subtle)
- Kein weißer Hintergrund mehr in Dark Mode

--c-bg-secondary: Zoom-Control 30px bleiben aus dem letzten Commit
SW by-v1022, APP_VER 1022
This commit is contained in:
rene 2026-05-16 11:11:09 +02:00
parent 161c1e3f73
commit 721e630a34
6 changed files with 63 additions and 24 deletions

View file

@ -410,7 +410,7 @@ async def serve_media(path: str, request: _Request):
raise _HE(404, "Nicht gefunden.") raise _HE(404, "Nicht gefunden.")
return _media_response(filepath) return _media_response(filepath)
APP_VER = "1021" # muss mit APP_VER in app.js übereinstimmen APP_VER = "1022" # muss mit APP_VER in app.js übereinstimmen
@app.get("/.well-known/assetlinks.json") @app.get("/.well-known/assetlinks.json")
async def assetlinks(): async def assetlinks():

View file

@ -5160,9 +5160,9 @@ html.modal-open {
/* "Stirbt der Hund?" Tags */ /* "Stirbt der Hund?" Tags */
.movie-tag-stirbt { .movie-tag-stirbt {
background: #fef2f2; background: var(--c-danger-subtle);
color: #dc2626; color: var(--c-danger);
border: 1.5px solid #dc2626; border: 1.5px solid var(--c-danger-border);
border-radius: var(--radius-md); border-radius: var(--radius-md);
padding: var(--space-2) var(--space-3); padding: var(--space-2) var(--space-3);
font-size: var(--text-xs); font-size: var(--text-xs);
@ -5172,9 +5172,9 @@ html.modal-open {
} }
.movie-tag-ueberlebt { .movie-tag-ueberlebt {
background: #f0fdf4; background: var(--c-success-subtle);
color: #16a34a; color: var(--c-success);
border: 1.5px solid #16a34a; border: 1.5px solid color-mix(in srgb, var(--c-success) 30%, transparent);
border-radius: var(--radius-md); border-radius: var(--radius-md);
padding: var(--space-2) var(--space-3); padding: var(--space-2) var(--space-3);
font-size: var(--text-xs); font-size: var(--text-xs);

View file

@ -3,7 +3,7 @@
Router, State-Management, Navigation, Initialisierung. Router, State-Management, Navigation, Initialisierung.
============================================================ */ ============================================================ */
const APP_VER = '1021'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen const APP_VER = '1022'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
const APP_VERSION = '1.6.0'; // ← semantische Version, wird bei make release gesetzt const APP_VERSION = '1.6.0'; // ← semantische Version, wird bei make release gesetzt
const IS_STAGING = location.hostname === 'staging.banyaro.app'; const IS_STAGING = location.hostname === 'staging.banyaro.app';
// Cache-Bust-Parameter nach Update-Reload sofort entfernen // Cache-Bust-Parameter nach Update-Reload sofort entfernen

View file

@ -31,13 +31,13 @@ window.Page_litters = (() => {
function _statusBadge(status) { function _statusBadge(status) {
const map = { const map = {
geplant: { label: 'Geplant', color: '#6B7280' }, geplant: { label: 'Geplant', cls: 'badge-warning' },
geboren: { label: 'Geboren', color: '#3B82F6' }, geboren: { label: 'Geboren', cls: 'badge-primary' },
verfuegbar: { label: 'Verfügbar', color: '#22C55E' }, verfuegbar: { label: 'Verfügbar', cls: 'badge-success' },
abgeschlossen: { label: 'Abgeschlossen', color: '#374151' }, abgeschlossen: { label: 'Abgeschlossen', cls: 'badge-muted' },
}; };
const s = map[status] || { label: status, color: '#6B7280' }; const s = map[status] || { label: status, cls: 'badge-muted' };
return `<span class="litters-badge" style="background:${s.color}">${_esc(s.label)}</span>`; return `<span class="badge ${s.cls}">${_esc(s.label)}</span>`;
} }
function _fmtDate(iso) { function _fmtDate(iso) {
@ -54,12 +54,12 @@ window.Page_litters = (() => {
function _puppyStatusBadge(status) { function _puppyStatusBadge(status) {
const map = { const map = {
verfuegbar: { label: 'Verfügbar', color: '#22C55E' }, verfuegbar: { label: 'Verfügbar', cls: 'badge-success' },
reserviert: { label: 'Reserviert', color: '#F59E0B' }, reserviert: { label: 'Reserviert', cls: 'badge-warning' },
abgegeben: { label: 'Abgegeben', color: '#6B7280' }, abgegeben: { label: 'Abgegeben', cls: 'badge-muted' },
}; };
const s = map[status] || { label: status, color: '#9CA3AF' }; const s = map[status] || { label: status, cls: 'badge-muted' };
return `<span class="litters-badge litters-badge--sm" style="background:${s.color}">${_esc(s.label)}</span>`; return `<span class="badge badge-sm ${s.cls}">${_esc(s.label)}</span>`;
} }
// ---------------------------------------------------------- // ----------------------------------------------------------

View file

@ -11,9 +11,11 @@ window.Page_map = (() => {
let _map = null; let _map = null;
let _leafletLoaded = false; let _leafletLoaded = false;
let _userPos = null; let _userPos = null;
let _weatherLoaded = false; let _weatherLoaded = false;
let _placingMarker = false; let _placingMarker = false;
let _tempMarker = null; let _tempMarker = null;
let _tileLayer = null;
let _themeObserver = null;
// Standort-Tracking // Standort-Tracking
let _locationMarker = null; let _locationMarker = null;
@ -528,7 +530,13 @@ window.Page_map = (() => {
if (!_userPos) { if (!_userPos) {
_frankfurtTimer = setTimeout(() => _map.flyTo(center, 14, { duration: 2.5 }), 1200); _frankfurtTimer = setTimeout(() => _map.flyTo(center, 14, { duration: 2.5 }), 1200);
} }
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 19 }).addTo(_map); _tileLayer = _buildTileLayer();
_tileLayer.addTo(_map);
// Theme-Wechsel → Tile-Layer tauschen
_themeObserver = new MutationObserver(() => _applyTileTheme());
_themeObserver.observe(document.documentElement, { attributes: true, attributeFilter: ['data-theme'] });
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', _applyTileTheme);
setTimeout(() => _map.invalidateSize(), 100); setTimeout(() => _map.invalidateSize(), 100);
setTimeout(() => _map.invalidateSize(), 600); setTimeout(() => _map.invalidateSize(), 600);
@ -614,6 +622,37 @@ window.Page_map = (() => {
return _clusterGroups[layerKey]; return _clusterGroups[layerKey];
} }
function _isDarkMode() {
const t = document.documentElement.getAttribute('data-theme');
if (t === 'dark') return true;
if (t === 'light') return false;
return window.matchMedia('(prefers-color-scheme: dark)').matches;
}
function _buildTileLayer() {
if (_isDarkMode()) {
return L.tileLayer(
'https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png',
{ maxZoom: 19, subdomains: 'abcd' }
);
}
return L.tileLayer(
'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
{ maxZoom: 19 }
);
}
function _applyTileTheme() {
if (!_map || !window.L) return;
const dark = _isDarkMode();
const url = dark
? 'https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png'
: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
if (_tileLayer) {
_tileLayer.setUrl(url);
}
}
function _updateZoomDisplay() { function _updateZoomDisplay() {
if (!_map) return; if (!_map) return;
const z = Math.round(_map.getZoom()); const z = Math.round(_map.getZoom());

View file

@ -3,7 +3,7 @@
Offline-Cache + Push Notifications + Tile-Cache Offline-Cache + Push Notifications + Tile-Cache
============================================================ */ ============================================================ */
const CACHE_VERSION = 'by-v1021'; const CACHE_VERSION = 'by-v1022';
const CACHE_STATIC = `${CACHE_VERSION}-static`; const CACHE_STATIC = `${CACHE_VERSION}-static`;
const CACHE_TILES = 'ban-yaro-tiles-v1'; // bleibt über SW-Updates erhalten const CACHE_TILES = 'ban-yaro-tiles-v1'; // bleibt über SW-Updates erhalten
const CACHE_API = 'ban-yaro-api-v1'; // API-Response-Cache const CACHE_API = 'ban-yaro-api-v1'; // API-Response-Cache