Am 07.09.2026 sind drei Commits am Ende von main entfernt und der Branch per
Force-Push zurueckgesetzt worden. Ein aelterer Klon - der Mac, auf dem
signiert wird - steht damit VORAUS statt zurueck. Der Waechter sagte dort
"Erst 'git pull' ausfuehren", und genau das ist die Falle: der Merge holt die
entfernten Commits zurueck in die Historie, der naechste Push stellt sie auf
dem Server wieder her, und zwar ohne --force.
Git kann diese Lage nicht von echter ungepushter Arbeit unterscheiden. Das
Skript entscheidet deshalb nicht, sondern listet die nur lokal vorhandenen
Commits auf, nennt beide Moeglichkeiten samt richtigem Befehl und bricht ab.
Nur der schlichte Rueckstand empfiehlt weiterhin 'git pull'.
Beide Zweige gegen Wegwerf-Repos in der jeweiligen Form geprueft, nicht nur
geparst - die erste Fassung stufte die Lage als "auseinandergelaufen" ein und
haette dem Mac zum Pushen geraten.
APPLE_DEV_BACKLOG.md nennt den einmaligen Schritt im Abschnitt "Vorher".
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Ansage des Eigentuemers. Die Portzuordnung des Testcontainers liest sich
irrefuehrend - "0.0.0.0:18123->8123/tcp" enthaelt eine 8123, die aber
containerintern ist. Host-seitig gehoert 8123 der realen Instanz: nicht
oeffnen, nicht abrufen, nicht aendern, auch keine Erreichbarkeitspruefung.
Geprueft, dass nichts im Projekt versehentlich dorthin zeigt: alle drei
Vite-Proxy-Ziele stehen auf 18123, in .claude/ steht nichts. Die uebrigen
Fundstellen von ":8123" sind Zeichenkettentests ohne Netzzugriff sowie
Dokumentation des realen Aufbaus (Reverse-Proxy, Architektur) - nichts davon
wird ausgefuehrt.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Der Docker-Container auf :18123 ist umbenannt (Ansage des Eigentuemers).
Umgestellt sind nur die betriebsrelevanten Verweise:
testumgebung/aufsetzen.sh NAME=
testumgebung/README.md docker rm -f
companion-app/vite.config.ts Kommentar am Entwicklungs-Proxy
Die uebrigen ~120 Nennungen in AGENTS.md stehen in Verlaufsabschnitten und
bleiben, wie sie geschrieben wurden - stattdessen eine bindende Notiz oben in
der Datei, dass "audi_ha_test" in allen aelteren Abschnitten denselben
Container meint. Sie haelt auch fest, dass aufsetzen.sh mit "docker rm -f" auf
diesen Namen beginnt: ein Lauf loescht den Container samt allem, was darin
aufgezeichnet ist.
Geprueft: Portzuordnung 18123 unveraendert, Container startet unter dem neuen
Namen sauber (Audi Dashboard 2026.9.6.9 eingerichtet, kein Traceback), Profil
und Daten unberuehrt.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Die Beschreibung gibt es zusaetzlich als veroeffentlichte Seite mit echt
gerenderten Farbmustern fuer Tag und Nacht. Adresse in
PORTIERUNG_UEBERSCHRITTEN.md und OFFEN.md nachgetragen, mit dem Hinweis, dass
Aenderungen an der Datei dort nachzuziehen sind - sonst laufen die beiden
Fassungen auseinander.
Die Seite ist markenfrei: keine lizenzierten Schriften, Embleme oder
Modellzeichen, nur die Farbwerte und Strukturen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
PORTIERUNG_UEBERSCHRITTEN.md fasst zusammen, was fuer ein Spin-off dieser App
nachgezogen werden muss: Fachregel, Farbschwellen mit den gemessenen Werten,
CSS und Markup beider Codebasen, Tests, und die Fallen, die hier Zeit gekostet
haben.
Das Erstzulassungsdatum im Testcontainer ist von 01.03.2020 auf 01.03.2025
zurueckgestellt, die Sicherung entfernt - OFFEN.md 3b entsprechend.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Zwei Rueckmeldungen des Eigentuemers vom 07.09.2026.
1. Die Service-Kachel auf "Mein Audi" war als Ganzes gelb hinterlegt. Gelb
wird jetzt nur das ueberschrittene Feld, analog zur Termingruppe im
Service-Blatt: .row.ueberschritten bzw. .dm-wertzeile--ueberschritten,
12 % --warn mit -12px Aussenabstand bis an den Kachelrand. Die dafuer
gebaute Hilfsfunktion serviceUeberschritten() entfaellt ersatzlos.
2. Auch #C55300 wirkte braeunlich. Das ist die Schwelle, nicht der Geschmack:
Apples systemOrange #FF9500 kommt auf Weiss nur auf 2,20:1, jedes Orange
mit 4,5:1 liest sich als Braun. Deshalb traegt jetzt jedes Element seine
eigene WCAG-Schwelle:
--warn-fig 32px = Grosstext, 3:1 -> #DD6000 (3,65:1 auf Weiss)
die Marke 10,5px = Kleintext, 4,5:1 -> gefuellte Pille #C55300 mit
weisser Schrift (4,55:1) statt duenner Schrift
Nachts #FF9F0A (8,41:1) bzw. #FFA056 mit #171B21 (8,57:1).
Im Panel live gemessen (Testcontainer, Tagmodus): Kachelgrund rgb(255,255,255),
nur die HU-Zeile rgba(255,159,10,0.12) und um 2 x 12px breiter als die uebrigen
Zeilen, Marke rgb(255,255,255) auf rgb(197,83,0), Kennzahl rgb(221,96,0).
Damit ist Abschnitt DJ auch im Panel optisch geprueft - OFFEN.md 3b angepasst.
327/327 Tests, tsc sauber, Buendel auf 2026.9.6.9 neu gebaut.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
GROESSE: vom Eigentuemer als "sehr gross" gemeldet, im Browser bei 375x812
nachgemessen (Kachel 307px): "8.600 km" war bei 40px 133px breit (43% der
Kachel) und damit BREITER als die Reichweite darueber (60px, 107px, 35%) - der
zweitrangige Wert schlug den Hauptwert in der Flaeche. Mit einem Datum stand es
deutlicher: "01.03.2028" misst bei 40px 231px, 75% der Kachel. Auf 32px sind es
108px bzw. 185px, damit liegt der Servicewert auf der Reichweite gleichauf statt
darueber. Schrift und Gewicht waren nie das Problem und bleiben Audi Type Wide
300. Nimmt die Entscheidung vom 18.08.2026 (40 statt 30) zurueck.
FARBE: auf die Frage "HIG oder Audi CI" nachgeschlagen. Die Werte stehen auf
developer.apple.com nur im Alternativtext der Farbfelder, nicht im Text. Meine
Erinnerung war falsch - Apples Yellow "Increased contrast (light)" ist #A16A00,
nicht #A05A00. Uebernommen wird er trotzdem nicht: auf unserem 12% hinterlegten
Grund liefert er 4.19:1, Apples Orange #C55300 4.16:1, beide unter 4.5:1. Apples
Schwelle gilt fuer Schrift auf einfarbigem Grund. Der gemessene Wert #A15800
(4.90:1) bleibt, jetzt mit belegter Begruendung statt ohne. Nebenbefund: die
Seite zeigt inzwischen die neue "unified"-Palette (systemRed dunkel #FF4245),
dieses Projekt fuehrt die aeltere (#FF453A) - ein einzelner Wert aus der neuen
waere ohnehin inkonsistent.
LIVE GEPRUEFT: der Eigentuemer hat auf einen offenen Browser hingewiesen, damit
liess sich der offene Punkt aus DJ schliessen. Mit voruebergehend
zurueckdatierter Erstzulassung (Profil gesichert, hinterher zurueckgestellt und
geprueft) zeigen alle drei Stellen die Markierung, und nur die ueberschrittene
Gruppe ist hinterlegt - Oelwechsel 2028 und Inspektion 2027 blieben unmarkiert.
Das Panel ist weiterhin nur ueber den Paritaetstest belegt, nicht am Bild.
327/327, tsc sauber, Panel als Modul geparst, Manifest und Buendel auf
2026.9.6.7, Container sauber gestartet.
Wunsch des Eigentuemers: faellige oder ueberschrittene Termine dezent
gelb/orange hinterlegen und mit "ueberschritten" markieren - Service-Seite und
Mein Audi; auf der Uebersicht zusaetzlich die Kennzahl im Warnton.
Erkannt wird am DATUM, nicht an den Restkilometern. Gemessen: die Sensoren
melden -28600 bzw. -22000 bei Faelligkeit 2028 bzw. 2027, negativ heisst hier
also "noch so weit hin". Welches Vorzeichen ein tatsaechlich ueberschrittener
Wert traegt, ist an den vorliegenden Daten nicht beobachtbar - geraten wird es
nicht. Der km-Fall faellt ohnehin unter die Datumsregel: servicePrognose()
setzt datum auf heute, sobald restKm auf 0 laeuft. Der Faelligkeitstag zaehlt
mit ("bereits faellig bzw. ueberschritten").
Dabei eine Luecke im Panel gefunden, vom Test und nicht im Betrieb:
datumAusText() ist verankert und nimmt keine vollen Zeitstempel - die
Fahrzeugmeldung ist aber genau das und bei Oelwechsel und Inspektion die
Hauptquelle. Sie waere still nie als ueberschritten erkannt worden.
zeitstempelAlsDatum() schliesst sie; die App hatte die Luecke nie.
Farbe nach Rolle geteilt wie --bad/--bad-flaeche: --warn ist die Flaeche,
--warn-text die Schrift. Grund: #FF9F0A als Text auf Weiss sind 2.06:1. Auf dem
12% hinterlegten Grund misst --warn-text 4.90:1 (Tag, #A15800) bzw. 9.30:1
(Nacht).
Geprueft: 15 Faelle gegen die echten Panel-Funktionen, 7 in der App, 14
Paritaetsfaelle Panel gegen App, 3 Rendertests ueber alle drei Anzeigestellen.
Gegenprobe: mit ausgehaengter Entscheidung fallen 9 Tests. 327/327, tsc sauber,
Panel als Modul geparst, Manifest und Buendel auf 2026.9.6.6, Container sauber
gestartet.
Offen: optisch nicht gesehen - der Testbestand enthaelt keinen ueberschrittenen
Termin. In OFFEN.md vermerkt.
Der Befehl liegt richtig im Repository, wurde aber nicht gefunden: Claude Code
sucht Projektbefehle nur in <Arbeitsverzeichnis>/.claude/commands/, und diese
Sitzungen laufen eine Ebene ueber dem Repo (.claude/sessions, mit Audi_app_TG
und Audi_app_Labor als Unterverzeichnissen). Weder dort noch unter ~/.claude/
gab es ein commands-Verzeichnis.
Behoben ueber einen Zeiger unter .claude/sessions/.claude/commands/stand.md,
der nur auf die Datei im Repo verweist - eine Quelle, zwei Wege. Der Zeiger
liegt ausserhalb jedes Repositories und ist deshalb nicht versionierbar; das
steht jetzt als Hinweis in der versionierten Datei, damit es nach einem Verlust
der Arbeitsumgebung nicht als Raetsel wiederkommt.
Der eben ergaenzte Abschnitt empfahl "aus" und behauptete, das sei entschieden.
Beides war falsch: der Schalter ist eingeschaltet, und es laeuft. Die Empfehlung
beantwortete die Frage "soll er an sein" - gefragt war "soll ich ihn umlegen",
und die ist anders, wenn der laufende Zustand traegt.
Die Messung bleibt gueltig und ist der Grund, ihn NICHT auszuschalten: /local/
liefert HA schon mit 31 Tagen Cache-Control, der Rest der Freigabeliste ist
dynamisch. Auf der Habenseite steht also nichts, und ein laufender Proxy wird
nicht ohne Gewinn umkonfiguriert.
Die Regex-Konkurrenz zwischen einem Asset-Block und dem handgesetzten
/local/bilder/-Block ist damit empirisch widerlegt - sie steht als Merkposten
fuer spaetere Aenderungen an der Freigabeliste weiter drin, zusammen mit den
zwei Symptomen, die diese Einschaetzung kippen wuerden.
Die Doku schwieg zur Frage. Gemessen an der laufenden Instanz: /local/bilder/
liefert HA bereits mit 31 Tagen Cache-Control, /audi_dashboard_static/ ganz ohne
Cache-Control (nur ETag und Last-Modified). Die Fotos sind die einzige
nennenswerte statische Last durch den Proxy und werden ohnehin schon behalten -
der Schalter bringt also nichts.
Dagegen steht, dass ein Asset-Block ein Regex-Block auf genau die Endungen ist,
auf die auch der handgesetzte /local/bilder/-Block hoert. Unter Regex-Blöcken
gewinnt bei nginx der erste passende in Konfigurationsreihenfolge; steht der
erzeugte davor, greift er statt seiner. Wie NPM den Block genau erzeugt, ist
nicht nachgesehen - als Grund genuegt die Konkurrenzsituation.
Gefaehrlich waere es nicht: Fotos und OTA-Buendel tragen Cache-Brecher, das
Buendel zusaetzlich eine SHA-256-Pruefung auf dem Geraet.
Auf die Frage, welche Datei man am Mac in die Hand nimmt: der Backlog war die
richtige Antwort, ihm fehlte aber genau das - er beschrieb den Zustand und die
Pruefliste, nicht den Ablauf.
Neuer Abschnitt "Wie ein Lauf abläuft": was vorher zu tun ist (git pull; das
Skript bricht selbst ab, wenn der Baum unsauber oder HEAD nicht gleich
origin/main ist), der eine Befehl samt seiner dreizehn Schritte, dass die
Fassung aus manifest.json kommt und nichts von Hand hochzuzaehlen ist, das
einmalige Schluesselbund-"Immer erlauben" samt Symptom wenn man es uebersieht,
und danach Push plus der itms-services-Link in Safari - ausdruecklich ohne ?v=,
mit Verweis auf den Befund aus Abschnitt CK.
Damit ist die Datei als alleinige Uebergabe brauchbar; AGENTS.md braucht man nur
noch fuers Warum. OFFEN.md 1.1 verweist entsprechend darauf.
Ansage des Eigentuemers: ueber eine zentrale Datei bzw. einen zentralen Aufruf
muss immer klar sein, was aktuell zu tun ist.
OFFEN.md ist diese Datei. Sie nennt den Zustand, nicht die Geschichte, und
teilt sich die Arbeit mit den vorhandenen: AGENTS.md beantwortet WARUM etwas so
ist, APPLE_DEV_BACKLOG.md was davon Xcode oder das Portal braucht, OFFEN.md WAS
JETZT zu tun ist. Jeder Punkt sagt auch, was konkret zu tun ist - nicht nur,
dass etwas offen ist.
Gegliedert nach Zustaendigkeit statt nach Thema: was auf den Eigentuemer wartet
(Xcode-Lauf, Gitea-Token DM180, steuer.faellig), was eine Entscheidung braucht
(Uebersicht-Box Versicherung), was eine Sitzung bauen kann (PDF-Ablage,
Notizfeld, Dokumentendrift), was gemeldet aber nicht reproduzierbar ist, und
was bewusst so bleibt - letzteres, damit bekannte Grenzen nicht als Fehler
wiederkommen.
/stand (.claude/commands/stand.md) ist der zentrale Aufruf. Er misst den
mechanischen Teil selbst - Repo-Gleichstand, Manifest gegen OTA-Buendel samt
sha256, Fassung der ausgelieferten .ipa, ob die eigenen Plugins darin
registriert sind, und welche nativen Commits sich seit ihr angesammelt haben -
und liest OFFEN.md dazu. Dieser Teil kann deshalb nicht veralten. Probelauf
ausgefuehrt: er meldet korrekt 2026.9.6.5, Buendel passend, .ipa auf
2026.9.4.17 ohne die beiden eigenen Plugins, zwei native Commits wartend.
Verankert in CLAUDE.md (wird beim Sitzungsstart geladen) und als Punkt 0 der
Leseordnung in AGENTS.md.
Ansage des Eigentuemers: alles, was Xcode oder das Apple Developer Portal
braucht, wird kuenftig in einer eigenen Liste gefuehrt - Xcode-Laeufe werden
gebuendelt und erst gestartet, wenn eine nennenswerte Menge zusammengekommen
ist.
APPLE_DEV_BACKLOG.md haelt den am Artefakt gemessenen Stand der ausgelieferten
.ipa fest (2026.9.4.17, beide Profile bis 2027-08-29, alle vier
Berechtigungsschluessel da, packageClassList ohne die beiden eigenen Plugins)
und trennt: was auf einen Lauf wartet, was auf das Portal wartet, was nach dem
Lauf zu pruefen ist, und was das Skript ohnehin selbst erledigt.
Offen sind zwei Positionen, beide bereits im Repo korrigiert und nur auf einen
Lauf wartend: die nicht registrierten Plugins (Zwischenablage und Kalender sind
auf dem Telefon tot) und der Installationslink mit dem zweiten Fragezeichen.
Im Portal ist derzeit nichts offen.
Verankert als verbindliche Apple-Regel in AGENTS.md neben Wartungs- und
Paritaetsregel, in der Leseordnung, und als Querverweis aus Abschnitt DH -
dessen Untersuchungsbericht bleibt stehen, gepflegt wird der Zustand im Backlog.
Der in DI vorgeschlagene Schalter zum Anhalten der Aufzeichnung beim
Abstoepseln des Dongles ist abgelehnt ("spaeter werden nur die Daten in der App
behalten die ich bestimme"). Die Trennung Werkbank/Fahrzeug wird nicht
automatisiert, sondern kuratiert - ueber das bereits vorhandene Wischen zum
Loeschen in der Messwertliste. Als "nicht erneut vorschlagen" vermerkt, damit
eine spaetere Sitzung die Frage nicht wieder aufmacht.
Der Vorschlag aus Abschnitt CB (CAN-Wert innerhalb 300 s verlangen) wurde
gemessen und trifft nicht: er haette zwei eindeutige Werkbank-Tage
durchgelassen (CAN 5 Minuten neben dem Minimum) und echte Fahrzeugtage
verworfen - am stehenden Fahrzeug schweigt CAN, eine CAN-Frist verwirft also
ausgerechnet die Ruhespannung.
Der wirkliche Mechanismus: zustand_oder_none() liefert den zuletzt bekannten
Zustand unabhaengig vom Alter, und pruefen() stempelte ihn mit "jetzt". Ein
schweigender Dongle "misst" damit alle fuenf Minuten weiter seinen letzten
Wert. Am Bestand belegt: der 16.08.2026 trug einen Tageseintrag, obwohl der
Sensor an dem Tag kein einziges Mal gemeldet hatte (naechste echte Meldung 885
Minuten entfernt); sieben von 19 Eintraegen standen mehr als fuenf Minuten von
jeder echten Meldung entfernt.
messzeitpunkt() beantwortet jetzt beide Fragen an einer Stelle: ist das eine
neue Messung, und wann wurde sie gemacht. Gestempelt wird mit der Geraetezeit,
wenn zuordenbar - so wie der Rueckblick es laengst tut, der damit die richtige
Umsetzung war und keine Aenderung brauchte. Der Tag kommt aus der Messung, nicht
aus date.today(). Die Frischepruefung steht vor der Plausibilitaetsgrenze, sonst
warnt ein offline gegangener Dongle alle fuenf Minuten ueber denselben Wert (77
identische Zeilen in 3000 Protokollzeilen gezaehlt).
Die erste Fassung mass das Alter an last_updated und hatte damit ein Loch, das
erst die Live-Pruefung zeigte: Home Assistant setzt beim Hochfahren jede
Entitaet neu, last_updated steht danach auf der Neustartzeit. Gemessen: nach dem
Neustart um 21:12:54 trug der Spannungssensor last_updated 21:12:54, waehrend
die Meldezeit desselben Datensatzes 14:46:47 sagte. Das Alter wird deshalb an
der Messzeit gemessen.
Geprueft: 18 Tests in tests/batterie/, davon fallen 16 gegen HEAD; alle 116
Backend-Tests gruen; live im Testcontainer belegt - der erste Takt nach dem
Neustart meldet "keine neue Messung" statt der bisherigen Warnung.
Offen: Werkbank und Fahrzeug lassen sich aus diesen Daten nicht sicher trennen.
Abgestellt sind die erfundenen Eintraege, nicht die Frage, wo der Dongle steckt.
Am veroeffentlichten Artefakt gemessen, nicht am Projekt: in App.ipa
(2026.9.4.17) stehen in packageClassList nur die sechs Fremd-Plugins.
BelegZwischenablagePlugin und KalenderTerminPlugin sind einkompiliert - je
sechs Treffer im Binaerprogramm - und trotzdem tot, weil Capacitor 8
ausschliesslich diese Liste liest.
Damit sind die beiden Meldungen vom 04.09. weiterhin zutreffend: die
Zwischenablage meldet, die App muesse erst aktualisiert werden, und der
Kalendereintrag faellt auf das Teilen-Blatt zurueck, das den Kalender nie
erreichen kann.
Das Repo ist vollstaendig: der Fix kam in a99ae43, genau einen Commit nach
9652a43, der die .ipa zuletzt erneuert hat. Es fehlt allein der Xcode-Lauf.
Der Abschnitt nennt die Pruefpunkte fuer danach - vier prueft das Skript
selbst, der fuenfte bleibt Handarbeit auf dem Geraet.
- Die zwei Tankvorgaenge vom 04.09. geloescht; sie stammen aus dem
asyncio-Wettlauf und haben nie stattgefunden (Anweisung des Eigentuemers).
- Der Beschriftungs-Schalter der Menueleiste verschwindet im Spaltenlayout,
wo die Beschriftungen ohnehin immer stehen und er nichts bewirkte.
- .dm-fussnote trug font-weight: 300, obwohl es "Audi Type" nur als 400
gibt - eine Angabe ohne Wirkung.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Drei Fehler, die zusammen eine 5-Minuten-Fahrt als 15 Stunden mit 0,1 km/h
im Bestand stehen liessen:
- nach_neustart_fortsetzen() schloss eine laufende Fahrt bei ALLEM ausser
"on" - auch bei Funkstille. Jetzt nur noch bei ausdruecklichem "off".
- _letztes_lebenszeichen() las nur die Zuendungsentitaet, die nur bei einem
Wechsel schreibt. Zusaetzliche Quelle ist die Meldezeit-Entitaet, deren
Werte die Geraetezeit jedes Datensatzes sind.
- Strecke und Dauer decken bei einer Luecke verschiedene Zeitraeume ab: der
Durchschnitt entfaellt, und die Plausibilitaetspruefung rechnet ohne die
verschlafenen Kilometer.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Der Dongle wacht nach dem Motorstart erst nach 28 s bis 19,5 min auf; was in
der Zeit gefahren wird, zeichnet er nicht auf. Die Kilometer holt das
Screening jetzt aus dem Endkilometerstand der Vorgaengerin zurueck und haelt
in luecke_km fest, wie viel davon betroffen ist.
Keine Sperre der GNSS-Verfeinerung, sondern eine Zerlegung: verschlafener
Anfang in ganzen Kilometern, aufgezeichneter Rest metergenau. Sonst waere die
feine Zahl systematisch zu klein und wuerde bei kleinen Luecken die Korrektur
stillschweigend wieder kassieren.
Zwei Schutzgitter, beide am Bestand gelernt: LUECKE_MAX_KM = 50 gegen
Differenzen, die keine Weckverzoegerung mehr sein koennen, und ein Rueckfall,
wenn _vollstaendig() die Werte daraufhin verwerfen wuerde.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Der Eigentuemer hat die gestrige Schriftaenderung zurueckgenommen - ausser
fuer die Reichweite ueber dem Tankbalken. Die Ausnahme haengt deshalb an
.tankzeile .fig bzw. .dm-tankzeile .ads-fig und nicht an .fig/.ads-fig,
sonst zoege sie Kilometerstand, Service-Wert und jede Detailseite mit.
Wide Normal (400) ist wieder heraus - nach der Ruecknahme nutzte es niemand
mehr, im Panel 53 kB base64 und in der App eine 39.888-Byte-woff2.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- Audi Type Wide Bold (700) eingebunden und fuer .fig/.ads-fig gesetzt, in
beiden Codebasen. Light war zu duenn, Normal ebenfalls (Ansage des
Eigentuemers). Die alte Notiz "es gibt nur 300 und 400, niemals fetter"
ist damit ueberholt und entfernt statt ergaenzt - sie stand nur da, weil
es keine anderen Schnitte gab.
- standort_genauigkeit_m wird jetzt angezeigt ("Position auf +-12 m genau",
unter der Anschrift im Standortblatt). Der Wert kam seit jeher vom
Backend, wurde im Panel in eine Variable gelesen und nirgends gezeigt -
im Audit als totes Schema gefunden. In der App fehlte er ganz und ist
jetzt durch Typ und Adapter verdrahtet.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Die Sicherheitsseite sagte "Zuendung an - Fahrzeug in Betrieb". Der Zusatz
behauptet mehr, als das Signal deckt: die Zuendungsquelle steht am Geraet
auf Motordrehzahl und meldet auch im Stand mit laufendem Motor "an".
Entscheidung des Eigentuemers ("zuendung an reicht") - jetzt in beiden
Oberflaechen und an allen drei Stellen derselbe Text.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- Audi Type Wide gab es hier nur als Light (300). Der Eigentuemer hat den
vollen Satz aus Audis Styleguide geliefert; Wide Normal (400) ist jetzt
eingebunden (App und Panel), Wide Bold liegt vor und bleibt bewusst
ungenutzt. Lizenz wie bei allen Audi-Assets: nur diese eine private
Installation, deshalb nichts davon in design-system.
- Dabei gefunden: die Aenderung im Design-System allein war wirkungslos.
audi-schrift.css bringt fuer .ads-fig eine eigene, spaetere Regel mit und
gewinnt. Im gebauten Stylesheet standen beide - nur die Reihenfolge
entschied, und sichtbar wurde es erst am gerenderten getComputedStyle.
- Vollstaendiger Durchgang (AGENTS.md Abschnitt DC): Statik, struktureller
Paritaetstest ueber Routen, Dienste, Sensorrollen, Wortlaut und
Statusfelder, dazu ein Funktionstest an beiden laufenden Oberflaechen.
Ein echter Befund: standort_genauigkeit_m ist totes Schema im Panel.
Drei Meldungen des Eigentuemers waren keine Fehler - das breite Layout,
der Beschriftungs-Schalter ohne Reiterleiste, und eine Testfahrt von mir.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- Neue Sensorrolle FEHLERSPEICHER_SENSOR (number_of_diagnostic_trouble_codes
vom CAN) und eine fuenfte Zeile auf der Sicherheitsseite: "Keine
Fehlermeldungen". Bewusst NICHT im _sicherheitscheck(): "gesichert"
rechnet ein UND ueber diese Liste, und ein Eintrag im Fehlerspeicher sagt
nichts darueber, ob der Wagen verschlossen dasteht.
- "Zuendung an" ist Amber statt Gruen. Gruen las sich als "alles in Ordnung
und sicher"; unterwegs ist kein guter Zustand, sondern ein anderer.
- Das Modell-Auswahlfeld bekam dm-eingabe statt dm-auswahl - nur letzteres
setzt appearance:none, deshalb zeichnete der Browser seinen nativen Pfeil
neben den des Design-Systems. Die Breitenregel heisst jetzt
dm-feld--fahrzeug und gilt fuer input und select.
- "aktuell" erscheint erst nach einer Pruefung, und fuer beide Abschnitte
gemeinsam. Der App-Abschnitt zeigte die Marke schon, sobald ein Buendel
vorlag - also unmittelbar nach einem Update wieder.
- Der Tankbalken wird rot ab 90 km Restreichweite, in Kilometern und nicht
in Prozent: die Reichweite ist die Aussage, um die es geht, und das
Fahrzeug rechnet die Fahrweise darin bereits ein. Farbe --red (Audi-CI,
#F50537), nicht --bad-flaeche - letzteres ist fuer weisse Schrift darauf
gewaehlt, und hier steht keine drauf.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- Die Update-Kachel hat genau einen Knopf am Ende. Er traegt in jedem
Zustand den naechsten faelligen Schritt (suchen, installieren, Neustart,
Neuladen); Beschriftung und Fuellung wechseln mit. Die Abschnitte
darueber behalten ihre Werte und verlieren nur ihre Knoepfe.
- Abstand unter der Trennlinie von 28 auf 16 px: das padding-top verhindert
das Kollabieren des margin der Werteliste, also zaehlt jetzt nur noch das
padding.
- Modell ist in der App ein Auswahlfeld statt eines Textfelds, wie im
Panel. Die Liste liegt als Zweitschrift in daten/fahrzeugmodelle.ts;
fahrzeugmodelle.test.ts liest die Panel-Quelle ein und vergleicht sie
Eintrag fuer Eintrag, damit die beiden nicht auseinanderlaufen.
- Faehrt der Wagen, sagen Uebersicht und Sicherheitsseite das, statt
"sicher abgestellt" zu behaupten. Die Zuendung meldet der Dongle in
Sekunden, Tuer- und Schlossmeldungen kommen verzoegert - die schnellere
Quelle hat Vorrang, weil sonst das Wort nicht stimmt.
- tankerkennung: der Tiefststand wird vor dem Anlegen gesetzt. Ein
gepufferter Schwung Datensaetze legte sonst denselben Tankvorgang
zweimal an, weil der zweite Zustandswechsel waehrend des Wartens noch
den alten Tiefststand las (04.09.2026, 29,8 l und 29,7 l).
- flespi: nach dem Leeren des Zwischenspeichers wird nur abgeglichen, wenn
ein Geraetewert vorliegt. Sonst ueberschrieb der Waechterfehler den
frisch gelesenen Stand in der Kachel.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Der Zeitstempel stand an der gruenen Marke des Integrations-Abschnitts und sah
dort aus, als gaelte er nur fuer sie - obwohl der Suchknopf seit dem Umbau fuer
die ganze Kachel steht. Vom Eigentuemer bemerkt.
Jetzt steht "Zuletzt geprueft <Zeitpunkt>" unter dem Knopf, die gruene Marke
sagt nur noch "aktuell". In beiden Codebasen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Auf Vorgabe des Eigentuemers:
* Die Kachel heisst "Update" statt "Version" - sie zeigt beide Update-Wege.
* Der Suchknopf steht ganz unten unter beiden Abschnitten und ist in JEDEM
Zustand da. Das legt nahe, was er tut: nach Neuem fuer Integration und App
sehen. Vorher sass er nur im Zweig "ist aktuell", und daneben brauchte es
ein zweites "Erneut pruefen", damit sich eine womoeglich wochenalte Zahl
ueberhaupt auffrischen liess, solange ein Update angeboten wurde. Beides
eruebrigt sich.
* Der Erklaertext "Laedt die neueste Fassung von Gitea ..." ist entfallen.
* Im App-Abschnitt steht statt eines Satzes nur noch "Update <Fassung>
vorhanden" - wer ohnehin auf Update klickt, braucht nicht mehr.
* Der Pruef-Spinner mitten in der Kachel ist weg; der Knopf sagt selbst
"Pruefe ...".
In beiden Codebasen. Am laufenden Panel nachgesehen: "Update | Integration
2026.9.5.33 | Auf Update pruefen", ein einziger Knopf. 300 Tests gruen,
0 Tracebacks.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Am iPhone gesehen: der Server meldete 2026.9.5.29, das mitgelieferte Buendel
war noch .28. buendelPasst() verlangt Gleichheit, die App hielt sich deshalb
fuer nicht erneuerbar - und die Meldung schickte den Eigentuemer zu Xcode,
obwohl nur meine Veroeffentlichung unvollstaendig war: ich hatte die
Versionsnummer erhoeht, ohne npm run ota laufen zu lassen. Betraf .29 und .30.
Zwei Aenderungen:
* buendelversion.test.ts vergleicht die Version in bundle.json mit der in
manifest.json. Gegengeprueft: der Test faellt, wenn sie auseinanderlaufen.
Damit wird daraus ein Fehlschlag vor der Auslieferung statt einer
irrefuehrenden Meldung auf dem Telefon.
* Der Hinweis unterscheidet jetzt zwei Faelle. Liegt ein Buendel, das nur
nicht zur Serverfassung passt, heisst es, die App koenne sich erneuern,
sobald eine Veroeffentlichung ein passendes mitbringt. Nach Xcode wird nur
noch verwiesen, wenn gar kein Buendel da ist.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Vom Eigentuemer am iPhone bemerkt: nach "Update installiert, Neustart noetig"
zeigte der App-Abschnitt "5.22 aktuell", obwohl auf der Platte bereits das
Buendel 5.29 lag.
Ursache ist kein Fehler, sondern eine bewusste Bedingung: buendelPasst()
verlangt, dass das Buendel der Fassung entspricht, die diese Installation
gerade ausliefert. Zwischen Installation und Neustart meldet der laufende
Server aber noch seine alte Nummer - das Buendel wird deshalb zurecht nicht
angeboten. Nur "aktuell" zu schreiben war dabei falsch.
Jetzt steht dort, dass die Fassung bereitliegt und nach dem Neustart abrufbar
ist. Kein Knopf: zu tun ist erst danach etwas.
Dazu auf Wunsch des Eigentuemers der Knopftext in beiden Oberflaechen:
"Installation abschliessen und neu starten" statt "... - Jetzt neu starten".
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Am laufenden System ausgeloest: nach einem "Jetzt lesen" - das leert flespis
Zwischenspeicher - kannte der Schreibweg das mode-Objekt nicht mehr und
schickte einen timeout ohne type. flespi lehnt das mit 400 ab (the following
properties are missing: type).
Der else-Zweig ist ersatzlos weg. Ist das mode-Objekt samt type unbekannt,
wird gar nicht geschrieben und der Grund gemeldet. Der zweite Grund wiegt
schwerer als der 400er: type IST der Schlafmodus (2 = Deep Sleep, 4 = Ultra
Deep Sleep). Ihn zu erraten hiesse, den Schlafmodus des Dongles zu verstellen
- das darf ohne ausdrueckliche Freigabe nie passieren.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Vorgabe des Eigentuemers: klarer Zustand statt einer Meldung, die auch nach
dem Neuladen stehenbleibt.
Panel: nach einem Update ohne Neustart wird der Sidebar-Eintrag mit der neuen
Versionsnummer neu angemeldet (koordinator.panel_neu_anmelden) - ohne das
traegt die Modul-URL weiter die alte Nummer. Das Panel vergleicht jetzt die
Version aus seiner Modul-URL mit der von der Platte gelesenen: sind sie
gleich, laeuft es bereits auf der installierten Fassung und die Meldung
entfaellt. Sie verschwindet damit genau durch das Neuladen, zu dem sie
auffordert.
App: fuer ein Update ohne Neustart erscheint gar nichts mehr. Geaendert wurden
Dateien des Panels; die App hat hier nichts zu tun. Damit gilt durchgehend:
keine Meldung = alles in Ordnung, Neustart-Knopf = handeln.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Der Zweig fuer ein Update ohne Neustart bot in der App 'App neu laden' an.
Das versprach etwas, das es nicht einloesen kann: geaendert wurden Dateien
unter frontend/, und das sind die des PANELS. Die App laedt ihren eigenen Code
aus /local/dmapp bzw. der nativen Huelle, ihr Update laeuft ueber das
OTA-Buendel im Abschnitt darunter. Vom Eigentuemer im Bild bemerkt.
Jetzt steht dort nur noch der Hinweis, dass kein Neustart noetig ist und das
Panel die Dateien beim naechsten Oeffnen laedt. Im Panel bleibt 'Seite neu
laden' - dort stimmt es.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Aendert nur audi-dashboard-app.js und die Versionsnummer. Damit muss die
Neustart-Erkennung 'kein Neustart noetig' melden.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Am echten Update-Weg gemessen: die installierte Fassung lag mit CRLF auf der
Platte, das Gitea-Archiv liefert LF. Drei .py-Dateien galten dadurch als
geaendert, obwohl sie nach Entfernen der CR byteweise identisch waren - die
Erkennung verlangte einen Neustart fuer einen rein kosmetischen Unterschied.
Textdateien werden jetzt vor dem Hashen auf LF normalisiert. Binaerdateien
(Schriften, Bilder, das OTA-Zip) bleiben roh, dort waere 0x0D0A echter Inhalt.
Drei neue Testfaelle: reiner Zeilenenden-Unterschied, echte Aenderung trotz
verschiedener Zeilenenden, Binaerdatei. 26 Tests der Suite gruen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Bisher verlangte jedes Update einen Home-Assistant-Neustart. Noetig ist er
aber nur fuer Python-Code: HA importiert die Module einmal beim Start und
haengt danach mit lebenden Objekten daran. frontend/ dagegen wird direkt von
der Platte ausgeliefert (StaticPathConfig, cache_headers=False) - eine
ersetzte .js ist sofort wirksam, es braucht nur ein Neuladen im Browser.
aktualisierung.neustart_noetig() vergleicht die alte gegen die neue Fassung
ueber sha256 je Datei und meldet "kein Neustart" nur, wenn JEDE Abweichung
unter frontend/ liegt oder die manifest.json ist. Alles andere - .py,
services.yaml, translations/, vorlage/ - gilt als neustartpflichtig, auch wo
es das im Einzelfall nicht waere. Die Schieflage ist Absicht: ein
faelschlich ausgelassener Neustart laesst neuen Python-Code nie anlaufen, und
der Fehler wird woanders gesucht.
manifest.json ist ausgenommen, weil sich seine Versionsnummer bei jeder
Veroeffentlichung aendert - sonst waere die Unterscheidung wertlos. Weil HA
das Manifest fuer die Laufzeit festhaelt (loader.py: hass.data[
DATA_INTEGRATIONS]), liest version_von_platte() die Nummer direkt von der
Platte; koordinator.version_neu_lesen() zieht sie nach einem Update ohne
Neustart nach, damit Panel und App die neue Fassung auch anzeigen.
Panel und App zeigen im Neustart-freien Fall "Seite neu laden" statt
"Installation abschliessen - Jetzt neu starten".
Neun neue Testfaelle fuer die Unterscheidung, 23 Tests in der
Aktualisierungs-Suite gruen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Statt "Diese App ist aktuell." dieselbe gruene Marke wie bei der Integration -
Vorgabe des Eigentuemers. Ohne Zeitpunkt: anders als bei der Integration wird
hier nicht auf Knopfdruck geprueft, das Buendel meldet der Server beim Laden
mit. Der Fall "kein Buendel hinterlegt" bleibt ein Satz.
Nicht im Bild geprueft: der Abschnitt erscheint nur in der nativen Huelle,
otaMoeglich() ist im Browser falsch.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Auf Entscheidung des Eigentuemers nach der HIG-Pruefung. Gegen die Leiste
sprach viererlei: iOS kennt kein solches Muster auf einer geschobenen
Einstellungsseite; sie schwebte ueber der Tab-Leiste und deckte einen Knopf
der Kachel dahinter zu (gemessen); sie war die Ursache des Datenverlusts bei
der Erstzulassung; und das Panel hatte sie nie - dort schreibt jede Aenderung
sofort ins Profil.
Jetzt speichern Textfelder beim Verlassen, Auswahlfelder sofort. Die Meldung
"Gespeichert." entfaellt mit. Der Regler "Fahrt beenden" behaelt seinen
eigenen Bestaetigungsschritt - ihn bei jedem Zwischenschritt zu sichern hiesse
ein Dutzend Schreibvorgaenge je Bedienung.
Mit echten Eingabeereignissen am laufenden System geprueft: getippt, ins
naechste Feld geklickt, Wert steht in fahrzeugprofil.json; danach der
urspruengliche Wert wiederhergestellt. 299 Tests gruen, 0 Tracebacks.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
"Home-Assistant-Integration" brach auf Telefonbreite in zwei Zeilen um. Auf
Entscheidung des Eigentuemers gekuerzt; nachgemessen einzeilig, 20px hoch.
In beiden Codebasen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
aktualisierung.py pruefte mit `remote_version != eigene_version` - reine
Ungleichheit ohne Richtung. Lief die Instanz einer Veroeffentlichung voraus,
bot die Integration an, sich auf die aeltere Fassung zu aktualisieren. Vom
Eigentuemer gemeldet. ist_neuer() ist jetzt das Gegenstueck zu
versionOrdnung() in appVersion.ts, wo derselbe Fehler am 04.09. behoben wurde:
fehlende Stellen zaehlen als 0, kein int() mit Vorabschnitt, und was sich
nicht in eine Reihenfolge bringen laesst, gilt als verfuegbar statt
verschwiegen. Sechs neue Testfaelle, 79 Python-Tests gruen.
Dazu auf Vorgabe des Eigentuemers: die Zeile benennt jetzt selbst, was sie
zeigt - "Home-Assistant-Integration | 2026.9.5.19" statt "Installiert" mit dem
Gegenstand klein darunter. Damit entfallen die Abschnitts-Ueberschriften aus
dem vorigen Commit, sie sagten dasselbe doppelt.
Live in beiden Oberflaechen gegengeprueft: Gitea auf .18, Instanz auf .19 -
gemeldet wird gruenes "aktuell" (--ok) mit Pruefzeitpunkt statt eines
Rueckschritts. 0 Tracebacks.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Die zusammengefuehrte Kachel war zerlegt: ich hatte den Wrapper
.dm-abschnitt genannt, den Namen gibt es aber schon - als Flex-Zeile mit
space-between (bausteine/FahrtDetail/TankDetail). Der Kachelinhalt lag dadurch
nebeneinander statt untereinander, der Knopf lief aus der Kachel. Der neue
Wrapper heisst .dm-kachelabschnitt, die bestehende Klasse bleibt unberuehrt.
Gefunden hat es der Eigentuemer, nicht ich: ich hatte nach dem Umbau die
Abstaende der eingesetzten Probe gemessen, aber nie die Kachel selbst
angesehen.
Dazu auf seine Vorgabe: statt "Integration ist aktuell (Zeitpunkt)." steht
jetzt ein gruenes "aktuell" direkt unter dem installierten Stand, der
Zeitpunkt gedaempft daneben. Wurde NIE geprueft, steht dort gar nichts mehr -
gruen "aktuell" waere ohne Pruefung eine Behauptung ohne Grundlage, und der
Knopf "Auf Update pruefen" sagt den Zustand ohnehin. In beiden Codebasen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Die App hatte "App-Update" (OTA-Buendel) und "Version" (Integration) als zwei
Kacheln nebeneinander - zweimal dieselbe Frage. Jetzt eine Kachel "Version"
mit zwei benannten, durch eine Haarlinie getrennten Abschnitten; ohne das
staenden zwei gleich aussehende "Update installieren"-Knoepfe untereinander,
ohne dass man ihnen ansieht, was sie erneuern.
Die Unterueberschrift "Integration" erscheint nur, wenn wirklich ein zweiter
Abschnitt folgt (otaMoeglich()) - sonst waere es eine Unterteilung ohne
zweiten Teil. Wo es kein OTA gibt, also im Panel und in der App im Browser,
sieht die Kachel damit aus wie zuvor.
Das Panel bekommt den App-Abschnitt nicht: die App traegt ihre Dateien fest
gebuendelt und kann veralten, das Panel laedt sie bei jedem Aufruf neu. Eine
geplante Abweichung.
Nachgemessen: Panel 216px, App im Browser 203px, gleicher Inhalt; die
Gestaltung des zweiten Abschnitts durch Einsetzen gegengeprueft. 299 Tests
gruen, 0 Tracebacks.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Das QR-Blatt benutzte dm-speicherleiste als reine Gestaltung eines Knopfpaares,
obwohl dort nichts gespeichert wird - vom Eigentuemer richtiggestellt. Der
Name machte eine Pruefung unbrauchbar, die genau danach suchte. Jetzt trennt
.dm-knopfpaar (zwei gleich breite Knoepfe) von .dm-speicherleiste (dasselbe
Paar als klebende Leiste fuer ein Formular mit Speichern-Schritt).
"RS 6 Avant performance" ist aus der Modellauswahl entfernt; "RS 6 Avant"
stand bereits darin, die Ausfuehrung traegt der Nutzer selbst ein. Es war der
einzige Eintrag, der in der auf 180px vereinheitlichten Auswahl abgeschnitten
wurde. Ein Profil mit dem alten Wert behaelt ihn - die Auswahl stellt einen
nicht gelisteten Titel als eigene Option voran.
Nachgemessen am laufenden System: .dm-knopfpaar flex mit 12px Abstand und zwei
gleich breiten Knoepfen, .dm-speicherleiste weiterhin klebend; zehn Modelle,
laengster 115px bei 142px Platz.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Ohne feste Breite bemisst sich jedes Feld nach seinem eigenen Inhalt, die
rechte Kante steht fest, und die linken Kanten fransen aus: gemessen
216/202/195/206 in der App und 220/209/203/213 im Panel.
Jetzt 180px in beiden. Der Wert ist die engste Grenze beider Oberflaechen -
das laengste Label ("Erstzulassung") laesst in der App nur 183px fuers Feld,
im Panel 196px.
Vorbehalt: von elf Modell-Eintraegen ist einer laenger als der verbleibende
Textplatz ("RS 6 Avant performance", 182px gegen 142px) und wird ausgewaehlt
abgeschnitten. In der aufgeklappten Liste steht er vollstaendig.
Nachgemessen in beiden: vier Felder je 180px, gleiche linke Kante, kein Label
bricht um.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Einstellungen.tsx fuehrt fuer die Erstzulassung einen eigenen Entwurf neben
`entwurf`. Zwei Stellen kannten ihn nicht: speichern() stieg in der ersten
Zeile aus, und die Speicherleiste haengt allein an `entwurf` - wer nur die
Erstzulassung aenderte, bekam also gar keinen Speichern-Knopf zu sehen und
verlor den Wert beim Verlassen der Seite. Damit blieb auch die
Hauptuntersuchung leer, die daraus abgeleitet wird. Das Panel speichert an
dieser Stelle sofort und war nie betroffen.
Dazu:
* Platzhalter beider Felder war MM/JJJJ, obwohl ein voller Tag gemeint ist -
jetzt TT.MM.JJJJ. Die Monatsform bleibt lesbar, damit gespeicherte Werte
wie "08/2026" gueltig bleiben.
* Das Tagesmuster nimmt jetzt Punkt oder Bindestrich, in beiden Codebasen
wortgleich. "01-03-2025" ergab vorher still nichts. Unmoegliche Daten
werden weiterhin abgewiesen, die ISO-Form nicht verwechselt.
Geprueft am laufenden System ueber die ganze Kette: eintragen, speichern,
Profildatei, dann App-Service, Panel-Service und Panel-Mein-Audi mit
uebereinstimmend 15.06.2027. 299 Tests gruen, 0 Tracebacks.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Der Abstand zwischen Kachelueberschrift und erster Inhaltszeile war 0, 10 oder
12px, je nachdem ob das folgende Element einen eigenen oberen Rand mitbrachte.
Bei 0 klebte die Ueberschrift an der Zeile und las sich als deren Beischrift.
Jetzt einheitlich 14px, gesetzt am Kopf selbst - benachbarte Raender fallen
zusammen, vorhandene 10/12 werden also angehoben statt addiert, und absolut
gesetzte Nachbarn wie das Zahnrad bleiben unberuehrt. Nur die erste
Beschriftung einer Kachel: .label/.ads-eyebrow tragen auch Inhaltszeilen wie
die Anschrift des Autohauses, die bleiben unveraendert.
Der urspruengliche Auftrag lautete "Panel wie App setzen" und beruhte auf einer
Falschaussage von mir: ich hatte die 10px-Grossschrift aus dem Design-System
gelesen statt die App zu messen. Die App ueberschreibt sie dort absichtlich auf
den Panel-Wert; beide waren laengst identisch.
Dazu: _profil_aufraeumen() entfernt ausgemusterte Profilfelder einmalig beim
Start, Anlass ist fahrzeug.hauptuntersuchung_faellig. Ohne das bliebe der tote
Schluessel fuer immer stehen, weil beide Oberflaechen das Profil vollstaendig
zurueckschreiben. An der Testinstanz geprueft, einschliesslich zweitem Start
ohne Schreibvorgang.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Musterseite entfernt (companion-app/muster, vite.muster.config.ts,
/config/www/dmmuster). Ansage des Eigentuemers: sie fuehrt nur zu neuen
Fehlerquellen. Ausloeser war ein Befund, den ich als App-Fehler gemeldet hatte
- Ringe und Typenschild schwarz auf schwarz - und der nur dort bestand.
Behoben:
* Das Zahnrad im Autohaus-Kasten hatte seine Ecke verlassen (58/288 statt
8/8). Ursache war mein HIG-Durchgang von gestern: .zahnrad kam in die
Gruppe fuer die 44x44-Trefferflaeche und bekam damit position:relative,
was das absolute aus dem Basisblatt ueberschrieb. Die Auflage war
ueberfluessig - .zahnrad ist dort schon 44x44.
* Das Fotomenue hing mit position:absolute an der Kachel statt am
Bildschirm und lag bei der hohen Raeder-Kachel ausserhalb des Sichtfelds;
einen Abbrechen-Knopf hatte es nie. Das Panel benutzt jetzt dasselbe
Aktionsblatt wie die App. .bildmenu ist samt Zustand, Markup, totem
Handler und CSS entfernt.
* Der Blattkopf las sich als dritte Auswahl (linksbuendig, 15px, --fg).
Jetzt zentriert, 13px, gedaempft - Apples Muster, in beiden Codebasen.
* "Anstehende Termine" stand 5px ueber "Oelwechsel" und wirkte als dessen
Beischrift. Entfernt.
* Wartungsplan-Formular: Art nach oben, Datum 124px statt Browser-Vorgabe,
Werkstatt ueber die volle Zeile (218 -> 306px), Kosten 116px. Zwei
Erklaertexte entfernt.
* Thema folgt jetzt einer Systemumstellung im laufenden Betrieb. Vorher las
es prefers-color-scheme genau einmal beim Laden. Drei Tests, die ohne die
Behebung nachweislich fallen.
Geprueft: 295 App-Tests, Panel node --check, 0 Tracebacks, alle Aenderungen
live an der Testinstanz gemessen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>