diff --git a/CHANGELOG.md b/CHANGELOG.md
index 64fa6ca..c1b313b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,6 +17,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
Nothing is deleted and no other app is affected — it's a Calendula-only view
choice — so you can re-enable it any time from the same screen, where disabled
calendars stay listed but dimmed.
+- An optional way to support development. Settings → About now has a "Support
+ development" button that opens Ko-fi in your browser. It's a plain donation
+ link with no perks attached, and it needs no new permissions — Calendula still
+ has no internet access of its own and just hands the link to your browser.
## [2.9.0] — 2026-06-25
diff --git a/README.md b/README.md
index 6753ecc..994ecd2 100644
--- a/README.md
+++ b/README.md
@@ -15,6 +15,12 @@ Reads, writes, and reminds — on top of the system calendar, with zero network
@@ -68,13 +74,20 @@ database, no sync stack reinvented.
## 📦 Install
-Calendula ships through a self-hosted F-Droid repository; every version tag
-is built, signed, and published there automatically.
+### F-Droid (recommended)
-1. Install an F-Droid client ([F-Droid](https://f-droid.org), Droid-ify, Neo
- Store, …).
-2. Add the repository — open this link on your phone, or paste it under
- *Settings → Repositories → Add*:
+Calendula is on the **official [F-Droid](https://f-droid.org) repository** —
+just search for **Calendula** in any F-Droid client, or
+[install it from f-droid.org](https://f-droid.org/packages/de.jeanlucmakiola.calendula/).
+
+### Self-hosted repo (latest builds)
+
+New versions are built, signed, and published to a self-hosted repository the
+moment each tag lands — usually a few days ahead of the official repo, which
+rebuilds on F-Droid's own schedule. Add it for the freshest builds:
+
+1. In your F-Droid client, open *Settings → Repositories → Add* (or open the
+ link below on your phone):
```
https://apps.dev.jeanlucmakiola.de/dev/fdroid/repo?fingerprint=C2C0640402BF458FC0ED957AF0B37AA4C14022E72F89CE90B5965B458CF73425
@@ -84,36 +97,16 @@ is built, signed, and published there automatically.
fingerprint (SHA-256):
`C2C0 6404 02BF 458F C0ED 957A F0B3 7AA4 C140 22E7 2F89 CE90 B596 5B45 8CF7 3425`
-3. Refresh, search for **Calendula**, install. Updates arrive like any
- other F-Droid app.
+2. Refresh, search for **Calendula**, install.
-Alternatively, build from source — see below.
+Both channels share the same signing key, so you can switch between them
+without reinstalling. Or build from source — see below.
-## 🛠 Building
+## 📚 Documentation
-Requires Android SDK 36+ and JDK 17. The Gradle wrapper is checked in:
-
-```bash
-./gradlew assembleDebug # debug APK
-./gradlew test # JVM unit tests
-./gradlew lint # Android lint
-```
-
-If your default JDK is not 17, set `JAVA_HOME` explicitly.
-
-## 🏗 Architecture
-
-Single-activity Compose app, layered `UI → Repository → DataSource →
-CalendarContract`, observer-driven refresh, JVM-first tests. The full tour —
-including the recurring-write and reminder pipelines — lives in
-[docs/ARCHITECTURE.md](docs/ARCHITECTURE.md).
-
-## 🗺 Roadmap
-
-Shipped: read (v1.0), write (v1.1–v2.0), reminder delivery (v1.4).
-Next up: power-user features — widget, search, tablet layouts. The living
-roadmap is in [.planning/ROADMAP.md](.planning/ROADMAP.md), the release
-history in [CHANGELOG.md](CHANGELOG.md).
+- **[Building from source](docs/BUILDING.md)** — requirements and Gradle tasks
+- **[Architecture](docs/ARCHITECTURE.md)** — the layered design and key pipelines
+- **[Roadmap](.planning/ROADMAP.md)** — what's shipped and what's next
## 📜 License
diff --git a/app/src/main/java/de/jeanlucmakiola/calendula/ui/settings/SettingsScreen.kt b/app/src/main/java/de/jeanlucmakiola/calendula/ui/settings/SettingsScreen.kt
index 5863ebd..21a8f7a 100644
--- a/app/src/main/java/de/jeanlucmakiola/calendula/ui/settings/SettingsScreen.kt
+++ b/app/src/main/java/de/jeanlucmakiola/calendula/ui/settings/SettingsScreen.kt
@@ -42,11 +42,13 @@ import androidx.compose.material.icons.filled.CalendarMonth
import androidx.compose.material.icons.filled.Check
import androidx.compose.material.icons.filled.ExpandLess
import androidx.compose.material.icons.filled.ExpandMore
+import androidx.compose.material.icons.filled.Favorite
import androidx.compose.material.icons.filled.Gavel
import androidx.compose.material.icons.filled.Language
import androidx.compose.material.icons.filled.Notifications
import androidx.compose.material.icons.filled.Palette
import androidx.compose.material.icons.filled.Tune
+import androidx.compose.material3.FilledTonalButton
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton
@@ -292,6 +294,7 @@ private fun AboutCard() {
val context = LocalContext.current
val sourceUrl = stringResource(R.string.about_source_url)
val licenseUrl = stringResource(R.string.about_license_url)
+ val supportUrl = stringResource(R.string.about_support_url)
Surface(
color = MaterialTheme.colorScheme.surfaceContainerHigh,
@@ -350,6 +353,19 @@ private fun AboutCard() {
Text(stringResource(R.string.settings_license))
}
}
+ Spacer(Modifier.height(8.dp))
+ FilledTonalButton(
+ onClick = { openUrl(context, supportUrl) },
+ modifier = Modifier.fillMaxWidth(),
+ ) {
+ Icon(
+ Icons.Default.Favorite,
+ contentDescription = null,
+ modifier = Modifier.size(18.dp),
+ )
+ Spacer(Modifier.width(8.dp))
+ Text(stringResource(R.string.settings_about_support))
+ }
}
}
}
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index 42e7f52..aa24a30 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -315,6 +315,7 @@