Blocks

Meditation Trial

A trial-explainer screen with a night-sky hero, plan toggle and a three-step timeline before billing.

How your trial works

First 5 days free, then $9.99/month

AnnualMonthly

Today

Unlock our library of meditations, sleep sounds, and more

In 3 days

We'll send you a reminder that your trial is ending soon

In 5 days

You'll be charged on December 15, cancel anytime before

You can cancel any time

Terms of UseRestorePrivacy Policy

Installation

caveui components are copy-paste Jetpack Compose built entirely on Material 3 — there's no caveui dependency to add. Make sure Material 3 is on your classpath (it ships with the Compose BOM), then copy the Usage snippet below into your project.

kotlin
// build.gradle.kts (module)
dependencies {
    implementation(platform("androidx.compose:compose-bom:2025.06.00"))
    implementation("androidx.compose.material3:material3")
}

Usage

kotlin
data class TrialStep(val title: String, val body: String, val icon: ImageVector)

@Composable
fun TrialTimelineScreen(onStart: () -> Unit) {
    val purple = Color(0xFF9333EA)
    val steps = listOf(
        TrialStep("Today", "Unlock our library of meditations, sleep sounds, and more", Icons.Filled.Check),
        TrialStep("In 3 days", "We'll send you a reminder that your trial is ending soon", Icons.Filled.Notifications),
        TrialStep("In 5 days", "You'll be charged on December 15, cancel anytime before", Icons.Filled.Star),
    )
    Column(Modifier.fillMaxSize().background(MaterialTheme.colorScheme.background)) {
        Box(
            Modifier.fillMaxWidth().height(180.dp)
                .background(Brush.verticalGradient(listOf(Color(0xFF581C87), Color(0xFFA855F7)))),
            contentAlignment = Alignment.Center,
        ) {
            Box(Modifier.size(64.dp).clip(CircleShape).background(Color(0xFFE9D5FF)))
        }
        Text("How your trial works",
            Modifier.padding(start = 24.dp, top = 12.dp),
            style = MaterialTheme.typography.headlineMedium, fontWeight = FontWeight.ExtraBold)
        Text("First 5 days free, then $9.99/month",
            Modifier.padding(start = 24.dp, top = 4.dp),
            color = MaterialTheme.colorScheme.onSurfaceVariant)
        Spacer(Modifier.height(20.dp))
        steps.forEach { s ->
            Row(Modifier.padding(horizontal = 24.dp, vertical = 8.dp)) {
                Surface(color = purple, shape = CircleShape, modifier = Modifier.size(36.dp)) {
                    Box(contentAlignment = Alignment.Center) {
                        Icon(s.icon, null, tint = Color.White, modifier = Modifier.size(18.dp))
                    }
                }
                Spacer(Modifier.width(12.dp))
                Column {
                    Text(s.title, fontWeight = FontWeight.Bold)
                    Text(s.body, style = MaterialTheme.typography.bodySmall,
                        color = MaterialTheme.colorScheme.onSurfaceVariant)
                }
            }
        }
        Spacer(Modifier.weight(1f))
        Button(
            onClick = onStart,
            modifier = Modifier.fillMaxWidth().padding(16.dp),
            shape = CircleShape,
            colors = ButtonDefaults.buttonColors(containerColor = purple),
        ) {
            Text("Start free trial")
            Spacer(Modifier.width(8.dp))
            Icon(Icons.AutoMirrored.Filled.ArrowForward, null, Modifier.size(18.dp))
        }
    }
}