Icons and initials are white, not the accent — matches ios!144

🔴 The accent was being used the wrong way round. It is a mid purple chosen to
be readable as a FILL with white on top of it; as the INK for a glyph on a dark
ground it is a light purple mark on a dark blue field, which reads as a
disabled control rather than a button.

`Palette.OnDark` is white. Three sets of avatar initials and fourteen
accent-tinted icons.

⚠️ The selected tab keeps the accent. Its tint reads
`if (selected) MaterialTheme.colorScheme.primary else Palette.SecondaryText` —
a conditional, so the sweep did not catch it, and that is the right outcome:
the selected tab is the one place the accent as ink is doing a job nothing else
does.

⚠️ The accent still fills: primary buttons, badges, the pill's selected state.
Ink versus fill, not "purple is gone".

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Paul Hitt
2026-09-07 14:57:40 -04:00
co-authored by Claude Opus 5
parent 8fa66cd603
commit 17495659eb
8 changed files with 32 additions and 18 deletions
@@ -89,7 +89,7 @@ fun CallScreenBody(
initials, initials,
fontSize = 40.sp, fontSize = 40.sp,
fontWeight = FontWeight.Bold, fontWeight = FontWeight.Bold,
color = MaterialTheme.colorScheme.primary, color = Palette.OnDark,
) )
} }
} }
@@ -69,7 +69,7 @@ fun ColumnScope.CallsScreen(
Icon( Icon(
KitIcon.Call, KitIcon.Call,
contentDescription = "New call", contentDescription = "New call",
tint = Palette.Accent, tint = Palette.OnDark,
modifier = Modifier modifier = Modifier
.size(28.dp) .size(28.dp)
.clickable { showNewCall.value = true } .clickable { showNewCall.value = true }
@@ -105,12 +105,12 @@ fun ColumnScope.CallsScreen(
overflow = TextOverflow.Ellipsis, overflow = TextOverflow.Ellipsis,
) )
Icon(KitIcon.Call, contentDescription = null, Icon(KitIcon.Call, contentDescription = null,
tint = Palette.Accent, modifier = Modifier.size(20.dp)) tint = Palette.OnDark, modifier = Modifier.size(20.dp))
Spacer(Modifier.width(Space.md)) Spacer(Modifier.width(Space.md))
Icon( Icon(
KitIcon.Video, KitIcon.Video,
contentDescription = "Video call", contentDescription = "Video call",
tint = Palette.Accent, tint = Palette.OnDark,
modifier = Modifier modifier = Modifier
.size(22.dp) .size(22.dp)
.clickable { .clickable {
@@ -226,7 +226,7 @@ fun ColumnScope.CallsScreen(
Icon( Icon(
KitIcon.Video, KitIcon.Video,
contentDescription = "Video call $name", contentDescription = "Video call $name",
tint = MaterialTheme.colorScheme.primary, tint = Palette.OnDark,
modifier = Modifier.size(Kit.icon), modifier = Modifier.size(Kit.icon),
) )
} }
@@ -243,7 +243,7 @@ fun ColumnScope.CallsScreen(
Icon( Icon(
KitIcon.Call, KitIcon.Call,
contentDescription = "Call $name", contentDescription = "Call $name",
tint = MaterialTheme.colorScheme.primary, tint = Palette.OnDark,
modifier = Modifier.size(Kit.icon), modifier = Modifier.size(Kit.icon),
) )
} }
@@ -437,7 +437,7 @@ fun ColumnScope.GroupsSection(
androidx.compose.material3.Icon( androidx.compose.material3.Icon(
if (creating) KitIcon.Close else KitIcon.NewGroup, if (creating) KitIcon.Close else KitIcon.NewGroup,
contentDescription = "New group", contentDescription = "New group",
tint = Palette.Accent, tint = Palette.OnDark,
modifier = Modifier modifier = Modifier
.size(22.dp) .size(22.dp)
.clickable { onCreatingChange(!creating) } .clickable { onCreatingChange(!creating) }
@@ -1448,7 +1448,9 @@ internal fun Avatar(
initials, initials,
fontSize = (size.value * 0.33f).sp, fontSize = (size.value * 0.33f).sp,
fontWeight = FontWeight.SemiBold, fontWeight = FontWeight.SemiBold,
color = MaterialTheme.colorScheme.primary, // White on the avatar circle. The accent as ink on a dark
// circle is a light purple mark on a dark blue field.
color = Palette.OnDark,
) )
} }
} }
@@ -1540,7 +1542,7 @@ private fun AlertGlyph(kind: String) {
Icon( Icon(
symbol, symbol,
contentDescription = null, contentDescription = null,
tint = MaterialTheme.colorScheme.primary, tint = Palette.OnDark,
modifier = Modifier.size(Kit.icon), modifier = Modifier.size(Kit.icon),
) )
} }
@@ -2789,7 +2791,7 @@ fun ColumnScope.StoryStrip(
Icon( Icon(
KitIcon.Add, KitIcon.Add,
contentDescription = null, contentDescription = null,
tint = MaterialTheme.colorScheme.primary, tint = Palette.OnDark,
modifier = Modifier.size(Kit.icon), modifier = Modifier.size(Kit.icon),
) )
} }
@@ -2826,7 +2828,7 @@ fun ColumnScope.StoryStrip(
label.take(1).uppercase(), label.take(1).uppercase(),
fontSize = 16.sp, fontSize = 16.sp,
fontWeight = FontWeight.SemiBold, fontWeight = FontWeight.SemiBold,
color = MaterialTheme.colorScheme.primary, color = Palette.OnDark,
) )
} }
Text( Text(
@@ -80,7 +80,7 @@ fun ColumnScope.ContactDetail(
Icon( Icon(
KitIcon.Back, KitIcon.Back,
contentDescription = null, contentDescription = null,
tint = MaterialTheme.colorScheme.primary, tint = Palette.OnDark,
modifier = Modifier.size(Kit.icon), modifier = Modifier.size(Kit.icon),
) )
} }
@@ -111,7 +111,8 @@ fun ColumnScope.ContactDetail(
initials, initials,
fontSize = 64.sp, fontSize = 64.sp,
fontWeight = FontWeight.Bold, fontWeight = FontWeight.Bold,
color = MaterialTheme.colorScheme.primary, // White on the avatar circle, like every other one.
color = Palette.OnDark,
) )
} }
} }
@@ -912,7 +912,7 @@ private fun BarAction(
Icon( Icon(
icon, icon,
contentDescription = null, contentDescription = null,
tint = MaterialTheme.colorScheme.primary, tint = Palette.OnDark,
modifier = Modifier.size(Kit.icon), modifier = Modifier.size(Kit.icon),
) )
} }
@@ -76,7 +76,7 @@ fun ColumnScope.MessagesScreen(
androidx.compose.material3.Icon( androidx.compose.material3.Icon(
KitIcon.Scan, KitIcon.Scan,
contentDescription = "Scan an address", contentDescription = "Scan an address",
tint = Palette.Accent, tint = Palette.OnDark,
modifier = Modifier modifier = Modifier
.size(24.dp) .size(24.dp)
.clickable { .clickable {
@@ -92,7 +92,7 @@ fun ColumnScope.MessagesScreen(
androidx.compose.material3.Icon( androidx.compose.material3.Icon(
if (addingContact) KitIcon.Close else KitIcon.Add, if (addingContact) KitIcon.Close else KitIcon.Add,
contentDescription = "Add contact", contentDescription = "Add contact",
tint = Palette.Accent, tint = Palette.OnDark,
modifier = Modifier modifier = Modifier
.size(26.dp) .size(26.dp)
.clickable { addingContact = !addingContact } .clickable { addingContact = !addingContact }
@@ -168,7 +168,7 @@ fun ColumnScope.MessagesScreen(
androidx.compose.material3.Icon( androidx.compose.material3.Icon(
KitIcon.NewChat, KitIcon.NewChat,
contentDescription = "New chat", contentDescription = "New chat",
tint = Palette.Accent, tint = Palette.OnDark,
modifier = Modifier modifier = Modifier
.size(22.dp) .size(22.dp)
.clickable { showNewChat.value = true } .clickable { showNewChat.value = true }
@@ -95,7 +95,7 @@ fun ColumnScope.StoriesFeed(
Icon( Icon(
KitIcon.Add, KitIcon.Add,
contentDescription = "New story", contentDescription = "New story",
tint = Palette.Accent, tint = Palette.OnDark,
modifier = Modifier modifier = Modifier
.size(28.dp) .size(28.dp)
.clickable { choosing = true } .clickable { choosing = true }
@@ -101,6 +101,17 @@ object Palette {
// ⚠️ A blue-tinted grey rather than the flat #F3F3F3: an initials avatar // ⚠️ A blue-tinted grey rather than the flat #F3F3F3: an initials avatar
// needs to read as a circle against the surface behind it, and two greys a // needs to read as a circle against the surface behind it, and two greys a
// shade apart do not. // shade apart do not.
// Icons and initials drawn ON a dark surface.
//
// 🔴 White, not the accent. The accent is a mid purple chosen to be
// readable as a FILL with white on top of it. Used as the ink for a glyph
// on a dark ground it is the wrong way round — a light purple mark on a
// dark blue field, the least legible thing on the screen, and it reads as
// a disabled control rather than a button.
//
// ⚠️ The accent still fills: primary buttons, the selected tab, badges.
val OnDark = Color(0xFFFFFFFF)
val AvatarFill = Color(0xFF243480) val AvatarFill = Color(0xFF243480)
// 🔴 **Darkened with the ground, not left behind it.** #505C69 read 5.0:1 // 🔴 **Darkened with the ground, not left behind it.** #505C69 read 5.0:1
// on the old bottom stop and only 3.5:1 on the darker one — below AA, and // on the old bottom stop and only 3.5:1 on the darker one — below AA, and