Typography: Manrope headings, Inter body — plus norsk dag/dager pluralization
Manrope (variable wght, instanced at 600/700/800) for display/headline/ title roles; Inter static Regular/Medium/SemiBold for body/label. M3 baseline metrics retained — only family and weight change, so component layouts and accessibility text scaling are untouched. Both fonts are OFL (THIRD_PARTY_LICENSES.md added) with full æøå/µ coverage, verified by emulator screenshot. ScheduleText.daysCount fixes 'lager for 1 dager' spotted in that screenshot. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
747a87a570
commit
9b99f2cf62
9 changed files with 63 additions and 3 deletions
13
THIRD_PARTY_LICENSES.md
Normal file
13
THIRD_PARTY_LICENSES.md
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# Third-party licenses
|
||||
|
||||
## Fonts (bundled in `app/src/main/res/font/`)
|
||||
|
||||
- **Inter** (`inter_*.ttf`) — © The Inter Project Authors,
|
||||
<https://github.com/rsms/inter>. Licensed under the SIL Open Font
|
||||
License 1.1 (<https://openfontlicense.org>).
|
||||
- **Manrope** (`manrope_variable.ttf`) — © The Manrope Project Authors,
|
||||
distributed via <https://github.com/google/fonts/tree/main/ofl/manrope>.
|
||||
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.
|
||||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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()) {
|
||||
|
|
|
|||
|
|
@ -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).
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
BIN
app/src/main/res/font/inter_medium.ttf
Normal file
BIN
app/src/main/res/font/inter_medium.ttf
Normal file
Binary file not shown.
BIN
app/src/main/res/font/inter_regular.ttf
Normal file
BIN
app/src/main/res/font/inter_regular.ttf
Normal file
Binary file not shown.
BIN
app/src/main/res/font/inter_semibold.ttf
Normal file
BIN
app/src/main/res/font/inter_semibold.ttf
Normal file
Binary file not shown.
BIN
app/src/main/res/font/manrope_variable.ttf
Normal file
BIN
app/src/main/res/font/manrope_variable.ttf
Normal file
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue