4e097b1b4521
chaos destroy screen: red header 'THIS IS YOUR LAST CHANCE', three single-sentence warnings in breach red, solid red 'DESTROY MY VAULT FOREVER' button, 'No — take me back' escape (v2.7.11)
- time
- 2026-07-28 01:25 UTC · 2 months ago
- machine
- koh2
- agent
- claude-MiniMax-M3
- session
- sync red indicator port from browser
- parent
- e8637519f572
↓ peach-android-4e097b1b.tar.gzatlas at this save
files changed2 files
app/build.gradle+2 −2app/src/main/java/com/peachpasswords/ui/settings/PanicScreen.kt+82 −14app/build.gradle+2 −2
@@ -16,8 +16,8 @@1616 applicationId "com.peachpasswords"1717 minSdk 261818 targetSdk 3519- versionCode 24013720- versionName "2.7.10"19+ versionCode 24013820+ versionName "2.7.11"2121 2222 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"2323 vectorDrawables {app/src/main/java/com/peachpasswords/ui/settings/PanicScreen.kt+82 −14
@@ -35,7 +35,6 @@3535 import androidx.hilt.navigation.compose.hiltViewModel3636 import androidx.lifecycle.ViewModel3737 import androidx.lifecycle.viewModelScope38-import com.peachpasswords.ui.components.PeachField3938 import com.peachpasswords.ui.components.RuneGridBackground4039 import com.peachpasswords.ui.components.PeachTopBar4140 import com.peachpasswords.ui.theme.LocalPeachAccent@@ -131,7 +130,7 @@131130 when (step) {132131 1 -> Step1(onCancel = onBack, onContinue = { step = 2 })133132 2 -> Step2(entryCount = entryCount, onBack = { step = 1 }, onContinue = { step = 3 })134- else -> Step3(onDestroy = { vm.destroy(onDestroyed) })133+ else -> Step3(onBack = { step = 2 }, onDestroy = { vm.destroy(onDestroyed) })135134 }136135 }137136 }@@ -179,19 +178,88 @@179178 }180179 181180 @Composable182-private fun Step3(onDestroy: () -> Unit) {183- var typed by remember { mutableStateOf("") }184- val confirmed = typed == "DESTROY"181+private fun Step3(onBack: () -> Unit, onDestroy: () -> Unit) {182+ // Chaos: the final step is designed to look like a point of no return.183+ // Bright red header, three single-sentence warnings, one solid red button.184+ // The user has already confirmed at Step1 and Step2; this screen is185+ // deliberately stark rather than carrying a third confirmation gate, so186+ // the only escape is the "No — take me back" line under the button.187+ Column(modifier = Modifier.fillMaxSize()) {188+ // Red header bar — the visual claim that this screen is different.189+ Box(190+ modifier = Modifier191+ .fillMaxWidth()192+ .background(peachColors.Breach)193+ .padding(vertical = 12.dp, horizontal = PeachSpacing.lg),194+ contentAlignment = Alignment.Center,195+ ) {196+ Text(197+ "THIS IS YOUR LAST CHANCE",198+ color = peachColors.ShellTopSolid,199+ style = PeachType.sortPill.copy(200+ fontSize = 12.sp,201+ fontStyle = FontStyle.Italic,202+ ),203+ )204+ }205+ Spacer(Modifier.height(PeachSpacing.lg))206+ Text(207+ "Your vault is about to be permanently destroyed.",208+ color = peachColors.T0,209+ style = PeachType.body,210+ )211+ Spacer(Modifier.height(PeachSpacing.lg))212+ Text("There is no recovery.", color = peachColors.Breach, style = PeachType.body)213+ Text("There is no support.", color = peachColors.Breach, style = PeachType.body)214+ Text("There is no undo.", color = peachColors.Breach, style = PeachType.body)215+ Spacer(Modifier.height(PeachSpacing.lg))216+ // Hairline divider, matches the body-copy t3 token used elsewhere.217+ Box(218+ modifier = Modifier219+ .fillMaxWidth()220+ .height(1.dp)221+ .background(peachColors.T3.copy(alpha = 0.25f)),222+ )223+ Spacer(Modifier.weight(1f))224+ ChaosDestroyButton("DESTROY MY VAULT FOREVER", onClick = onDestroy)225+ Spacer(Modifier.height(PeachSpacing.sm))226+ Box(227+ modifier = Modifier.fillMaxWidth(),228+ contentAlignment = Alignment.Center,229+ ) {230+ Text(231+ "No — take me back",232+ color = peachColors.T2,233+ style = PeachType.sortPill.copy(fontSize = 11.sp),234+ modifier = Modifier235+ .clip(RoundedCornerShape(999.dp))236+ .clickable(onClick = onBack)237+ .padding(horizontal = PeachSpacing.lg, vertical = 8.dp),238+ )239+ }240+ }241+}185242 186- Headline("type DESTROY to confirm", 28.sp, peachColors.T0)187- Spacer(Modifier.height(PeachSpacing.lg))188- PeachField(189- label = "confirmation",190- value = typed,191- onValueChange = { typed = it },192- )193- Spacer(Modifier.height(PeachSpacing.xl))194- DangerButton("Destroy vault", enabled = confirmed, onClick = onDestroy)243+@Composable244+private fun ChaosDestroyButton(label: String, onClick: () -> Unit) {245+ Box(246+ modifier = Modifier247+ .fillMaxWidth()248+ .clip(RoundedCornerShape(10.dp))249+ .background(peachColors.Breach)250+ .clickable(onClick = onClick)251+ .padding(vertical = 14.dp),252+ contentAlignment = Alignment.Center,253+ ) {254+ Text(255+ label,256+ color = peachColors.ShellTopSolid,257+ style = PeachType.sortPill.copy(258+ fontSize = 12.sp,259+ fontStyle = FontStyle.Italic,260+ ),261+ )262+ }195263 }196264 197265 @Composable