diff --git a/src/main/kotlin/dev/zapstore/app/Markdown.kt b/src/main/kotlin/dev/zapstore/app/Markdown.kt index ab6dc35..6cead88 100644 --- a/src/main/kotlin/dev/zapstore/app/Markdown.kt +++ b/src/main/kotlin/dev/zapstore/app/Markdown.kt @@ -37,6 +37,7 @@ import androidx.compose.ui.text.withStyle import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.TextUnit import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.em import androidx.compose.ui.unit.sp object ZapMarkdown { @@ -86,9 +87,10 @@ object ZapMarkdown { val level = match.groupValues[1].length withStyle( SpanStyle( - fontFamily = FigtreeFontFamily, + fontFamily = WixMadeforTextFontFamily, fontWeight = FontWeight.ExtraBold, fontSize = headingSize(level), + letterSpacing = (-0.016).em, ), ) { appendInline(match.groupValues[2], onOpenUrl) diff --git a/src/main/kotlin/dev/zapstore/app/Theme.kt b/src/main/kotlin/dev/zapstore/app/Theme.kt index 30198ec..4d8e0c5 100644 --- a/src/main/kotlin/dev/zapstore/app/Theme.kt +++ b/src/main/kotlin/dev/zapstore/app/Theme.kt @@ -9,6 +9,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.font.Font import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.em @@ -97,16 +98,21 @@ object ZapRadius { } // ---- Type ---- -// One workhorse grotesque (Figtree) carries everything; hierarchy comes from size and weight. +// One workhorse grotesque (Wix Madefor Text) carries everything; hierarchy comes from size and weight. -val FigtreeFontFamily = FontFamily( - Font(R.font.figtree_light, FontWeight.Light), - Font(R.font.figtree_regular, FontWeight.Normal), - Font(R.font.figtree_medium, FontWeight.Medium), - Font(R.font.figtree_semibold, FontWeight.SemiBold), - Font(R.font.figtree_bold, FontWeight.Bold), - Font(R.font.figtree_extra_bold, FontWeight.ExtraBold), - Font(R.font.figtree_black, FontWeight.Black), +private val ZapLetterSpacing = (-0.016).em + +val WixMadeforTextFontFamily = FontFamily( + Font(R.font.wix_madefor_text_regular, FontWeight.Normal), + Font(R.font.wix_madefor_text_italic, FontWeight.Normal, FontStyle.Italic), + Font(R.font.wix_madefor_text_medium, FontWeight.Medium), + Font(R.font.wix_madefor_text_medium_italic, FontWeight.Medium, FontStyle.Italic), + Font(R.font.wix_madefor_text_semibold, FontWeight.SemiBold), + Font(R.font.wix_madefor_text_semibold_italic, FontWeight.SemiBold, FontStyle.Italic), + Font(R.font.wix_madefor_text_bold, FontWeight.Bold), + Font(R.font.wix_madefor_text_bold_italic, FontWeight.Bold, FontStyle.Italic), + Font(R.font.wix_madefor_text_extrabold, FontWeight.ExtraBold), + Font(R.font.wix_madefor_text_extrabold_italic, FontWeight.ExtraBold, FontStyle.Italic), ) private val ZapColorScheme = darkColorScheme( @@ -137,85 +143,91 @@ private val ZapColorScheme = darkColorScheme( private val ZapTypography = Typography( // Display — hero headline only. displayLarge = Typography().displayLarge.copy( - fontFamily = FigtreeFontFamily, + fontFamily = WixMadeforTextFontFamily, fontWeight = FontWeight.SemiBold, fontSize = 36.sp, lineHeight = 38.sp, - letterSpacing = (-0.04).em, + letterSpacing = ZapLetterSpacing, ), // Heading 1 — section and screen titles. displaySmall = Typography().displaySmall.copy( - fontFamily = FigtreeFontFamily, + fontFamily = WixMadeforTextFontFamily, fontWeight = FontWeight.SemiBold, fontSize = 26.sp, lineHeight = 30.sp, - letterSpacing = (-0.025).em, + letterSpacing = ZapLetterSpacing, ), // Heading 2 — sheet titles, welcome card. headlineSmall = Typography().headlineSmall.copy( - fontFamily = FigtreeFontFamily, + fontFamily = WixMadeforTextFontFamily, fontWeight = FontWeight.SemiBold, fontSize = 22.sp, lineHeight = 28.sp, - letterSpacing = (-0.015).em, + letterSpacing = ZapLetterSpacing, ), titleLarge = Typography().titleLarge.copy( - fontFamily = FigtreeFontFamily, + fontFamily = WixMadeforTextFontFamily, fontWeight = FontWeight.SemiBold, fontSize = 22.sp, lineHeight = 28.sp, - letterSpacing = (-0.015).em, + letterSpacing = ZapLetterSpacing, ), // Heading 3 — app names in detail heads and rows. titleMedium = Typography().titleMedium.copy( - fontFamily = FigtreeFontFamily, + fontFamily = WixMadeforTextFontFamily, fontWeight = FontWeight.SemiBold, fontSize = 17.sp, lineHeight = 24.sp, + letterSpacing = ZapLetterSpacing, ), // Body — 16sp on Android. bodyLarge = Typography().bodyLarge.copy( - fontFamily = FigtreeFontFamily, + fontFamily = WixMadeforTextFontFamily, fontWeight = FontWeight.Normal, fontSize = 16.sp, lineHeight = 24.sp, + letterSpacing = ZapLetterSpacing, ), // Body small — descriptions in rows and cards. bodyMedium = Typography().bodyMedium.copy( - fontFamily = FigtreeFontFamily, + fontFamily = WixMadeforTextFontFamily, fontWeight = FontWeight.Normal, fontSize = 15.sp, lineHeight = 22.sp, + letterSpacing = ZapLetterSpacing, ), // Caption — timestamps, secondary facts. bodySmall = Typography().bodySmall.copy( - fontFamily = FigtreeFontFamily, + fontFamily = WixMadeforTextFontFamily, fontWeight = FontWeight.Normal, fontSize = 13.sp, lineHeight = 18.sp, + letterSpacing = ZapLetterSpacing, ), // Button label — 14sp/600. labelLarge = Typography().labelLarge.copy( - fontFamily = FigtreeFontFamily, + fontFamily = WixMadeforTextFontFamily, fontWeight = FontWeight.SemiBold, fontSize = 14.sp, lineHeight = 20.sp, + letterSpacing = ZapLetterSpacing, ), // Evidence — verifiable values (versions, hashes, package IDs); tabular figures. labelMedium = Typography().labelMedium.copy( - fontFamily = FigtreeFontFamily, + fontFamily = WixMadeforTextFontFamily, fontWeight = FontWeight.Medium, fontSize = 13.sp, lineHeight = 17.sp, + letterSpacing = ZapLetterSpacing, fontFeatureSettings = "tnum", ), // Label — list-group headers, table headers, nav groups. Uppercase at call sites. labelSmall = Typography().labelSmall.copy( - fontFamily = FigtreeFontFamily, + fontFamily = WixMadeforTextFontFamily, fontWeight = FontWeight.SemiBold, fontSize = 11.sp, lineHeight = 16.sp, - letterSpacing = 0.08.em, + letterSpacing = ZapLetterSpacing, ), ) diff --git a/src/main/kotlin/dev/zapstore/app/components/CatalogCards.kt b/src/main/kotlin/dev/zapstore/app/components/CatalogCards.kt index e52d638..eab2332 100644 --- a/src/main/kotlin/dev/zapstore/app/components/CatalogCards.kt +++ b/src/main/kotlin/dev/zapstore/app/components/CatalogCards.kt @@ -89,29 +89,17 @@ fun AppCard( .clickable(onClick = onClick) .padding(ZapSpacing.space4), ) { - BoxWithConstraints { - val iconSize = (maxWidth * 0.21f).coerceIn(50.dp, 68.dp) - Row(verticalAlignment = Alignment.Top) { - AppIcon( - title = app.name, - iconUrl = app.iconUrl, - size = iconSize, - ) - Spacer(Modifier.width(ZapSpacing.space3)) - Column(Modifier.weight(1f)) { - AppNameWithByline( - name = app.name, - authorName = authorName, - authorProfile = authorProfile, - authorPubkey = authorPubkey, - version = release?.version, - onAuthorClick = onProfileClick, - authorTestTag = authorPubkey?.let { "profile:$it" }, - showAuthor = showAuthor, - ) - } - } - } + AppIdentityRow( + name = app.name, + iconUrl = app.iconUrl, + authorName = authorName, + authorProfile = authorProfile, + authorPubkey = authorPubkey, + version = release?.version, + onAuthorClick = onProfileClick, + authorTestTag = authorPubkey?.let { "profile:$it" }, + showAuthor = showAuthor, + ) if (app.summary.isNotBlank()) { Spacer(Modifier.height(ZapSpacing.space2)) Text( @@ -125,6 +113,43 @@ fun AppCard( } } +@Composable +fun AppIdentityRow( + name: String, + iconUrl: String?, + authorName: String?, + authorProfile: ProfileInfo?, + authorPubkey: String?, + version: String?, + modifier: Modifier = Modifier, + onAuthorClick: (() -> Unit)? = null, + authorTestTag: String? = null, + showAuthor: Boolean = true, +) { + BoxWithConstraints(modifier = modifier.fillMaxWidth()) { + val iconSize = (maxWidth * 0.21f).coerceIn(50.dp, 68.dp) + Row(verticalAlignment = Alignment.Top) { + AppIcon( + title = name, + iconUrl = iconUrl, + size = iconSize, + ) + Spacer(Modifier.width(ZapSpacing.space3)) + AppNameWithByline( + name = name, + authorName = authorName, + authorProfile = authorProfile, + authorPubkey = authorPubkey, + version = version, + onAuthorClick = onAuthorClick, + authorTestTag = authorTestTag, + showAuthor = showAuthor, + modifier = Modifier.weight(1f), + ) + } + } +} + @Composable fun AppNameWithByline( name: String, @@ -137,18 +162,20 @@ fun AppNameWithByline( authorTestTag: String? = null, showAuthor: Boolean = true, ) { - Column(modifier = modifier) { + Column( + modifier = modifier, + verticalArrangement = Arrangement.spacedBy(6.dp), + ) { Text( text = name, style = MaterialTheme.typography.titleMedium.copy( - fontSize = 19.sp, - lineHeight = 23.sp, + fontSize = 23.sp, + lineHeight = 28.sp, fontWeight = FontWeight.Black, ), maxLines = 1, overflow = TextOverflow.Ellipsis, ) - Spacer(Modifier.height(8.dp)) Row( verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(8.dp), @@ -218,8 +245,8 @@ fun VersionPill( fun StackCard( stack: StackInfo, appsByAddress: Map, - onClick: () -> Unit, modifier: Modifier = Modifier, + onClick: (() -> Unit)? = null, ) { Column( modifier = modifier @@ -227,7 +254,7 @@ fun StackCard( .clip(RoundedCornerShape(ZapRadius.lg)) .background(ZapSurface1) .border(1.dp, ZapLine, RoundedCornerShape(ZapRadius.lg)) - .clickable(onClick = onClick) + .then(if (onClick != null) Modifier.clickable(onClick = onClick) else Modifier) .padding(ZapSpacing.space4), ) { Text( diff --git a/src/main/kotlin/dev/zapstore/app/screens/AppDetailScreen.kt b/src/main/kotlin/dev/zapstore/app/screens/AppDetailScreen.kt index 0974fe2..c404bf6 100644 --- a/src/main/kotlin/dev/zapstore/app/screens/AppDetailScreen.kt +++ b/src/main/kotlin/dev/zapstore/app/screens/AppDetailScreen.kt @@ -57,7 +57,6 @@ import java.text.DateFormat import java.text.NumberFormat import java.util.Date -private val BigIconSize = 84.dp private val SmallIconSize = 26.dp private val SmallHeaderHeight = 32.dp @@ -350,29 +349,16 @@ private fun RegularAppHeader( authorProfile: ProfileInfo?, onProfileClick: () -> Unit, ) { - // Reuses the same icon+title+version+byline block as the search/home AppCard, so the - // header reads as the same component, just bigger — not a bespoke hero layout. val authorName = authorPubkey?.let { profileDisplayName(authorProfile, it) } - Row( - modifier = Modifier.fillMaxWidth(), - verticalAlignment = Alignment.Top, - horizontalArrangement = Arrangement.spacedBy(ZapSpacing.space3), - ) { - AppIcon( - title = app.name, - iconUrl = app.iconUrl, - size = BigIconSize, - ) - AppNameWithByline( - name = app.name, - authorName = authorName, - authorProfile = authorProfile, - authorPubkey = authorPubkey, - version = release?.version, - onAuthorClick = onProfileClick, - modifier = Modifier.weight(1f), - ) - } + AppIdentityRow( + name = app.name, + iconUrl = app.iconUrl, + authorName = authorName, + authorProfile = authorProfile, + authorPubkey = authorPubkey, + version = release?.version, + onAuthorClick = onProfileClick, + ) } @Composable diff --git a/src/main/res/font/figtree_black.ttf b/src/main/res/font/figtree_black.ttf deleted file mode 100644 index ed64fc2..0000000 Binary files a/src/main/res/font/figtree_black.ttf and /dev/null differ diff --git a/src/main/res/font/figtree_bold.ttf b/src/main/res/font/figtree_bold.ttf deleted file mode 100644 index 9ffd705..0000000 Binary files a/src/main/res/font/figtree_bold.ttf and /dev/null differ diff --git a/src/main/res/font/figtree_extra_bold.ttf b/src/main/res/font/figtree_extra_bold.ttf deleted file mode 100644 index ec2f77f..0000000 Binary files a/src/main/res/font/figtree_extra_bold.ttf and /dev/null differ diff --git a/src/main/res/font/figtree_light.ttf b/src/main/res/font/figtree_light.ttf deleted file mode 100644 index 6682ac0..0000000 Binary files a/src/main/res/font/figtree_light.ttf and /dev/null differ diff --git a/src/main/res/font/figtree_medium.ttf b/src/main/res/font/figtree_medium.ttf deleted file mode 100644 index 17081d0..0000000 Binary files a/src/main/res/font/figtree_medium.ttf and /dev/null differ diff --git a/src/main/res/font/figtree_regular.ttf b/src/main/res/font/figtree_regular.ttf deleted file mode 100644 index 50c9e0e..0000000 Binary files a/src/main/res/font/figtree_regular.ttf and /dev/null differ diff --git a/src/main/res/font/figtree_semibold.ttf b/src/main/res/font/figtree_semibold.ttf deleted file mode 100644 index 0bf073a..0000000 Binary files a/src/main/res/font/figtree_semibold.ttf and /dev/null differ diff --git a/src/main/res/font/wix_madefor_text.xml b/src/main/res/font/wix_madefor_text.xml new file mode 100644 index 0000000..7a562a0 --- /dev/null +++ b/src/main/res/font/wix_madefor_text.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + diff --git a/src/main/res/font/wix_madefor_text_bold.ttf b/src/main/res/font/wix_madefor_text_bold.ttf new file mode 100644 index 0000000..d20de33 Binary files /dev/null and b/src/main/res/font/wix_madefor_text_bold.ttf differ diff --git a/src/main/res/font/wix_madefor_text_bold_italic.ttf b/src/main/res/font/wix_madefor_text_bold_italic.ttf new file mode 100644 index 0000000..67c46b7 Binary files /dev/null and b/src/main/res/font/wix_madefor_text_bold_italic.ttf differ diff --git a/src/main/res/font/wix_madefor_text_extrabold.ttf b/src/main/res/font/wix_madefor_text_extrabold.ttf new file mode 100644 index 0000000..948d67d Binary files /dev/null and b/src/main/res/font/wix_madefor_text_extrabold.ttf differ diff --git a/src/main/res/font/wix_madefor_text_extrabold_italic.ttf b/src/main/res/font/wix_madefor_text_extrabold_italic.ttf new file mode 100644 index 0000000..9ae3eba Binary files /dev/null and b/src/main/res/font/wix_madefor_text_extrabold_italic.ttf differ diff --git a/src/main/res/font/wix_madefor_text_italic.ttf b/src/main/res/font/wix_madefor_text_italic.ttf new file mode 100644 index 0000000..6ba412b Binary files /dev/null and b/src/main/res/font/wix_madefor_text_italic.ttf differ diff --git a/src/main/res/font/wix_madefor_text_medium.ttf b/src/main/res/font/wix_madefor_text_medium.ttf new file mode 100644 index 0000000..a4119f4 Binary files /dev/null and b/src/main/res/font/wix_madefor_text_medium.ttf differ diff --git a/src/main/res/font/wix_madefor_text_medium_italic.ttf b/src/main/res/font/wix_madefor_text_medium_italic.ttf new file mode 100644 index 0000000..d865640 Binary files /dev/null and b/src/main/res/font/wix_madefor_text_medium_italic.ttf differ diff --git a/src/main/res/font/wix_madefor_text_regular.ttf b/src/main/res/font/wix_madefor_text_regular.ttf new file mode 100644 index 0000000..7d43fdd Binary files /dev/null and b/src/main/res/font/wix_madefor_text_regular.ttf differ diff --git a/src/main/res/font/wix_madefor_text_semibold.ttf b/src/main/res/font/wix_madefor_text_semibold.ttf new file mode 100644 index 0000000..e7ba4ef Binary files /dev/null and b/src/main/res/font/wix_madefor_text_semibold.ttf differ diff --git a/src/main/res/font/wix_madefor_text_semibold_italic.ttf b/src/main/res/font/wix_madefor_text_semibold_italic.ttf new file mode 100644 index 0000000..2923ca1 Binary files /dev/null and b/src/main/res/font/wix_madefor_text_semibold_italic.ttf differ diff --git a/src/main/res/values/styles.xml b/src/main/res/values/styles.xml index f02cb8c..c44a450 100644 --- a/src/main/res/values/styles.xml +++ b/src/main/res/values/styles.xml @@ -1,6 +1,6 @@