mana-swift-ui/CHANGELOG.md
Till JS 3907e3268f ManaAccountView: „Profilbild ändern"-Zeile → hub/profil (Weg B)
Geteilter Konto-Screen verlinkt eingeloggt aufs Profilbild-Studio
(hub.mana.how/profil) statt den Editor pro App zu duplizieren. Damit ist
das Profilbild-Setzen in allen nativen Apps erreichbar. swift build grün.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 22:34:54 +02:00

42 KiB
Raw Permalink Blame History

Changelog

Alle Änderungen werden hier dokumentiert. Format orientiert an Keep a Changelog, Versionierung nach Semver.

[Unreleased]

Neu — ManaAccountView: „Profilbild ändern"-Zeile (Vereinheitlichung Weg B)

Der geteilte Konto-Screen rendert im eingeloggten Zustand jetzt eine „Profilbild ändern"-Zeile im Konto-Block (nach „Name ändern"), die das Profilbild-Studio hub.mana.how/profil im Browser öffnet. Damit ist das Profilbild-Setzen (Foto→3D + Pixel-Baukasten) in allen nativen Apps erreichbar, ohne den Editor pro App zu duplizieren — das Studio bleibt single-source im Vereins-Hub. Pendant zur Compose-ManaAccountScreen (mana-kotlin-ui 0.18.0) + Web-UserMenuPanel (@mana/shared-ui 1.21.0).

Neu — ManaComponentsUI: ManaScreenHeader / ManaSectionHeader / ManaPinnedGlyph

Geteilte Bausteine für die Listen-Optik, drift-sicher als Pendant-Paare zur Compose-Lib (mana-kotlin-ui):

  • ManaScreenHeader — links-bündiger, unterstrichener Seitentitel (jetzt fett) + optionaler Untertitel/Trailing-Slot. titleColor-Override für monochrome Titel auf dunkler Fläche.
  • ManaSectionHeader — großer (.title2/SemiBold) Abschnitts-Header für scrollende Listen, optional einklappbar (Chevron). Ersetzt das winzige Caption-Muster.
  • ManaPinnedGlyph — gezeichneter Fünfzack-Stern (geteilte Geometrie mit Android, ManaStarShape) als „Angepinnt"-Marker; kein SF-Symbol, damit er pixelgleich zum Material-Pendant bleibt.

Neu — ManaComponentsUI: ManaSettingsSection / ManaSettingsRow

Geteilte Settings-Bausteine, SwiftUI-Pendant zur Compose-ManaSettingsSection (mana-kotlin-ui 0.11.0). ManaSettingsSection(icon:title:footer:) rendert eine native, gruppierte Section mit Icon-Label-Header + Footer; ManaSettingsRow ist die auswählbare Zeile (Symbol + Titel/Untertitel + Häkchen). Damit lassen sich Settings-Screens iOS↔Android struktur- und wortgleich bauen (gleiche API, je native Optik). Erstkonsument: memoro-natives KI-Menü (AISettingsView).

Geändert — ManaOnboardingUI: eine scrollbare Seite, ein Titel

Der Flow ist jetzt eine einzige scrollbare Seite mit genau einem Titel statt mehrerer Wisch-Seiten:

  • Kein TabView-Pager, keine Seiten-Indikator-Punkte mehr.
  • Ganz oben ein Titel (der der ersten ManaOnboardingPage) neben dem App-Icon (jetzt 40×40 statt 48×48). Darunter ausschließlich die Info-Karten — alle Zeilen aller Seiten flach untereinander, ohne Zwischen-/Abschnitts-Titel.
  • Unten genau ein Button („Los geht's“), kein „Weiter“ mehr.
  • Vollständig datengetrieben aus dem bestehenden [ManaOnboardingPage] — keine App muss etwas anpassen, greift via Pfad-Dependency überall. (Titel von Seiten ab der zweiten werden nicht mehr angezeigt.)

Geändert — ManaOnboardingUI: ruhigere Seiten (Icon überall, kein Fließtext)

Flottenweite Design-Angleichung aller Onboarding-Seiten:

  • App-Icon steht jetzt auf jeder Seite neben dem Titel (vorher nur auf der ersten/Willkommens-Seite).
  • Titel eine Stufe kleiner (.title → .title2), Icon entsprechend 48×48 statt 54×54.
  • Vorspann (intro) und Fußnote (footnote) werden nicht mehr gerendert — eine Seite trägt nur noch Überschrift + Zeilen-Karten. Die Model-Felder bleiben quellkompatibel (Default nil), werden aber ignoriert; Apps müssen nichts anpassen. Bei Gelegenheit können die jetzt toten intro:/footnote:-Argumente in den App-Onboardings entfernt werden.

Greift automatisch in allen Apps (lokale Pfad-Dependency), kein Bump nötig.

Hinzugefügt — ManaTransparencyUI (neues Product): „Danke & Transparenz"

Neues Library-Product ManaTransparencyUI — der geteilte native Renderer der ökosystemweiten „Danke & Transparenz"-Fläche (Open-Source-Dank + Offenlegung des Stacks). Pure SwiftUI, app-agnostisch, keine Dependencies.

  • ManaCredit (Codable/Sendable) + ManaTransparencyData.load(_:in:) — dekodiert die vom Generator (mana/scripts/transparenz/generate.mjs, Ziel native) erzeugte JSON aus dem App-Bundle.
  • ManaTransparencyView(intro:entries:) bzw. ManaTransparencyView(_:) — gruppiert nach Sektion (Aufbauend auf / Frameworks / Bibliotheken / Schriften / Dienste / Bewusst externe Dienste), Einträge mit Lizenz + tippbarem Link.
  • Pendant zur Web-<Transparenz> (@mana/shared-ui). SOT: ../mana/docs/TRANSPARENZ.md. Adoption: 1 Dep + JSON ins Bundle + ein ManaTransparencyView(...) in den Einstellungen.

Hinzugefügt — ManaCreditsUI (neues Product): Gesamt-Mana-Anzeige

Neues Library-Product ManaCreditsUI — die native „Mana"-Seite, Pendant zur Web-<ManaPage>:

  • ManaView(client:) — Gesamt-Guthaben (groß) + EUR-Gegenwert + Topf-Split (80/5/5/5/5 aus MISSION.md) + letzte Bewegungen. Read-only (Aufladen im Web).
  • ManaBalanceRow(balance:) — kompakte Guthaben-Zeile für Account-/Settings- Screens.
  • ManaBalanceLink(auth:) — fertiger Eintrag (Row + Laden + Navigation zur ManaView) als Einzeiler für Form/List-Sections; macht den App-Rollout trivial.
  • ManaAccountView.Config.showManaBalance (ManaAuthUI, Default false) — schaltet die Gesamt-Mana-Anzeige direkt im geteilten Konto-Gerüst ein. Apps, die ManaAccountView nutzen, brauchen so nur das Flag (kein eigener Code). ManaAuthUI hängt dafür neu (transitiv, leichtgewichtig) an ManaCreditsUI.
  • ManaFormat — Mana/EUR/Datum-Formatierung; ManaCreditsModel — Loader.
  • Konsumiert ManaCreditsClient aus ManaCore; System-Styling (app-agnostisch), keine ManaTokens-Abhängigkeit.

Hinzugefügt — ManaAiActionMetaView (ManaLLMUI)

Geteilte, app-agnostische Anzeige-Zeile für KI-Verbrauch: Modell · Dienst · Dauer · Tokens · Mana · ≈ Strom (System-Styling, .secondary). Pendant zur Web-Komponente <AiActionMeta> in @mana/shared-ui. Konsumiert ManaAiMeta aus ManaLLMShared. Energie ist bewusst als Schätzung markiert (≈). SOT: mana/docs/AI_TRANSPARENCY.md.

  • ManaAiActionMetaView(meta:) in ManaLLMUI.
  • Apps: opt-in — unter ein KI-Ergebnis setzen, sobald die App ein ManaAiMeta von ihrer Produkt-API erhält.

Geändert — Login-AutoFill zuverlässiger (.manaUsernameField())

  • Neuer View-Modifier manaUsernameField() (ManaFields): wie manaEmailField(), aber mit textContentType(.username) statt .emailAddress. ManaLoginView nutzt ihn jetzt fürs Account-Feld. Warum: iOS-AutoFill erkennt das Feld dadurch als Credential-Account und überschreibt es auch, wenn der User bereits ein paar Zeichen getippt hat (vorher füllte .emailAddress oft nur leere Felder). Sign-Up/Reset bleiben bewusst bei manaEmailField() (reine Email-Eingabe).
  • Apps: kein Anpassungsbedarf — ManaLoginView wirkt automatisch. Eigene Login-Formulare können manaEmailField() → manaUsernameField() umstellen.

Hinzugefügt — ManaJobStatusView (Wartezeit-Anzeige für GPU-Jobs)

  • Ehrliche Inline-Anzeige für lang laufende KI-/GPU-Jobs (Stem-Separation, Musik-Generierung, Transkription) in ManaComponentsUI. Zustände queued/running/done/failed mit „läuft seit …", „dauert meist … / bei Andrang bis zu X min" und optionaler Warteschlangen-Position; optionaler Abbrechen-Button via onCancel. Sichtbares Gegenstück zum GPU-Broker (../mana/docs/GPU_BROKER.md), der die geteilte RTX 3090 serialisiert — die dadurch mögliche Wartezeit wird benannt statt versteckt.
  • Natives Pendant zu <JobStatus> aus @mana/shared-ui 1.14.0 (Web) — identische Formulierungen, damit web + nativ gleich klingen.
  • Spinner über ProgressView (respektiert Reduce-Motion automatisch), Farben ausschließlich aus dem injizierten manaTheme (12 Tokens), Spacing/Radius aus ManaTokens. Reine Texthelfer ManaJobStatusText (formatElapsed/ formatEstimate/defaultTitle) separat — getestet im neuen Test-Target ManaComponentsUITests (9 Tests, swift test grün).

Hinzugefügt — ManaSearchResultsView (iOS-26-Such-Tab-Baustein)

  • Geteilte Hülle für die native Such-Ansicht hinter Tab(role: .search) (iOS 26: unten schwebendes Liquid-Glass-Suchfeld; ab iOS 18 als regulärer Such-Tab — kein Availability-Gating nötig). Vereinheitlicht die drei Such-Zustände flottenweit: leere Query (Einstiegs-Prompt), keine Treffer (ContentUnavailableView.search), Treffer (app-eigene Liste). Die App reicht nur Query + Treffer-Status + Ergebnis-Liste; NavigationStack/.searchable/ navigationDestination bleiben app-seitig (Ziel-Typen sind app-spezifisch).
  • Pilot: memoro (Such-Tab über alle Memos: Titel/Headline/Intro/Transkript), im iOS-26-Sim verifiziert (Suchfeld unten, eigener Such-Tab). Ersetzt perspektivisch den Custom-ManaSearchButton durch das native Muster.
  • Rollout abgeschlossen (2026-06-06): memoro, zitare, seepuls (Events + Orte zusammengeführt), pageta, audioguide, comicello, wordeck (eigene Decks lokal + Marktplatz server) haben alle den nativen Such-Tab; alle Inline- .searchable/ManaSearchButton-Suchen sind entfernt.

Veraltet — ManaSearchButton

  • Mit @available(*, deprecated) markiert. Die Suche läuft flottenweit über den nativen Such-Tab (Tab(role: .search)) + ManaSearchResultsView statt über ein Custom-Such-Icon in der Filter-Leiste. Keine Konsumenten mehr; bleibt für Übergangs-Fälle, soll aber nicht neu adoptiert werden. Playbook: ../mana/docs/playbooks/SEARCH_TAB_ROLLOUT.md.

Behoben — ManaAccountView folgt dem Theme-Variant in allen Sektionen

  • Bisher folgten nur die selbstgetönten Karten (Anmelden/Feedback) dem Theme; die Standard-Sektionen (Konto/Sicherheit, „Darstellung", „Status", „Über" und app-eigene extra()-Sektionen) nutzten den System-Grouped- Cell-Hintergrund und blieben beim Variant-Wechsel neutral-grau. Fix: ManaAccountView liest @Environment(\.manaTheme) und legt .listRowBackground(theme.surface) auf alle Nicht-Karten-Sektionen (inkl. extra()). listRowBackground ist ein Default — app-eigene Zeilen mit eigenem Row-Background überschreiben ihn weiterhin.
  • Page-Hintergrund themed + recessed für genug Card-Kontrast. Die Theme-Tokens setzen background in Light fast deckungsgleich mit surface (L≈98 vs 100) — die Card-Abgrenzung ist im Theme über den Border gedacht, der full-bleed in der grouped Form an den Ecken clippt. Lösung: Page- Hintergrund = in Light der klar recessed theme.muted (L≈92), in Dark das dunklere theme.background (deutlich unter surface) — gewählt per @Environment(\.colorScheme). Beides ist themed (folgt dem Variant) und klar von den surface-Cards abgesetzt; mehr Kontrast als der zuvor genutzte near-white System-Grouped-Background, in beiden Modi.

Hinzugefügt — ManaAccountView: Profil-Avatar im Sheet + Icons

  • Eingeloggt zeigt der Konto-Block jetzt oben einen Profil-Header: das große, rund beschnittene Ökosystem-Avatarbild (gleiche Quelle wie der Toolbar-Avatar, ManaAvatarImageStore), darunter Anzeigename (aus AuthClient.getProfile()) und E-Mail. Fällt auf ein person.crop.circle.fill-Glyph (in theme.primary) zurück, solange kein Bild gesetzt/geladen ist. Kein App-Code nötig — ManaAccountView lädt selbst.
  • Icons auf den Konto-Einträgen: E-Mail (envelope), E-Mail ändern (pencil), Passwort ändern (key), Abmelden (rectangle.portrait.and.arrow.right), Konto löschen (trash). Stil (gedämpftes Icon + Vordergrund-Titel + Chevron) konsistent mit ManaTwoFactorAccountRow; destruktive Zeilen in error-Farbe ohne Chevron.
  • „Name ändern"-Zeile in der Konto-Sektion (person-Icon) — leichter Alert mit Textfeld, schreibt via AuthClient.updateName(_:) (mana-swift-core ≥ Unreleased). Der Avatar-Header-Name aktualisiert sich danach. Damit ist der Anzeigename erstmals nativ änderbar (vorher nur Registrierung/Web). Voraussetzung: mana-swift-core mit updateName.

Behoben — Karten-Border in ManaAccountView an den Ecken abgeschnitten

  • Der Anmelde-CTA (ManaSignInCTA) und die Feedback-Karte (ManaFeedbackCard) saßen full-bleed in der inset-grouped Form und zogen einen .manaCard(border:). Die gerundete Section-Maske der Form clippt den Zelleninhalt auf ihre Ecken — unabhängig vom Karten-Radius (empirisch verifiziert: 4/10/12 pt liefern identische Ecken). Ein Overlay- strokeBorder wird dadurch an den vier Ecken abgeschnitten; sichtbar vor allem in dunklen Themes (seepuls). Fix: Die beiden Karten verzichten full-bleed auf den Manual-Border und definieren sich über Surface- Kontrast, genau wie eine native grouped Section — volle Section-Breite bleibt erhalten, keine abgeschnittenen Ecken mehr. Neuer geteilter Marker View.manaCardListRow() (ManaThemeUI) kapselt die full-bleed-Row- Konfiguration (Null-Insets + transparenter Row-Background) und dokumentiert die Regel.
  • Der Anmelde-CTA-Block trägt jetzt den Section-Header „Konto" (parallel zur eingeloggten Konto-Sektion), die Feedback-Karte den Header „Feedback" — damit auch diese beiden Blöcke, wie alle übrigen Konto-Tab-Sektionen, eine Überschrift haben.

Hinzugefügt — ManaAccountAvatarButton: Ökosystem-Profilbild (Stufe 1)

  • Der geteilte Konto-Avatar oben rechts zeigt jetzt das im Avatar-Baukasten (avatar.mana.how) gebaute Profilbild des angemeldeten Nutzers, rund beschnitten — statt nur Initialen/Icon. Fällt sauber auf Initialen bzw. System-Icon zurück (lädt / kein Bild gesetzt / ausgeloggt).
  • Neuer ManaAvatarImageStore (@MainActor, prozessweiter Cache): fragt mana-me GET /api/v1/me/images/primary/avatar mit dem User-JWT ab und baut die öffentliche mana-media-Thumb-URL. Dedupliziert über alle Buttons (einer pro Tab) und verwirft den Cache bei Abmeldung. invalidate() für „Profilbild gerade geändert".
  • Null App-Code nötig: der Button lädt selbst, Defaults zeigen auf die Produktiv-Services (me.mana.how / media.mana.how). Jede App, die ManaAccountAvatarButton / manaAccountToolbar schon nutzt, erbt das Bild nach einem Rebuild. Overrides additiv: loadsProfileImage (aus für rein anonyme Apps), meBaseURL / mediaBaseURL (Dev/Localhost).

Hinzugefügt — ManaLLMUI: KI-Einstellungen als geteilte Unterseite

  • ManaLLMSettingsLink — eine NavigationLink-Zeile (SF-Symbol + Titel + Use-Case-Untertitel), die auf eine eigene KI-Unterseite pusht, statt die vier KI-Sections inline in den Konto-/Settings-Tab zu kippen. Flottenweites Muster, damit der KI-Bereich in allen nativen Apps gleich aussieht.
  • ManaLLMSettingsScreen — die Zielseite: hostet die bestehende ManaLLMSettingsView-Komposition in einer Form plus optionalen app-eigenen KI-Inhalt über einen generischen extra-Slot (@ViewBuilder, Default EmptyView). So zieht z.B. memoros Server-LLM-Picker hinter denselben einen KI-Link.
  • Beide Views additiv: ManaLLMSettingsView und die granularen ManaLLM*Section-Views bleiben unverändert und weiter public. Apps, die bewusst inline bleiben wollen, sind nicht betroffen.
  • Defaults: Titel „Künstliche Intelligenz", Icon sparkles — beides überschreibbar.

Hinzugefügt — ManaOnboardingUI (geteilter Einstiegs-Flow)

  • Neues Library-Product ManaOnboardingUI — Onboarding-Flow im Stil von Apples „Neue Funktionen“-Sheet für alle nativen Verein-Apps. Damit der Einstieg flottenweit gleich aussieht/sich anfühlt, aber im Signatur-Theme der App (Farben aus @Environment(\.manaTheme), kein hardcodetes Branding).
  • ManaOnboardingPage — app-geliefertes Seiten-Modell: großer Titel, optionaler Vorspann, eine Liste von Rows (SF-Symbol + Titel + Text), optionale Fußnote. Voll Sendable (keine Action-Closures).
  • Doktrin: kein Berechtigungs-Abfragen im Onboarding. Das Paket fragt nie System-Rechte ab — Berechtigungen hängen an konkreten Features und werden just-in-time erfragt. Onboarding informiert nur (Werte-Entscheidung 2026-06-05: kein Extrahieren auf Vorrat).
  • ManaOnboardingView — Container. Links ausgerichteter Titel (auf Seite 1 mit dem App-Icon links daneben, automatisch aus dem Bundle), Zeilen als eingefasste Karten (.manaCard), wischbar zwischen Seiten (iOS Page-Style; macOS Cross-Fade), unten der brand-getönte Seiten-Indikator + genau ein Primär-Button. Reduced-Motion-aware.
  • View.manaOnboarding(storageKey:pages:onFinish:) — @AppStorage- Gate, präsentiert als .sheet mit .presentationDetents([.large]) + Griff (Apple-Optik, nicht eingezwängt). Per Wischen verlassbar = als „gesehen“ gemerkt. Versionierter Key (…vN) zeigt bei großen Updates erneut. Erster Konsument: stetig-native.
  • Hängt nur an ManaTokens + ManaThemeUI. Keine externen Deps, Public API Sendable/@MainActor. Tests: ManaOnboardingUITests (7, Seiten-Modell).

Hinzugefügt — BYOK in der LLM-Settings-UI

  • ManaLLMByokSection (ManaLLMUI) — natives Pendant zum Web- ByokKeyManager. Verwaltet pro Anbieter (OpenAI / Anthropic / Gemini / Mistral) genau einen API-Schlüssel: hinzufügen (SecureField + Modell- Picker), ändern, löschen; bei ≥2 hinterlegten Schlüsseln ein „Standard-Anbieter“-Picker. Schlüssel liegen in der ByokKeyVault (Keychain, app-privat, keine iCloud-Sync) aus ManaLLM ≥0.3.0. Der Schlüssel wird nie zurück in die UI geschrieben (nur „hinterlegt“ + Modell sind sichtbar).
  • ManaLLMSettingsView(context:showByok:) — neuer showByok-Parameter (Default true) blendet die BYOK-Section ein/aus. Apps ohne Dritt- Anbieter-Wunsch setzen false.
  • ManaLLMSettingsState verwaltet jetzt BYOK: byokVault, byokStoredProviders, byokDefaultProvider (UserDefaults-persistiert), saveByokKey/deleteByokKey/byokModel/setByokDefaultProvider. makeRouter() reicht den Vault-Resolver durch, sodass .byok in der Availability-Map als .available erscheint, sobald ein Schlüssel hinterlegt ist.
  • ManaLLMBackendPickerSection kennt jetzt die Quelle LLMBackendID.byok (Icon key.fill, eigener Footer-Text, „Schlüssel hinterlegen“-Hinweis statt generischem „Fehlt: …“).

Voraussetzung: ManaLLM (mana-swift-llm) ≥ 0.3.0 — diese Version fügt LLMBackendID.byok hinzu. Konsumenten-Apps mit eigenen erschöpfenden switch-Statements über LLMBackendID müssen den Fall .byok ergänzen (Xcode-Rebuild nötig).

Hinzugefügt

  • ManaAccountAvatarButton + .manaAccountToolbar(auth:profile:onTap:) (ManaAuthUI). Runder Konto-Avatar für die Navigationsleiste oben rechts; Tippen öffnet das Konto als Sheet statt eines eigenen Bottom-Tabs (Apple-Muster aus Podcasts / App Store). Darstellung nach Auth-Zustand: Initialen (signed-in + Name) → person.circle (signed-in ohne Name) → person.crop.circle (guest/signed-out); immer sichtbar, damit Settings
    • Sign-In im Sheet in jedem Zustand erreichbar bleiben. Initialer Konsument: memoro. Flotten-Rollout siehe ../mana/docs/playbooks/ACCOUNT_AVATAR_MIGRATION.md.

Behoben

  • 2FA-Status flackerte endlos im Konto-Tab aller nativen Apps (Text sprang zwischen „2FA-Status lädt…" und „2FA aktivieren", teils „Netzwerkverbindung abgebrochen"). Ursache: .task/.sheet lagen auf einem Group, der einen zustandsabhängigen switch umschloss — Group verteilt Modifier auf jeden Zweig, also re-attachte sich .task bei jedem State-Wechsel und feuerte reload() erneut (Endlosschleife; der in-flight getProfile() wurde dabei gecancelt → URLError.cancelled). stateContent ist jetzt eine @ViewBuilder-Property, der Modifier wrappt von außen → .task feuert einmal pro Erscheinen. (ManaTwoFactorAccountRow)
  • ManaLLMSettingsView: dieselbe Group+.task-Falle — refreshAvailability() lief pro Section (3×) und erneut beim Ein-/Ausblenden der Prepare-Section. .task jetzt an der stabilen Backend-Picker-Section.

Hinzugefügt

  • ManaFeedbackUI Soft-Anerkennung — die Erfolgs-Ansicht zeigt eingeloggten Nutzern jetzt einen ehrlichen Aura-Hinweis („Wird daraus ein bestätigter Bug oder ein vielgewünschtes Feature, schreiben wir dir Aura gut."). Keine Sofort-Aura fürs reine Absenden — Anerkennung erst bei Bestätigung (siehe mana/docs/INVITES_AND_AURA.md).

  • ManaSafariLink (ManaAuthUI) — öffnet eine URL in-App (iOS: SFSafariViewController, macOS: System-Browser-Fallback) statt eine separate Browser-App aufzureißen. Für rechtliche/redaktionelle Seiten (Impressum, Datenschutz, Lizenz). Rendert als Form-Zeile wie ein Link.

  • ManaAboutSection.Link.inApp (ManaAuthUI) — neuer Init-Parameter (inApp: Bool = false). true → die „Über"-Sektion öffnet den Link via ManaSafariLink in-App statt extern. Damit deckt eine Sektion App-Info und Rechtliches ab, statt einer separaten Legal-Links-Sektion pro App. Additiv, Default unverändert (externer Link).

  • ManaAppearanceSection (ManaThemeUI) — vereinheitlichte „Darstellung"- Sektion für den Konto-/Einstellungen-Tab: bündelt ManaAppearancePicker (Hell/Dunkel/Automatik) + ManaThemeGallery in einer Section mit Header

    • ökosystemweit gleichem Footer (defaultFooter). Die Einzel-Picker waren schon geteilt, der Section-Rahmen + Footer-Wortlaut nicht — jede App baute ihn (leicht abweichend) von Hand. Persistenz bleibt App-Sache (zwei Bindings rein, kein UserDefaults-Schreiben); Theme-Pass via unlocked/onLockedTap durchgereicht. Additiv.
  • ManaAppearanceCard (ManaThemeUI) — Karten-Variante von ManaAppearanceSection für Apps mit Card-Layout (ScrollView/VStack statt Form/List, z.B. viadocu). Gleicher Inhalt im .manaCard-Container (continuous Squircle + Border) statt einer Section; Farben aus @Environment(\.manaTheme). Schließt die letzte Appearance-Lücke der Flotte.

  • ManaComponentsUI (neues Library-Target) mit ManaPill — eine einheitliche Kapsel-Pille (Filter-Chip / Bulk-Aktion) für alle nativen Apps. Größe und Form sind zentral festgelegt (Referenz: seepuls-Filterleiste — 18/11 Padding, .callout.semibold, Capsule), die Farben kommen aus @Environment(\.manaTheme) (keine Farb-Parameter → jede App behält ihre Theme-Variant). Varianten .selected / .neutral / .destructive plus isOn-Komfort-Init für Toggle-Filter. Behebt die zu kleinen Bulk-Aktions- Pills im Auswahl-Modus und vereinheitlicht sie mit den seepuls-Filtern. Dependency: nur ManaTokens.

  • .manaCard(surface:border:cornerRadius:borderWidth:padding:) (ManaThemeUI) — geteiltes Karten-Chrome für alle Verein-Apps: gefüllte surface-Fläche, durchgehende continuous (Apple-Squircle-)Ecken und optionaler Hairline-Border aus einer gemeinsamen Form (sauberer Eckenverlauf statt zwei getrennter circular Shapes). Theming-agnostisch (Farben explizit), nutzt Radius-Token als Defaults. Eine Quelle für die Kartenoptik, statt pro Komponente hardcoded cornerRadius mal mit, mal ohne Border. ManaThemeUI ist jetzt Dependency von ManaAuthUI + ManaFeedbackUI.

  • RoundedRectangle.mana(_:) (ManaThemeUI) — Vereins-Standard-Form: continuous (Squircle-)Ecke an einem Radius-Token. Für Buttons, Eingabe- felder und kleine Inline-Boxen, die keine volle .manaCard brauchen, aber dieselbe Ecken-Sprache sprechen sollen. Verhindert stilles Zurückfallen auf den eckigeren .circular-Default.

  • ManaAboutSection (ManaAuthUI) — vereinheitlichte „Über"-Sektion für den Konto-Tab: App-Name + Version/Build (automatisch aus dem Bundle) + konfigurierbare Link-Liste. ManaAccountView rendert sie an fester Position (ganz unten, nach den App-Sektionen), wenn der neue about:- Parameter gesetzt ist — additiv, kein Breaking-Change (Default nil). Beendet das per-App-Handbauen der App-Info-Sektion (vorher uneinheitlich: comicello App/Version/Build+Links, wordeck nur Hosts, memoro gar nichts).

Geändert

  • Rest-Chrome auf Radius-Token + continuous gezogen — ManaTextField / ManaSecureField (Feld-Box + Border, jetzt strokeBorder statt stroke), ManaPrimaryButton, die Feedback-Buttons (ManaFeedbackCard/ManaFeedbackSheet) und die 2FA-Views (QR-Box, Backup-Code-Chips, Kopier-Buttons) nutzen statt hardcoded cornerRadius-Literalen (6/8/10/12) jetzt RoundedRectangle.mana(Radius.*). Radien konvergieren auf die Token-Skala (Felder/Buttons → Radius.md 8, Code-Chips → Radius.sm 4, QR-Box → Radius.lg 12); alle Ecken jetzt continuous. Rein optisch, keine API-Änderung.

  • ManaSignInCTA (Login-CTA) + ManaFeedbackCard ziehen auf .manaCard — beide Karten teilen jetzt identisches Chrome (continuous Squircle-Ecken, Radius.lg, 1pt-Border in border-Farbe). Vorher: Login rahmenlos mit circular cornerRadius 12, Feedback mit getrenntem Background+Overlay-Border bei cornerRadius 16, dessen Strich den Ecken nicht sauber folgte. Optische Vereinheitlichung über alle Apps mit ManaAccountView. Kein API-Bruch.

  • ManaSignInCTA (ManaAuthUI) — prominente Anmelde-Card für den abgemeldeten Zustand: optionale Headline + Erklärtext + vollbreiter Brand-Button (ManaPrimaryButton), komplett über \.manaBrand getönt. Gehoben aus viadocus handgebautem guestBanner, der als einzige App optisch „richtig" wirkte. Ersetzt die blasse Form- Listenzeile, die ein nackter Button/Label in einer Section rendert.

  • ManaAccountView.Config.signInHeadline (ManaAuthUI) — Headline über dem Anmelde-CTA (Default „Noch nicht angemeldet", nil blendet sie aus).

Geändert

  • ManaThemeGallery Reihenfolge + App-Brücke — (1) freigeschaltete Variants stehen jetzt zuerst, gesperrte danach (stabile Partition über unlocked); vorher lagen freie Themes quer zwischen Schlössern verstreut. (2) Der „ öffnen"-Button bleibt nach dem Freischalten sichtbar (mit geändertem Infotext „Signatur-Theme von " statt der Freischalt- Aufforderung) — als dauerhafte Brücke zur Herkunfts-App, damit die anderen mana-Apps immer erreichbar bleiben und klar bleibt, woher das Theme stammt. Baseline-Variants (ohne Signatur-App) bekommen weiterhin keinen Button. onLockedTap feuert jetzt auch beim freigeschalteten Button-Druck. Reine View-Änderung, keine API-Signatur-Änderung. Siehe THEME_PASS.md.

  • ManaThemeGallery Theme-Pass-Lock — gesperrte Variant öffnet die Signatur-App nicht mehr automatisch. Tippen/Einrasten zentriert sie nur; darunter erscheint „Probier aus, um „" freizuschalten" plus ein „ öffnen"-Button, der erst auf Druck die eigene Landingpage öffnet (ManaTheme.signatureAppHomepage, mana-swift-core ≥ 1.15.0; via @Environment(\.openURL)). onLockedTap ist jetzt ein optionaler Analytics-Hook (feuert beim Button-Druck), keine Navigation mehr — Konsumenten können den Closure droppen. Datei zugleich auf die Repo-Konvention (4 Spaces) normalisiert. Siehe THEME_PASS.md.

  • ManaAccountView signed-out rendert jetzt ManaSignInCTA statt einer Label-Listenzeile — alle Apps, die ManaAccountView nutzen (seepuls, pageta, wordeck, audioguide), bekommen den prominenten CTA automatisch, ohne Code-Änderung.

  • ManaFeedbackCard (ManaFeedbackUI) — prominenter Feedback-Block für den Konto-/Einstellungen-Tab: Icon + aktivierender Titel („Hilf mit, die App zu formen") + ein Satz Einladung + gefüllter CTA in Vereinsfarbe. Löst die dezente ManaFeedbackButton-Listenzeile ab und präsentiert dasselbe ManaFeedbackSheet. Theme-aware (\.manaTheme, surface+border als Karten-Rahmen). Copy überschreibbar (title/message/cta).

  • ManaAccountView.feedbackClient (ManaAuthUI) — neuer optionaler Init-Parameter. Ist er gesetzt, rendert der Standard-Block die ManaFeedbackCard an fester Position (direkt nach dem Konto-/Anmelden-Block, vor extra) — vereinheitlicht Platzierung + Optik des Feedbacks über alle Apps, statt es pro App handgebaut tief im extra-Slot zu verstecken. ManaAuthUI hängt dafür neu von ManaFeedbackUI ab. Additiv, kein Breaking-Change (Default nil).

  • ManaPasswordStrength + ManaPasswordStrengthView (ManaAuthUI) — segmentierte Passwortstärke-Anzeige unter den newPassword-Feldern in ManaSignUpView und ManaResetPasswordView. Reine Heuristik (Länge + Zeichenklassen, keine externe Bibliothek), testbar (PasswordStrengthTests). Blendet sich bei leerem Feld aus, markiert .weak per brand.error. Stufen: schwach/mittel/gut/stark.

[0.9.0] — 2026-06-01

Minor — zwei neue Library-Produkte (ManaFeedbackUI, ManaThemeUI) plus das vereinheitlichte Konto-Gerüst ManaAccountView und der Passwort-Reveal in ManaSecureField.

Hinzugefügt

  • ManaThemeUI — neues Library-Produkt. Geteilte Theme-Galerie (ManaThemeGallery — Orb-Karussell mit Snap-to-Center und Lock-State für den Theme-Pass) plus ManaAppearancePicker (Hell/Dunkel/System). Konsumiert ManaTokens. Beendet das per-App-Handbauen der Theme-Auswahl. Siehe mana/docs/THEME_PASS.md.

  • ManaAccountView (ManaAuthUI) — vereinheitlichtes Konto-Gerüst: Form-basierter Standard-Block (E-Mail-Anzeige, E-Mail/Passwort ändern, 2FA, Konto löschen [Apple 5.1.1(v)], Abmelden) aus einem AuthClient, plus Sign-In-CTA im abgemeldeten Zustand. Config-Flags (showChangeEmail/showChangePassword/showTwoFactor), onSignIn/onSignOut-Callbacks, @ViewBuilder extra-Slot für App-spezifische Sektionen. Pendant zur Login-Konsolidierung — beendet das per-App-Handbauen des Konto-Tabs.

  • ManaFeedbackUI — neues Library-Produkt. ManaFeedbackSheet (Kind-Picker Wunsch/Problem/Feedback, Titel, Beschreibung; bei anonymer Nutzung optionales Kontakt-Mail-Feld + Moderations-Hinweis), ManaFeedbackButton (Default-Label „Feedback" oder Custom-Label) und der .manaFeedbackSheet(isPresented:client:isLoggedIn:)-Modifier für eigene Trigger (z.B. Toolbar/Settings-Row). Postet via ManaCore.FeedbackClient an die zentrale Wunsch-App — Pendant zum Web-@mana/shared-feedback-Widget. Theming über \.manaTheme (ManaTokens). Siehe mana/docs/FEEDBACK_NATIVE_PLAN.md.

Geändert

  • ManaSecureField (ManaAuthUI) — Augen-Button zum Sichtbarmachen des Passworts (SecureField ↔ TextField, Default verborgen). Barrierearm gelabelt („Passwort anzeigen"/„Passwort verbergen"), Fokus bleibt über den Feld-Tausch erhalten. Der Button erscheint erst, wenn etwas im Feld steht; ein geleertes Feld kehrt zur Maskierung zurück. Auf macOS warnt ein Feststelltasten-Symbol (capslock.fill) bei aktivem Caps-Lock — wie in Apples eigenen Passwortfeldern. Wirkt ökosystemweit: alle nativen Apps teilen diese Komponente (Login, Sign-Up, Reset, Passwort ändern, 2FA, Konto löschen).

  • ManaWebShell: Die Fehler-Leiste in WebShellView hat jetzt einen „Erneut laden"-Button. Bisher war ein Lade-Fehler eine Sackgasse — der User sah die Meldung, konnte die Seite aber nicht neu laden. Intern via reloadNudge → effectiveTarget.reloadToken.

[0.8.0] — 2026-05-22

Minor — neues Library-Product ManaLLMUI. Drop-in-Settings-UI für die lokalen LLM-Backends aus mana-swift-llm. Pendant zu ManaAuthUI — vorher hatte nur Memoro die UI handgeschrieben, die drei anderen Konsumenten (pageta, comicello, herbatrium) hatten gar nichts.

Hintergrund

Vier Apps konsumieren ManaLLM (Memoro, Pageta, Comicello, Herbatrium). Memoros 250-Zeilen-LLM-UI (Picker + Prepare + Cellular-Toggle) war strukturell shared-fähig — wurde rausgehoben, generalisiert und steht jetzt allen Apps zur Verfügung.

Neu

  • ManaLLMUI-Product (deps: ManaLLM, ManaLLMShared)
  • ManaLLMSettingsView — Convenience-Wrapper, drei Sections in einem Schwung
  • ManaLLMBackendPickerSection — Picker mit Availability-Status + Empfohlen-Badge
  • ManaLLMPrepareSection — Download/Init-Card mit Progress, nur sichtbar für Gemma-Backends (shouldShow(for:)-Gate)
  • ManaLLMDownloadPolicySection — WiFi-only-Toggle
  • ManaLLMSettingsState — @Observable-State-Klasse, hält Backend-Wahl + Availability + Prepare-Progress + delegiert an die Stores aus mana-swift-llm
  • ManaLLMContext — App-spezifischer Kontext (useCaseShort + useCaseLong) für Section-Texte. .generic als Fallback

Migration

Apps die heute eigene LLM-Settings-UI haben (Memoro):

  • import ManaLLM für die Settings-View durch import ManaLLMUI ersetzen
  • Lokale llmSection/llmPrepareSection/llmDownloadPolicySection- Bodies entfernen
  • ManaLLMSettingsView(context: ...) einhängen
  • LLMBackendPreferenceStore + LLMDownloadOverCellularStore bleiben funktionsgleich — wandern aber nach ManaLLM (siehe mana-swift-llm CHANGELOG)

Apps die heute keine LLM-Settings-UI haben (Pageta, Comicello, Herbatrium):

  • ManaLLMUI-Product in project.yml adden
  • ManaLLMSettingsView(context: ...) an passender Stelle einhängen (eigene Settings-View oder NavigationLink im Profile-Tab)

[0.7.0] — 2026-05-22

Minor — logoAssetName in ManaBrandConfig. Apps können jetzt ein eigenes Logo-Asset (Asset-Catalog-Name) statt eines SF-Symbols für den Login-/Sign-Up-/Forgot-Password-Header liefern.

Hintergrund

Pageta hat ein eigenes Apple-Icon-Composer-SVG; das SF-Symbol book.pages (vorher) sah neben dem polierten App-Icon unecht aus. Andere Apps mit echten Logo-Assets (kommt) werden den gleichen Migrationspfad gehen können.

Neu

  • ManaBrandConfig.logoAssetName: String? — Name eines Image-Assets im Bundle der konsumierenden App. Hat Vorrang vor logoSymbol.
  • ManaAuthScaffold rendert logoAssetName 64×64pt, aspectRatio(.fit), ohne Tint (Asset behält Originalfarben — typisch Apple-Icon- Composer-Output mit Gradient). Fallback bleibt SF-Symbol mit Tint.

Geändert

  • ManaBrandConfig.init hat einen zusätzlichen optionalen Parameter logoAssetName: String? = nil. Quellkompatibel — bestehende Apps brauchen nichts ändern.
  • systemDefault-Config setzt logoAssetName: nil explizit (kein Verhaltenswechsel).

Tests

  • 50/50 grün (keine neuen Tests — die ManaBrandConfig-Änderung ist rein additiv, gerendertes Asset hängt am Bundle der App).

Adoption

Apps mit eigenem Logo:

ManaBrandConfig(
    appName: "Pageta",
    logoSymbol: "book.pages",      // SF-Fallback bleibt
    logoAssetName: "PagetaLogo",   // Asset-Catalog-Name, hat Vorrang
    ...
)

[0.6.0] — 2026-05-17

Minor — neues Library-Product ManaWebShell. WKWebView-Hülle für Hybrid-Apps (Web-Lese-Surfaces + native Submit/Widget/ShareExt). Extrahiert aus den fast-byte-identischen WebShell/-Ordnern in seepuls-native und zitare-native (~900 LOC, davon ~700 LOC Duplikat). Audit 2026-05-17 Vorschlag V2.

Neu

  • WebShellView (public SwiftUI View) — WKWebView-Wrapper mit Progress-Bar, Pull-to-Refresh (iOS), Fehler-Snackbar, External-Link- Delegation in den System-Browser. Universal (iOS + macOS).
  • WebShellConfig (public, Sendable) — Host-Whitelist mit Wildcard- Support ("*.mana.how"), User-Agent, Theme-Hints (background, progressTint, errorBackground/Foreground/Icon), User-Scripts.
  • WebTarget (public, Equatable+Sendable) — URL + monoton wachsender reloadToken. Forciert Reload bei Universal-Link auf aktuelle URL.
  • WebNavState (public, @Observable, @MainActor) — reaktiver Navigation-State (isLoading, estimatedProgress, lastError, currentURL, canGoBack).
  • WebShellCoordinator (public, @MainActor) — WKNavigationDelegate
    • WKUIDelegate-Implementierung. KVO-Observations, Pull-to-Refresh- Action.
  • WebShellScripts (public Enum, @MainActor) — vor-gefertigte WKUserScript-Helfer: preferDarkScheme, syncDarkMode(localStorageKey:), hideElements(selectors:tagName:). Apps stapeln nach Bedarf.

Logging

  • ManaWebShell loggt unter Subsystem ev.mana.webshell, Kategorie web. App-OSLog bleibt unverändert.

Tests

  • ManaWebShellTests mit 6 Tests gegen WebShellConfig.isAllowed. Coverage für exakte Hosts, *.root-Wildcard, Root-selbst, Negativ-Cases, leere Whitelist. 6/6 grün.

Migrations-Hinweis

seepuls-native und zitare-native können ihre lokalen Sources/Features/WebShell/-Dateien gegen ManaWebShell ersetzen. Pattern in mana/docs/playbooks/HYBRID_NATIVE_APP.md (entsteht parallel). App-spezifisches (CookieBridge, App-Theme als config.backgroundColor) bleibt in der App.

[0.5.0] — 2026-05-14

Minor — ManaTwoFactorAccountRow + ManaBackupCodeRegenerateView. Macht den 2FA-Vollausbau in der AccountView nutzbar. Setzt mana-swift-core ≥ 1.5.0 voraus (getProfile()).

Neu

  • ManaTwoFactorAccountRow — Drop-in für AccountView. Holt den 2FA-Status via AuthClient.getProfile() und zeigt:
    • Off: "Zwei-Faktor aktivieren" → öffnet ManaTwoFactorEnrollView
    • An: "Zwei-Faktor aktiv" + "Backup-Codes erneuern" + "Zwei-Faktor deaktivieren"
  • ManaBackupCodeRegenerateView — Re-Auth via Passwort, zeigt neue Backup-Codes + Copy-to-Clipboard.
  • TwoFactorAccountRowModel — internes @Observable-VM, reloaded Status nach Enroll/Disable/Regenerate.

Damit ist 2FA in den Apps end-to-end nutzbar — User kann aktivieren, Backup-Codes verwalten, deaktivieren. Der Login-Flow ist seit v0.3.0 durchgängig.

[0.4.0] — 2026-05-14

Minor — 2FA-Enrollment-UI (Mini-Sprint B). Setzt mana-swift-core ≥ 1.4.0 voraus.

Neu

  • ManaTwoFactorEnrollView + TwoFactorEnrollmentViewModel — 3-Phasen-Wizard:
    1. Passwort eingeben (Re-Auth)
    2. QR-Code (via CoreImage.CIFilter.qrCodeGenerator, plattform- unabhängig auf iOS+macOS) scannen + 6-stelligen Test-Code eingeben
    3. Backup-Codes anzeigen + Copy-to-Clipboard
  • ManaTwoFactorDisableView — Single-Step-Sheet, Re-Auth via Passwort + destruktiver Bestätigungs-Button.

Tests

  • 5 neue Tests für Enroll-VM (Success, falsches PW, canSubmitVerify 6-Ziffern-Guard, confirmVerify Phase-Wechsel, backupCodes-Accessor).
  • 44/44 grün.

[0.3.0] — 2026-05-14

Minor — ManaTwoFactorChallengeView für 2FA-Login. Setzt mana-swift-core ≥ 1.3.0 voraus (Status .twoFactorRequired).

Neu

  • ManaTwoFactorChallengeView + TwoFactorChallengeViewModel — 6-stelliger TOTP-Code-Input (Number-Pad auf iOS), Fallback auf Backup-Codes via Toggle, "Abbrechen" routet via auth.signOut(keepGuestMode:) zurück zum Login.
  • LoginViewModel.Status.twoFactorRequired(email:) als neuer Case.
  • ManaLoginView schaltet bei .twoFactorRequired automatisch auf ManaTwoFactorChallengeView um (analog zu .emailNotVerified).

Tests

  • 6 neue Tests für TwoFactorChallengeViewModel: canSubmit-Guards (TOTP 6 Ziffern, Backup beliebig), toggleMode-State-Reset, submit bei Erfolg/Fehler, Backup-Code-Routing.
  • 39/39 grün.

[0.2.0] — 2026-05-13

Minor — Action-Level-Gate für Apps mit Guest-/Login-optional-Modus. Komplett additiv; braucht mana-swift-core ≥ 1.2.0.

ManaAuthUI — neu: ManaAuthGate

  • ManaAuthGate — @Observable-State-Maschine, die eine Aktion erst laufen lässt, wenn der User eingeloggt ist. Wenn nicht, wird das Sign-In-Sheet aufgeklappt und die Aktion gemerkt; nach erfolgreichem Sign-In läuft sie automatisch.
  • Zwei require-Overloads: synchron (() -> Void) und async (() async -> Void). Konsumenten schreiben gate.require { ... } ohne sich um das Gate-Lifecycle zu kümmern.
  • ManaAuthGateModifier / View.manaAuthGate(_:signIn:) — hängt das Sign-In-Sheet an einen Root-View und beobachtet auth.status. Wechsel auf .signedIn schließt das Sheet und löst die Pending- Aktion aus; manuelles Dismiss verwirft die Pending-Aktion.
  • lastReason als optionaler Telemetrie-Hint pro require-Call.

Konvention

Native-Apps sollen mana-swift-core v1.2.0 + Guest-Mode + diesen Gate als Standardweg nutzen. Pattern für Cards/Manaspur/Memoro:

  1. Beim App-Start: bootstrap(), dann bei .signedOut → enterGuestMode().
  2. Root-View zeigt immer App-Inhalte; nie eine Vollbild-Login-Wall.
  3. Aktionen, die einen Account brauchen, werden in gate.require { ... } gewrappt — Login wird zur Inline-Eskalation statt zum App-Block.

Memoro hat dieses Muster informell schon umgesetzt (ContentView ohne Hard-Gate). Cards + Manaspur ziehen mit ihren nächsten Releases nach.

Tests

  • 7 neue Tests für ManaAuthGate: sofortiger Run bei .signedIn, Defer bei .signedOut/.guest, resolvePending nach Sign-In, cancelPending, lastReason-Tracking.

[0.1.0] — 2026-05-13

Phase 2 aus dem Native-Auth-Vollausbau-Plan (Option A, siehe ../mana/docs/MANA_SWIFT.md). Entstanden weil drei Apps fast-byte- identische LoginView.swift-Dateien hatten und Sign-Up/Forgot-PW komplett fehlten.

ManaAuthUI (neu)

  • ManaBrandConfig — App-injiziertes Bündel aus appName, tagline, primary/surface/background/error-Colors. Apps liefern hier ihr Theme (z.B. forest für Cards/Manaspur, default-mana für Memoro).
  • Base-Components: ManaAuthScaffold, ManaPrimaryButton, ManaTextField, ManaSecureField — geteilte Bausteine, alle brand-aware.
  • ManaLoginView + LoginViewModel — Email/PW-Login mit Sign-Up- und Forgot-PW-Buttons. Bei .emailNotVerified automatisch ins ManaEmailVerifyGateView umgeleitet (Resend-Mail-Button).
  • ManaSignUpView + SignUpViewModel — Registrierung mit Email/Name/Passwort. Nach Submit: Bestätigungs-Mail-Hinweis-Screen.
  • ManaEmailVerifyGateView — wenn Login .emailNotVerified warf, bietet "Bestätigungs-Mail erneut senden".
  • ManaForgotPasswordView + ForgotPasswordViewModel — Reset-Mail anfordern. Server antwortet immer 200 (keine User-Enumeration), UI meldet generisch.
  • ManaResetPasswordView + ResetPasswordViewModel — neues Passwort setzen mit Token aus Reset-Mail. Wird aus dem Universal-Link-Handler der App aufgerufen.
  • ManaChangeEmailView, ManaChangePasswordView, ManaDeleteAccountView — Account-Bausteine für die AccountView der App. ManaDeleteAccountView ist App-Store-Pflicht (Guideline 5.1.1(v)) für jede App mit Account-Erstellung.

Tests

  • ViewModel-Tests via URLProtocol-Mock für jeden Auth-Flow.
  • Brand-Config-Defaults.

Bekannte Einschränkungen

  • ManaChangeEmailView/ManaChangePasswordView/ManaDeleteAccountView funktionieren erst nach Phase-3-Server-PR (Bearer-Plugin in mana-auth). UI ist fertig, Wire ist fertig, Server muss nachziehen.
  • 2FA, Magic-Link, Passkey-Flows nicht enthalten. Folgen in v0.2.0 zusammen mit ManaCore v1.2.0 und dem Server-PR.