Theme: charcoal canvas + pink accent per reference screenshot; teal reserved for the brand logo only

This commit is contained in:
avi 2026-09-21 13:17:43 -05:00
commit 93151bf85e

View file

@ -72,38 +72,39 @@ data class ShonarPalette(
val onError: Color, val onError: Color,
) )
/** The signature near-black cool-navy workspace. */ /** Near-black neutral charcoal workspace, per the reference: no navy
* cast, one subtle tonal step per surface level, hairline borders a
* few shades above each surface, pink accent used with restraint. */
private val DarkPalette = ShonarPalette( private val DarkPalette = ShonarPalette(
background = Color(0xFF0A0E15), // page: near-black cool navy background = Color(0xFF141517), // page: neutral near-black
surface = Color(0xFF121A25), // cards, fields, pills surface = Color(0xFF1B1D21), // cards, fields, pills
surfaceAlt = Color(0xFF0E151F), // pressed / hover / inset surfaceAlt = Color(0xFF101113), // pressed / hover / inset
border = Color(0xFF1E2A38), // hairline on dark border = Color(0xFF26282E), // hairline on dark
accent = Color(0xFF5EEAD4), // mint-teal: icons, selection accent = Color(0xFFF45B87), // pink-magenta: active, primary
accentStrong = Color(0xFF4FD1C5), // filled-accent hover depth accentStrong = Color(0xFFDE4373), // filled-accent hover depth
accentGlow = Color(0x405EEAD4), // soft halo (~25% mint) accentGlow = Color(0x33F45B87), // soft halo (~20% pink)
inkOnAccent = Color(0xFF06231F), // text on filled accent inkOnAccent = Color(0xFF1F0A13), // text on filled accent
textPrimary = Color(0xFFE8EEF4), textPrimary = Color(0xFFE6E7EA),
textSecondary = Color(0xFF8A97A8), textSecondary = Color(0xFF9A9DA5),
textMuted = Color(0xFF6B7686), textMuted = Color(0xFF6E7178),
error = Color(0xFFF27272), // red readable on navy error = Color(0xFFF27272), // red readable on charcoal
onError = Color(0xFF1A0B0D), onError = Color(0xFF1A0B0D),
) )
/** Light mode: cool paper tones, same three-step surface ramp /** Light mode: warm-neutral paper, same tonal-step hierarchy; the
* (page < card < inset). The accent darkens to teal-700 so accent * accent darkens to a rose that meets AA contrast on white. */
* text on paper meets AA contrast; filled accent takes white ink. */
private val LightPalette = ShonarPalette( private val LightPalette = ShonarPalette(
background = Color(0xFFF4F6F9), // page: cool paper background = Color(0xFFF5F4F6), // page: neutral paper
surface = Color(0xFFFFFFFF), // cards, fields, pills surface = Color(0xFFFFFFFF), // cards, fields, pills
surfaceAlt = Color(0xFFEAEFF5), // pressed / hover / inset surfaceAlt = Color(0xFFECEBEE), // pressed / hover / inset
border = Color(0xFFD5DDE7), // hairline on light border = Color(0xFFDBDADF), // hairline on light
accent = Color(0xFF0F766E), // deep teal: readable on paper accent = Color(0xFFBE2A5C), // deep rose: readable on paper
accentStrong = Color(0xFF115E59), // filled-accent hover depth accentStrong = Color(0xFF9D1F4B), // filled-accent hover depth
accentGlow = Color(0x330E9488), // soft halo (~20% teal) accentGlow = Color(0x26BE2A5C), // soft halo (~15% rose)
inkOnAccent = Color(0xFFF6FFFD), // text on filled accent inkOnAccent = Color(0xFFFFF5F8), // text on filled accent
textPrimary = Color(0xFF18222E), textPrimary = Color(0xFF1D1E22),
textSecondary = Color(0xFF52606F), textSecondary = Color(0xFF5A5C63),
textMuted = Color(0xFF7A8695), textMuted = Color(0xFF84868D),
error = Color(0xFFBA1A1A), // AA red on white error = Color(0xFFBA1A1A), // AA red on white
onError = Color(0xFFFFF8F7), onError = Color(0xFFFFF8F7),
) )
@ -132,6 +133,12 @@ object Shonar {
val Error: Color @Composable get() = LocalPalette.current.error val Error: Color @Composable get() = LocalPalette.current.error
val OnError: Color @Composable get() = LocalPalette.current.onError val OnError: Color @Composable get() = LocalPalette.current.onError
/** Brand teal for the sonar logo only — per the reference, teal is
* the ambient brand signature while the theme accent (pink) owns
* interactive states. Not used for controls. */
val BrandTeal = Color(0xFF5EEAD4)
val BrandTealDeep = Color(0xFF4FD1C5)
// ---- shape tokens ---- // ---- shape tokens ----
val RadiusCard = 14.dp // cards + fields val RadiusCard = 14.dp // cards + fields
val RadiusButton = 12.dp // rectangular buttons val RadiusButton = 12.dp // rectangular buttons
@ -306,9 +313,10 @@ fun ShonarTheme(
*/ */
@Composable @Composable
fun SonarLogo(size: Dp = 32.dp, modifier: Modifier = Modifier) { fun SonarLogo(size: Dp = 32.dp, modifier: Modifier = Modifier) {
// Canvas draws run outside composition: hoist palette reads to locals. // Brand teal always — the logo keeps its identity in both themes;
val accent = Shonar.Accent // hoist reads out of the Canvas draw lambda.
val accentStrong = Shonar.AccentStrong val accent = Shonar.BrandTeal
val accentStrong = Shonar.BrandTealDeep
Canvas(modifier = modifier.size(size)) { Canvas(modifier = modifier.size(size)) {
val s = this.size.minDimension / 108f val s = this.size.minDimension / 108f
fun c(x: Float, y: Float) = Offset(x * s, y * s) fun c(x: Float, y: Float) = Offset(x * s, y * s)