Take the palette from the site instead of inventing one

flamenetmessenger.com declares its colours as CSS custom properties, so they
were there to be read rather than guessed:

    --bg: #0a0e1a   --panel: #121a2e   --border: #1f2b45
    --ink: #e8edf7  --muted: #9aa7c2
    --flame: #ff5a1f  --blue: #3b6fff  --accent: #2dd4a7

⚠️ The site is dark and the apps are light, so only the accents transfer
literally. --ink and --muted are light-on-dark values that would be invisible
on a light ground; the neutrals here are the same navy family resolved for
light instead. Dark mode DOES use the site's real --bg and --panel.

The apps had been warm — ember on parchment. They are now the site's flame on
a cool navy-tinted ground, with the site's blue and teal available for
informational and success states rather than a second invented accent.

⚠️ Two flames, on purpose. White on #ff5a1f is about 3.1:1 — acceptable for a
bold button label under AA Large and not acceptable for small text. Small text
and links take a darkened #c4400f, which clears 5:1 on white. An accent used
uniformly is how it quietly becomes unreadable.

`Palette.Parchment` is now `Palette.Mist`: it is a cool near-white and the old
name described a colour that no longer exists here.

Also fixes the contacts card reserving a slab of empty white. BuddyList's
LazyColumn carried weight(1f), which always expands to whatever height it is
offered — so bounding the CARD just moved the problem, and one contact still
reserved 340dp. The list now caps itself with heightIn and the card sizes to
its content, scrolling only once the list is genuinely long.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Paul Hitt
2026-08-26 06:37:32 -04:00
co-authored by Claude Opus 5
parent 4fd648382f
commit 3c66d3e9bd
3 changed files with 42 additions and 22 deletions
@@ -56,6 +56,7 @@ import androidx.compose.ui.unit.dp
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import androidx.compose.foundation.layout.heightIn
/**
* The people you talk to.
@@ -155,7 +156,11 @@ fun ColumnScope.BuddyList(model: MessengerViewModel, phase: MessengerViewModel.P
var expanded by remember { mutableStateOf<Long?>(null) }
LazyColumn(modifier = Modifier.fillMaxWidth().weight(1f).testTag("buddies")) {
// ⚠️ heightIn, not weight(1f). Inside its card `weight` always expands to
// the full height it is offered, so a single contact still reserved a
// fixed slab of empty white. A max lets the card size to its content
// and start scrolling only once the list is actually long.
LazyColumn(modifier = Modifier.fillMaxWidth().heightIn(max = 320.dp).testTag("buddies")) {
items(phase.buddies, key = { it.userId }) { buddy ->
Row(
modifier = Modifier
@@ -353,7 +353,7 @@ private fun ColumnScope.SignedIn(
shape = RoundedCornerShape(Radius.medium),
color = MaterialTheme.colorScheme.surface,
shadowElevation = 2.dp,
modifier = Modifier.fillMaxWidth().heightIn(min = 96.dp, max = 340.dp),
modifier = Modifier.fillMaxWidth(),
) {
Column(Modifier.padding(Space.lg)) { BuddyList(model, phase) }
}
@@ -21,39 +21,54 @@ import androidx.compose.ui.unit.sp
/**
* The Flamenet design system.
*
* 🔴 **Taken from flamenetmessenger.com, not invented.** The site declares
* `--flame: #ff5a1f`, `--blue: #3b6fff`, `--accent: #2dd4a7` over a dark navy
* ground (`--bg: #0a0e1a`, `--panel: #121a2e`). The accents transfer as-is;
* the site's `--ink`/`--muted` are light-on-dark and are NOT pasted in here,
* because the apps are light. Dark mode does use the site's real grounds.
*
* 🔴 **One palette, two apps.** iOS carries the same values under the same
* names in `Sources/Theme/Theme.swift`. This file's comment used to claim the
* two were already matched — while iOS was indigo and this was ember, so the
* claim was simply false and nobody noticed because nothing checks it.
* **Change a value here and change it there in the same commit.**
*
* The look: light parchment ground, white cards with a soft shadow and a
* The look: a light cool-navy ground, white cards with a soft shadow and a
* generous corner radius, one confident accent, quiet neutrals, and space
* between things. Screen structure and every `testTag` are deliberately
* untouched — this is a skin over working screens.
*/
object Palette {
// Brand
val Ember = Color(0xFFE2571F)
val EmberDeep = Color(0xFFB33F12)
val EmberSoft = Color(0x1AE2571F)
// Brand — the site's --flame.
// ⚠️ White on Ember is about 3.1:1: fine for a bold button label (AA
// Large), NOT fine for small text. Small text and links use EmberDeep.
val Ember = Color(0xFFFF5A1F)
val EmberDeep = Color(0xFFC4400F)
val EmberSoft = Color(0x1AFF5A1F)
// Neutrals
val Ink = Color(0xFF16130F)
val Parchment = Color(0xFFFBF7F2)
val SurfaceAlt = Color(0xFFF4EFE9)
val IncomingBubble = Color(0xFFF1ECE5)
val AvatarFill = Color(0xFFF1E4DA)
val SecondaryText = Color(0xFF6B625A)
val Divider = Color(0x1416130F)
// The site's other two accents, used sparingly.
val Blue = Color(0xFF3B6FFF) // --blue, informational only
val Teal = Color(0xFF2DD4A7) // --accent, success and presence
// Neutrals: the site's navy family resolved for a LIGHT ground.
// ⚠️ --ink (#e8edf7) and --muted (#9aa7c2) are light-on-dark values and
// would be invisible here, so they are not pasted in literally.
val Ink = Color(0xFF0F1626)
val Mist = Color(0xFFF6F8FC) // the light ground (was 'Parchment' when the palette was warm)
val SurfaceAlt = Color(0xFFEDF1F8)
val IncomingBubble = Color(0xFFEDF1F8)
val AvatarFill = Color(0xFFE4EAF6)
val SecondaryText = Color(0xFF5A6884)
val Divider = Color(0x1A1F2B45)
// Semantic
val Success = Color(0xFF2E7D5B)
val Success = Color(0xFF1F9E7A)
val Warning = Color(0xFFB8860B)
val Danger = Color(0xFFC0392B)
// Dark-mode grounds
val InkSurface = Color(0xFF1F1B16)
// Dark-mode grounds — these ARE the site's, since the site is dark.
val InkSurface = Color(0xFF121A2E) // --panel
val NightGround = Color(0xFF0A0E1A) // --bg
}
/** Corner radii, matching `Theme.Radius` on iOS. */
@@ -125,11 +140,11 @@ fun MessengerTheme(content: @Composable () -> Unit) {
primary = Palette.Ember,
onPrimary = Color.White,
secondary = Palette.EmberDeep,
background = Palette.Ink,
background = Palette.NightGround,
surface = Palette.InkSurface,
surfaceVariant = Palette.InkSurface,
onBackground = Palette.Parchment,
onSurface = Palette.Parchment,
onBackground = Palette.Mist,
onSurface = Palette.Mist,
onSurfaceVariant = Palette.SecondaryText,
error = Palette.Danger,
outline = Palette.Divider,
@@ -139,7 +154,7 @@ fun MessengerTheme(content: @Composable () -> Unit) {
primary = Palette.EmberDeep,
onPrimary = Color.White,
secondary = Palette.Ember,
background = Palette.Parchment,
background = Palette.Mist,
surface = Color.White,
surfaceVariant = Palette.SurfaceAlt,
onBackground = Palette.Ink,