Phase 1: all rows slide up together until selected row reaches y=0.
Phase 2: rows below selected row slide up as a group.
No per-row height scaling, only y-offset translation + fade.
Rows now keep full height and slide upward sequentially instead of
compressing. The anchor row (selected) moves to y=0 and stays fixed;
other rows exit top-to-bottom with staggered timing.
Apply consistent formatting: import ordering, line wrapping,
indentation, and XML normalization. No functional changes.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
When month or week number changes, the text slides vertically with fade:
upward for increasing values, downward for decreasing values, using
slideInVertically/slideOutVertically with tween(250).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Replace hard-switched background/border modifiers with updateTransition-based
animated properties: revealProgress for circular indicator radius, contentColor
and selectedColor via animateColor, borderAlpha for today stroke. Use drawBehind
for custom circle drawing with tween(250, FastOutSlowInEasing) spec.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Use pagerState.currentPageOffsetFraction to compute alpha for page content:
alpha drops from 1 to 0 as offset goes from 0% to 30%, preventing
mid-point brightness dip (combined alpha of adjacent pages always >= 1f).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Non-selected rows now fade out with alpha = 1f - collapseProgress via
graphicsLayer, naturally following the spring animation curve. When
rowScale < 0.1f and collapseProgress > 0.9f, DayCell rendering is
skipped and replaced with an empty Spacer to reduce draw overhead at
the end of the collapse animation.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Collapse triggers when progress > 0.25 (was 0.5). Expand triggers when
progress < 0.75 (1 - threshold), creating asymmetric thresholds that make
both fold and unfold easy to trigger with a short drag.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Quick swipe now snaps to the target state regardless of progress position,
matching the behavior of HorizontalPager's fling logic. Uses VelocityTracker
to measure release velocity and a 800 dp/s threshold (FLING_VELOCITY_THRESHOLD_DP).
Slow drags still use the positional COLLAPSE_THRESHOLD (50%) as before.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The fixed DRAG_RANGE_DP=200dp caused the collapse progress to advance faster
than the visual height change, making the calendar feel like it "outruns" the
finger. Now dragRangePx is computed as (weeks-1)×rowHeight, matching the
actual visual height delta during collapse so finger movement maps 1:1 to
visual change.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Inject Clock into CalendarViewModel for testability, add kotlinx-coroutines-test dependency, replace placeholder test with real coverage for ISO week numbers, month day grids, page mapping, and utility functions.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Move padding after onSizeChanged in CalendarMonthPage so row height
measurement excludes padding. Rename p→collapseProgress for clarity.
Add comments explaining grid height calculation and pager switching.
Increase ROW_PADDING_DP from 4 to 6.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Card gap now interpolates between 24dp (expanded) and 12dp (collapsed)
instead of using a fixed value, providing a smoother visual transition.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Include CARD_GAP_DP in calendar area height calculation so BottomCard
positioning accounts for the gap. Add horizontal padding to MonthHeader
for better visual alignment.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
WeekPager had no height constraint (unlike CalendarPager which uses
pagerModifier with gridHeightPx), causing the pager to freely expand
instead of staying at the computed single-row height. Also, WeekPager
used 2dp row padding while CalendarMonthPage uses ROW_PADDING_DP (4dp),
creating a height mismatch at the switch point.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
gridHeightPx changed from derivedStateOf to direct computation because
derivedStateOf cannot track non-State local variable changes, causing
gridHeightPx to not update when rowHeightPx transitions from 0 to measured value.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Move shared constants and helper functions into CalendarUtils.kt,
replace manual state synchronization with derivedStateOf in
CalendarViewModel and UI composables.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Remove unused currentWeeksCount variable and onWeeksChanged callback
- Replace deprecated monthNumber with month.number (requires explicit import)
- Remove all @Suppress("DEPRECATION") annotations for monthNumber
- Convert double comparison to range check (today in weekMonday..weekSunday)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Replace hardcoded padding values with constants, use Spacer instead of
space character for spacing, remove fontSize override on bodySmall, and
fix WeekdayHeader modifier order (padding before onSizeChanged).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Use currentPage instead of settledPage for interpolatedWeeks calculation
to prevent gridH jumps during month transitions. When offsetFraction is
near zero, compute weeks from currentPage rather than stale callback
state. Remove all debug println statements and TAG constants.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Pass effectiveWeeks from CalendarMonthView through CalendarPager to
CalendarMonthPage so both use the same formula H*(1+(weeks-1)*(1-p)).
Fix interpolatedWeeks to anchor on settledPage instead of currentPage,
preventing direction/fraction discontinuity when currentPage jumps during
swipe transitions.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Replace the fragile approach of computing rowHeightPx by dividing
Column height by weeks count with direct measurement via onSizeChanged
on the first DayCell row. Add estimated row height fallback based on
screen width and cell aspect ratio so the pager can be constrained
before the first measurement completes. Remove lockedRowHeightPx,
expandedWeeksCount, and calendarHeightPx state variables that are no
longer needed.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Clean up println debug logging and TAG constants added for
diagnosing the collapse animation issue. CalendarViewModel and
BottomCard restored to pre-debug versions; CalendarMonthView
and CalendarMonthPage cleaned inline.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add rowHeightPx parameter to CalendarPager and pass it through to
CalendarMonthPage. Remove onRowHeightMeasured callback which is no
longer needed since CalendarMonthPage now receives row height
externally. Update CalendarMonthView to pass rowHeightPx to CalendarPager.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Replace internal rowHeightPx measurement with external rowHeightPx
parameter passed from CalendarMonthView. This eliminates the mismatch
between outer gridHeightPx (based on shrinking container) and inner
totalHeightDp (based on independently measured row height), which was
causing visual jitter during collapse animation.
Remove onRowHeightMeasured callback, TAG constant, and debug printlns
from CalendarMonthPage as part of this refactor.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add lockedRowHeightPx state that is only updated when fully expanded
(p < 0.01f). During collapse, rowHeightPx uses the locked value instead
of recalculating from the shrinking container height, which was causing
rowH to drop from 137→0 and gridH to become 0 at p=1.0.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Calculate actual weeks needed per month and interpolate row count during
page swipe so BottomCard follows the grid height smoothly. Remove debug
println statements.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Distinguish the selected-today state from regular selection by using
primaryContainer/onPrimaryContainer instead of primary/onPrimary,
providing a softer visual treatment for the combined state.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
When swiping to a different month or week, select today if it falls
within the target period instead of always picking the 1st or Monday.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Adding .drop(1) prevents the settledPage flow from firing on initial
composition, which would override the "today" date selection.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Select the Monday of the week when WeekPager changes, and the 1st of
the month when CalendarPager changes, so the selected date always
matches the visible page.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Switch CalendarMonthPage from Column to Box with calculated y positions per row,
enabling precise height computation that aligns with CalendarMonthView's
BottomCard positioning. Simplify cardTopPx calculation by deriving grid height
from the same formula instead of tracking expandedCalendarHeightPx separately.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Non-selected rows now compress their height proportionally with
collapse progress, replacing the previous overlay-based approach.
Remove KDoc that described the old overlay behavior.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Selected row now moves up via offset + zIndex to cover other rows, which
stay in place. Collapse offset calculation excludes MonthHeader and
WeekdayHeader heights so only the grid portion is collapsed.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
When rowHeightPx is 0 (first frame), use aspectRatio-based natural
height instead of collapsing to 0.dp, preventing a visible flash.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>