Read Tab Bars, Sidebars, Sheets, Alerts, Action Sheets, Toolbars, Buttons,
Pickers, Loading, Feedback, Privacy, and Undo/Redo off developer.apple.com
and cross-checked each against the actual code. profilSpeichern() (the
shared save path for ~25 fields) had no error handling at any call site,
so a failed backend write was an unhandled promise rejection with zero
user feedback - fixed centrally, plus the same for serviceRufen(). Also
added a spinner to the "Ladt ..." bootstrap screen and gave the
Anzugsmoment/km-correction popups the same primary-button styling the
Setup popup already used.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Replaced the hand-drawn placeholder battery icon with the real Audi CI
battery-12v-l/-s (user supplied the actual SVGs) next to "Ruhespannung",
matching the existing poi-l/poi-s size-variant convention.
Added a km-correction control to the Sommerräder/Winterräder tiles: a
pencil icon (Audi CI edit-s) opens an inline field to manually correct
the tire-set's accumulated km. The tricky part was persistence -
configCarZuProfil() deliberately never writes km back (a stale browser
copy could otherwise clobber a since-elapsed automatic increment), so
this needed its own backend service, audi_dashboard_reifen_km_setzen,
that overwrites only the stored counter and leaves referenz_odo_km
alone - the existing odometer-delta tracking in reifenzaehler.py then
continues accumulating from the corrected value on its own, no other
backend change required.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The tile headline now reads "Sommerräder"/"Winterräder" and renders as an
actual headline (new .tile-headline class, 20px/var(--fg)) instead of the
small muted .label styling used for other in-tile section titles.
Headline + km now sit above "Montiert" instead of the wheel photo
overlaying it: new .radkopf-row (flex) puts headline/km and the photo
side by side at the tile's top; Montiert dropped position:absolute (no
longer needed once the photo stopped sharing its space) and is now a
normal-flow pill below the headline block.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The reported "whole tab bar disappears when hiding labels" bug was real,
just one level deeper than first checked. .tabbar.ohne .tab span{display:
none} targeted the label span, but the icon is also wrapped in a <span
class="tabpille"> - a bare "span" type selector doesn't care about class,
so the icon's own wrapper collapsed too. Confirmed by measuring the <svg>
directly (0x0 bounding rect) after a live screenshot showed all 5 tab
buttons empty. Fixed with :not(.tabpille) in both stylesheets.
The Modell dropdown was still bright despite the color-scheme hint from
the last commit: a <select>'s opened option list is rendered by the
browser/OS as its own surface, entirely outside the page's paint tree -
confirmed when a screenshot call hung 30s trying to capture it open.
color-scheme only gets partial credit there; explicit background-color/
color on <option> is what Chrome/Firefox/Edge actually honor for the
popup rows. Added that, verified via getComputedStyle since the open
popup itself can't be screenshotted by this tooling.
Swapped the wheel photo (now right-aligned via margin-left:auto on the
now-correctly-square .bildbox.radbild) and Montiert (already left) per
request.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
.bildbox.radbild lost to a same-specificity, later-declared .bildbox rule,
so the wheel photo stayed a full-width 4:3 box despite the earlier crop
fix - only which slice showed ever changed. Fixed with a compound selector
and moved "Montiert" to top-left to match the now-correctly-sized photo.
Native <select> popups had no color-scheme hint and rendered in the
browser's default light palette regardless of the app's dark theme -
this is what made "Modell" and other dropdowns flash bright white.
bildWeiter() (Mein Audi image-cycle tap) referenced a CSS class that was
never emitted (.platzhalter-datei vs. the real .platzhalter-aktion),
throwing and aborting before the page-dot indicator update - the photo
advanced but the dots never moved.
Merged the separate "Fahrzeugbilder" upload grid into "Bild der
Übersicht": pick a view from the existing dropdown, tap its preview to
upload/replace/delete - same generic popup plumbing, no new mechanism.
Removed the now-dead BILDER_UPLOAD_SLOTS/.bildgrid/.bildslot/.carfix.mini.
Back arrow changed from red to the neutral headline color, matching every
other navigation-color decision in this project.
Investigated but could not reproduce: user-reported "whole tab bar
disappears" when hiding labels. Traced the exact commit that added the
icon+label highlight and confirmed it's correctly scoped to :not(.ohne);
live DOM/computed-style testing across toggle, navigation, and both
mobile/desktop widths showed the tab bar staying visible throughout.
Left unchanged pending a repro from the user.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Battery voltage stat cutoff 13.2V -> 12.8V (values above that are already
alternator output, not the battery); fixed the battery chart's Y-axis
"stretching" on zoom by computing it once from the full dataset; removed
two explanatory paragraphs from the battery detail view; Tankfuellung now
shows "X % / X l"; removed the "noch etwa X l im Tank" suffix; fuel bar
color now matches the headline instead of a red/yellow/green gradient;
active/primary buttons are grey again, not red (destructive stays red per
HIG); select fields gained an Apple-HIG pull-down chevron (appearance:none
had removed the native one with nothing replacing it); selected menu icon
is white on desktop, matching mobile; Reifenfoto crops from the right edge;
"Montiert" button rebuilt as a compact top-right pill with a 44px invisible
tap target; tab-bar active highlight now covers icon+label, not just the
icon; removed two leftover explanatory texts from Einstellungen.
Root-caused the map pins looking "transparent": the CI poi-car/poi icons
are pure contour forms (nonzero-fill-rule ring + thin detail lines, only
13-40% of their own bounding box actually filled). Fixed by extracting each
icon's own first sub-path (the true outer balloon silhouette, verified by
rasterizing it in isolation) as a solid-filled layer behind the original
icon, applied to both the vehicle and station markers.
Read Color/Typography/Layout/Buttons/Materials on developer.apple.com and
applied the user-approved subset (11px text floor, 44px tap targets);
declined items (font weight, materials) documented with rationale.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The station marker was a red circleMarker. It is now the CI poi pin
(poi-l/poi-s via tankstellenMarkerSVG) - the plain pin rather than poi-car, so
the vehicle and the station stay distinguishable on a map.
While testing it turned out nothing in the backend ever writes station_lat /
station_lon, so that marker had never been reachable in practice. The receipt
address is now geocoded in the frontend via Nominatim /search
(adresseAufloesen, the forward counterpart to the existing reverse lookup),
with results cached in localStorage - negative ones too, since a station
address does not move and Nominatim's terms ask for caching. Verified live:
"Shell, SÖLDEN" resolves to 46.9756 / 11.0111.
The map card gained a centre button (CI.gps, which is byte-identical to the
delivered gps-s.svg), disabled until the coordinates arrive. .mapbox needed
position:relative so the control anchors to the card instead of an ancestor.
Only in the Einzelbeleg, as requested - the Standort fullscreen already has
its own centre controls.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Leaflet's stylesheet was appended to document.head, so it never reached the
panel's shadow root: .leaflet-tile{position:absolute} never applied, tiles laid
out as in-flow images (~1040px inside a 190px box) and the marker pane ended up
far below the visible area. That is the real cause of the long-standing
"fragmented Leaflet rendering" finding and of the invisible vehicle pin - every
tile request had actually succeeded. The stylesheet now goes into the shadow
root and is awaited before the map is built.
Also in this round:
- Map tiles are always light (Google-Maps-style), no dark variant at night.
- Vehicle marker uses the real CI poi-car icons (poi-car-l >=34px, poi-car-s
below), with a white halo so the outline stays readable on tiles.
- Removed the obsolete combined STANDORT_TRACKER field; only the split
lat/lon sensors remain.
- Receipt upload: widened the try block so base64/save failures surface, and
the frontend call site now reports a rejected service call.
- Generic receipt parser: total detection is line-based (letter-spaced
headings, no more matching the SUMME-EUR column header, tax lines excluded),
address heuristic handles 4-digit postcodes and single-line address blocks,
and "Preis/L" matches without a spelled-out "Liter".
- Design backlog: red hairline frame on list rows (delete button bled through
at fractional row heights) and select fields now use the grey background box.
Shell 10-receipt regression suite still passes; all changes verified live in
the audi_ha_test container.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Entfernt Haubenschloss-/Tuerschloss-Erkennung dauerhaft aus Setup-Katalog und
Sicherheitscheck (auf ausdruecklichen Wunsch, nicht nur leer/unzuordenbar wie
der Rest der abgeloesten VAG-Integration). Behebt eine durchscheinende
Bestaetigungs-Sheet ("Doppelt zugeordnet" u.a.) - derselbe --tile-2-
Transparenz-Fehler, der fuer das Setup-Popup schon behoben war, hier
nachgezogen. Ergaenzt einen zweiten GPS-Pfad (STANDORT_LAT_SENSOR/
STANDORT_LON_SENSOR) fuer Integrationen wie flespi, die Breiten-/Laengengrad
als zwei eigene Sensoren statt als device_tracker-Attribute liefern. Haertet
den bekannten "Laedt ..."-Haenger beim App-Start zusaetzlich ab: Tab-Klicks
pruefen jetzt aktiv nach, ob Daten inzwischen da sind. Ergaenzt
shell_beleg_parser.py um einen stationsunabhaengigen Fallback fuer
Tankbelege unbekannter Formate (Adresse/Gesamtbetrag/Menge/Rabatt-Herleitung
wie vom Nutzer vorgegeben) - die bestehende Shell-Erkennung bleibt
unveraendert und weiterhin durch die zehn echten Testbelege abgedeckt.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Entfernt die letzten Verweise auf die abgeloeste TommiG1/HA_VAG-EU-Data-Act-
Integration (Versionstile, Testumgebungs-Fixture) und ersetzt sie durch die
FMM003-Werte. Behebt eine CSS-Spezifitaetskollision, durch die alle iOS-
Toggle-Switches viel zu breit gerendert wurden. Dokumentiert und behebt sieben
Layout-Befunde aus zwei Design-Audit-Runden (Zahnrad-Ueberlauf auf breiten
Bildschirmen, zu kleine Ringe als mobiler Einstellungen-Zugang, zu breite
Popups, Kopfzeilen-Versatz, ueberlappende Kachel-Pfeile, fehlender
Editierbarkeits-Hinweis bei Auswahlfeldern, Haekchen-artige Auf/Zu-Pfeile) -
siehe DESIGN_AUDIT_2026-08-13.md fuer Root-Cause und Beleg je Befund.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Zwei unabhaengig vom iOS-Entscheid offene Befunde aus DESIGN_REVIEW_2026-08-13.md
§B behoben:
- .aktion (audi-dashboard-ios.css) fuellte bisher JEDE Aktion rot statt nur
destruktive - jetzt neutrale --ios-fill-Flaeche fuer die Sekundaeraktion,
neue .aktion.primaer-Regel traegt die rote Fuellung als einzige Stelle
(deckt sich mit dem Sekundaer/Primaer/Loeschen-Schema, das die Basis-CSS
schon vorgibt). Gleiche Ursache auch bei Schalter-Ein-Zustand (jetzt --ok
gruen statt rot, echtes iOS-Systemgruen) und aktiver Desktop-Sidebar-
Navigation (Flaeche jetzt neutral, Rot bleibt Text-/Icon-Akzent).
- Zwei Balkensegmente in audi-dashboard-app.js nutzten --red fuer eine
neutrale Kategorie (Arbeitsweg-Fahrten, Versicherungsbeitrag-Aufteilung) -
jetzt wie die Nachbarsegmente auf --fg umgestellt.
- .setup-popup/.standortmenu (audi-dashboard.css) hatten 20px als Literal
statt var(--r-tile) - folgen jetzt dem Token wie alle anderen Kacheln.
Im Docker-Testcontainer verifiziert: Setup-Popup, Einstellungen (mobil und
Desktop-Sidebar), Schalter - korrekte Fuellungen, keine Konsolenfehler.
Frontend, kleinere Befunde:
- Das Standort-Menue liess sich nur wischen oder ueber den Kartenmarker
oeffnen. Der Griff ist jetzt ein Knopf mit aria-expanded, damit auch per
Tastatur erreichbar; der Umschalter Strasse/Satellit hat aria-pressed und
ein Label, das den Zustand nennt.
- Der Filterschalter "Nur passende Sensoren anzeigen" wirkte nicht, solange
eine Auswahlliste offen war: der Klick-Handler ersetzte das Overlay-DOM,
bevor das change-Ereignis des Kontrollkaestchens ausgeliefert wurde. Er
wird jetzt vor dem Schliessen der Liste behandelt.
- Der Theme-Wechsel zeichnete nicht neu, die Leaflet-Kacheln blieben bis zum
naechsten Backend-Update im alten Stil - seit der Dauerkarte auf der
Uebersicht deutlich sichtbar.
- Toter Code entfernt (fahrzeugGlyphPfade, .dot.neutral) und zwei Kommentare
berichtigt, die Gegenteiliges behaupteten.
Dokumentation:
- AGENTS.md widersprach sich an sechs Stellen. Berichtigt: Fahrterkennung
laeuft ueber die Zuendung, nicht ueber WLAN; Datenweg ist flespi, nicht
MQTT; Modulzahl und Zeilenzahl stimmen wieder; Entity-IDs werden im
Setup-Menue zugeordnet, nicht in einstellungen.py; STANDORT_TRACKER ist
belegt, nicht leer.
- SPECIFICATION.md beschreibt durchgehend den Stand vor der FMM003-
Umstellung. Statt es zu Teilen umzuschreiben und dabei Ungenauigkeiten zu
riskieren, steht jetzt ein datierter Hinweis am Anfang, der die drei
geaenderten Punkte benennt und auf AGENTS.md verweist. Alles Uebrige des
Dokuments gilt unveraendert weiter.
- INSTALL.md: Die zirkulaere Schrittfolge (Schritt 4 verweist auf 9, Schritt
7 auf 4) ist als solche benannt und aufgeloest. Die Override-Datei ist mit
Pfad genannt, samt dem Hinweis, dass sie gesichert wird. Und die drei mit
Test-Entitaeten der Entwicklungsinstanz vorbelegten Rollen sind erwaehnt -
auf einer frischen Installation zeigen sie ins Leere.
- README, Profilvorlage: WLAN-Reste entfernt, zwei Falschaussagen aus dem
ersten Review nachgezogen (Statistik rechnet echt, die
97-Prozent-Volltankungsregel wurde entfernt), Dateiuebersicht um die
fuenf fehlenden pyscript-Dateien und entitaeten.py ergaenzt.
- update.ps1 liefert jetzt auch shell_beleg_parser.py aus. Die Datei liegt in
data/, ist aber Code - Aenderungen am Belegleser, dem einzigen getesteten
Teil des Projekts, kamen bisher auf keiner Instanz an.
- design/README: Zwei Dateien der Inhaltstabelle liegen gar nicht in dem
Ordner, weshalb das Board aus der Repo-Kopie heraus leer bleibt - jetzt
vermerkt. Ausserdem die Behauptung berichtigt, die Auflage ruehre
audi-dashboard-app.js nicht an: der Stylesheet-Loader wurde dort ergaenzt.
Geprueft: Panel laedt, alle neun pyscript-Entitaeten werden veroeffentlicht,
Zuordnen und Zuruecksetzen funktionieren, keine neuen Fehler im Protokoll.
Befund 9: In Telefonbreite blendet die iOS-Auflage das Zahnrad aus, die Ringe
waren dort der einzige Zugang zu den Einstellungen - als div mit
pointer-events:none aber weder fokussierbar noch fuer Sprachausgabe
erreichbar. Sie sind jetzt ein echter Knopf mit aria-label, in jeder Breite
bedienbar und unabhaengig davon, ob die Auflage geladen wurde.
Befund 10: .navmarke{display:none} stand nur in der iOS-Auflage. Ohne sie
waere der Markenklon ein sechstes Element im fuenfspaltigen Raster und die
Menueleiste zerfiele. Die Regel steht jetzt in der Basis-CSS, die
Sichtbarkeit in der Auflage - genau andersherum als bisher.
Befund 13: Das Setup-Fenster deklariert role=dialog aria-modal=true, hielt den
Vertrag aber nicht ein. Escape schliesst jetzt (Reihenfolge: Auswahlliste,
dann Fenster), der Tabulator wandert im Fenster im Kreis statt in den
verdeckten Hintergrund, und der Filterschalter hat einen zugaenglichen Namen.
CSS-Spezifitaet: main{padding} in der Auflage verlor gegen main#view in der
Basis - auf grossen Bildschirmen blieb der Seitenrand bei 20px statt 44px.
Der Rand liegt jetzt in einer Variablen, die auch der negative Rand der
randlosen Standortkarte benutzt; sonst haette deren Ausgleich nach dem Fix
nicht mehr gepasst.
Drei Anzeigefehler, im Browser gegen die Testinstanz gefunden und behoben:
ein unlesbares Datum ergab NaN/N statt eines Strichs (das Profil wird laut
INSTALL.md von Hand gepflegt, ein ISO-Datum genuegt), ein fehlender
Tanksensor ergab 0 Prozent statt unbekannt, und neben dem Typenschild stand
die Ausfuehrung doppelt, wenn sie schon im Modellnamen steckt.
Alles im echten Panel geprueft: #marke ist ein BUTTON mit aria-label, der
Markenklon ist ohne die Auflage versteckt, der Seitenrand folgt der
Variablen, und die drei Anzeigen zeigen jetzt Striche statt Rechenreste.
Fünf Erweiterungen des bestehenden Setup-Popups: Live-Wert neben jedem
Such-Kandidaten, Warnhinweis bei unavailable/unknown/fehlender Entität,
Duplikat-Check mit Bestätigung vor dem Speichern, Zurücksetzen-Button je
Feld (Standardwerte-Snapshot in entitaeten.py, vor jedem Override
genommen), und ein bestätigter "Jetzt neu starten"-Knopf nach dem
Speichern, falls sich eines der drei trigger-gebundenen Felder geändert
hat (neuer Service audi_dashboard_neustart). Im Docker-Testcontainer
Feld für Feld verifiziert.
Setup-Menü (Einstellungen -> Fahrzeug einrichten -> Setup): ordnet alle von
der App genutzten Sensor-Rollen echten HA-Entitäten zu, statt sie in
einstellungen.py von Hand einzutragen - durchsuchbares Dropdown je Feld,
Vorauswahl aus vorhandenen Entitäten, Schalter für "nur passende Sensoren".
Neues Modul entitaeten.py (Katalog + JSON-Override, zur Laufzeit über
setattr() auf einstellungen angewendet, kein Neustart nötig außer für die
drei trigger-gebundenen Felder).
Zusätzlich: Fahrzeug-WLAN-Erkennung und alle Entity-IDs der nicht mehr
genutzten TommiG1/HA_VAG-EU-Data-Act-Integration entfernt. Fahrterkennung
läuft jetzt über den Zündungs-/ACC-Status des neu angebundenen Teltonika
FMM003 (ersetzt die WLAN-Verbindungserkennung); Standort und 12V-
Batteriespannung kommen ebenfalls vom FMM003. Kilometerstand, Tankfüllstand,
Reichweite, Türen/Fenster/Schlösser sowie Ölwechsel-/Inspektionsdaten haben
dadurch vorerst keine Quelle mehr und zeigen "unbekannt" - die Funktionen
selbst bleiben erhalten und lassen sich über das neue Setup-Menü jederzeit
neu zuordnen.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Neue Kachel oberhalb von "Zuletzt" mit echter Leaflet-Mini-Karte,
öffnet per Klick eine Vollbild-Standortansicht (Kartendarstellung
wählen, auf Fahrzeug/User zentrieren, beide zeigen) mit einem
ausziehbaren myAudi-Stil-Menü: Distanz zum Gerät, Adresse (Reverse-
Geocoding via Nominatim), fährt/steht/Letzter-Parkplatz-Status,
Tankfüllstand/Reichweite, Route- und Teilen-Aktionen.
Backend: STANDORT_TRACKER-Einstellung (device_tracker-Entity) plus
_standort()-Veröffentlichung, bewusst leer gelassen bis eine echte
GPS-Quelle (FMM003/flespi) angebunden ist - Kachel zeigt bis dahin
"kein GPS-Signal". Verifiziert in audi_ha_test mit einer manuell
gesetzten Test-Position.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Drei zusammengehörige Teile in einem Repository:
- homeassistant/ Das fertige, im Einsatz befindliche Home-Assistant-Panel
(panel_custom Custom Element + pyscript-Backend). Echte Fahrzeug- und
Personendaten (fahrzeugprofil.json, fahrten.jsonl, tankvorgaenge.jsonl,
Tankbelege) bleiben per .gitignore außen vor; die anonymisierte Vorlage
fahrzeugprofil.example.json ist mit dabei.
- design-system/ Eigenständige React-Komponentenbibliothek (@audi-dash/ui),
die die visuelle Sprache des Panels nachbildet - ohne Audi-Markenzeichen
und ohne die lizenzierte Hausschrift. Dient als Grundlage für Claude
Design. War bis hierher ein eigenes Repository und ist in dieses
eingeschmolzen worden.
- companion-app/ Datenschicht der neuen App DataMetric360 (iOS/Android via
Capacitor, zusätzlich als Iframe im HA-Dashboard). Noch ohne Oberfläche:
REST- und WebSocket-Zugriff auf Home Assistant plus Warteschlange für
Änderungen ohne Netz. Ersetzt das eingespritzte hass-Objekt, das nur
innerhalb des HA-Frontends existiert.
Dazu die Projektdokumentation: SPECIFICATION.md (Ist-Stand des Panels),
COMPANION_APP_ARCHITECTURE.md (Architekturentscheidungen der neuen App),
AUDIT_2026-08-10.md, DESIGN_BRIEF_DATAMETRIC360.md und der ursprüngliche
Bauauftrag.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>