diff --git a/THIRD_PARTY_LICENSES.md b/THIRD_PARTY_LICENSES.md new file mode 100644 index 0000000..ac93fc8 --- /dev/null +++ b/THIRD_PARTY_LICENSES.md @@ -0,0 +1,13 @@ +# Third-party licenses + +## Fonts (bundled in `app/src/main/res/font/`) + +- **Inter** (`inter_*.ttf`) — © The Inter Project Authors, + . Licensed under the SIL Open Font + License 1.1 (). +- **Manrope** (`manrope_variable.ttf`) — © The Manrope Project Authors, + distributed via . + Licensed under the SIL Open Font License 1.1. + +Library licenses (Apache-2.0 and similar) are declared by their respective +artifacts via Gradle metadata. diff --git a/app/src/main/java/no/naiv/meddetsamme/alarm/SupplyCheckReceiver.kt b/app/src/main/java/no/naiv/meddetsamme/alarm/SupplyCheckReceiver.kt index d771308..b0ca4a9 100644 --- a/app/src/main/java/no/naiv/meddetsamme/alarm/SupplyCheckReceiver.kt +++ b/app/src/main/java/no/naiv/meddetsamme/alarm/SupplyCheckReceiver.kt @@ -50,7 +50,7 @@ class SupplyCheckReceiver : BroadcastReceiver() { for (med in meds) rate += ScheduleEngine.dailyConsumption(db.doseTimeDao().getForMed(med.med.id)) if (ScheduleEngine.needsRefill(item.stockUnits, rate, item.lowStockLeadDays)) { val days = ScheduleEngine.daysOfSupply(item.stockUnits, rate) - lowStock += "${item.name}: lager for ${days?.toInt() ?: 0} dager" + lowStock += "${item.name}: lager for ${no.naiv.meddetsamme.domain.ScheduleText.daysCount(days?.toInt() ?: 0)}" } if (ScheduleEngine.needsRenewal(item.rxExpiryEpochDay, today, RX_LEAD_DAYS)) { val expired = item.rxExpiryEpochDay!! < today.toEpochDay() diff --git a/app/src/main/java/no/naiv/meddetsamme/domain/ScheduleText.kt b/app/src/main/java/no/naiv/meddetsamme/domain/ScheduleText.kt index e3b2c9d..fe738d3 100644 --- a/app/src/main/java/no/naiv/meddetsamme/domain/ScheduleText.kt +++ b/app/src/main/java/no/naiv/meddetsamme/domain/ScheduleText.kt @@ -36,6 +36,9 @@ object ScheduleText { } } + /** "1 dag", "3 dager" — norsk flertall. */ + fun daysCount(days: Int): String = if (days == 1) "1 dag" else "$days dager" + /** "1 tablett", "2,5 ml" — norsk desimalkomma. */ fun amountText(amount: Double, unit: String): String { val number = if (amount == amount.toLong().toDouble()) { diff --git a/app/src/main/java/no/naiv/meddetsamme/ui/Theme.kt b/app/src/main/java/no/naiv/meddetsamme/ui/Theme.kt index db8c365..1b0086f 100644 --- a/app/src/main/java/no/naiv/meddetsamme/ui/Theme.kt +++ b/app/src/main/java/no/naiv/meddetsamme/ui/Theme.kt @@ -1,8 +1,11 @@ +@file:OptIn(androidx.compose.ui.text.ExperimentalTextApi::class) + package no.naiv.meddetsamme.ui import android.os.Build import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Typography import androidx.compose.material3.darkColorScheme import androidx.compose.material3.dynamicDarkColorScheme import androidx.compose.material3.dynamicLightColorScheme @@ -10,6 +13,11 @@ import androidx.compose.material3.lightColorScheme import androidx.compose.runtime.Composable import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.text.font.Font +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontVariation +import androidx.compose.ui.text.font.FontWeight +import no.naiv.meddetsamme.R /** * App theme: dynamic Material You colors on Android 12+ (follows the user's @@ -26,7 +34,43 @@ fun MedDetSammeTheme(content: @Composable () -> Unit) { dark -> DarkScheme else -> LightScheme } - MaterialTheme(colorScheme = scheme, content = content) + MaterialTheme(colorScheme = scheme, typography = AppTypography, content = content) +} + +// Manrope for headings/titles (friendly, confident), Inter for body/labels +// (built for UI legibility at small sizes). Both OFL, full æøå/µ coverage. +private val Manrope = FontFamily( + Font(R.font.manrope_variable, FontWeight.SemiBold, variationSettings = FontVariation.Settings(FontVariation.weight(600))), + Font(R.font.manrope_variable, FontWeight.Bold, variationSettings = FontVariation.Settings(FontVariation.weight(700))), + Font(R.font.manrope_variable, FontWeight.ExtraBold, variationSettings = FontVariation.Settings(FontVariation.weight(800))), +) + +private val Inter = FontFamily( + Font(R.font.inter_regular, FontWeight.Normal), + Font(R.font.inter_medium, FontWeight.Medium), + Font(R.font.inter_semibold, FontWeight.SemiBold), +) + +// M3 baseline metrics, only family/weight swapped — sizes and line heights +// are already tuned for the components. +private val AppTypography: Typography = Typography().let { base -> + Typography( + displayLarge = base.displayLarge.copy(fontFamily = Manrope, fontWeight = FontWeight.ExtraBold), + displayMedium = base.displayMedium.copy(fontFamily = Manrope, fontWeight = FontWeight.ExtraBold), + displaySmall = base.displaySmall.copy(fontFamily = Manrope, fontWeight = FontWeight.Bold), + headlineLarge = base.headlineLarge.copy(fontFamily = Manrope, fontWeight = FontWeight.Bold), + headlineMedium = base.headlineMedium.copy(fontFamily = Manrope, fontWeight = FontWeight.Bold), + headlineSmall = base.headlineSmall.copy(fontFamily = Manrope, fontWeight = FontWeight.Bold), + titleLarge = base.titleLarge.copy(fontFamily = Manrope, fontWeight = FontWeight.Bold), + titleMedium = base.titleMedium.copy(fontFamily = Manrope, fontWeight = FontWeight.SemiBold), + titleSmall = base.titleSmall.copy(fontFamily = Manrope, fontWeight = FontWeight.SemiBold), + bodyLarge = base.bodyLarge.copy(fontFamily = Inter), + bodyMedium = base.bodyMedium.copy(fontFamily = Inter), + bodySmall = base.bodySmall.copy(fontFamily = Inter), + labelLarge = base.labelLarge.copy(fontFamily = Inter, fontWeight = FontWeight.Medium), + labelMedium = base.labelMedium.copy(fontFamily = Inter, fontWeight = FontWeight.Medium), + labelSmall = base.labelSmall.copy(fontFamily = Inter, fontWeight = FontWeight.Medium), + ) } // Green-seeded Material 3 palette (seed ≈ launcher background #1B5E20). diff --git a/app/src/main/java/no/naiv/meddetsamme/ui/TodayScreen.kt b/app/src/main/java/no/naiv/meddetsamme/ui/TodayScreen.kt index f188bc5..77b830c 100644 --- a/app/src/main/java/no/naiv/meddetsamme/ui/TodayScreen.kt +++ b/app/src/main/java/no/naiv/meddetsamme/ui/TodayScreen.kt @@ -115,7 +115,7 @@ fun TodayScreen(nav: Nav) { val rate = ratePerItem[item.id] ?: 0.0 if (ScheduleEngine.needsRefill(item.stockUnits, rate, item.lowStockLeadDays)) { val days = ScheduleEngine.daysOfSupply(item.stockUnits, rate)?.toInt() ?: 0 - warn += "${item.name}: lager for $days dager" + warn += "${item.name}: lager for ${ScheduleText.daysCount(days)}" } if (ScheduleEngine.needsRenewal(item.rxExpiryEpochDay, today)) { warn += "${item.name}: resept må fornyes" diff --git a/app/src/main/res/font/inter_medium.ttf b/app/src/main/res/font/inter_medium.ttf new file mode 100644 index 0000000..458cd06 Binary files /dev/null and b/app/src/main/res/font/inter_medium.ttf differ diff --git a/app/src/main/res/font/inter_regular.ttf b/app/src/main/res/font/inter_regular.ttf new file mode 100644 index 0000000..b7aaca8 Binary files /dev/null and b/app/src/main/res/font/inter_regular.ttf differ diff --git a/app/src/main/res/font/inter_semibold.ttf b/app/src/main/res/font/inter_semibold.ttf new file mode 100644 index 0000000..47f8ab1 Binary files /dev/null and b/app/src/main/res/font/inter_semibold.ttf differ diff --git a/app/src/main/res/font/manrope_variable.ttf b/app/src/main/res/font/manrope_variable.ttf new file mode 100644 index 0000000..23dcf5e Binary files /dev/null and b/app/src/main/res/font/manrope_variable.ttf differ