feat: complete 20-screen onboarding flow

Full quiz flow s01-s20: splash, intro, value prop, social proof,
name/skin-type/age/concerns/goal quiz with insights, analysing loader,
result with skin score, AM/PM routines, ingredient science, signup, welcome.

Duolingo-style design: flat cards, pressable SButton (Stack trick),
4px progress bar, mascot moods (wave/think/analyze/celebrate),
confetti on result+welcome, personalized content throughout.
This commit is contained in:
mav
2026-05-28 17:11:27 +02:00
parent 6311088256
commit 93042cbb4c
26 changed files with 2582 additions and 2 deletions

View File

@@ -0,0 +1,51 @@
import 'package:flutter/material.dart';
import '../../theme.dart';
class QuizNav extends StatelessWidget {
final int step;
final int total;
final VoidCallback onBack;
final String? skipLabel;
final VoidCallback? onSkip;
const QuizNav({
super.key,
required this.step,
required this.total,
required this.onBack,
this.skipLabel,
this.onSkip,
});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.fromLTRB(16, 12, 16, 0),
child: Row(
children: [
GestureDetector(
onTap: onBack,
child: Container(
width: 36, height: 36,
decoration: BoxDecoration(
color: SColors.bgSurface,
borderRadius: BorderRadius.circular(10),
border: Border.all(color: SColors.borderLight, width: 1.5),
),
child: const Icon(Icons.arrow_back_ios_new_rounded, size: 15, color: SColors.textBody),
),
),
const Spacer(),
Text('$step of $total', style: SText.caption(SColors.textSub).copyWith(fontWeight: FontWeight.w600)),
if (onSkip != null) ...[
const SizedBox(width: 16),
GestureDetector(
onTap: onSkip,
child: Text(skipLabel ?? 'Skip', style: SText.caption(SColors.textSub)),
),
],
],
),
);
}
}