# 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 F1–F4),
   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: **277–319 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).
