Tapping an event in the week/day timeline opens a full-screen detail
destination (MD3 list→detail, not a bottom sheet) overlaying the calendar
with a slide transition. One card per field (when, calendar, location,
description, attendees, recurrence) with leading icons; location taps open
a maps intent. Loading/Failure/Success throughout.
Recurrence is humanized from the RRULE — e.g. "Every week on Tue and Thu
until 31 Dec 2026" — covering FREQ/INTERVAL/BYDAY/UNTIL/COUNT with
abbreviated, italicised day names and localized list formatting, falling
back to a generic label for rules it can't render.
Also:
- fix: recurring events failed to open (series row stores DURATION, not
DTEND, so the mapper dropped them as EventNotFound). The detail keeps
them and shows the tapped occurrence's own times from Instances.
- feat: month day cell → opens the day view anchored to that date.
- build: add material-icons-extended (R8 strips unused icons in release).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace the throwaway debug screen with the first real calendar UI and a
functional Month <-> Week switcher, on Material 3 Expressive.
Month view (S1):
- Material 3 Expressive card-per-day grid; only the current month's weeks
render (neighbouring days left blank)
- per-day event dots with "+N" overflow, today via primaryContainer
- spring-based press feedback from the active motion scheme
- swipe + drawer navigation, Loading/Failure/Success states
Week view (S2):
- vertical time schedule with overlap-resolved lanes (per-day clipping,
midnight spanning, instant events)
- all-day / multi-day events as connected horizontal spans
- single scroll container (gutter + day columns stay aligned), columns
bundled in a rounded container, noon-centred on load
- top section colour-shifts with the app bar on scroll; swipe navigation,
three states
Shared / infra:
- CalendarHost holds the active view; RootScreen renders it post-permission
- ui/common building blocks: CalendarDrawer, CalendarFailure,
ViewSwitcherPill, pastelize, observable locale, M3 Expressive slide
transition (motionScheme fastSpatialSpec)
- unit tests for the week layout (lanes, clipping, all-day spans)
- build: compileSdk 37, material3 pinned to 1.5.0-alpha21 for Expressive
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The previous batch fix tried to move ui-tooling-preview to
debugImplementation per a reviewer suggestion, but @Preview is used
in MainActivity.kt which lives in the main source set, so the
annotation class must be available at release-build compile time.
Moving @Preview composables to a debug-only source set would let the
dep stay debug-scoped - that is a Plan 02+ refactor, not foundation
work.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- ROADMAP: mark v0.1 (Foundation & CI) as complete
- REQUIREMENTS: move Foundation & CI from Active to Validated (shipped)
- AndroidManifest: drop redundant android:label and android:theme on
MainActivity - both inherited from <application>
- build.gradle.kts: move ui-tooling-preview to debugImplementation
(@Preview annotations are dev-only; release APK stays smaller)
All foundation verification (lint + test + assembleDebug) still green.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The release workflow (release.yaml) drops a key.properties at project
root and an upload-keystore.jks in app/ from Gitea secrets. This
commit makes Gradle read them when present, configure a 'release'
signing config, and attach it to the release build type. When the
files are absent (local debug builds, fresh clones), the signing
config block is skipped and release builds emit unsigned APKs - that
is the intended local behavior; only CI tags signed releases.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Material 3 Expressive 1.5.0-alpha21 transitively requires
material-ripple-android:1.12.0-alpha03, which mandates compileSdk >= 37
via its AAR metadata. The Android SDK platform 37.0 was installed
locally (already available as a preview).
targetSdk stays at 36 - we compile against API 37 only for the new
material-ripple constants, not to opt into runtime behavior changes.
targetSdk will follow when API 37 reaches stable.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Restore 4-space indent on kotlin-compose plugin alias (regression from
the previous cleanup commit)
- Fix invalid ProGuard rule: HiltAndroidApp is an annotation type, not
a class - use '-keep @dagger.hilt.android.HiltAndroidApp class *' to
actually retain the @HiltAndroidApp-annotated Application
- Remove vectorDrawables.useSupportLibrary - dead config since minSdk 29
(native VectorDrawable support since API 21)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>