Coding Style & Linting
The project enforces strict Kotlin style guides. These are enforced via CI checks.
- Max Line Length: 120 chars.
- Naming:
- Classes:
PascalCase
- Functions/Variables:
camelCase
- Consts:
SCREAMING_SNAKE_CASE
- ❌ No Hungarian notation (e.g.,
mContext, strName).
- Complexity: Methods > 20 lines are flagged. Break them down.
- Imports: No wildcard imports (
import java.util.*).
Design System (The UI Contract)
We utilize a Dynamic Material 3 system driven by seed colors.
Theming Strategy
Do not hardcode hex colors for primary UI elements. We generate palettes dynamically based on the AppTheme enum.
Approved Themes (Seeds):
| Theme Name | Seed Color | Usage |
|---|
ClarityTeal | #006A64 | Default / Focus |
FocusBlue | #345CA8 | Productivity |
CalmLavender | #6750A4 | Relaxation |
VitalityOrange | #BD3400 | Energy |
UpliftingGreen | #336B25 | Growth |
OptimisticYellow | #6E5F00 | Positivity |
Deprecation Notice: The static objects ClarityTeal, FocusBlue, etc., inside AppColors.kt are DEPRECATED. Do not use them. Use MaterialTheme.colorScheme which is generated from the seed.
Domain-Specific Colors
For non-thematic, functional colors, use AppColors:
- Feedback: Use
AppColors.Feedback (e.g., TerribleBg, ExcellentTrack).
- Mascot: Use
AppColors.Mascot for mood states.
- Charts: Use
AppColors.premiumTreemapPalette.
Typography
We use Google Sans Flex (Variable Font). Do not manually set font families. Use the Material tokens.
| Token | Size | Weight | Usage |
|---|
displayLarge | 57sp | Black (900) | Hero numbers, Splash |
headlineLarge | 32sp | ExtraBold (800) | Screen Titles |
titleMedium | 16sp | SemiBold (600) | Card Headers |
bodyLarge | 16sp | Normal (400) | Primary Content |
labelSmall | 11sp | Medium (500) | Captions, Badges |
Layout & Window Insets
- Edge-to-Edge: The app enforces Edge-to-Edge.
- System Bars: Status and Navigation bars are
Color.Transparent.
- Root Composable: All screens must be wrapped in
ScrollLessTheme.
- Spacing: Use
LocalSpacing.current (e.g., spacing.medium) instead of hardcoded 8.dp.
Haptics
Do not use Android Vibrator directly.
- ✅
LocalHaptics.current.performClick()
- ✅
LocalHaptics.current.performSuccess()
Logging Standards
We use Timber for logging to ensure logs are stripped in release builds automatically.
- ✅
Timber.d("User clicked button")
- ✅
Timber.e(exception, "Failed to load data")
- ❌
Log.d("TAG", "Clicked") (Strictly Forbidden)
- ❌
System.out.println(...)
Testing Strategy
- Unit Tests: JUnit 5 + MockK.
- Coroutines: Use
runTest and Turbine for Flow assertions.
- UI Tests: Compose Test Rule.
Security & Build
- Obfuscation: ProGuard is enabled for Release builds.
- Rules: The
proguard-rules.pro is currently using default Android strictness.
- Reflection: If you use a library requiring reflection (e.g., Gson, Retrofit), you must add a
@Keep annotation or a specific rule in proguard-rules.pro.