Files
audi-app/DESIGN_REVIEW_2026-08-13.md
Paul Nothaft 6230648f29 Design-Review des main-Stands gegen die Audi-CI-Vorgaben ablegen
Code-Review aller UI-Schichten plus Headless-Browser-Screenshots des
Panels mit Mock-hass. Kernbefunde: die iOS-Auflage ersetzt Palette,
Radien und die Rot-Semantik ohne dokumentierte Entscheidung; das
design-system traegt noch den Vor-Audit-Stand (fg3, Fokus, Feldgroessen);
vier im Browser nachgewiesene Darstellungsfehler. Nur Bericht, keine
Fixes.
2026-08-13 18:15:38 +02:00

259 lines
18 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Design-Review des `main`-Branch — Abgleich gegen die Audi-CI-Vorgaben des Repos
**Datum:** 2026-08-13 · **Gegenstand:** `origin/main` @ `2a3c4f2` („Zugangswege zum privaten
Repository dokumentieren und trennen") · **Nur Befunde, keine Änderungen.**
> Hinweis vorab: Das **lokale** `main` hängt 28 Commits hinter `origin/main`. Dieses Review
> basiert auf `origin/main` — der Stand mit FMM003-Umstellung, Setup-Menü, Standort-Feature und
> der scharf geschalteten iOS-/Großbildschirm-Auflage.
## Methode
1. **Vorgaben-Checkliste** aus den Repo-Dokumenten destilliert (`bauauftrag.md`,
`SPECIFICATION.md`, `AUDIT_2026-08-10.md`, `DESIGN_BRIEF_DATAMETRIC360.md`, `AGENTS.md`,
`design-system/`-Tokens) — Farben, Typografie, Layout, Marke, Formate, Interaktion, A11y.
2. **Code-Review** aller UI-Schichten auf `main` gegen diese Checkliste:
`homeassistant/www/` (Panel-JS + beide CSS), `design/`-Export, `design-system/`,
`companion-app/`.
3. **Browser-Test mit Screenshots:** Das Panel wurde in einem Harness mit Mock-`hass`-Objekt
und realistischen Beispieldaten (Beispielprofil, 5 Fahrten, 3 Tankvorgänge, Fahrzeugstatus,
Setup-Katalog) headless in Chromium gerendert — iPhone-Viewport (390×844, hell + dunkel) und
Desktop (1440×900, Großbildlayout ≥860 px), alle 5 Tabs plus 10 Unterseiten, Einstellungen,
Einrichten-Formular und Setup-Popup. ~40 Screenshots, Pfade im Annex.
**Grenzen:** Kein echtes Home Assistant, kein echtes iOS-Gerät. Native Steuerelemente
(`<input type="date">`) und Leaflet-Verhalten können im Harness abweichen — solche Befunde sind
unten ausdrücklich als „am Gerät verifizieren" markiert.
---
## Kernaussagen (TL;DR)
1. **Die iOS-Auflage (`audi-dashboard-ios.css`) ist der größte offene CI-Konflikt.** Sie ersetzt
die dokumentierte Audi-Palette durch iOS-Systemfarben, führt Schatten und Blur ein, ändert den
Kachelradius auf 16 px und macht Rot zur Flächenfüllung — alles Verstöße gegen in mehreren
Dokumenten wiederholte, bindende Regeln, und **nirgends als Entscheidung dokumentiert**
(`design/README.md` sagt selbst, das sei „noch zu klären", faktisch ist es seit 2026-08-11
produktiv).
2. **Die Rot-Semantik ist dadurch invertiert.** `ios.css` füllt jeden `.aktion`-Knopf rot. Sichtbare
Folge (Screenshots): im Setup-Popup ist **„Abbrechen" rot gefüllt und „Speichern" schwarz**;
„Einrichten", „Setup — Sensoren zuordnen", „In den Kalender übernehmen" und die
Notruf-/Telefonnummern sind großflächig rote Balken. Der Audit-Befund A7 („Rot bleibt Akzent
und Destruktiv") ist damit rückgebaut.
3. **`design-system/` (Basis für DataMetric360) trägt den Vor-Audit-Stand:** kontrastschwaches
`--fg3 #657081` (WCAG-AA-Fail, im Panel längst korrigiert), Versalien-Sperrschrift in 6+
Komponenten, **kein einziger Fokus-Stil in der ganzen Bibliothek**, Formularfelder 13,5 px
(iOS-Zoom-Falle), IconButton 34 px. Wer die App darauf aufbaut, erbt behobene Fehler zurück.
4. **Vier echte Darstellungs-/Zustandsfehler im Panel, im Browser nachgewiesen** (unten F1F4),
darunter gestreckte Schalter mit widersprüchlicher Zustandsanzeige (Ursache identifiziert:
`.feld label { flex: 1 1 auto }` trifft auch `label.switch`).
5. **Positiv:** Schriftgewichts-Regel (nur 300/400) wird zu 100 % gehalten, de-DE-Formate sind
praktisch lückenlos, `design-system/` ist nachweislich **marken-frei** (Lizenzregel bestanden),
die Marke steht auf jedem Layout genau einmal, und die neuen main-Features sind bei
aria-Attributen überdurchschnittlich sorgfältig.
---
## A. Grundsatzkonflikt: iOS-Auflage vs. Audi-CI (hoch)
Verbindlich laut `bauauftrag.md` §Design, `SPECIFICATION.md` §Design und Audit: Palette als
Rollen (Nacht `#161b23`/`#1f2733`, Tag `#FFFFFF`/`#f2f2f2`), Signalfarben `#15da15/#ffaa00/#fd2c4e`,
Kachelradius 20 px, **keine Schatten, keine Verläufe** (einzige Ausnahme Fahrbahn/`.szene`),
Rot `#F50537` nur als Akzent. Die seit 2026-08-11 aktive `audi-dashboard-ios.css` bricht das
systematisch:
| Regel | ios.css-Ist | Fundstelle |
|---|---|---|
| Nacht-Canvas `#161b23` | `#0C1014` | `audi-dashboard-ios.css:21-41` |
| Tag: Canvas weiß, Kachel `#f2f2f2` | **invertiert**: Canvas `#F2F2F7`, Kachel `#FFFFFF` | ebd. |
| Audi-Signalfarben | iOS-Systemfarben `#30D158/#FFD60A/#FF453A` bzw. `#34C759/#FF9F0A/#FF3B30` | ebd. |
| Kachelradius 20 px (`--r-tile`) | `--r-tile: 16px` | `audi-dashboard-ios.css:16` |
| Keine Schatten/Blur | `box-shadow` auf Segmented Control, Switch-Knopf, Popups; `backdrop-filter: blur()` auf Tabbar/Popups | `:116, :135, :156-166` |
| Rot nie als Fläche | `.aktion{background:var(--ios-tint)}`, roter Schalter, `.tab.on` rot hinterlegt | `:118-136, :221` |
| Safe-Area-Insets (Audit B1) | ersetzt durch Festwerte `padding:56px` / `26px` | `:65, :163` |
| Trefferfläche ≥44 px (Audit B6) | `.back` auf **34×34 px** gedrückt | `:69` |
Dazu kommt: `.setup-popup` und `.standortmenu` schreiben `border-radius: 20px` als **Literal**
fest (`audi-dashboard.css:895, :744`) — mit dem ios-Token 16 px sind Popups sichtbar runder als
alle Kacheln daneben.
**Empfehlungscharakter (keine Umsetzung hier):** Entweder die iOS-Optik als neue verbindliche
Linie dokumentieren (und `bauauftrag.md`-/`SPECIFICATION.md`-Regeln als ÜBERHOLT markieren, wie
es die Projektkonvention für Entscheidungen vorsieht) — oder die Auflage auf das zurückschneiden,
was mit der CI vereinbar ist. Der jetzige Zustand ist ein unbeschlossener Bruch.
## B. Rot-Semantik invertiert (hoch, visuell belegt)
- **Setup-Popup: „Abbrechen" rot gefüllt, „Speichern" schwarz** (Screenshot
`iphone-hell-15e-setup-popup.png`). Nach der eigenen Systematik (`.aktion` =
Umriss-Sekundäraktion, `.primaer` = gefüllt, Rot = destruktiv) liegt die Signalfarbe auf der
falschen Aktion.
- Gleiche Ursache (`ios.css .aktion`-Füllung) auf: „Einrichten" (Einstellungen), „Setup —
Sensoren zuordnen" + schwarzes „Fertig" daneben (Einrichten-Formular), „In den Kalender
übernehmen" (Service, Reifen), beide Notrufnummern (Versicherung — drei rote Großflächen
untereinander auf einer Seite, `iphone-hell-07-versicherung.png`).
- Ebenfalls rot gefüllt: alle Schalter im Ein-Zustand (A7-Rückbau), aktive Navigation
(`.tab.on` rosa hinterlegt, Desktop-Sidebar).
- Kleinere Fälle: `--red` als Balkensegment für die neutrale Kategorie „Arbeitsweg"
(`audi-dashboard-app.js:2423`) und im Versicherungs-Beitragsbalken (`:1628`).
## C. `design-system/` — Vor-Audit-Stand als DataMetric360-Basis (hoch)
| Befund | Fundstelle | Schwere |
|---|---|---|
| `--fg3: #657081` — der im Audit als kontrastschwach identifizierte Wert (3,0:1 auf `--tile`), im Panel seit 2026-08-10 auf `#8a94a3` korrigiert; Bibliothek **und** `design/_ds`-Bundle tragen ihn weiter | `design-system/src/tokens/tokens.css:33`, `design/_ds/.../_ds_bundle.css:20` | hoch |
| **Kein einziger Fokus-Stil** in Tokens + allen 20 Komponenten (Audit fordert `:focus-visible` 2 px `#F50537`; das Panel hat ihn) | gesamtes Paket, grep-verifiziert | hoch |
| Formularfelder **13,5 px** → iOS-Auto-Zoom (Audit-Regel ≥16 px); propagiert bis in den `design/`-Entwurf (Bundle-Regel gewinnt gegen `.dm-in`) | `Feld/Feld.css:24-33`; `DM360.dc.html:24/41/44/422-428` | hoch |
| Versalien-Sperrschrift in 6 Komponenten über die bekannten `.ads-label`/`.ads-eyebrow` hinaus; StatGrid/TabBar mit nur **9 px** | `ActionButton.css:7`, `Pill.css:6`, `Seg.css:14`, `SwipeRow.css:16`, `StatGrid.css:15`, `TabBar.css:39` | mittel |
| TabBar: aktiver Tab = **roter Oberkantenstrich** statt gefüllter Pille — exakt das Muster, das der Audit (B5) im Panel abgeschafft hat | `TabBar.css:22-24` | mittel |
| Trefferflächen: IconButton 34×34, Switch 46×27, Popup-Items ≈34 px, Seg ≈35 px | jeweilige Komponenten-CSS | mittel |
| Literalfarben (`#fff` auf Switch-Knopf und SwipeRow) | `Switch.css:35`, `SwipeRow.css:11` | niedrig |
| Englischer Default-UI-Text `deleteLabel = "Delete"` | `SwipeRow.tsx:27` | niedrig |
| **Positiv: Markenreinheit bestanden** — keine Fonts/Ringe/Typenschilder im Paket (Lizenzregel eingehalten); keine Gewichte ≥500, keine Schatten, Radius über Token | — | ✓ |
## D. `design/`-Export (mittel)
- **Der RS-6-Fehler reicht bis in die Fachdaten**, nicht nur Badge/Name: „V8 biturbo · 600 PS",
441 kW, 3.996 cm³, 2.150 kg, Tank **73 l** (RS 4: 58 l), Reifen **285/30 R22**, FIN-Baureihe
„4G" statt „8W" (`DM360.dc.html:116-628` diverse). Die korrekten RS-4-Schilder liegen bereits
unter `design/uploads/RS-S Badges/` — nur `assets/` enthält die RS-6-Kopien.
- **`design/datametric360-ios.css` und `homeassistant/www/audi-dashboard-ios.css` sind divergente
Geschwister**, keine Kopien: der `.ads`-Variante fehlen Fokusring, gefüllte Tab-Pille (sie färbt
stattdessen das Icon rot) und das komplette ≥860-px-Layout; die Panel-Variante hat dafür die
Schatten. Zwei Wahrheiten für dieselbe Optik → Drift vorprogrammiert.
- **Einstellungen-Einstieg widersprüchlich:** Entwurf + `DESIGN_BRIEF` sagen Zahnrad oben rechts,
Panel/`SPECIFICATION` sagen Audi-Ringe (Zahnrad erst ≥860 px). Vor der App-Umsetzung entscheiden.
- IconButton-Hints 36 px (`DM360.dc.html:78, 90`); variable Audi Type mit `font-weight: 100 900`
registriert (lädt zur Verletzung der 300/400-Regel ein, genutzt werden nur 300/400);
Literalfarben/Schatten im Präsentationsrahmen (nur Board, nicht App-UI).
- `companion-app/` auf `main` ist nur die Datenschicht; der dort noch offene Feldnamen-Defekt
(`tank_prozent`/`sicher_abgestellt`/`sicherheit` vs. Backend) ist auf dem Arbeitsbranch behoben
und löst sich beim Merge — bis dahin auf `main` latent.
## E. Panel-Frontend: weitere Verstöße gegen die Vorgaben (Auswahl)
**Farben nur als Tokens:**
- **iOS-Systemblau `#0A84FF`** als palettenfremde Farbe für den Nutzer-Pin
(`audi-dashboard.css:702, :707`) — Blau existiert in der Palette nicht. (hoch)
- Kartensteuerung komplett aus Literalen (`rgba(16,20,26,.84)`, `#fff`, `#101418`;
`audi-dashboard.css:722-734`), Leaflet-Startmarker `#fff`/`#000`
(`audi-dashboard-app.js:459`), Scrims 2× `rgba(0,0,0,.45)` ohne Token. (mittel/niedrig)
**Typografie:**
- **Zweite und dritte Versalien-Stelle** neben `.eyebrow`: `.setup-gruppe-titel` (uppercase,
.1em — im Setup-Popup sichtbar) und `.marke-logo .ph` (`audi-dashboard.css:913, :481`). (mittel)
- Die selbst gesetzte Regel „`--fg3` nie unter 12 px" wird an ≥7 Stellen gebrochen
(`.sync` 10,5 px, `.quad .l` 11 px, `row dd small` 11,5 px, mehrere Inline-11-px;
Kontrast 4,6:1 ist unter der WCAG-Großtext-Schwelle für so kleine Schrift). (mittel)
**Layout/A11y:**
- Schatten/Blur auch im **Haupt-CSS** (nicht nur ios.css): Pins, Kartensteuerung
(+`backdrop-filter`), Standortmenü, Setup-Entitätenliste (`audi-dashboard.css:697-745, :950`). (mittel)
- Trefferflächen <44 px bei neuen Elementen: Standortmenü-Schließen 32 px,
Setup-Reset 26 px, Fahrtart-Pille ≈31 px, `.rings` im Basis-CSS nur 42×24 px (erst ios.css
hebt an — ohne geladene Auflage ist der einzige Einstellungszugang zu klein). (mittel)
- Bei ausgeschalteter Tab-Beschriftung sind **alle fünf Tabs namenlos** (Text per
`display:none`, SVG `aria-hidden`, kein `aria-label`; `audi-dashboard-app.js:3072-3074`,
`audi-dashboard.css:266`). (mittel)
- Escape schließt Sheet und Setup, aber nicht Bildmenü/SmartDeal-Popup/Standortmenü. (niedrig)
- Koordinaten als einzige nicht-de-DE-Zahl im UI (`toFixed(4)` mit Punkt,
`audi-dashboard-app.js:786-789`). (niedrig)
**Auf `main` bereits behoben** (bekannte Befunde, die nicht mehr gelten): die Ringe sind
inzwischen ein echter `<button aria-label="Einstellungen">`, und das Setup-Popup **hat** Fokusfalle
+ Escape (`audi-dashboard-app.js:3054-3070`) — die Einträge in `REVIEW_main_2026-08-13.md` §7.10/6.13
sind insoweit überholt (Rest: Trefferfläche).
## F. Im Browser nachgewiesene Darstellungs-/Zustandsfehler
**F1 — Schalter werden gestreckt und zeigen widersprüchlichen Zustand (Ursache identifiziert).**
`audi-dashboard.css:493` `.feld label { flex: 1 1 auto }` trifft auch `label.switch` — der Schalter
in einer `.feld`-Zeile wächst mit dem freien Platz (gemessen: **277319 px statt 51 px** im
Desktop-Einrichten-Formular; auch am iPhone auf der Reifen-Seite sichtbar verbreitert). Da der
Knopf fix um `translateX(20px)` wandert, steht er auf der gestreckten Bahn optisch **links
(= „Aus"), obwohl die Bahn rot (= „Ein") ist**. Screenshots `desktop-hell-14-einstellungen.png`,
`iphone-hell-08-reifen.png`. (hoch — Zustandsanzeige mehrdeutig)
**F2 — Offene Fahrten zeigen zweimal „offen" untereinander.** In der Fahrtenliste rendert der
Wert-Slot `"offen"` und das `<small>` darunter `t.status` = „offen"
(`audi-dashboard-app.js:2275`). Screenshot `iphone-hell-09-trips.png`. (niedrig)
**F3 — Ölwechsel-Kachel der Übersicht bleibt komplett leer** bei leerem Servicebuch: `termine()`
baut nur auf Servicebuch-Einträgen auf (`audi-dashboard-app.js:1522-1534`); ohne Eintrag sind
`km`/`datum`/`kmDatum` null und die Kachel zeigt **nur das Label ohne jeden Wert** — kein
Leerzustand nach der eigenen D5-Regel („Ursache und nächste Handlung nennen"), und die vom
Fahrzeug gemeldeten Fälligkeiten (`oelwechsel_faellig_ts/km` waren im Test gesetzt) werden auf
der Übersicht nicht herangezogen. Auch die Service-Seite zeigt daneben nur „kein Eintrag im
Servicebuch". Screenshots `iphone-hell-01-home.png`, `iphone-hell-06-service.png`. (mittel)
**F4 — Alle drei Leaflet-Karten rendern im Harness nur fragmentarisch** (Übersichts-Kachel,
Standort-Vollbild, Einzelfahrt/Beleg): Kacheln erscheinen nur in Teilbereichen, der Rest bleibt
canvas-farbig — unverändert auch nach 4 s Wartezeit, also kein Ladeproblem, sondern
Initialisierungs-/`invalidateSize`-Timing (Karte wird aufgebaut, bevor der Container seine
endgültige Größe hat). **Am echten HA/Gerät verifizieren** — falls dort reproduzierbar, ist es
der sichtbarste Fehler der neuen Standort-Features. Screenshots `iphone-hell-02b-standort-lang.png`,
`desktop-hell-01-home.png`, `iphone-hell-10-trip-detail.png`. (verifizieren)
**Weitere Beobachtungen (verifizieren, evtl. Harness-Artefakte):**
- Native Datumsfelder zeigten `mm/dd/yyyy` (Werkstatttermin, Reifenwechsel) — `<input type=date>`
formatiert nach System-Locale; am deutschen iPhone vermutlich korrekt, auf Desktop-Browsern mit
englischer UI nicht. Kein Codefehler, aber ein bekannter Plattform-Seiteneffekt.
- FIN-Wert im Einrichten-Formular rechts abgeschnitten ohne Ellipse
(`iphone-hell-15-setup.png`).
- Im Desktop-Layout wirkte der Fahrzeugbild-Platzhalter der Übersicht gestaucht
(Beschriftung ragt an die Kachelkante, `desktop-hell-01-home.png`).
## G. Was konsequent eingehalten wird (positiv)
- **Schriftgewichte:** kein einziges `font-weight` ≥500 in ~5.300 Zeilen Panel-Code; alle
`<strong>`-Kontexte bewusst auf 400 neutralisiert; `tabular-nums` global. Auch design-system
und Entwurf nutzen nur 300/400.
- **de-DE-Disziplin:** zentrales `de()/eur()/dedat()`-Trio, jeder Locale-Aufruf explizit
`"de-DE"`, ISO nur wo die Plattform es verlangt; im Entwurf durchgehend deutsche Texte und
Formate. Einzige Grauzone: Koordinaten (E, niedrig).
- **Marke:** Typenschild exakt 18 px mit CSS-Theme-Wechsel (positive/negative-SVG); Marke steht
in jedem Layout genau einmal (Ringe mobil, `.navmarke` in der Desktop-Sidebar + Zahnrad);
`design-system/` nachweislich asset-frei — die harte Lizenzregel wird eingehalten.
- **A11y der neuen Features:** Kartensteuerung mit präzisen `aria-label` + `aria-pressed`,
Standortmenü-Griff mit `aria-expanded/-controls` und 88×44-px-Trefferfläche, Setup-Dialog mit
`role="dialog"`, Fokusfalle und Escape; 16-px-Formularregel im Panel konsequent (inkl. neuem
Combo-Input).
- Ehrliche Leerzustände („kein Eintrag im Servicebuch", „Fahrt ohne Ortsangabe", Startort
„unbekannt") statt erfundener Werte — mit Ausnahme F3.
## H. Widersprüche in den Vorgaben selbst (fürs Aufräumen der Dokumente)
1. `--fg3` hat **drei Werte im Repo**: `#657081` (bauauftrag, design-system, \_ds-Bundle) vs.
`#8a94a3` (SPECIFICATION, Panel) — der Audit hat nur SPEC nachgezogen.
2. Kontrastangabe inkonsistent: CSS-Kommentar sagt „4,6:1", der Audit rechnet 5,6:1/4,9:1.
3. `SPECIFICATION.md` ist bei Platzhaltern (nennt noch „exact expected filename", vom Audit
abgeschafft) und bei `confirm()`/Action-Sheet (B4) veraltet; §7.8 behauptet, `--sp-*`/`--r-func`
existierten nicht — sie existieren, werden aber (das stimmt) teils nicht genutzt.
4. `DESIGN_BRIEF` (Zahnrad, Live-Telemetrie) widerspricht `bauauftrag.md`/`SPECIFICATION.md`
(Ringe, „keine Live-Telemetrie"); Auflösung über FMM003 ist nirgends explizit festgehalten.
5. Bildmaße: `bauauftrag.md` nennt 206/165/78 px, der Code nutzt aspect-ratio + 96 px — Absicht
erfüllt, Zahlen nie als überschrieben dokumentiert.
## Zählung (konsolidiert, ohne Doppelzählung der Sammelthemen)
| Bereich | hoch | mittel | niedrig | verifizieren |
|---|---|---|---|---|
| A/B iOS-Auflage + Rot-Semantik | 2 Themenkomplexe (≥10 Einzelstellen) | — | — | — |
| C design-system | 3 | 3 | 2 | — |
| D design/-Export | — | 4 | 3 | — |
| E Panel-Einzelbefunde | 1 | 8 | 6 | — |
| F Browser-Nachweise | 1 | 1 | 1 | 4 |
## Annex: Screenshots
Liegen (sitzungsgebunden, nicht im Repo) unter
`/private/tmp/claude-501/-Users-paul-Development-audi-app/a6c2c477-dbf4-43ec-9a25-88d762b653bf/scratchpad/harness/shots/`.
Benennung: `iphone-hell-*` (390×844 hell), `iphone-dunkel-*`, `desktop-hell-*` (1440×900).
Harness: `…/scratchpad/harness/` (`index.html` = Mock-`hass`, `shots*.mjs` = Playwright-Läufe,
`profil.json` = Beispielprofil) — reproduzierbar gegen jeden Stand von `homeassistant/www/`.
Aussagekräftigste Belege: `15e-setup-popup` (Abbrechen rot/Speichern schwarz),
`14-einstellungen` + `desktop-14` (rote Flächen, gestreckte Schalter), `07-versicherung`
(3 rote Großflächen), `08-reifen` (Schalter-Zustand mehrdeutig), `09-trips` (doppeltes „offen"),
`01-home` (leere Ölwechsel-Kachel, Kartenfragment), `02b-standort-lang` (Kartenfragment nach 4 s).