Zuletzt aktualisiert:

Frontend-Audit: Silverscale als iPhone-App

Datum: 07.06.2026 · Stand: v1.7 (nach ADR-40, Capacitor-Hülle live auf Dennis' iPhone) Annahme: Die Capacitor-iOS-App wird der primäre Nutzungsweg – für Dennis und (bald) Jaqueline. Anspruch: Die App soll sich wie eine echte, hochwertige iOS-App anfühlen. Die Nutzerin weiß nicht, dass darunter eine Website läuft – und soll es auch nie merken. Scope: Nur Audit + Plan, kein Code geändert.

Methodik: Code-Review des kompletten Frontends (app/frontend/src, 23 Svelte-Dateien, ~6 200 Zeilen) und der Capacitor-Hülle (app/ios-shell), drei unabhängige Analyse-Durchläufe (Native-Illusion, UX-Flows, Design/A11y), plus frischer Screenshot-Sweep aller 16 Routen (iPhone-Viewport 390×844, hell + dunkel, Chromium). Befunde wurden gegen die Screenshots verifiziert; nicht verifizierbare Punkte sind als (prüfen) markiert. Einschränkung: Der Sweep lief in Chromium, nicht in WKWebView – echte Geräte-Eigenheiten (Keyboard, Rubber-Banding, Swipe-Back) sind aus Code + iOS-Doku abgeleitet.


1. Executive Summary

Silverscale ist als Web-App bemerkenswert gut gebaut: durchdachtes OKLCH-Token-System mit sauberem Dark Mode, Bottom-Sheets mit History-Integration, Safe-Area-Handling, 16-px-Inputs gegen iOS-Zoom, prefers-reduced-motion, Undo-Toasts im Tagebuch, ein cleverer Geräte-Code-Login für die WKWebView. Das Fundament stimmt – hier ist in den letzten Wochen sichtbar viel richtig gemacht worden.

Als „native iOS-App" gemessen, fällt sie aber an den Rändern auf – und genau die Ränder entscheiden über den Wife-Acceptance-Factor:

  1. Verpackung verrät alles, bevor die App überhaupt offen ist. App-Icon und Splash-Screen sind noch das Default-Capacitor-Logo (blaues X auf weißem Grid). Das ist das Erste, was Jaqueline auf ihrem Homescreen sieht – und der billigste Illusionsbruch der gesamten Liste.
  2. Die App hängt zu 100 % am Netz – verhält sich aber nicht so. Remote-Modus heißt: jeder Tap ist ein Internet-Roundtrip. Es gibt aber keinen Retry, kein konsistentes Optimistic-UI mit Rollback, keine Lade-Skeletons und beim Offline-Kaltstart eine weiße Wand bzw. einen WKWebView-Fehler. Im Lidl-Funkloch beim Abhaken der Einkaufsliste wird das real.
  3. Touch-Semantik ist Web, nicht iOS. Long-Press öffnet Textlupe/Kopieren-Menü, Hover-Stile kleben nach dem Tippen, kein Swipe-Back zwischen Seiten, kein haptisches Feedback, Scroll-Physik ohne Bounce. Externe Links (Garmin, OpenFoodFacts) kapern die WKWebView – die App „wird" plötzlich garmin.com, ohne Zurück-Knopf.
  4. Die App weiß nicht, dass sie eine App ist. Die Einstellungen zeigen in der nativen App die PWA-Anleitung „Teilen → Zum Home-Bildschirm" für Push – ein Text, der in der App falsch und verwirrend ist (und Web-Push geht in der WKWebView ohnehin nicht).

Nichts davon ist ein Architekturproblem. Es ist konzentrierte Randarbeit: Phase 0 („Jaqueline-Gate", ~1 Arbeitstag) macht die App rollout-fähig, zwei weitere Phasen heben sie auf echtes Native-Niveau. Detailplan in §6.

Gesamtnote als Web-App: sehr gut. Als iOS-App heute: befriedigend mit klarem, kurzem Weg zu sehr gut.


2. Zusammenfassung in einfachen Worten

Stell dir vor, Jaqueline bekommt nächste Woche die App aufs iPhone. Was passiert?

Jeder Punkt für sich ist klein. Zusammen entscheiden sie, ob die App „die tolle App von Dennis" oder „die komische Bastel-App" wird. Die gute Nachricht: Das Innere stimmt schon – es geht fast nur um die Hülle, das Verhalten bei schlechtem Netz und ein paar Touch-Details. Das meiste davon ist in einem konzentrierten Tag erledigt.


3. Was bereits richtig gut ist

Damit der kritische Teil die Proportionen nicht verzerrt – diese Dinge sind auf oder über 2026-Niveau:

Was Beleg
Design-Token-System: OKLCH-Palette, semantische Tokens, Spacing-/Radius-Skala, zentrale Schatten app.css:6–107
Dark Mode: eigene Token-Overrides, Theme-fähige theme-color-Meta, im Sweep durchweg lesbar (auch Hero/Ring – ein Agent-Verdacht „weißer Text unsichtbar" hat sich nicht bestätigt) app.css:110–144, Screenshots unten
Sheet-Architektur: Bottom-Sheet mobil / Dialog am Desktop, History-Back schließt das oberste Sheet (Stack-Logik nach Bugfix 07.06.), Escape, role="dialog" Sheet.svelte
iOS-Grundlagen: env(safe-area-inset-*) in Header/Bottom-Nav/Sheets, 16-px-Inputs gegen Auto-Zoom, -webkit-tap-highlight-color, playsinline im Scanner, prefers-reduced-motion app.css, ScanSheet.svelte
Undo-Kultur (angefangen): Tagebuch-Löschen mit „Rückgängig"-Toast, ConfirmDialog statt window.confirm Diary.svelte:81–86, stores.js:47–59
Geräte-Code-Login (ADR-40): pragmatische, saubere Lösung für das WebAuthn-Problem der WKWebView backend/auth.py, Settings
Frische-Logik: Visibility-Refresh für den Wir-Modus, adaptives AI-Polling, Offline-/Online-Toasts stores.js:65–82, 165–192
Typografie: Fraunces als Charakter-Font, Inter Tight als Arbeitsfont, tabular-nums für alle Zahlen app.css:53–56, 178

Heute hell und dunkel Heute-Ansicht (hell). Hero-Ring, Makros, Fitness-Karten – dichte, aber klare Hierarchie.

Heute dunkel Dieselbe Ansicht im Dark Mode: Kontraste halten, Token-Overrides greifen.


4. Detailbefunde

Schweregrade: 🔴 kritisch (bricht Illusion oder kostet Daten) · 🟠 mittel (fällt im Alltag auf) · 🟡 klein (Polish).

4.1 Verpackung & Identität der Hülle

F1 🔴 App-Icon und Splash sind das Default-Capacitor-Logo. ios-shell/ios/App/App/Assets.xcassets/ enthält unverändert AppIcon-512@2x.png und splash-2732x2732.png mit dem Capacitor-X. Das ist der erste und nachhaltigste Eindruck auf dem Homescreen – noch vor jedem Pixel der eigentlichen App. Fix: 1024er-Icon (🐟-Branding, maritimer Verlauf aus --ss-grad-depth) + Splash in --ss-bg mit zentriertem Logo; cap sync, IPA neu bauen (der eine IPA-Rebuild, der sich wirklich lohnt).

Default-Capacitor-Icon Ist-Zustand: Dieses Icon liegt aktuell auf dem Homescreen.

F2 🔴 Offline-/Fehler-Kaltstart = weiße Wand. Remote-Modus: server.url zeigt auf die Domain, www/index.html ist ein Platzhalter mit einem Satz Text, der Service Worker cacht bewusst nichts (ADR-17). Startet die App ohne Netz (Flugmodus, Keller, Funkloch), zeigt WKWebView eine leere/Fehler-Ansicht ohne Branding und ohne „Nochmal versuchen". Fix-Idee: lokale Fallback-Seite in www/ (Logo, „Keine Verbindung", Retry-Button der auf die Domain redirected) – Capacitor lädt sie zwar nicht automatisch bei Remote-Fehlern, aber ein kleines errorPath-/AppDelegate-Handling bzw. minimaler App-Shell-Cache im SW sind beide gangbar. Entscheidung nötig (→ Offene Frage 3).

F3 🟠 Landscape ist freigeschaltet, aber nicht designt. Info.plist erlaubt Portrait + beide Landscape-Richtungen. Kein einziges Layout (Bottom-Nav-Höhe, Sheets mit 88dvh, Safe-Area-„Ohren" der Dynamic Island, fehlende safe-area-inset-left/right) ist für Landscape gedacht oder getestet. Empfehlung: Portrait-Lock – eine Zeile Info.plist, eliminiert eine ganze Fehlerklasse. Native Food-Tracker (Yazio, MyFitnessPal) sind ebenfalls portrait-only.

F4 🟠 Statusbar/Start-Übergang unkonfiguriert. Kein @capacitor/status-bar/splash-screen-Plugin: Die Statusbar-Färbung hängt allein an der Web-theme-color, der Übergang Splash → geladene Remote-Seite ist ein weißer Blitz (auf Mobilfunk auch mal 1–3 s). Fix: Splash-Hintergrund = --ss-bg, StatusBar-Style passend zum Theme, SplashScreen erst nach bootstrap-Antwort ausblenden (SplashScreen.hide() aus dem Frontend, guarded per Capacitor-Detection).

4.2 Touch & Gesten – wo das Web durchschimmert

F5 🔴 Long-Press öffnet Textlupe und Kopieren-Menü. Nirgendwo -webkit-user-select: none / -webkit-touch-callout: none auf UI-Chrome (Buttons, Chips, Nav, Karten-Titel, Zahlen). Long-Press auf irgendein Label → iOS-Textauswahl mit Lupe. Der zuverlässigste „Das ist ja eine Webseite!"-Moment überhaupt. Fix: global user-select: none auf interaktiven Elementen + gezielt user-select: text dort, wo Kopieren gewollt ist (z. B. Bon-Summen, EANs).

F6 🟠 Hover-Stile kleben auf Touch. :hover-Regeln (App.svelte:214, Stepper, Listenzeilen, .x:hover u. v. m.) feuern auf iOS beim Tap und bleiben bis zum nächsten Tap stehen. Fix: alle Hover-Stile in @media (hover: hover) einhausen; auf Touch stattdessen :active-Zustände (die .btn:active-Scale existiert schon, gilt aber nicht für Listen/Chips/Nav-Items).

F7 🟠 Kein Swipe-Back. Seitenwechsel gehen nur über Buttons/Tabs; die iOS-Kerngeste „vom linken Rand zurückwischen" tut nichts (in WKWebView standardmäßig deaktiviert). Da das Routing History-basiert ist (Hash + Sheet-pushState), würde allowsBackForwardNavigationGestures = true im AppDelegate Swipe-Back für Seiten und Sheets quasi gratis aktivieren. Einmaliger IPA-Rebuild (mit F1 bündeln). (Auf Geräte-Verhalten mit dem Sheet-Stack testen.)

F8 🟡 Kein haptisches Feedback. Eintragen, Abhaken, Löschen, Favorit – alles stumm. Native iOS-Apps quittieren Kernaktionen mit dezenter Haptik. Capacitor-Bridge ist im Remote-Modus verfügbar → @capacitor/haptics (guarded: nur wenn Capacitor.isNativePlatform()), an ~6 Stellen (Essen geloggt, Liste abgehakt, Undo, Scan-Treffer) reicht völlig.

F9 🟡 Scroll-Physik fühlt sich „tot" an. overscroll-behavior-y: none global (app.css:156) unterbindet das iOS-typische Rubber-Banding. Verständlich als Pull-to-Refresh-Schutz fürs Web – aber in der App ist federloses Scrollen ein subtiler Fremdkörper. Option: Bounce zulassen und kontrolliertes Pull-to-Refresh anbieten (Heute/Tagebuch/Liste wären natürliche Kandidaten, ersetzt zudem den „unsichtbaren" Visibility-Refresh). → Offene Frage 4.

F10 🟡 Touch-Targets teils unter 44 pt. Profil-Avatare 38 px (App.svelte:189), Sheet-Schließen-✕ ohne Mindestmaß (Sheet.svelte:76), kleine Chips (app.css:206). Die Einkaufslisten-Checkbox ist via ::before-Inset vorbildlich vergrößert – dieses Muster konsequent überall anwenden.

4.3 Netz & Robustheit – Remote-Modus heißt: alles ist Internet

F11 🔴 api.js ohne Retry, Fehlermeldungen technisch. Ein fetch, ein Wurf: Bei Timeout/5xx/Abbruch erscheint „Fehler: 503" o. ä. (api.js:16–26) – kein automatischer Retry (auch nicht für idempotente GETs), kein freundlicher Text, kein „Nochmal"-Button im Toast. Auf Mobilfunk ist ein verlorenes Paket Normalbetrieb, kein Ausnahmefall. Fix: 1–2 Retrys mit Backoff für GETs; für Schreibzugriffe Fehlertext in Menschensprache + Retry-Action im Toast.

F12 🟠 Optimistic-UI inkonsistent, teils ohne Rollback. Drei Muster nebeneinander: Tagebuch-Löschen optimistisch mit Undo (gut) · Einkaufslisten-Haken optimistisch ohne Rollback bei Fehler (ShoppingList.svelte:51–56 – Haken bleibt falsch stehen) · Plan-Eintrag-Löschen mit Server-Roundtrip ohne Undo (Plan.svelte:85). Fix: ein Standard-Pattern (optimistisch + Rollback + ggf. Undo) als Helper, überall anwenden.

F13 🟠 Keine Lade-Skeletons, Layout springt. Seiten-/Profilwechsel rendern erst nach dem API-Roundtrip; bei Mobilfunk-Latenz gibt es leere Karten, springende Ringe und Verschiebungen (Today.svelte:25–30, Plan.svelte:51). Fix: leichte Skeleton-Zustände (Ring-Platzhalter, 3 graue Zeilen) – gefühlte Performance ist auf dem iPhone wichtiger als reale.

F14 🟡 Rückkehr aus dem Hintergrund > 30 min = harter location.reload(). stores.js:75 – gewollt für frische Bundles, aber in der App sieht das nach „App startet neu" aus (weiße Wand auf Mobilfunk). Milder: Reload nur bei tatsächlich neuer Frontend-Version (Build-Hash-Endpoint), sonst Daten-Bump.

F15 🟡 Foto-Logging ohne Bestätigung. Foto-Schnelleintrag lädt direkt hoch, die KI schätzt und bucht ein (FoodSheet.svelte, Toast „Die KI schätzt …"); beim Barcode-Scan gibt es das Ergebnis-Popup (ADR-24), beim Foto nicht. Falsch erkannte Mahlzeit landet kommentarlos im Tagebuch → Vorschau-/Korrektur-Schritt analog Scan-Popup.

4.4 Wife-Acceptance-Factor: Alltag, Verständlichkeit, Vertrauen

F16 🔴 Externe Links kapern die App. target="_blank" (Garmin-Connect-Link Diary.svelte:172, OFF-Links Article.svelte:189, Aktivitäts-Links) öffnet in der WKWebView im selben Fenster: Die App „verwandelt sich" in garmin.com – ohne App-Chrome, ohne Zurück. Einzige Rettung: App killen. Fix: zentraler Link-Handler – in der App via window.open-Intercept/@capacitor/browser als In-App-Safari-Sheet (SFSafariViewController, fühlt sich nativ an), im Web weiterhin _blank.

F17 🔴 Einstellungen sprechen Web-Sprache in der App. Der Push-Hinweis „Seite über Teilen → ‚Zum Home-Bildschirm' installieren" (Settings.svelte:146) erscheint genauso in der Capacitor-App – wo es weder „Teilen" noch eine sinnvolle PWA-Installation gibt und Web-Push prinzipbedingt nicht funktioniert. Für eine Nutzerin, die nicht weiß, dass es eine Website ist, ist dieser Text ein direkter Bruch. Fix: App-Erkennung (UA SilverscaleApp ist schon da!) → in der App diesen Block ersetzen („Mitteilungen kommen aufs gekoppelte Gerät" o. ä.) – und grundsätzlich die Benachrichtigungsstrategie klären (→ Offene Frage 1). Auch der „📱 Geräte-Login"-Block gehört in der App versteckt (man ist ja schon drin).

Einstellungen mit PWA-Hinweis Einstellungen: Der gelbe Hinweis-Block erklärt PWA-Installation – in der nativen App falsch. Gut dagegen: Profile, Budget und Geräte-Login klar strukturiert.

F18 🟠 Profil-Switcher: leise, folgenreich, nur Emoji. Zwei Emoji-Avatare im Header (App.svelte:89–100), kein Name, kein Wechsel-Feedback – die gesamte App (Tagebuch! Budget!) wechselt still den Kontext. Klassischer Multi-User-Unfall: versehentlich im falschen Profil tracken und es abends merken. Fix: aktiven Namen anzeigen (oder Toast „Du trackst jetzt als Jaqueline 🐠"), deutlicherer Aktiv-Zustand, evtl. Akzentfarbe pro Profil.

F19 🟠 Sheets verwerfen Eingaben ohne Rückfrage. Backdrop-Tap, ✕ oder Zurück-Geste schließen Sheets sofort – halb ausgefüllte Portionen/Custom-Einträge sind weg (Sheet.svelte, FoodSheet.svelte). Fix: Dirty-Flag pro Sheet; bei Eingaben ConfirmDialog „Eingaben verwerfen?".

F20 🟠 Onboarding-Lücken für die zweite Nutzerin. Makro-Ziele sind optional und unbeworben (Ring zeigt dann nur kcal, ohne Hinweis warum), leere Tagebuch-Tage zeigen vier stumme „+ eintragen"-Buttons statt einer Einladung, der erste Einstieg (Geräte-Code von Dennis' Gerät holen) braucht Anleitung. Kein Blocker, aber der erste Eindruck entscheidet. Fix: dezente Hinweis-Chips („Makro-Ziele festlegen →"), ein einladender Empty-State im Tagebuch, Mini-Checkliste für den Ersteinrichtungstag.

F21 🔴 (operativ, nicht Frontend) SideStore-Ablauf = App plötzlich tot. Verpasster 7-Tage-Refresh → App startet kommentarlos nicht mehr. Größte einzelne WAF-Bombe überhaupt, weil sie nach gelungener Einführung explodiert. Gehört nicht zum Frontend, muss aber im Plan stehen: 14.06.-Check ernst nehmen, Refresh-Routine für Jaquelines Gerät definieren, ggf. PWA als dokumentierter Fallback („wenn die App nicht startet, nimm das Lesezeichen").

4.5 Design-System, A11y, Konsistenz-Polish

F22 🟠 Zwei Icon-Sprachen in einer Navigation. Haupt-Tabs: feine SVG-Strokes. „Mehr"-Menü + Desktop-Sidebar: bunte Emojis (🫀🛒🪸📦🧾📈⚙️). Der Stilbruch passiert genau beim Öffnen des Mehr-Sheets. Emojis als Inhalts-Sprache (Profile, Mahlzeiten ☀️🌙, Metriken) sind charmant und dürfen bleiben – als Navigations-Icons wirken sie neben den SVGs unentschieden. Fix: 7 SVG-Icons im Stil der Haupt-Tabs nachziehen.

F23 🟠 A11y-Basics mit Lücken. Gut: focus-visible, aria-label auf Avataren/✕, role="dialog"/alertdialog. Fehlt: Focus-Trap + Focus-Return in Sheets (VoiceOver entkommt in den Hintergrund), aria-live für Toasts und KI-Status (dynamische Änderungen bleiben stumm), Labels auf Favoriten-Sternen (Articles.svelte:93) und einigen Emoji-Buttons. Mit VoiceOver ist die App aktuell nur teilweise bedienbar – für 2026 ein Soll, kein Kann.

F24 🟡 Token-Treue ~90 %, Rest Wildwuchs. Hartkodierte Farben mit Dark-Mode-Risiko (#3a2c00 auf Amber-Chips in Articles.svelte/Receipt.svelte, NutriChip-Paare, rgba()-Schatten in Activity.svelte:595), Inline-margin-Pixel statt --ss-space-*, @keyframes sonar dreifach kopiert (App/Dish/Stats), .row-Listenmuster fünffach leicht unterschiedlich. Nichts davon sichtbar kaputt – aber jede künftige Theme-Änderung stolpert darüber.

F25 🟡 Seitenwechsel sind harte Schnitte. Hash-Routing tauscht <main> instantan; zusammen mit Lade-Roundtrips wirken Wechsel abrupt (Web-Feeling). Schon ein 150-ms-Crossfade ({#key $route.page} + fade) plus Skeletons (F13) erzeugt App-Gefühl; echte Push-Transitions wären Kür.

F26 🟡 Statistik-Charts im Sweep leer. (prüfen) Im Screenshot rendert „Ausgaben pro Monat" als leere Fläche (nur Ø-Zeile), auch der kcal-Verlauf bleibt blass. Kann ein Screenshot-Timing-Artefakt sein (Canvas/Animation) – auf dem Gerät verifizieren; falls echt, ist die Statistik-Seite de facto leer.

Statistik Statistik im Audit-Sweep: leere Chart-Flächen (prüfen), Top-Produkte-Liste dagegen stark.

Screenshot-Galerie (weitere Kernseiten)

Tagebuch Tagebuch: klare Mahlzeiten-Struktur, Quell-Badges, Undo beim Löschen – die stärkste Seite der App.

Wochenplan Wochenplan: HF-Box-Integration, „einplanen"-Flow. Lange Scroll-Strecke; gegessen-Status gut sichtbar.

Gerichte Gerichte-Galerie: Foto-Grid mit HF-Kennzeichnung – wertig. Karten-Tap-Flächen großzügig.

Gericht-Detail Gericht-Detail: Zutaten mit Vorrats-Punkten, Schritt-Anleitung mit Bildern, „Essen loggen"-CTA.

Einkaufsliste Einkaufsliste: „Aus Wochenplan", Preisschätzung, 1-Klick-Zuletzt-verwendet. Hier zählt Offline-Robustheit (F11/F12) am meisten.

Fitness Fitness: eGYM/Garmin-Karten mit Sparklines – dichter, motivierender Screen.

Vorräte Vorräte: lange gruppierte Liste mit Steppern; Kandidat für klebrige Hover-Stile (F6) und 44-pt-Targets (F10).


5. Top 10 Improvements/Fixes

Priorisiert nach (Illusionsbruch × Alltagshäufigkeit) ÷ Aufwand. „IPA" = erfordert einmaligen Rebuild der Hülle.

# Fix Befunde Aufwand Wirkung
1 Icon + Splash branden, Portrait-Lock, Swipe-Back aktivieren – ein gebündelter IPA-Rebuild (Assets, Info.plist, allowsBackForwardNavigationGestures) F1 F3 F7 ½ Tag (IPA) Homescreen-Eindruck + Kerngeste + ganze Fehlerklasse weg
2 Externe Links → In-App-Safari: zentraler Link-Handler, in der App SFSafariViewController-Sheet, im Web _blank F16 2–3 h „App-Kaperung" durch Garmin/OFF beseitigt
3 Touch-Semantik nativieren: user-select/touch-callout aus auf UI-Chrome, Hover hinter @media (hover: hover), :active-Feedback auf Listen/Chips F5 F6 2–3 h Der häufigste Illusionsbruch (Long-Press/Klebe-Hover) verschwindet
4 App-Bewusstsein in Einstellungen: UA SilverscaleApp erkennen → PWA-/Push-Hinweise und Geräte-Login-Block in der App ersetzen/verstecken F17 1–2 h Kein Web-Vokabular mehr in der App
5 Netz-Robustheit: GET-Retry mit Backoff, Schreibfehler in Menschensprache + „Nochmal"-Action, einheitliches Optimistic-Pattern mit Rollback (Liste!), Plan-Löschen mit Undo F11 F12 ½ Tag Funkloch kostet keine Daten und kein Vertrauen mehr
6 Profil-Switcher absichern: Name sichtbar/Toast beim Wechsel, stärkerer Aktiv-Zustand F18 1–2 h Falsch-Profil-Unfälle (WAF-Klassiker) verhindert
7 Sheet-Dirty-Check: „Eingaben verwerfen?" vor Schließen mit Inhalt F19 2 h Keine still verlorenen Eingaben
8 Offline-Kaltstart-Fallback: gebrandete lokale Fehlerseite mit Retry statt weißer Wand F2 2–4 h Würdevolles Scheitern ohne Netz
9 Skeletons + 150-ms-Crossfade bei Seiten-/Profilwechsel; Reload-aus-Hintergrund nur bei neuer Version F13 F14 F25 ½ Tag Gefühlte Native-Performance trotz Remote-Modus
10 Polish-Paket: 7 SVG-Icons fürs Mehr-Menü, Haptics an Kernaktionen, 44-pt-Targets, A11y (Focus-Trap, aria-live), Foto-Vorschau vor KI-Buchung F8 F10 F15 F22 F23 1 Tag Von „gut" zu „fühlt sich teuer an"

6. Roadmap / Plan

Phase 0 — „Jaqueline-Gate" (vor Rollout auf ihr iPhone; ~1–1,5 Arbeitstage)

Kriterium: Kein Befund mehr, der beim normalen Tagesgebrauch die Illusion bricht oder Daten kostet.

  1. IPA-Paket (einmalig, alles zusammen): Icon + Splash (F1), Portrait-Lock (F3), Swipe-Back (F7), dabei @capacitor/haptics + @capacitor/status-bar gleich mit installieren (Nutzung kann später kommen — Plugins nachrüsten = neuer IPA-Build, also jetzt einpacken).
  2. Externe Links → In-App-Safari (Top-2).
  3. Touch-CSS: user-select/touch-callout/hover (Top-3).
  4. Einstellungen app-bewusst (Top-4).
  5. Profil-Switcher-Feedback (Top-6) + Sheet-Dirty-Check (Top-7).
  6. Plan-Löschen-Undo + Listen-Rollback (aus Top-5, der schnelle Teil).
  7. Geräte-Test auf Dennis' iPhone: Long-Press, Garmin-Link, Funkloch-Simulation (Flugmodus mitten im Abhaken), Swipe-Back mit offenem Sheet.

Danach erst SideStore + Pocket-ID-Erstlogin auf Jaquelines iPhone — zusammen mit dem ohnehin geplanten 14.06.-SideStore-Refresh-Check.

Phase 1 — Native-Feinschliff (Woche danach; ~1–2 Tage verteilt)

Phase 2 — Delight & Hygiene (laufend, kein Blocker)

Nicht tun (bewusste Anti-Empfehlungen): kein Landscape-Support nachbauen (sperren ist besser) · keinen Offline-Schreib-Sync-Layer erfinden, bevor Offene Frage 3 entschieden ist · kein Icon-Redesign der Inhalts-Emojis (Profile/Mahlzeiten/Metriken funktionieren) · keine SPA-Framework-Migration — Svelte 4 + Hash-Routing tragen das Zielbild problemlos.


7. Offene Fragen

  1. Benachrichtigungen in der App? Web-Push funktioniert in der WKWebView nicht, echtes APNs scheitert an der Gratis-Apple-ID (keine Push-Entitlements via SideStore). Optionen: (a) keine Pushes in der App, PWA bleibt stiller Push-Kanal, (b) lokale Notifications (Capacitor-Plugin, ohne Server-Push, z. B. Erinnerungen), (c) später bezahlter Dev-Account. Was ist der Anspruch?
  2. Bleibt die PWA auf den iPhones sichtbar? Zwei „Apps" mit demselben Inhalt auf Jaquelines Homescreen wären verwirrend — PWA als dokumentierter Notfall-Fallback (SideStore-Ablauf!) behalten, aber vom Homescreen nehmen?
  3. Offline-Anspruch: Reicht „würdevoll scheitern" (Fallback-Seite + ehrliche Toasts), oder soll Eintragen im Funkloch gepuffert werden (Queue mit Nach-Sync)? Letzteres ist deutlich mehr Arbeit (Konflikte, Wir-Modus!) — Empfehlung: erst Phase 1 erleben, dann entscheiden.
  4. Scroll-Gefühl: Bounce + Pull-to-Refresh aktivieren (nativer, aber Verhaltensänderung) oder bewusst beim ruhigen, festen Scrollen bleiben?
  5. iPad: Info.plist deklariert iPad-Orientierungen, die UI ist aber rein Phone-first. iPad explizit ausschließen (Targeted Device Family) oder ist Jaquelines/Familien-iPad ein künftiger Use-Case?
  6. Statistik-Charts (F26): Rendern sie auf echten Geräten — oder ist die Seite aktuell faktisch leer?
  7. Einkaufsliste im „Mehr"-Menü: Wenn Jaqueline primär einkauft und isst, gehört die Liste dann nicht in die Haupt-Tab-Leiste (z. B. statt „Gerichte" oder als 5. Tab statt „Mehr"-Slot)? Nutzungsdaten nach 2–3 Wochen entscheiden lassen.
  8. SideStore-Betrieb für Jaqueline (F21): Wer refresht ihr Gerät, was ist die Routine, was sagt man ihr, wenn die App nicht startet? (Direkt mit dem 14.06.-Check beantworten.)

Audit erstellt am 07.06.2026 · Screenshots: Chromium-Sweep 390×844@2x gegen den Live-Stand (127.0.0.1:9300, interner Token) · Code-Stand: main 9c306d0.