From d362dc6f422be9890cfb7fd3965ae1cbb5e5301e Mon Sep 17 00:00:00 2001 From: avi Date: Mon, 21 Sep 2026 19:36:43 -0500 Subject: [PATCH] Sonar theme = Android's real default: teal 4FD1C5 accent (not coral), dark ink on teal, logo tile #0B1220 with teal hairline, single-accent-color ping logo; icon.png regenerated teal-on-#0B1220 to match Android launcher --- .../main/kotlin/com/shonar/desktop/Theme.kt | 61 ++++++++++-------- app/src/main/resources/icon.png | Bin 2804 -> 3977 bytes icon.png | Bin 2804 -> 3977 bytes 3 files changed, 33 insertions(+), 28 deletions(-) diff --git a/app/src/main/kotlin/com/shonar/desktop/Theme.kt b/app/src/main/kotlin/com/shonar/desktop/Theme.kt index 809ffcd..20f6d1f 100644 --- a/app/src/main/kotlin/com/shonar/desktop/Theme.kt +++ b/app/src/main/kotlin/com/shonar/desktop/Theme.kt @@ -77,6 +77,11 @@ data class ShonarPalette( /** Vertical page gradient endpoints; default flat = [background]. */ val backgroundTop: Color = background, val backgroundBottom: Color = background, + /** Header logo-tile treatment; default = the generic surface/border + * look. The Sonar theme overrides these to Android's launcher + * treatment: #0B1220 tile with a teal hairline. */ + val tileBackground: Color = surface, + val tileBorder: Color = border, ) /** Charcoal with a faint blue cast, per the reference: page #16181C, @@ -126,29 +131,31 @@ private val LightPalette = ShonarPalette( ) /** The Android companion app's palette (android/.../ui/theme/Theme.kt): - * deep-sea sonar navy + the phone's coral accent (#E76F51), flat - * background (no gradient). Values are 1:1 with the Android tokens: - * DeepNavy/NavySurface/NavyElevated/BorderDark/TextPrimary-Dark etc. - * Android derives ink-on-accent from luminance; coral (0.29) < 0.4 → - * white, matching the phone. Kept in sync by hand — if Android's - * palette changes, change this too. */ + * deep-sea sonar navy + teal accent — the app's built-in default, + * exactly what the phone shows (screenshot Sep 21). Values are 1:1 + * with the Android tokens: DeepNavy/NavySurface/NavyElevated/ + * BorderDark/Teal etc. Android derives ink-on-accent from luminance; + * teal (0.55) > 0.4 → Ink, matching the phone. Kept in sync by hand — + * if Android's palette changes, change this too. */ private val SonarPalette = ShonarPalette( background = Color(0xFF070D18), // DeepNavy surface = Color(0xFF0F1A2B), // NavySurface surfaceAlt = Color(0xFF16233A), // NavyElevated border = Color(0xFF22364F), // BorderDark - accent = Color(0xFFE76F51), // phone's accent_color setting - accentStrong = Color(0xFFC95B41), // filled-accent hover depth - accentGlow = Color(0x33E76F51), // soft halo (~20% coral) - inkOnAccent = Color(0xFFF4F8FF), // Android: white on coral + accent = Color(0xFF4FD1C5), // Android Teal (default accent) + accentStrong = Color(0xFF2A9D94), // Android TealDark + accentGlow = Color(0x334FD1C5), // soft halo (~20% teal) + inkOnAccent = Color(0xFF10141A), // Android Ink: dark on bright teal textPrimary = Color(0xFFE6EDF3), textSecondary = Color(0xFF9FB3C8), textMuted = Color(0xFF6B7E94), error = Color(0xFFFF6B6B), // Android ErrorDark onError = Color(0xFF10141A), // Android Ink // Android's background is flat — no gradient. - highlight = Color(0xFFFF8A70), // warm coral-tint for title text - highlightTint = Color(0xFF3A1D16), // coral row wash on navy + tileBackground = Color(0xFF0B1220), // Android ic_launcher_background + tileBorder = Color(0xFF4FD1C5), // teal hairline tile, per phone header + highlight = Color(0xFF5EEAD4), // TealBright for title text + highlightTint = Color(0xFF0B2E26), // deep teal row wash on navy ) /** Which palette the app renders in. Persisted as "sonar" / "meridian" @@ -411,42 +418,40 @@ fun ShonarTheme( */ @Composable fun SonarLogo(size: Dp = 32.dp, modifier: Modifier = Modifier) { - // Brand blue — same #6190E5 as the launcher icon and the theme's - // interactive accent, per the user's request (Sep 21). - val accent = Shonar.BrandBlue - val accentStrong = Shonar.BrandBlueDeep + // Single-color glyph like Android's launcher foreground (teal under + // Sonar): logo and UI accent can never disagree. + val accent = Shonar.Accent Canvas(modifier = modifier.size(size)) { val s = this.size.minDimension / 108f fun c(x: Float, y: Float) = Offset(x * s, y * s) // Center dot: r=6 at (54,54) drawCircle(accent, radius = 6f * s, center = c(54f, 54f)) - // Upper-right quarter arcs (teal), centered on the dot. val arcStyle = Stroke(width = 4f * s, cap = StrokeCap.Round) - fun arc(color: Color, startDeg: Float, boxTopLeft: Float) { + fun arc(startDeg: Float, boxTopLeft: Float) { val box = when (boxTopLeft) { 38f -> 32f; else -> 56f } drawArc( - color, startAngle = startDeg, sweepAngle = 90f, useCenter = false, + accent, startAngle = startDeg, sweepAngle = 90f, useCenter = false, topLeft = c(boxTopLeft, boxTopLeft), size = androidx.compose.ui.geometry.Size(box * s, box * s), style = arcStyle, ) } - arc(accent, -90f, 38f) - arc(accent, -90f, 26f) - // Lower-left quarter arcs (teal-dark). - arc(accentStrong, 90f, 38f) - arc(accentStrong, 90f, 26f) + arc(-90f, 38f) + arc(-90f, 26f) + arc(90f, 38f) + arc(90f, 26f) } } -/** The reference header's logo treatment: ping inside a hairline - * rounded tile. */ +/** The header's logo treatment: ping inside a rounded tile. Under the + * Sonar theme this is Android's launcher look — teal ping on #0B1220 + * with a teal hairline border. */ @Composable fun SonarLogoTile(modifier: Modifier = Modifier, size: Dp = 40.dp) { Surface( modifier = modifier.size(size) - .border(Shonar.BorderW, Shonar.Border, Shonar.ShapeCard), - color = Shonar.Surface, + .border(Shonar.BorderW, Shonar.LocalPalette.current.tileBorder, Shonar.ShapeCard), + color = Shonar.LocalPalette.current.tileBackground, shape = Shonar.ShapeCard, ) { Column( diff --git a/app/src/main/resources/icon.png b/app/src/main/resources/icon.png index 987e0ee726ad49e945054209c3ea541a57175ecf..6274f7139137e9391402c1ed799f013e2418d021 100644 GIT binary patch literal 3977 zcmeAS@N?(olHy`uVBq!ia0y~yU}6Aa4mJh`hA$OYelalc2Y9+ThE&XXdp9;u#8;^8 z;-ks$cO)d3@k#U0wXItUgUjcY$)CL|4-q^|KA_p{@ba} zm?q3{z*Vo4bs|G82SdV)>q?Fi4z^4T7I!}z2(WCJ$H1^m7)(tQW-*x0z;LQkiY1BR zoFYTRr6UY;oEaE$I~XO7=QFWH{rdO$c4lEm_ z85yPoTe7t<>=s~f$P@($F*7o33D9M6VYti5uwbs2p#sYbF9wF(P)NDKwG0iL*Ge5(9q)P| zI)|Y_L%VI0FM}v2gTkdZ0s@R7k3|^-GQT-|vueo7VQ8o@Zr|+75PE}w;bR(K>THHp z0t^i8918v63=HSbNL`3y-!O@n;ehdGw#~i_+MEmx;vEcS&qWyySf}x1u4kTcmW|I&O zCU7h;W@IQ}7IX+_VtC+YCk*mrLW8mL0kH;S4u%Ft7lyeU3=NGg46%3C+A(Z6r^-Gj+ zhSi)53--ja&pyw*VG;vF)D2T6x8nIbrZ6zvy76%;NS=dX!Q8t_2`1m$y*U^bES=jn zN0&kSM|Q)3)w_6Z#Hs54m2wro8;|9xt*DMSMQ#p3@sF$5nV`zA}>dzI2N$V7kRI)H^IJ1W1 zh1DMyp>!dJ13{a&F~%wg;5mFa;E6NARt%kLLY{O z+91fna3SoKmCe^(lHLpqHi_I0T#O7`o@M?pYf`^{_Z2fkam=sYeUBY#f0X47PP)rVBD$@L1~jJLc(T#{WVL7hKvIqo4L{W4ONh)7E4;Mh4!J zU(fEmTr+(|oo!NkzYs$}%vZ)Qlls!zOqdwBUfXzt&%Zm_aE~vf!gF0)*CdzNo^8=r zyN-FD5JSKPKj!r1*^P5K7!soG*csLfGX$LJ^FL!9CtRY=z%WaC>q~*GNJu3aaN?YQ z!rk?2fB$@F$;gm%mYwloDiZ?(6DI=$hYG`jj+XK>oYy&GIlx>7g$WD{4GtjryKC(j zKKJ}$2zxqzwcif6b<;n5_1WQeY!f3?9-<$lp+QN=?#R@F-V3cTy_^gcjrLK@Z~PcG zOnvu$#_sw5b*#@$~lZ)ah|D?Szyn|aP-X%t@|HmEwE-}Sij*VLzx=Gf(3Ku z%_!d`cB7La!Fo5(9NBfr?b!{n5X&C$uC`~t@RM`b=bMU+3=NO0_%4A1tbsrBZ_1x} zci94#zkXQ~=Ap)L=*P2~y;>VDKg_=Vu;+j>BSUY9+=i*=+5UJl9AI6Q!`Qd@*@Cqd zY7cUm8gk#-Owo#sUb>lKx-dgc#M0%DT=?(5o6dLt>VLZeX+{R|RZ=$EZ5s~q|K)6O z@Vvh#cwOnW%R83W-8g>t6|;l-{rZ0zwhZ&<a@xa-j`E9}L zrEfGdC>)cFW)Ng3QDta~>}Gx<#K3d$spkzbh6fWF8W>#|F7z@eoQqs<=fZHIlYzs$ zNTN)t!R|l95@7~|faM%an>ZPgDn%Jogc*+PW3!n2n;}G#hbJoN2`0{3I0qC|Gn#Z3uHbkIdFgq zHNVTHC(d#$T=$**Ml-_${cQ}zH`y3gb1?W_E!}aJZ{fP{oG-i?4rqtDGzc)H{RFq* zR`WaBE@lsW9?reGt>}3*+m&=?hW8Ps9rgJvIjjxFHyA!>MK|mZl{j+uy<$K+FGI|V zLm#$^GPrGIeBir{;r}YDn(`gn57>Z8!n-y#yY(d*_2+tuFs$Fm_#k#0!}`?{OxJI` z%w~)^p3X31-R}!Erx;jw2{G(BJ)wH`Z{`vehKQu)x(5nv+!_QJtOOZijuhj5!(X&a7_u*ur4Yy`SyG z*>h4i*d8u6Za!h#76bCZp0__I_}!bp@c0IUL5uDItL=BHzl#@fGPDUYZjJf$wIE+{ zIzxiQ`&Ep;J_IxH6hE8r?Vfak4 UC58p;j0Xyo7#7$uI#??)JSbyo2%htIp{*c8 zfi&ZROcw@+Sf+;HPKJhAEDUcu85&-5GWeN4p8lhQq2VhH@9yNXL8VzX7HM6J0X|3A;gSf%9bR9+iVP;EDWh@tE|MC z9GKQKXk=ei_!hJ1VfepL(a-7mOpB24WTRy(XWM=_H!~Nh%p}cw#)TEa1(!ox2UyPAYb$UxTxDUKEr?P7q;a=#BYQ&F;cf x(CI&af6d>mzXTW##MB8ZjCOfOdwehI|JMGiZ+*(c&A`CG;OXk;vd$@?2>`e*tR4UW literal 2804 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 UC58p;j0Xyo7#7$uI#??)JSbyo2%htIp{*c8 zfi&ZROcw@+Sf+;HPKJhAEDUcu85&-5GWeN4p8lhQq2VhH@9yNXL8VzX7HM6J0X|3A;gSf%9bR9+iVP;EDWh@tE|MC z9GKQKXk=ei_!hJ1VfepL(a-7mOpB24WTRy(XWM=_H!~Nh%p}cw#)TEa1(!ox2UyPAYb$UxTxDUKEr?P7q;a=#BYQ&F;cf x(CI&af6d>mzXTW##MB8ZjCOfOdwehI|JMGiZ+*(c&A`CG;OXk;vd$@?2>`e*tR4UW literal 2804 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