fix(settings): the paired "Connected with" card rendered muddy and unpolished
Two defects, both only in the paired state — the unpaired state was already styled correctly, which is why this hid. 1. The card was see-through. `partnerCardColor` used primaryContainer at 52% alpha, and the page behind it is a gradient brush, so the gradient bled up through the card: it read muddy against the crisp profile card directly above (which is 96%), and the card's own content bounds showed as a paler, sharp-edged band inside it — measured, not guessed: a 24-unit jump (218,209,226 -> 242,232,251 -> 217,208,225) across the Row's 18dp content inset. Now 96% like its sibling; the same scanline is flat (240,229,253 -> 241,231,255). Content colours are the container's own on* pair rather than the page's ink, so contrast is correct in both themes. 2. The heart was a bare, outsized glyph. ProfileAvatar's no-photo fallback is a 40dp Icon with no container, so the paired row showed a naked heart unlike anything else on the page — while the *unpaired* branch right below it, and every settings row, use a 48dp tile + 24dp glyph. The avatar is now used only when a real partner photo exists; otherwise it falls back to that same tile. Verified live both fixtures (dark 5554 / light 5556) with pixel probes before and after. theme-scan REVIEW 25 -> 24 (one hardcoded-colour hit removed); CRITICAL/MAJOR unchanged. Unit tests green, 0 FATAL. Filed alongside this round's Pass C results (R32) in ClaudeReport/ClaudeQACoverage. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
eb254d9a9c
commit
76d8746a9b
|
|
@ -355,17 +355,24 @@ fun SettingsScreen(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Partner card — fully tappable, visually obvious
|
// Partner card — fully tappable, and deliberately tinted so it reads as the one
|
||||||
|
// relationship row rather than another settings row.
|
||||||
|
// The tint must be a near-opaque container: the page behind is a gradient brush, so
|
||||||
|
// a see-through card (this was `primaryContainer` at 52%) lets that gradient bleed
|
||||||
|
// up and the card renders muddy — and its own inner content bounds show as a paler
|
||||||
|
// band against it. The sibling profile card directly above is 96% and never does
|
||||||
|
// this. Content colours are the container's `on*` pair so contrast is correct in
|
||||||
|
// both themes rather than borrowed from the page's ink.
|
||||||
val partnerCardColor = if (state.isPaired) {
|
val partnerCardColor = if (state.isPaired) {
|
||||||
SettingsSoft.copy(alpha = 0.52f)
|
MaterialTheme.colorScheme.primaryContainer.copy(alpha = 0.96f)
|
||||||
} else if (isCloserDarkTheme()) {
|
} else if (isCloserDarkTheme()) {
|
||||||
MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.74f)
|
MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.96f)
|
||||||
} else {
|
} else {
|
||||||
MaterialTheme.colorScheme.secondaryContainer.copy(alpha = 0.46f)
|
MaterialTheme.colorScheme.secondaryContainer.copy(alpha = 0.96f)
|
||||||
}
|
}
|
||||||
val partnerAccent = if (state.isPaired) SettingsPrimaryDeep else MaterialTheme.colorScheme.secondary
|
val partnerAccent = if (state.isPaired) MaterialTheme.colorScheme.onPrimaryContainer else MaterialTheme.colorScheme.secondary
|
||||||
val partnerContentColor = if (state.isPaired) SettingsInk else MaterialTheme.colorScheme.onSecondaryContainer
|
val partnerContentColor = if (state.isPaired) MaterialTheme.colorScheme.onPrimaryContainer else MaterialTheme.colorScheme.onSecondaryContainer
|
||||||
val partnerMutedColor = if (state.isPaired) SettingsMuted else MaterialTheme.colorScheme.onSecondaryContainer.copy(alpha = 0.72f)
|
val partnerMutedColor = if (state.isPaired) MaterialTheme.colorScheme.onPrimaryContainer.copy(alpha = 0.72f) else MaterialTheme.colorScheme.onSecondaryContainer.copy(alpha = 0.72f)
|
||||||
Card(
|
Card(
|
||||||
onClick = {
|
onClick = {
|
||||||
onNavigate(
|
onNavigate(
|
||||||
|
|
@ -386,11 +393,16 @@ fun SettingsScreen(
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
horizontalArrangement = Arrangement.spacedBy(12.dp)
|
horizontalArrangement = Arrangement.spacedBy(12.dp)
|
||||||
) {
|
) {
|
||||||
if (state.isPaired) {
|
// A real partner photo shows as the avatar; otherwise fall back to the same
|
||||||
|
// 48dp tile + 24dp glyph the unpaired state and every settings row use.
|
||||||
|
// ProfileAvatar's own fallback is a bare 40dp icon with no container, which
|
||||||
|
// left the paired state showing an outsized naked heart unlike anything
|
||||||
|
// else on the page.
|
||||||
|
if (state.isPaired && !state.partnerPhotoUrl.isNullOrBlank()) {
|
||||||
ProfileAvatar(
|
ProfileAvatar(
|
||||||
imageUrl = state.partnerPhotoUrl,
|
imageUrl = state.partnerPhotoUrl,
|
||||||
fallbackIcon = CloserGlyphs.Heart,
|
fallbackIcon = CloserGlyphs.Heart,
|
||||||
fallbackTint = SettingsPrimaryDeep
|
fallbackTint = partnerAccent
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
Box(
|
Box(
|
||||||
|
|
@ -401,7 +413,7 @@ fun SettingsScreen(
|
||||||
contentAlignment = Alignment.Center
|
contentAlignment = Alignment.Center
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
CloserGlyphs.HeartOutline,
|
if (state.isPaired) CloserGlyphs.Heart else CloserGlyphs.HeartOutline,
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
tint = partnerAccent,
|
tint = partnerAccent,
|
||||||
modifier = Modifier.size(24.dp)
|
modifier = Modifier.size(24.dp)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue