package com.peachpasswords.ui.components import androidx.compose.animation.core.Spring import androidx.compose.animation.core.animateDpAsState import androidx.compose.animation.core.spring import androidx.compose.foundation.gestures.Orientation import androidx.compose.foundation.gestures.scrollable import androidx.compose.foundation.gestures.rememberScrollableState import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.peachpasswords.ui.theme.LocalReduceMotion import com.peachpasswords.ui.theme.PeachSpacing import com.peachpasswords.ui.theme.peachColors @Composable fun PeachExpandableCard( modifier: Modifier = Modifier, collapsedHeight: Dp = 168.dp, expandedHeight: Dp = 360.dp, content: @Composable ColumnScope.(progress: Float) -> Unit, ) { val reduceMotion = LocalReduceMotion.current var progress by remember { mutableFloatStateOf(0f) } val animatedHeight by animateDpAsState( targetValue = collapsedHeight + (expandedHeight - collapsedHeight) * progress, animationSpec = if (reduceMotion) { spring(stiffness = Spring.StiffnessHigh, dampingRatio = Spring.DampingRatioNoBouncy) } else { spring(stiffness = Spring.StiffnessLow, dampingRatio = Spring.DampingRatioMediumBouncy) }, label = "peach_expandable_card_height", ) val scrollState = rememberScrollableState { delta -> val old = progress progress = (progress + delta / 900f).coerceIn(0f, 1f) if (old == progress) 0f else delta } Surface( modifier = modifier .fillMaxWidth() .height(animatedHeight) .scrollable(scrollState, orientation = Orientation.Vertical), color = peachColors.SurfaceElevated, // Gate 1: colorScheme.onSurface is PeachTheme's exact mapping of T0. contentColor = MaterialTheme.colorScheme.onSurface, shape = RoundedCornerShape(18.dp), tonalElevation = 1.dp, ) { Column(Modifier.padding(PeachSpacing.lg)) { content(progress) } } }