Match reference palette: charcoal page, blue interactive accent, pink-red reserved for recording titles and selected rows
This commit is contained in:
parent
93151bf85e
commit
30a9facf89
3 changed files with 56 additions and 31 deletions
|
|
@ -82,6 +82,8 @@ fun Modifier.shonarFocus(
|
||||||
fun SonarCard(
|
fun SonarCard(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
onClick: (() -> Unit)? = null,
|
onClick: (() -> Unit)? = null,
|
||||||
|
containerColor: Color = Shonar.Surface,
|
||||||
|
borderColor: Color = Shonar.Border,
|
||||||
content: @Composable () -> Unit,
|
content: @Composable () -> Unit,
|
||||||
) {
|
) {
|
||||||
val clickModifier = if (onClick != null)
|
val clickModifier = if (onClick != null)
|
||||||
|
|
@ -90,8 +92,8 @@ fun SonarCard(
|
||||||
Surface(
|
Surface(
|
||||||
modifier = modifier.then(clickModifier),
|
modifier = modifier.then(clickModifier),
|
||||||
shape = Shonar.ShapeCard,
|
shape = Shonar.ShapeCard,
|
||||||
color = Shonar.Surface,
|
color = containerColor,
|
||||||
border = BorderStroke(1.dp, Shonar.Border),
|
border = BorderStroke(Shonar.BorderW, borderColor),
|
||||||
content = content,
|
content = content,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -409,7 +409,14 @@ fun LibraryScreen(state: DesktopState) {
|
||||||
items(entries, key = { it.file.absolutePath }) { e ->
|
items(entries, key = { it.file.absolutePath }) { e ->
|
||||||
val isSelected = e.file.absolutePath in selected
|
val isSelected = e.file.absolutePath in selected
|
||||||
SonarCard(Modifier.fillMaxWidth(),
|
SonarCard(Modifier.fillMaxWidth(),
|
||||||
onClick = { state.openDetail(e.file) }) {
|
onClick = { state.openDetail(e.file) },
|
||||||
|
// Selected rows take the reference's muted rose
|
||||||
|
// wash instead of a plain surface lift.
|
||||||
|
containerColor = if (isSelected) Shonar.HighlightTint
|
||||||
|
else Shonar.Surface,
|
||||||
|
borderColor = if (isSelected) Shonar.Highlight
|
||||||
|
.copy(alpha = 0.5f) else Shonar.Border,
|
||||||
|
) {
|
||||||
Row(Modifier.fillMaxWidth().padding(Shonar.CardPadding),
|
Row(Modifier.fillMaxWidth().padding(Shonar.CardPadding),
|
||||||
verticalAlignment = Alignment.CenterVertically) {
|
verticalAlignment = Alignment.CenterVertically) {
|
||||||
Checkbox(
|
Checkbox(
|
||||||
|
|
@ -417,8 +424,11 @@ fun LibraryScreen(state: DesktopState) {
|
||||||
onCheckedChange = { state.toggleSelected(e.file.absolutePath) },
|
onCheckedChange = { state.toggleSelected(e.file.absolutePath) },
|
||||||
)
|
)
|
||||||
Column(Modifier.weight(1f)) {
|
Column(Modifier.weight(1f)) {
|
||||||
|
// Recording titles carry the reference's
|
||||||
|
// hot pink highlight; metadata stays gray.
|
||||||
Text(e.file.nameWithoutExtension,
|
Text(e.file.nameWithoutExtension,
|
||||||
style = MaterialTheme.typography.titleSmall,
|
style = MaterialTheme.typography.titleSmall,
|
||||||
|
color = Shonar.Highlight,
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
overflow = TextOverflow.Ellipsis)
|
overflow = TextOverflow.Ellipsis)
|
||||||
Text(
|
Text(
|
||||||
|
|
|
||||||
|
|
@ -70,43 +70,52 @@ data class ShonarPalette(
|
||||||
val textMuted: Color,
|
val textMuted: Color,
|
||||||
val error: Color,
|
val error: Color,
|
||||||
val onError: Color,
|
val onError: Color,
|
||||||
|
/** Hot pink-red used to highlight recording entries (titles,
|
||||||
|
* selected-row wash) — decorative emphasis, not an error color. */
|
||||||
|
val highlight: Color = Color(0xFFFB3F7F),
|
||||||
|
val highlightTint: Color = Color(0x26FB3F7F),
|
||||||
)
|
)
|
||||||
|
|
||||||
/** Near-black neutral charcoal workspace, per the reference: no navy
|
/** Charcoal with a faint blue cast, per the reference: page #16181C,
|
||||||
* cast, one subtle tonal step per surface level, hairline borders a
|
* lifted blue-charcoal cards, hairline borders. Blue owns all
|
||||||
* few shades above each surface, pink accent used with restraint. */
|
* interactive accent; the reference's hot pink is reserved for
|
||||||
|
* highlighting recordings (see [ShonarPalette.highlight]). */
|
||||||
private val DarkPalette = ShonarPalette(
|
private val DarkPalette = ShonarPalette(
|
||||||
background = Color(0xFF141517), // page: neutral near-black
|
background = Color(0xFF16181C), // page: charcoal, blue-cast
|
||||||
surface = Color(0xFF1B1D21), // cards, fields, pills
|
surface = Color(0xFF1C2029), // cards, fields, pills
|
||||||
surfaceAlt = Color(0xFF101113), // pressed / hover / inset
|
surfaceAlt = Color(0xFF12151C), // pressed / hover / inset
|
||||||
border = Color(0xFF26282E), // hairline on dark
|
border = Color(0xFF2A2E38), // hairline on dark
|
||||||
accent = Color(0xFFF45B87), // pink-magenta: active, primary
|
accent = Color(0xFF6190E5), // blue: chips, links, progress
|
||||||
accentStrong = Color(0xFFDE4373), // filled-accent hover depth
|
accentStrong = Color(0xFF4C6FAD), // filled-accent hover depth
|
||||||
accentGlow = Color(0x33F45B87), // soft halo (~20% pink)
|
accentGlow = Color(0x336190E5), // soft halo (~20% blue)
|
||||||
inkOnAccent = Color(0xFF1F0A13), // text on filled accent
|
inkOnAccent = Color(0xFF0B1526), // text on filled accent
|
||||||
textPrimary = Color(0xFFE6E7EA),
|
textPrimary = Color(0xFFE6E8EC),
|
||||||
textSecondary = Color(0xFF9A9DA5),
|
textSecondary = Color(0xFF969CAA),
|
||||||
textMuted = Color(0xFF6E7178),
|
textMuted = Color(0xFF6B7080),
|
||||||
error = Color(0xFFF27272), // red readable on charcoal
|
error = Color(0xFFF85149), // true red, distinct from highlight
|
||||||
onError = Color(0xFF1A0B0D),
|
onError = Color(0xFF1A0B0D),
|
||||||
|
highlight = Color(0xFFFB3F7F), // hot pink-red: recording titles
|
||||||
|
highlightTint = Color(0x26FB3F7F), // ~15% pink row wash
|
||||||
)
|
)
|
||||||
|
|
||||||
/** Light mode: warm-neutral paper, same tonal-step hierarchy; the
|
/** Light mode: neutral-cool paper; blue and pink darken to AA values
|
||||||
* accent darkens to a rose that meets AA contrast on white. */
|
* (the highlight pink would be illegible at #FB3F7F on white). */
|
||||||
private val LightPalette = ShonarPalette(
|
private val LightPalette = ShonarPalette(
|
||||||
background = Color(0xFFF5F4F6), // page: neutral paper
|
background = Color(0xFFF4F5F8), // page: cool paper
|
||||||
surface = Color(0xFFFFFFFF), // cards, fields, pills
|
surface = Color(0xFFFFFFFF), // cards, fields, pills
|
||||||
surfaceAlt = Color(0xFFECEBEE), // pressed / hover / inset
|
surfaceAlt = Color(0xFFE9ECF2), // pressed / hover / inset
|
||||||
border = Color(0xFFDBDADF), // hairline on light
|
border = Color(0xFFD7DBE4), // hairline on light
|
||||||
accent = Color(0xFFBE2A5C), // deep rose: readable on paper
|
accent = Color(0xFF0550AE), // deep blue: AA on paper
|
||||||
accentStrong = Color(0xFF9D1F4B), // filled-accent hover depth
|
accentStrong = Color(0xFF0B3E78), // filled-accent hover depth
|
||||||
accentGlow = Color(0x26BE2A5C), // soft halo (~15% rose)
|
accentGlow = Color(0x260969DA), // soft halo (~15% blue)
|
||||||
inkOnAccent = Color(0xFFFFF5F8), // text on filled accent
|
inkOnAccent = Color(0xFFF4F8FF), // text on filled accent
|
||||||
textPrimary = Color(0xFF1D1E22),
|
textPrimary = Color(0xFF1C2028),
|
||||||
textSecondary = Color(0xFF5A5C63),
|
textSecondary = Color(0xFF585F6C),
|
||||||
textMuted = Color(0xFF84868D),
|
textMuted = Color(0xFF828A97),
|
||||||
error = Color(0xFFBA1A1A), // AA red on white
|
error = Color(0xFFBA1A1A), // AA red on white
|
||||||
onError = Color(0xFFFFF8F7),
|
onError = Color(0xFFFFF8F7),
|
||||||
|
highlight = Color(0xFFC2185B), // AA rose: recording highlight
|
||||||
|
highlightTint = Color(0x1AC2185B), // faint rose row wash
|
||||||
)
|
)
|
||||||
|
|
||||||
/** Which palette the app renders in. Persisted as "dark" / "light". */
|
/** Which palette the app renders in. Persisted as "dark" / "light". */
|
||||||
|
|
@ -139,6 +148,10 @@ object Shonar {
|
||||||
val BrandTeal = Color(0xFF5EEAD4)
|
val BrandTeal = Color(0xFF5EEAD4)
|
||||||
val BrandTealDeep = Color(0xFF4FD1C5)
|
val BrandTealDeep = Color(0xFF4FD1C5)
|
||||||
|
|
||||||
|
/** Pink-red recording highlight (see [ShonarPalette.highlight]). */
|
||||||
|
val Highlight: Color @Composable get() = LocalPalette.current.highlight
|
||||||
|
val HighlightTint: Color @Composable get() = LocalPalette.current.highlightTint
|
||||||
|
|
||||||
// ---- 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
|
||||||
|
|
@ -236,7 +249,7 @@ private fun schemeFor(p: ShonarPalette) =
|
||||||
if (p === DarkPalette) ShonarDarkScheme else ShonarLightScheme
|
if (p === DarkPalette) ShonarDarkScheme else ShonarLightScheme
|
||||||
|
|
||||||
private val ShonarDarkScheme = darkColorScheme(
|
private val ShonarDarkScheme = darkColorScheme(
|
||||||
primary = DarkPalette.accentStrong,
|
primary = DarkPalette.accent,
|
||||||
onPrimary = DarkPalette.inkOnAccent,
|
onPrimary = DarkPalette.inkOnAccent,
|
||||||
primaryContainer = DarkPalette.accentGlow,
|
primaryContainer = DarkPalette.accentGlow,
|
||||||
onPrimaryContainer = DarkPalette.accent,
|
onPrimaryContainer = DarkPalette.accent,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue