Phase 4 Stage 0: design system foundation (client_app)

- HaloTokens, HaloSpacing, HaloRadius, HaloMotion, HaloShadows (warm palette;
  calm/playful stubbed for phase 5).
- Bundled Bricolage Grotesque, Poppins, JetBrains Mono (~1.2 MB total, OFL).
- haloThemeData() wired into MaterialApp.router with Figma-aligned text
  scale, pill ElevatedButton, 64px input height, 24px-corner BottomSheet,
  dark pill SnackBar.
- Halo* widget primitives: Button, Orb, StepDots, BottomSheet, Popup,
  Snackbar, Chip.
- Dev-only /_theme_preview route gated by --dart-define=THEME_PREVIEW=true
  for visual reference during stages 2-8.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-10 15:56:00 +08:00
parent 8c212cb464
commit 4ada7c991a
21 changed files with 1308 additions and 1 deletions

View File

@@ -19,6 +19,7 @@ import 'features/chat/screens/chat_screen.dart';
import 'features/chat/screens/chat_history_screen.dart';
import 'features/chat/screens/chat_transcript_screen.dart';
import 'features/payment/screens/payment_screen.dart';
import 'core/theme/_preview.dart';
class RouterNotifier extends ChangeNotifier {
final Ref _ref;
@@ -47,9 +48,12 @@ GoRouter buildRouter(Ref ref) {
final notifier = RouterNotifier(ref);
return GoRouter(
initialLocation: '/splash',
initialLocation: kThemePreviewEnabled ? '/_theme_preview' : '/splash',
refreshListenable: notifier,
redirect: (context, state) {
// Theme preview is dev-only and intentionally bypasses auth + onboarding
// gates so it can be opened on any device build.
if (state.matchedLocation == '/_theme_preview') return null;
final authState = ref.read(authProvider);
final isSplash = state.matchedLocation == '/splash';
final isOnboarding = state.matchedLocation == '/onboarding';
@@ -89,6 +93,8 @@ GoRouter buildRouter(Ref ref) {
return null;
},
routes: [
if (kThemePreviewEnabled)
GoRoute(path: '/_theme_preview', builder: (_, __) => const ThemePreviewScreen()),
GoRoute(path: '/splash', builder: (_, __) => const SplashScreen()),
GoRoute(path: '/onboarding', builder: (_, __) => const OnboardingScreen()),
GoRoute(path: '/welcome', builder: (_, __) => const WelcomeScreen()),