Blocks
AI Chat Paywall
A premium upsell with a glowing orb, social proof, feature checklist, two plan cards and a trial toggle.
9:41
Try our AI Chat Pro for free
Join 18,742 others who went Pro this week
Higher message limits for Pro conversations
Priority access to latest AI models anytime
Use AI in integrated productivity tools
Adjust AI response speed up to 4.5×
Monthly-5%
$9.05
Annual-15%
$97.88
Monthly charges apply until cancelled in settings. View our Privacy Policy and Terms.
You'll receive an update on July 20
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
@Composable
fun AiChatPaywallScreen(onStartTrial: () -> Unit, onBack: () -> Unit) {
val violet = Color(0xFF7C3AED)
var updateOn by remember { mutableStateOf(true) }
var selected by remember { mutableStateOf(0) }
val features = listOf(
"Higher message limits for Pro conversations",
"Priority access to latest AI models anytime",
"Use AI in integrated productivity tools",
"Adjust AI response speed up to 4.5x",
)
Column(
Modifier.fillMaxSize().background(MaterialTheme.colorScheme.background),
) {
IconButton(onClick = onBack, modifier = Modifier.padding(8.dp)) {
Icon(Icons.AutoMirrored.Filled.ArrowBack, "Back")
}
Box(
Modifier.size(96.dp).align(Alignment.CenterHorizontally)
.clip(CircleShape)
.background(Brush.linearGradient(listOf(violet, Color(0xFF6366F1)))),
)
Text(
"Try our AI Chat Pro for free",
Modifier.fillMaxWidth().padding(top = 16.dp),
textAlign = TextAlign.Center,
style = MaterialTheme.typography.headlineSmall,
fontWeight = FontWeight.ExtraBold,
)
Spacer(Modifier.height(20.dp))
features.forEach { f ->
Row(
Modifier.fillMaxWidth().padding(horizontal = 28.dp, vertical = 6.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Icon(Icons.Filled.Check, null, Modifier.size(18.dp), tint = violet)
Spacer(Modifier.width(12.dp))
Text(f, style = MaterialTheme.typography.bodyMedium)
}
}
Spacer(Modifier.height(16.dp))
Row(
Modifier.padding(horizontal = 16.dp),
horizontalArrangement = Arrangement.spacedBy(12.dp),
) {
listOf("Monthly" to "$9.05", "Annual" to "$97.88").forEachIndexed { i, (label, price) ->
OutlinedCard(
onClick = { selected = i },
modifier = Modifier.weight(1f),
border = if (i == selected) BorderStroke(2.dp, violet)
else CardDefaults.outlinedCardBorder(),
) {
Column(Modifier.padding(12.dp)) {
Text(label, style = MaterialTheme.typography.labelMedium)
Text(price, style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.ExtraBold)
}
}
}
}
Spacer(Modifier.weight(1f))
Row(
Modifier.fillMaxWidth().padding(16.dp),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
) {
Text("You'll receive an update on July 20",
style = MaterialTheme.typography.bodyMedium)
Switch(checked = updateOn, onCheckedChange = { updateOn = it })
}
Button(
onClick = onStartTrial,
modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp, vertical = 8.dp),
shape = CircleShape,
colors = ButtonDefaults.buttonColors(
containerColor = MaterialTheme.colorScheme.onBackground,
contentColor = MaterialTheme.colorScheme.background,
),
) { Text("Start 7 day free trial") }
}
}