Passer au contenu principal

Système de conception

Palette de couleurs​

La palette Trainium est définie sur ui/theme/Color.kt. Il s’ensuit une esthétique sombre et monochrome avec le bleu électrique comme couleur d’accent.

Tonalités de base (indépendantes du thème)​

JetonValeur HEXUtilisation principale
BlueDark#0B1426Fond de thème sombre
BlueMid#121F3DSurface du thème sombre
BlueDeep#162347Surface de variante de thème sombre
BlueAccent#2196F3Couleur primaire des actions (boutons, bordures actives)
BlueElectric#448AFFBoutons CTA dégradés
BlueSoft#64B5F6Textes secondaires et sous-titres en thème sombre
BlueGlow#332196F3Effets de lueur et d'ombre avec transparence
BlueLight#BBDEFBFonds doux dans le thème clair
WhiteSoft#F0F4FFFond de thème clair

Schéma de couleurs du thème sombre​

Matériau du rouleau 3JetonValeur HEX
primaryDarkPrimary#448AFF
onPrimaryDarkOnPrimary#001E5F
primaryContainerDarkPrimaryContainer#1A3A6E
backgroundDarkBackground#0B1426
surfaceDarkSurface#121F3D
surfaceVariantDarkSurfaceVariant#1A2D54
errorDarkError#FF6B6B

Schéma de couleurs du thème clair​

Matériau du rouleau 3JetonValeur HEX
primaryLightPrimary#1565C0
onPrimaryLightOnPrimary#FFFFFF
primaryContainerLightPrimaryContainer#D0E4FF
backgroundLightBackground#F0F4FF
surfaceLightSurface#FFFFFF
surfaceVariantLightSurfaceVariant#E3ECFA
errorLightError#D32F2F

Typographie​

L'échelle de police est définie sur ui/theme/Type.kt et utilise FontFamily.SansSerif (la police sans empattement par défaut du système Android, généralement Roboto) pour tous les niveaux.

NiveauPoidsTamañoInterletraje
displayLargeNoir (900)34 pages-0,25 sp
headlineLargeGras (700)28 sp0 sp
headlineMediumGras (700)24 heures0 sp
titleLargeSemi-gras (600)20 heures0,15 sp
titleMediumSemi-gras (600)16 étapes0,15 sp
bodyLargeNormale (400)16 étapes0,5 sp
bodyMediumNormale (400)14 étapes0,25 sp
labelLargeGras (700)14 étapes1,2 vitesse
labelMediumMoyen (500)12 étapes0,5 sp
labelSmallMoyen (500)11 étapes0,5 sp

Le labelLarge avec letterSpacing = 1.2 sp est utilisé sur les boutons CTA (tels que « COMMENCER MAINTENANT », « CONTINUER ») pour donner l'effet de texte étendu caractéristique de l'interface.

Formes​

Le système de forme personnalisé PremiumShapes remplace le schéma de coin par défaut Material 3 :

NiveauRadio de sport
small10 points de vue
medium16 points de vue
large22 points de vue
extraLarge28 points de vue

Ces rayons plus généreux que les valeurs par défaut de Material 3 contribuent à l'aspect arrondi haut de gamme des cartes et des boutons.

Gestion des thèmes​

Le thème est géré en deux couches :

MaterialTheme (ui/theme/Theme.kt) : Définit le composable Trainium2Theme qui applique le ColorScheme, le Typography et le Shapes selon le paramètre darkTheme.

ThemeManager (ThemeManager.kt) : Conserve les préférences de l'utilisateur dans le DataStore. La préférence est lue comme un Flow<Boolean?> et collectée dans MainActivity.kt avec collectAsState(initial = null). La valeur initiale null signifie que la préférence n'a pas encore été lue sur le disque ; dans ce cas, le thème système (isSystemInDarkTheme()) est utilisé.

val savedDarkMode by themeManager.isDarkMode.collectAsState(initial = null)
val systemTheme = isSystemInDarkTheme()
var isDarkTheme by remember(savedDarkMode) {
mutableStateOf(savedDarkMode ?: systemTheme)
}

Dégradés d'arrière-plan​

Tous les écrans utilisent des dégradés verticaux au lieu d'arrière-plans plats. Le dégradé varie en fonction du thème actif :

Thème sombre :

Brush.verticalGradient(listOf(BlueDark, BlueMid, BlueDeep))
// #0B1426 → #121F3D → #162347

Thème clair :

Brush.verticalGradient(listOf(Color(0xFFF0F4FF), Color(0xFFE3ECFF), Color(0xFFD6E4FF)))

Animations d'entrée​

Tous les écrans implémentent des animations d'entrée échelonnées à l'aide de LaunchedEffect(Unit) + animateFloatAsState. Le modèle standard est le suivant :

var elementoVisible by remember { mutableStateOf(false) }
val alpha by animateFloatAsState(
targetValue = if (elementoVisible) 1f else 0f,
animationSpec = tween(durationMillis = 500),
label = "elemento_alpha"
)

LaunchedEffect(Unit) {
delay(100)
elementoVisible = true
}

Les éléments sont révélés séquentiellement avec des délais de 100 à 300 ms entre chacun, créant un effet d'apparence en cascade.