app/lib/screens/welcome_screen.dart
John Mizerek 151106aa8e Initial commit: Add Months MVP
Local-first Flutter app that identifies the single behavioral change
most likely to extend lifespan using hazard-based modeling.

Features:
- Risk engine with hazard ratios from meta-analyses
- 50 countries mapped to 4 mortality groups
- 6 modifiable factors: smoking, alcohol, sleep, activity, driving, work hours
- SQLite local storage (no cloud, no accounts)
- Muted clinical UI theme
- 23 unit tests for risk engine

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-20 21:25:00 -08:00

128 lines
3.7 KiB
Dart

import 'package:flutter/material.dart';
import '../theme.dart';
import 'baseline_screen.dart';
class WelcomeScreen extends StatelessWidget {
const WelcomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 32),
child: Column(
children: [
const Spacer(flex: 2),
// Icon or logo area
Container(
width: 80,
height: 80,
decoration: BoxDecoration(
color: AppColors.surfaceVariant,
borderRadius: BorderRadius.circular(20),
),
child: const Icon(
Icons.timeline,
size: 40,
color: AppColors.primary,
),
),
const SizedBox(height: 32),
// Title
Text(
'Add Months',
style: Theme.of(context).textTheme.headlineLarge,
textAlign: TextAlign.center,
),
const SizedBox(height: 16),
// Description
Text(
'Identify the single change most likely to extend your lifespan.',
style: Theme.of(context).textTheme.bodyLarge?.copyWith(
color: AppColors.textSecondary,
),
textAlign: TextAlign.center,
),
const SizedBox(height: 48),
// Features list
_buildFeatureItem(
context,
Icons.shield_outlined,
'Private',
'All data stays on your device',
),
const SizedBox(height: 16),
_buildFeatureItem(
context,
Icons.science_outlined,
'Evidence-based',
'Hazard ratios from meta-analyses',
),
const SizedBox(height: 16),
_buildFeatureItem(
context,
Icons.trending_up_outlined,
'Actionable',
'Focus on what matters most',
),
const Spacer(flex: 3),
// Start button
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: () => _navigateToBaseline(context),
child: const Text('Start'),
),
),
const SizedBox(height: 32),
],
),
),
),
);
}
Widget _buildFeatureItem(
BuildContext context,
IconData icon,
String title,
String description,
) {
return Row(
children: [
Container(
width: 44,
height: 44,
decoration: BoxDecoration(
color: AppColors.surfaceVariant,
borderRadius: BorderRadius.circular(12),
),
child: Icon(icon, color: AppColors.primary, size: 22),
),
const SizedBox(width: 16),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: Theme.of(context).textTheme.labelLarge,
),
Text(
description,
style: Theme.of(context).textTheme.bodySmall,
),
],
),
),
],
);
}
void _navigateToBaseline(BuildContext context) {
Navigator.of(context).push(
MaterialPageRoute(builder: (_) => const BaselineScreen()),
);
}
}