48 Commits
Author SHA1 Message Date
adminandClaude Opus 5.5 abbfc56a7a fix(mobile): Tierliste nach Foto-Upload neu laden, Abschluss zeigt Foto
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 08:21:36 +02:00
adminandClaude Opus 5.5 d81f080077 docs(mobile): found.md – Einladen/Onboarding per OTA ausgeliefert
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 07:22:32 +02:00
adminandClaude Opus 5.5 fdc41b7b69 feat(mobile): Rest zu 0ec0583 – Onboarding-Schritte, InviteCard-Inhalt, Texte
Der vorige Commit enthielt durch einen fehlgeschlagenen git add nur die
Umbenennungen und Löschungen. Hier folgen die eigentlichen Änderungen:
neue Onboarding-Schritte (flow/), InviteCard/RankLadder/invite.tsx,
Reveal-Importpfade, DE/EN-Texte und der found.md-Eintrag.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 07:14:50 +02:00
adminandClaude Opus 5.5 b50c982f86 docs(mobile): found.md – Login-Rework per OTA ausgeliefert
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 06:38:30 +02:00
adminandClaude Opus 5.5 53e1af5196 feat(mobile): Login und Registrierung neu gestaltet (Logo, Animationen, Android-Gesten)
- Gemeinsamer AuthShell: Logo + Wortmarke oben, Sprach-Chip mit Menü,
  Formular unten in der Daumenzone, Apple/Google unter "oder weiter mit"
- Animationen mit eingebautem Animated (OTA-fähig): Logo federt rein,
  gestaffeltes Einblenden, Fokusrahmen, Ladekringel, Wackeln bei Fehler;
  respektiert "Bewegung reduzieren"
- Android: Safe-Area für Status- und Gestenleiste, Seitenrand außerhalb der
  Zurück-Wischzone, Sprachmenü als Modal (Zurück schließt nur das Menü),
  KeyboardAvoidingView auch auf Android (Edge-to-Edge)
- Registrierung: Google/Apple nicht mehr ausgegraut; ohne Zustimmung
  markiert ein Tipp die Checkbox und zeigt einen Hinweis

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 06:33:27 +02:00
adminandClaude Opus 5.5 9ba965ae11 docs(mobile): found.md — OTA für Vermisst-Dialoge
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 06:20:44 +02:00
adminandClaude Opus 5.5 b1d3b61339 fix(mobile): Vermisst-Dialoge auf Android nicht mehr abgeschnitten
Android kürzt Alert-Titel auf zwei Zeilen. Lange Texte stehen jetzt als
Nachricht unter einem kurzen Titel (Meldung gestartet, Entwarnung, Fehler).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 21:09:32 +02:00
adminandClaude Opus 5.5 b244ef4c10 docs(mobile): found.md — Mitteilungen fuehren direkt zum Ziel
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 17:56:34 +02:00
adminandClaude Opus 5.5 9cf8369307 docs(mobile): found.md — Story-Mitteilung oeffnet Story
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 17:32:31 +02:00
adminandClaude Opus 5.5 53d1382ac0 docs(mobile): found.md — Story-Editor iOS/Android-Fix
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 17:23:34 +02:00
adminandClaude Opus 5.5 84a430a92a docs(mobile): found.md — Story-Editor live
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 16:57:46 +02:00
adminandClaude Opus 5.5 a907654de5 docs(mobile): found.md — Research gemeinsame Tierhalter
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 16:48:36 +02:00
adminandClaude Opus 5.5 0a0ff90745 docs(mobile): found.md — Raenge im Admin, Nachrichten-Badge, Profil-Ring
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 15:17:01 +02:00
adminandClaude Opus 5.5 361aba0d1d docs(mobile): found.md — Gewichtsdiagramm
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 14:55:19 +02:00
adminandClaude Opus 5.5 81e617ece5 fix(admin): Melder-Nachricht grammatisch korrekt (zum Beitrag/Profil)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 13:16:48 +02:00
adminandClaude Opus 5.5 c678c4cf27 docs(mobile): found.md — Rassensuche + Report-Rückmeldung
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 13:16:12 +02:00
adminandClaude Opus 5.5 a2af4eda6a docs(mobile): found.md — iOS-Tastatur verdeckt Datumsfeld
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 12:56:09 +02:00
adminandClaude Opus 5.5 9136981af7 docs(mobile): found.md — Impf-Erinnerung live
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 12:52:20 +02:00
adminandClaude Opus 5.5 6a88214186 docs(mobile): found.md — Datum TT.MM.JJJJ + Impf-Erinnerung
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 12:46:30 +02:00
adminandClaude Opus 5.5 80e27a7f0b docs(mobile): found.md — Upload-Fortschritt Video-Storys
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 14:47:03 +02:00
adminandClaude Opus 5.5 6979447b6d docs(mobile): found.md — Video-Storys per OTA live
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 14:29:48 +02:00
adminandClaude Opus 5.5 a9b6a57585 docs(mobile): found.md — HEIF-Fix vom Nutzer bestätigt
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 21:37:50 +02:00
adminandClaude Opus 5.5 9f7acf1d98 docs(mobile): found.md — 7-Tage-Story-Ansicht deployt
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 19:35:46 +02:00
adminandClaude Opus 5.5 2c0680cef9 feat: 7-Tage-Ansicht der eigenen Storys für den Ersteller (Web + App)
- stories.listActive: der Owner bekommt seine Storys der letzten 7 Tage mit
  isExpired, alle anderen weiterhin nur die aktiven 24 Stunden
- stories.hasActiveStory: optional includeOwnRecent → grauer Ring
  (expiredOnly) nur in der Story-Leiste, nicht an Profilbildern im Feed
- Viewer: Hinweis "Abgelaufen – nur für dich sichtbar", Kommentare bei
  abgelaufenen Storys nur lesbar, Pfote nur als Zähler; Löschen und
  Zuschauerliste bleiben

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 19:30:22 +02:00
adminandClaude Opus 5.5 a01c58e5f0 feat: Aufräum-Job für Storys älter als 7 Tage
- /api/cron/cleanup-stories (CRON_SECRET): löscht Storys älter als 7 Tage
  samt Aufrufen, Pfoten, Kommentaren, Supabase-Bild und Mux-Asset; max. 200
  pro Lauf, Fehler einzelner Storys brechen den Lauf nicht ab
- gemeinsame Funktion deleteStoryWithMedia (src/lib/story-cleanup.ts), auch
  von stories.delete genutzt
- Datenschutzerklärung Abschnitt 6: Storys spätestens nach 7 Tagen gelöscht
- Datenexport: Story-Block heißt "stories" statt "activeStories"
- CLAUDE.md: Cron-Jobs laufen über die NAS-Crontab + docker/run-cron.sh
  (der alte Hinweis "nichts ruft trim-feeds auf" war veraltet)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 16:43:07 +02:00
adminandClaude Opus 5.5 ac664d488d docs(mobile): found.md — Story löschen deployt
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 21:21:12 +02:00
adminandClaude Opus 5.5 81d9c6da30 feat: eigene Story löschen (Web + App)
- stories.delete: nur Owner; Aufrufe, Story (Pfoten/Kommentare per Cascade),
  danach Bild in Supabase Storage bzw. Mux-Asset best-effort
- Web: Papierkorb neben der Zuschauerzahl + Rückfrage, Timer pausiert,
  gelöscht wird die beim Antippen gemerkte Story
- App: gleicher Papierkorb mit nativer Rückfrage, Timer pausiert
- found.md: Nutzer-Feedback "Story löschbar" erledigt, 7-Tage-Wunsch mit
  Befund als offener Punkt

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 21:17:16 +02:00
adminandClaude Opus 5.5 4ec5d8c5f4 docs(mobile): found.md — Story-Fixes deployt (Web + OTA)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 21:03:06 +02:00
adminandClaude Opus 5.5 ccebfa46a6 feat: Story-Kommentare, Pfoten und Zuschauerliste in der App
- App-Viewer: Pfote, Kommentar-Sheet (schreiben, eigene löschen) und für die
  eigene Story die Zuschauerliste; Timer pausiert, solange ein Sheet offen ist
- stories.listActive: optionales viewerPetId → reactedByViewer, damit die
  Pfote gefüllt startet (abwärtskompatibel für alte App-Builds)
- Web-StoryPawButton nutzt reactedByViewer ebenfalls und wird pro Story
  neu initialisiert

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 20:59:02 +02:00
adminandClaude Opus 5.5 204d5f6831 fix: eigene Story als Ring "Deine Story" in der Story-Leiste (Web + App)
Die Leiste zeigte nur Storys gefolgter Tiere — das eigene aktive Tier war
nie enthalten, man konnte die eigene Story nach dem Posten nicht ansehen.
Neuer Ring direkt nach der "+"-Kachel, solange stories.hasActiveStory für
das aktive Tier true ist.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 20:46:29 +02:00
adminandClaude Opus 5.5 1a24ebae89 docs(mobile): found.md — HEIC-Fix deployt (Web + OTA)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 20:32:11 +02:00
adminandClaude Opus 5.5 1bf0f9282a fix: HEIF/HEIC-Fotos (Apple) für Beiträge und Storys annehmen
- App: post-new.tsx sortierte HEIC/HEIF still aus, obwohl resizeForUpload()
  ohnehin in JPEG umwandelt — jetzt erlaubt, plus Hinweis bei übersprungenen
  Fotos
- Web: neues src/lib/heic-to-jpeg.ts wandelt HEIC vor dem Upload im Browser
  in JPEG um (Safari kann HEIC nativ dekodieren); eingebaut in Beiträge,
  Storys, Meilensteine und Tierbild, accept um HEIC ergänzt. Browser ohne
  HEIC-Dekodierung bekommen eine klare Meldung statt "falsches Format".
- Server-Whitelist (JPEG/PNG/WebP) bleibt unverändert

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 20:26:24 +02:00
adminandClaude Opus 5.5 2cd13537f7 docs(mobile): found.md — gesture-bar and story-ring fixes shipped via OTA
Also includes the user's own pending found.md edits (new entries, iOS
section header, trailing-whitespace cleanup).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 12:43:26 +02:00
adminandClaude Sonnet 5 779f18966d docs(mobile): note main-merge and OTA publish for sso-callback fix
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-22 17:36:04 +02:00
adminandClaude Sonnet 5 17a17bd392 fix(mobile): add sso-callback route to fix Unmatched Route on Android Google login
Multiple users reported "Unmatched Route pawfeed://sso-callback" after
Google sign-in. Root cause: Android's custom tab delivers the OAuth
redirect intent to the app twice — once caught correctly by
expo-web-browser's openAuthSessionAsync() session, but also as a plain
deep link seen by expo-router's own Linking listener. With no matching
route, expo-router briefly showed its built-in Unmatched Route error
screen instead of letting the real sign-in flow (GoogleSignInButton ->
setActive -> router.replace) take over.

Adds app/sso-callback.tsx as a themed loading spinner so expo-router has
a valid screen for that window; no auth logic needed there since
useProtectedRoute() in app/_layout.tsx already redirects based on
Clerk's session state. JS-only change, OTA-deployable, no native rebuild
needed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-22 17:24:35 +02:00
adminandClaude Sonnet 5 1e8e6bbd7d docs: document Clerk redirect-URL allowlist as the Google SSO gotcha
Google SSO broke live with 'redirect url ... does not match an
authorized redirect URI ... pawfeed://sso-callback', despite the SSO
code (99575dd) being unchanged. Root cause was outside the repo
entirely: Clerk's per-instance authorized-redirect-URL allowlist is
server-side config (CLERK_SECRET_KEY-authenticated Backend API), not
tracked in git, and only had a stale org.pawfeed.app2 entry - the
current pawfeed:// scheme's callback was never registered.

Fixed live via POST https://api.clerk.com/v1/redirect_urls (no app
deploy needed), verified through the Google consent screen on an
emulator and end-to-end by the user on a real device.

Documented in both mobile/found.md (full incident) and README.md's
Known Issues table (the reusable gotcha: check Clerk's redirect-URL
allowlist before debugging app code when SSO breaks unexpectedly).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-19 18:30:43 +02:00
adminandClaude Sonnet 5 31b3f7b81b docs(mobile): note merge/verification/OTA-publish in found.md
Adds the merge commit (30c57b6), emulator end-to-end verification, and
OTA update group reference to the Settings-header-icon found.md entry.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-19 18:21:04 +02:00
adminandClaude Sonnet 5 be5a333de1 feat(mobile): move Settings out of Meine Tiere into a header-icon screen
Closes Gitea #36. Plan: ~/.claude/plans/mobile-settings-tab-extraction.md.

Extracts the 5 footer sections pets.tsx had grown (Darstellung, Sprache,
Tier-Vorschlaege opt-out, Rechtliches+Version/OTA, Abmelden) into their
own files under src/components/settings/, and a new app/(app)/settings.tsx
screen reached via a gear icon in every tab's header, next to Messages -
not a 5th bottom tab. Chosen over a tab (see the two mockups in the plan
folder) because Settings is a low-frequency destination for a typical
user; the header icon still reaches it in one tap from anywhere without
spending permanent bottom-nav space on it.

settings.tsx lives outside (tabs)/, registered as a plain Stack.Screen
(app/(app)/_layout.tsx) matching search.tsx's pattern - normal back-arrow
push, no presentation:modal, no tab bar visible while it's open.
SettingsHeaderButton is wired into (tabs)/_layout.tsx's global headerRight
default plus the 3 tabs (index/explore/pets) that override it.

pets.tsx is pet-list-only again. FooterErrorBoundary now wraps the whole
Settings screen instead of only the logout button, closing a gap a prior
code review found (AppearanceSection/LegalSection were rendering
unprotected).

Code-reviewed before commit (WORKFLOW.md step 6) - fixed two of three
findings: extracted the section/sectionTitle style duplicated across
AppearanceSection/LanguageSection/PetSuggestionsSection into a shared
sectionTitleStyle.ts, and reduced every header icon's hitSlop 12->8 (rows
can now hold 3 icons with gap:16; 12+12=24 overlapped the gap, 8+8=16
exactly meets it - see the comment on headerButtons in (tabs)/_layout.tsx).
Left the pets.* i18n namespace as-is on the moved strings (documented in
settings.tsx's doc comment) - pets.language* is shared with the pre-login
LanguageSwitcher, so a partial rename would misdescribe those call sites.

Typecheck + lint clean across all touched/new files, i18n key parity
verified (de/en).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-19 12:39:34 +02:00
adminandClaude Sonnet 5 be2ab20273 fix(mobile): dark-mode white-on-white search input text
Same root cause as post-new.tsx/story-new.tsx: search.tsx imported the
static light-only colors/typography instead of useTheme(). Bigger
refactor than the other two since TabButton/PetRow/Loading/EmptyState
are separate top-level components, not closures inside the screen -
they now receive styles/colors as props from the theme-aware
makeStyles(colors) built in SearchScreen, rather than importing the
static tokens themselves.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-19 09:44:12 +02:00
adminandClaude Sonnet 5 9185e54402 fix(mobile): dark-mode white-on-white caption text in New Post
post-new.tsx (and story-new.tsx, same latent bug) still imported the
static, light-only colors/typography from theme/tokens.ts instead of
useTheme() - container background stayed permanently light while the
shared TextField correctly pulled dark-mode text color from the theme,
producing white text on a white background in the caption input.

Migrated both to the useTheme() + makeStyles(colors) pattern already
used by milestone-new.tsx. search.tsx has the same underlying issue but
needs a larger refactor (several sub-components reference the static
tokens directly) - left for a separate pass, noted in found.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-18 22:25:08 +02:00
adminandClaude Sonnet 5 e9bad092f2 feat: pet-suggestion notifications, story music overlay, auth UX fixes
Three pieces of work from this session:

- Pet-suggestion notifications: a weekly cron (species/breed affinity
  heuristic) suggests pets to follow, with an owner opt-out and web/mobile
  notification UI wiring.
- Story music overlay: admin-curated royalty-free track catalog
  (/p/[secret]/music), attachable to stories on web (StoryForm/StoryViewer),
  with mute-original support for video stories. Mobile UI is deferred to
  the next native build (needs an audio-playback module) — tracked in
  mobile/PENDING-NATIVE-BUILD.md.
- Auth UX fixes: sign-in/sign-up now use KeyboardAvoidingView + ScrollView
  and a shared PasswordField with a show/hide toggle (mobile). Web's
  ActivePetContext gained clearGactivePetId(), wired to sign-out via a new
  SignOutCleanup component, fixing a false "you do not have permission to
  access this pet" error after switching accounts on the same browser.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-14 21:02:49 +02:00
admin df4d5ccec2 fix(mobile): video-loop, breed/birthday edit, avatar zoom, milestone dark mode
- Videos kept looping forever after scrolling off-screen (expo-video has
  no visibility awareness). New useVisiblePostIds hook tracks FlatList
  viewability and pauses VideoPlayer once a post scrolls away, wired
  into both the feed and the pet-profile post list.
- Pet edit screen couldn't change breed or set birthday/adoption date,
  even though the backend (pets.update) already supported all three —
  web already used them. Extracted BreedPicker out of PetCreateForm
  into a shared component, added it plus TT-MM-JJJJ date fields (same
  validation pattern as the health forms) to edit.tsx. Its BreedPicker
  nests a ScrollView, so edit.tsx's outer ScrollView was swapped for a
  FlatList to avoid the same nested-scroll gesture conflict fixed
  earlier for onboarding/pet.tsx.
- Pet profile's own avatar was a plain, non-tappable Image. Tapping it
  now opens the existing /image-viewer (same pinch-to-zoom viewer post
  images already use) when the pet has an avatar set.
- milestones.tsx and milestone-new.tsx still imported the static
  light-only colors/typography tokens instead of useTheme() — switched
  to the established makeStyles(colors) pattern.
2026-09-07 21:33:23 +02:00
admin f700000e87 fix(mobile): dark mode + nested-scroll fix in pet creation, invalidate pets.list after create
- PetCreateForm.tsx and onboarding/pet.tsx used the static light-only
  colors/typography tokens instead of useTheme() — pet creation stayed
  light even in dark mode.
- onboarding/pet.tsx wrapped its steps in a plain ScrollView; the breed
  OptionPicker nests its own vertical ScrollView, and two same-axis
  ScrollViews swallow the inner one's scroll gesture on Android even
  with nestedScrollEnabled. Switched the outer container to a FlatList
  (empty data + ListHeaderComponent), matching explore.tsx's already
  working fix for the same component.
- pets.create's mutation never invalidated trpc.pets.list, so
  ActivePetContext kept seeing zero pets after the first pet was
  created — OnboardingRedirect then bounced the user straight back to
  /onboarding/pet after the avatar step, with only an app restart
  breaking the loop. Added the missing invalidateQueries call.
2026-09-07 21:16:31 +02:00
admin 82c9bb87b9 feat(mobile): add multi-image indicator to feed posts
Multi-photo posts gave no visual hint they were swipeable — a viewer
would only ever see the first image unless they already knew to swipe.
Adds a "1 / N" counter badge (top-right overlay) and a dot-page
indicator below the carousel, porting web's PostCard indicators.
2026-09-06 20:12:21 +02:00
admin 086b0e8900 docs(mobile): update found.md for notification/comments dark-mode fixes 2026-09-06 19:57:31 +02:00
admin 73ea97ac16 fix(mobile): notification separators/navigation, own-post delete option
Notifications: add a visible hairline separator between rows and make
each row tappable — it marks read and navigates to the relevant post
(comments screen) or pet profile, porting web's getHref()/getPostId()
routing logic.

Feed: the "..." menu on a post now opens a delete confirmation instead
of the report sheet when the post belongs to the currently active pet;
report sheet stays unchanged for posts from other pets. Reuses the
pre-existing posts.delete mutation, no backend changes needed.
2026-09-06 19:39:52 +02:00
admin 4a35fce20b fix(mobile): found.md batch — reports, dark mode, health form fixes
- new report feature: a "..." button on every post opens a reason-picker
  sheet (reports.create), matching web's ReportSheet reasons/copy
- pet profile, edit, followers/following, and the whole health screen
  (incl. consent gate) converted to the makeStyles(colors) dark-mode
  pattern
- fixed the invisible back button on every pushed (app)/_layout.tsx
  screen: headerTintColor was never set, so the native-stack default
  back chevron kept its platform tint instead of the theme color —
  black-on-black in dark mode looked like a missing button entirely
- health forms (weight/vet visit/vaccine) now take dates as DD-MM-YYYY
  instead of the backend's raw YYYY-MM-DD, converting internally
  (src/lib/date-format.ts); invalid dates now show an error instead of
  the mutation silently failing with no onError handler at all — this,
  not persistence, was the actual "Gesundheitsdaten werden nicht
  gespeichert" bug
- pinch-to-zoom on the full-screen image viewer via a plain
  PanResponder (no new native dependency)
- Pets tab: language switcher now uses flag emoji (🇩🇪/🇬🇧/🌐), and a
  new footer section links Impressum/Datenschutz/Nutzungsbedingungen
  plus the installed app version

All live-verified against the deployed backend except pinch-zoom
(two-finger gestures aren't simulatable over adb).
2026-09-06 18:55:12 +02:00
admin 0c6421c8de fix(mobile): dark mode on Explore/Notifications, breed dropdown overlay
- Explore and Notifications tabs now read colors from ThemeContext
  instead of the static light-only tokens
- OptionPicker's option list is position:absolute so it overlays
  following content instead of pushing it down, with zIndex on the
  component root (and FlatList's ListHeaderComponentStyle on Explore)
  so it actually paints above sibling content instead of underneath it
- check off found.md's resolved items, record the three newly reported ones
2026-09-06 16:30:02 +02:00