The standard Android back-gesture preview — the surface scales to ~90%, rounds its corners and shifts toward the swiped edge as the gesture is dragged, then commits or springs back. Plus rememberReduceMotion() to honour the system "remove animations" setting. Drawn from Calendula's CalendarTransitions so both apps preview back the same way; adds the activity-compose dependency. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
floret-kit
The shared Material 3 Expressive design system + plumbing for the Floret family of Android apps (Calendula, Agendula, and future siblings).
"Floret" is the family's design language: a Calendula flower head is a cluster of many small florets, and each app is one of them. This repo is the bloom they share — so a new app doesn't reinvent a settings screen, an edit form, or a theme; it draws from here.
How it's consumed
Each app embeds this repo as a git submodule and wires it in with a Gradle composite build, so the kit is always built from source (no published artifacts — keeps every app reproducible for F-Droid):
// app's settings.gradle.kts
includeBuild("floret-kit")
// app module's build.gradle.kts
implementation("de.jeanlucmakiola.floret:core-time")
Gradle's dependency substitution maps de.jeanlucmakiola.floret:<module> to the
local source module — edit the kit and the app picks it up immediately.
Modules
| Module | What it holds |
|---|---|
core-time |
Pure-Kotlin date/time helpers: local-day windows (DayWindow) for smart-list logic and locale/zone-aware display formatting (Instant.formatDate() / formatTime() / formatDateTime()). No Android, no deps. |
core-reminders |
Pure-Kotlin reminder-lead plumbing: the lead-time unit model (ReminderUnit, decomposeReminderMinutes), the per-target override model (ReminderOverride + reminderLeadFor / applyReminderOverride) and the stored-format codec (ReminderOverrideCodec, separators configurable per app). No Android, no deps. Each app layers its own DataStore + string labels on top. |
core-locale |
Per-app language plumbing (AppLanguage): read the shipped languages from the app's res/xml/locales_config.xml, get/set the applied language via AppCompatDelegate, and render each language's autonym. The app passes its own locales_config resource id; appcompat only, no Compose. |
More modules (identity/theme, components, screen recipes, provider/prefs/crash plumbing) land as they're extracted from the apps.
Build
./gradlew :core-time:test