Commit graph

71 Commits

Autor SHA1 Nachricht Datum
claude-dev
e745814230 fix: Scroll-Block bis 300ms nach Rendering (GridStack-Resizes abwarten)
overflow:hidden bleibt 300ms nach loadIncidentDetail aktiv, damit
die verzögerten GridStack resizeTileToContent-Operationen keinen
Scroll zum Faktencheck ausloesen koennen.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 10:56:20 +01:00
claude-dev
d983042503 fix: Scroll-Ruckeln beseitigt - overflow:hidden waehrend Rendering
Statt den Scroll nach unten mit Timeouts zurueckzukaempfen, wird
overflow:hidden auf main-content gesetzt bevor das Rendering startet.
Nach Abschluss wird scrollTop=0 gesetzt und overflow wiederhergestellt.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 10:54:45 +01:00
claude-dev
376f0d093b fix: Scroll-to-Top bei Lagewechsel verstaerkt (sofort + rAF + setTimeout)
Scroll-Reset erfolgt nun an 4 Zeitpunkten um sicherzustellen, dass
der Hauptbereich nach oben scrollt, auch wenn GridStack oder andere
asynchrone Rendering-Operationen den Scroll verschieben.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 10:38:05 +01:00
claude-dev
144787f1e7 fix: Modal nicht mehr per Backdrop-Klick schliessbar + Scroll-to-Top bei Lagewechsel
1. Modal (Anlegen/Bearbeiten) schliesst nur noch ueber den X-Button,
   nicht mehr durch Klick auf den dunklen Hintergrund
2. Beim Anklicken einer Lage in der Sidebar scrollt der Hauptbereich
   nach oben statt zum Faktencheck-Bereich

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 10:33:15 +01:00
claude-dev
32dbfe99ac fix: sources_json Fallback auf vorherige Quellen wenn Analyse leer
Gleicher Bug wie bei der Summary: Wenn die Claude-API-Analyse keine Quellen
zurueckgibt, wurde sources_json mit NULL ueberschrieben. Dadurch konnten die
Quellenverweise [1], [2] etc. im Dashboard nicht mehr als Links gerendert werden.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 07:42:37 +01:00
claude-dev
61ca1f54f9 fix: Keine Gedankenstriche (em/en-dash) in Lageberichten
Regel in alle 4 Analyse-Prompt-Templates eingefuegt: Claude soll keine
Gedankenstriche verwenden, sondern Kommas, Doppelpunkte oder neue Saetze.
Bestehende Dashes in DB (Summary + 76 Snapshots) bereinigt.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 07:37:03 +01:00
claude-dev
ad41b8f4ea fix: Leere Summary nicht mehr in DB schreiben - Fallback auf vorherige Summary
Wenn die Claude-API-Analyse keinen oder einen leeren Summary zurueckgibt,
wird jetzt die vorherige Summary beibehalten statt mit einem leeren String
ueberschrieben zu werden.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 07:33:33 +01:00
claude-dev
6b11d643b9 Fix: Analyse-Parser erkennt jetzt Markdown-Code-Fences
Claude-Antworten mit ```json ... ``` Wrapping werden korrekt geparst.
Verhindert den Verlust von Analyse-Ergebnissen bei inkrementellen Refreshes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 20:55:08 +01:00
claude-dev
1f3b3cb858 Zwei-Phasen-Faktencheck + parallele Analyse/Faktencheck-Ausführung
- Neuer Zwei-Phasen-Faktencheck: Haiku-Triage identifiziert betroffene Fakten,
  dann parallele Opus-Verifikation pro thematischer Gruppe (max 8 Fakten/Gruppe)
- Analyse und Faktencheck laufen jetzt parallel via asyncio.gather
- Snapshot-Erstellung vor parallele Verarbeitung verschoben
- Fallback auf Standard-Faktencheck bei Triage-Fehler
- Erwartete Verbesserung: ~19 Min -> ~8 Min pro Refresh bei gleichbleibender Qualität

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 20:16:45 +01:00
claude-dev
984a5a8184 Increase Claude CLI timeout from 420s to 1800s (30 min)
Lage updates with many articles were consistently timing out at 7 minutes.
Increased to 30 minutes to allow complex analyses to complete.
2026-03-09 17:25:39 +01:00
claude-dev
606c60a815 Geoparsing: Laender vor Staedten pruefen, Alias-Tabelle
Behebt falsche Geocodierung bei Laendernamen die auch als Staedte
existieren (Lebanon->US statt Libanon, Jordan->HK statt Jordanien).

- Laender-Aliase (50+ deutsch/englisch) werden zuerst geprueft
- geonamescache Laendersuche vor Staedtesuche
- Stadtsuche in eigene _geocode_city() Funktion extrahiert
- Bestehende falsche Marker in DB korrigiert

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 23:39:45 +01:00
claude-dev
e761c86a28 Fakten ohne Quellen-URL werden automatisch herabgestuft
_validate_facts() prueft nach dem Parsen: confirmed/established ohne
URL in der Evidenz wird zu unconfirmed/unverified herabgestuft.
183 bestehende confirmed-Fakten ohne URL wurden ebenfalls korrigiert.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 22:41:31 +01:00
claude-dev
22eaa2f80a Fix: Database-locked-Fehler beim Löschen von Lagen behoben
- PRAGMA busy_timeout=5000 in get_db() hinzugefügt (SQLite wartet bis zu 5s auf Lock-Freigabe)
- Try/except im Delete-Endpoint: gibt HTTP 409 statt 500 bei Lock-Konflikt

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 22:23:27 +01:00
claude-dev
204422ced9 Fakten-Konsolidierung: Evidenz zusammenfuehren statt nur loeschen
Beim Mergen von Duplikaten werden jetzt URLs und Quellen aus allen
Duplikaten in den besten Fakt uebernommen, bevor die Duplikate
entfernt werden. So gehen keine Belege verloren.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 22:03:25 +01:00
claude-dev
e2ea4eaaa0 Faktencheck-Deduplizierung und Auto-Resolve implementiert
3-Ebenen-System gegen Duplikate:
1. Pre-Dedup: LLM-Antwort wird vor DB-Insert dedupliziert (deduplicate_new_facts)
2. Auto-Resolve: Bestaetigte Fakten loesen automatisch stale developing/unconfirmed Fakten auf
3. Periodische Konsolidierung: Haiku clustert alle 6h semantische Duplikate und entfernt sie

Verbessertes Claim-Matching: SequenceMatcher (70%) + Jaccard-Keyword-Overlap (30%)
statt reinem SequenceMatcher. Threshold von 0.7 auf 0.75 erhoeht.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 21:59:50 +01:00
claude-dev
62aa63c7fb Bestätigungstext beim Ausschließen von Quellen erweitert
Klarerer Hinweis: betrifft alle eigenen Recherchen, nicht andere Nutzer der Organisation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 21:12:25 +01:00
claude-dev
13143b9447 Fix: Duplikat-Vorschläge + Stale-Check nur für RSS-Feeds
- Duplikat-Check basiert auf source_id+type statt exaktem Titel
- add_source ohne source_id prüft per Domain-Match
- Stale-Check überspringt web_sources (nur RSS-Feeds prüfen)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 19:05:45 +01:00
claude-dev
5986d03209 Haiku-Suggester: source_id in Issues-Summary für korrekte Zuordnung
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 17:29:16 +01:00
claude-dev
45d4d35f49 CLAUDE.md: Health-Check Services + DB-Tabellen dokumentiert
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 15:27:22 +01:00
claude-dev
40f2954811 Täglicher Quellen-Health-Check + Haiku-Vorschläge
- Neue Tabellen: source_health_checks, source_suggestions
- source_health.py: Prüft Erreichbarkeit, Feed-Validität, Aktualität, Duplikate
- source_suggester.py: KI-gestützte Vorschläge via Claude Haiku
- APScheduler Job: Automatischer Check täglich um 04:00

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 15:26:24 +01:00
claude-dev
6f2aac7313 Domain-ausschließen-Formular aus Toolbar entfernt
Redundant - jede Domain hat bereits einen eigenen Ausschließen-Button.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 14:40:30 +01:00
claude-dev
5e19736a25 Per-User Domain-Ausschlüsse + Grundquellen-Schutz
- Neue Tabelle user_excluded_domains für benutzerspezifische Ausschlüsse
- Domain-Ausschlüsse wirken nur für den jeweiligen User, nicht org-weit
- user_id wird durch die gesamte Pipeline geschleust (Orchestrator → Researcher → RSS-Parser)
- Grundquellen (is_global) können nicht mehr bearbeitet/gelöscht werden im Frontend
- Grundquelle-Badge bei globalen Quellen statt Edit/Delete-Buttons
- Filter Von mir ausgeschlossen im Quellen-Modal

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 14:30:21 +01:00
claude-dev
18954cf70e Wording: Domain sperren → Domain ausschließen
Einheitliche Umbenennung in UI-Texten, Kommentaren und Docstrings:
- Sperren → Ausschließen
- Gesperrt → Ausgeschlossen
- Entsperren → Ausschluss aufheben

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 14:02:36 +01:00
claude-dev
2dd11c9db7 DB-Migrationen (status_history, category) + Claude CLI stdin-Übergabe
- status_history Spalte für fact_checks (Faktencheck-Verlauf als JSON)
- category Spalte für article_locations (Marker-Klassifizierung)
- Prompt-Übergabe an Claude CLI via stdin statt Argument (ARG_MAX)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 13:25:21 +01:00
claude-dev
bcad3e9f3c Theme-Toggle als Schalter + Karten-Vollbild + Zoom-Begrenzung
- Theme-Toggle: Button durch Sun/Moon-Slider ersetzt (Dark Mode Standard)
- Karte: Fullscreen-Overlay mit Expand-Icon, Escape zum Schließen
- Karte: Zoom-Limits (minZoom:2, maxBounds, noWrap)
- Karte: Button 'Orte erkennen' -> 'Orte einlesen', rechts ausgerichtet

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 13:18:04 +01:00
claude-dev
7734eefd35 Dynamische Keyword-Extraktion fuer RSS-Filterung + min_matches-Fix
- researcher.py: Neuer dedizierter Haiku-Call extract_dynamic_keywords()
  analysiert die letzten 30 Headlines und generiert 5 DE+EN Begriffspaare
- orchestrator.py: Dynamische Keywords vor Feed-Selektion aus DB-Headlines
- rss_parser.py: min_matches auf max 2 gedeckelt (vorher n/2, bei 10 Keywords = 5)
- analyzer.py: Fettdruck-Anweisungen entfernt

Vorher: 0 RSS-Treffer (min_matches=5 unerreichbar)
Nachher: 22 RSS-Treffer (Tagesschau 11, Al Jazeera 5, BBC 4, NYT 2)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:12:17 +01:00
claude-dev
29dc457ceb Fix: NoneType.upper() Fehler bei country_code=None im Geoparsing
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 22:21:00 +01:00
claude-dev
5ae61a1379 Geoparsing von spaCy auf Haiku umgestellt
- geoparsing.py: Komplett-Rewrite (spaCy NER + Nominatim -> Haiku + geonamescache)
- orchestrator.py: incident_context an geoparse_articles, category in INSERT
- incidents.py: incident_context aus DB laden und an Geoparsing uebergeben
- public_api.py: Locations aggregiert im Lagebild-Endpoint
- components.js: response-Kategorie neben retaliation (beide akzeptiert)
- requirements.txt: spaCy und geopy entfernt

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 22:00:40 +01:00
claude-dev
7e600184e8 Geoparsing: Nominatim-Plausibilitätsprüfung + regionale Stopwords
- SequenceMatcher prüft ob Nominatim-Ergebnis zum Suchbegriff passt (Schwelle 0.3)
- Verwirft Fehlzuordnungen wie 'Golf-Staaten' -> Uganda
- Regionale/vage Begriffe als Stopwords (Naher Osten, Golf-Staaten, Balkan etc.)
- Falscher DB-Eintrag (Botschafter-Residenz Uganda) bereinigt

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 21:00:01 +01:00
claude-dev
3c4170bead Karte: Standard-Höhe auf h:8 (640px) erhöht
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 20:42:38 +01:00
claude-dev
ba8f807c96 Fix: Refresh-Verlauf zeigte Zeiten 1 Stunde in der Zukunft
parseUTC() hängte blind ein 'Z' (UTC) an alle Timestamps, aber
die DB speichert Lokalzeit (Europe/Berlin). Bei CET (UTC+1) wurden
alle Zeiten 1 Stunde zu spät angezeigt.

Neue Logik: Timestamps mit 'Z' oder '+' werden direkt geparst.
Timestamps ohne Zeitzonen-Info werden als Europe/Berlin interpretiert
mit korrektem Offset (auch bei Sommer-/Winterzeit-Wechsel).

Betrifft: Refresh-Verlauf, Artikel-Zeitstempel, Snapshots, Lagebild-Stand

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 11:33:04 +01:00
claude-dev
1c7adafa70 Fix: Progress-Timer zeigte negative Zahlen (-58:-10)
Ursache: Server sendete started_at als Lokalzeit (Europe/Berlin),
aber der Client interpretierte es als UTC via parseUTC().
Bei UTC+1 lag die Startzeit dadurch 1 Stunde in der Zukunft.

- orchestrator.py: started_at in WebSocket-Nachrichten als echtes UTC
  (ISO 8601 mit Z-Suffix) senden, DB-Timestamps bleiben Lokalzeit
- components.js: elapsed auf min. 0 clampen als Sicherheitsnetz

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 10:51:33 +01:00
claude-dev
f7809ccc77 Fix: TimeoutError wird nicht mehr verschluckt - Retry greift jetzt
- researcher.py/factchecker.py: TimeoutError wird nach oben durchgereicht
  statt vom breiten except Exception geschluckt zu werden
- orchestrator.py: Built-in TimeoutError zu TRANSIENT_ERRORS hinzugefuegt
  (war nur asyncio.TimeoutError, aber claude_client wirft TimeoutError)
- config.py: CLAUDE_TIMEOUT von 300s auf 420s erhoeht

Vorher: Timeout fuehrte zu "0 Artikel" ohne Retry (8 Timeouts seit 28.02.)
Nachher: Timeout loest bis zu 3 Retries aus (sofort, +2min, +5min)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 10:48:48 +01:00
claude-dev
ac3291f608 fix: Alle Zeitanzeigen fest auf Europe/Berlin Zeitzone
Alle toLocaleTimeString/toLocaleDateString-Aufrufe und
getHours/getMinutes-Zugriffe verwenden jetzt fix die
Zeitzone Europe/Berlin statt der Browser-Zeitzone.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 10:31:21 +01:00
claude-dev
a69352575d Fix: Komplett auf Europe/Berlin + DB-Migration + Timer-Fix
- ALLE Timestamps einheitlich Europe/Berlin (kein UTC mehr)
- DB-Migration: 1704 bestehende Timestamps von UTC nach Berlin konvertiert
- Auto-Refresh Timer Fix: ORDER BY id DESC statt completed_at DESC
  (verhindert falsche Sortierung bei gemischten Timestamp-Formaten)
- started_at statt completed_at fuer Timer-Vergleich (konsistenter)
- Manuelle Refreshes werden bei Intervall-Pruefung beruecksichtigt
- Debug-Logging fuer Auto-Refresh Entscheidungen
- astimezone() fuer Timestamps mit Offset-Info

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 02:56:51 +01:00
claude-dev
a8e9f34ff8 Fix: UTC fuer interne Timer, Berlin nur fuer Anzeige
Korrektur: Alle DB-Timestamps (refresh_log, created_at, updated_at,
auth, notifications) bleiben UTC fuer korrekte Timer-Vergleiche.
Europe/Berlin nur fuer angezeigte Werte (Exporte, Prompts, API).
Verhindert zu fruehes Ausloesen des Auto-Refresh-Timers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 02:40:02 +01:00
claude-dev
706d0b49d6 Fix: Alle Timestamps einheitlich auf Europe/Berlin Zeitzone
Inkonsistenz behoben: Manche Timestamps wurden in UTC, andere in
Berlin-Zeit gespeichert. Das fuehrte zu Fehlern beim Auto-Refresh
und Faktencheck, da Zeitvergleiche falsche Ergebnisse lieferten.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 02:37:30 +01:00
claude-dev
584cfa819b Protect: Grundquellen im Monitor vor Löschen/Bearbeiten schützen
- delete_source/update_source: Quellen mit tenant_id=NULL geschützt
- block/unblock_domain: Nur tenant-spezifische Quellen betroffen

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 19:46:41 +01:00
claude-dev
46cbf94a49 UI: Email-Dropdown im Header mit Org-Name und Lizenztyp
- Klick auf Email öffnet Dropdown mit Organisation und Lizenzinfo
- Org-Name und Lizenz-Badge nicht mehr direkt sichtbar im Header
- Dropdown schliesst bei Klick ausserhalb
- Barrierefreie ARIA-Attribute

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 19:00:31 +01:00
claude-dev
32f0281a96 Refactor: Email statt Username als Anzeige-Identifier
- Header zeigt volle Email statt Username
- Lagen-Karten/Sidebar zeigen Email-Prefix (vor dem @) als Ersteller
- Feedback-Emails nutzen Email-Prefix statt Username
- Login/Notification-Emails nutzen Email-Prefix als Anrede
- DB-Queries holen email statt username für Ersteller-Anzeige

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 18:55:24 +01:00
claude-dev
536e7f585b Feat: Claude-Keywords für RSS-Suche, Jahreszahlen-Filter, strikteres Matching
- rss_researcher liefert jetzt Keywords zurück, die direkt für RSS-Suche genutzt werden
- Neue _clean_search_words() filtert rein-numerische Begriffe (Jahreszahlen etc.)
- Matching-Schwelle aufgerundet: bei 3 Keywords müssen mindestens 2 matchen

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 18:36:08 +01:00
claude-dev
faa273f0de Fix: Barrierefreiheit "Größere Schrift" funktioniert jetzt
CSS zoom statt font-size auf Root, da alle Schriftgrößen in px definiert
sind und font-size:115% auf :root keine Wirkung hatte.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 18:02:53 +01:00
claude-dev
70ef7a1dd0 Revert: Englische Sprachintegration (i18n DE/EN) komplett entfernen
Frontend-Dateien auf Zustand vor i18n zurückgesetzt.
lang.js entfernt, CSP bereinigt. Backend-Umlaut-Fix bleibt erhalten.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 17:39:16 +01:00
claude-dev
d274a9c9b6 Fix: Echte UTF-8-Umlaute in KI-generierten Inhalten erzwingen
- Claude CLI Umgebung: LANG=C.UTF-8, LC_ALL=C.UTF-8 setzen
- Alle 10 Agent-Prompts: Explizite Anweisung für echte Umlaute (ä,ö,ü,ß)
  statt Umschreibungen (ae,oe,ue,ss)
- Betrifft: Researcher, Analyzer, Factchecker (jeweils initial + inkrementell)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 17:28:36 +01:00
claude-dev
b604a80842 i18n: Fix gray map tiles, translate A11y/Notification panels, remaining strings
- Fix gray map on EN: always use tile.openstreetmap.de (org has rate limits)
- Add A11yManager._updateLabels() for live language switch of accessibility panel
- Add NotificationCenter._updateLabels() for notification panel translation
- Replace all remaining hardcoded de-DE locales with dynamic locale switch
- Translate sidebar stats, source discovery toasts, session expiry warning
- Translate source form hints, type labels, article progress counter
- Add 15+ new translation keys for missing strings

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 16:36:28 +01:00
claude-dev
28458118d4 i18n: Fix last hardcoded German error string in export function
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 16:13:54 +01:00
claude-dev
44997d511b i18n: Complete DE/EN language switcher integration
- Add LangManager with 270+ translation keys, anti-flicker lang detection
- Replace all hardcoded German strings in app.js, components.js, dashboard.html, index.html
- Dynamic getter properties for fact-check labels, category badges
- Language-aware map tiles (DE/EN OSM servers), CSP updated for tile.openstreetmap.org
- Lang switcher in header bar and login page
- Locale-aware date formatting, translateApiError for backend messages

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 16:13:11 +01:00
claude-dev
1644f8786c Add i18n translation dictionary and LangManager singleton (DE/EN)
Provides full German/English translation support for the OSINT dashboard
with anti-flicker init, DOM hydration via data-i18n attributes, placeholder
replacement, API error translation, and locale-aware map tile URLs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 15:45:59 +01:00
claude-dev
e91829d215 Karte: Deutsche OSM-Kacheln, einheitlich fuer beide Themes
- tile.openstreetmap.de statt OSM/CartoDB: deutsche Ortsnamen
- Graue Vierecke behoben (Subdomain 'd' existierte nicht bei OSM)
- Gleiche helle Karte in Dark und Light Mode
- CSP img-src auf neuen Tile-Server aktualisiert

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 13:08:45 +01:00
claude-dev
559ace2f02 WCAG 2.1 AA: Focus-Styles, ARIA-Attribute, Tastatur-Navigation, Formvalidierung
- Default :focus-visible auf allen interaktiven Elementen (WCAG 2.4.7)
- A11y-Panel: role=group, Esc/Pfeiltasten, Fokus-Management
- Checkbox sr-only statt display:none (Screenreader-zugaenglich)
- Toggle-Switch Focus-Indikator
- aria-required, aria-expanded, aria-haspopup auf Formularen/Dropdowns
- Export-Dropdown: role=menu/menuitem/separator
- Sidebar: aria-expanded auf Sektionen, aria-hidden auf Chevrons
- Globaler Esc-Handler mit korrekter Schliess-Reihenfolge
- Formvalidierung: aria-invalid, aria-describedby, Fokus auf Fehler
- Notification-Items: role=button, tabindex=0
- Badges: aria-label/aria-hidden fuer Screenreader
- SR-Announcement bei Sidebar-Lage-Auswahl

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 12:53:13 +01:00