kasy-cli 1.31.14 → 1.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/bin/kasy.js +42 -0
  2. package/lib/commands/apple-web.js +222 -0
  3. package/lib/commands/configure.js +3 -91
  4. package/lib/commands/doctor.js +20 -0
  5. package/lib/commands/facebook.js +189 -0
  6. package/lib/commands/new.js +65 -3
  7. package/lib/scaffold/CHANGELOG.json +27 -0
  8. package/lib/scaffold/backends/api/patch/README.md +87 -2
  9. package/lib/scaffold/backends/api/patch/lib/features/authentication/api/authentication_api.dart +34 -0
  10. package/lib/scaffold/backends/api/patch/lib/features/subscriptions/api/stripe_backend_api.dart +12 -2
  11. package/lib/scaffold/backends/firebase/setup-from-scratch.js +186 -0
  12. package/lib/scaffold/backends/supabase/deploy.js +92 -0
  13. package/lib/scaffold/backends/supabase/edge-functions/send-push-notification/README.md +26 -22
  14. package/lib/scaffold/backends/supabase/edge-functions/send-push-notification/index.ts +8 -11
  15. package/lib/scaffold/backends/supabase/edge-functions/stripe-create-checkout-session/index.ts +3 -1
  16. package/lib/scaffold/backends/supabase/edge-functions/stripe-create-portal-session/index.ts +60 -3
  17. package/lib/scaffold/backends/supabase/patch/lib/features/authentication/api/authentication_api.dart +22 -0
  18. package/lib/scaffold/backends/supabase/patch/lib/features/subscriptions/api/stripe_backend_api.dart +12 -2
  19. package/lib/scaffold/backends/supabase/pubspec.yaml.tpl +3 -2
  20. package/lib/scaffold/generate.js +1 -1
  21. package/lib/scaffold/shared/generator-utils.js +34 -3
  22. package/lib/utils/apple-web.js +147 -0
  23. package/lib/utils/facebook.js +162 -0
  24. package/lib/utils/i18n/messages-en.js +64 -0
  25. package/lib/utils/i18n/messages-es.js +64 -0
  26. package/lib/utils/i18n/messages-pt.js +64 -0
  27. package/package.json +2 -2
  28. package/templates/firebase/AGENTS.md +87 -0
  29. package/templates/firebase/CLAUDE.md +16 -0
  30. package/templates/firebase/DESIGN_SYSTEM.md +234 -0
  31. package/templates/firebase/docs/auth-setup.en.md +7 -1
  32. package/templates/firebase/docs/auth-setup.es.md +7 -1
  33. package/templates/firebase/docs/auth-setup.pt.md +7 -1
  34. package/templates/firebase/functions/src/subscriptions/stripe_functions.ts +79 -5
  35. package/templates/firebase/lib/components/components.dart +1 -0
  36. package/templates/firebase/lib/components/kasy_accordion.dart +2 -2
  37. package/templates/firebase/lib/components/kasy_alert.dart +1 -1
  38. package/templates/firebase/lib/components/kasy_app_bar.dart +7 -4
  39. package/templates/firebase/lib/components/kasy_bottom_sheet.dart +1 -1
  40. package/templates/firebase/lib/components/kasy_button.dart +8 -8
  41. package/templates/firebase/lib/components/kasy_chip.dart +1 -1
  42. package/templates/firebase/lib/components/kasy_date_picker.dart +26 -21
  43. package/templates/firebase/lib/components/kasy_dialog.dart +2 -2
  44. package/templates/firebase/lib/components/kasy_screen.dart +114 -0
  45. package/templates/firebase/lib/components/kasy_sidebar.dart +2 -2
  46. package/templates/firebase/lib/components/kasy_tabs.dart +2 -2
  47. package/templates/firebase/lib/components/kasy_text_area.dart +37 -5
  48. package/templates/firebase/lib/components/kasy_text_field.dart +77 -16
  49. package/templates/firebase/lib/components/kasy_toast.dart +39 -70
  50. package/templates/firebase/lib/components/kasy_web_header.dart +4 -3
  51. package/templates/firebase/lib/core/chrome/chrome_visibility.dart +22 -0
  52. package/templates/firebase/lib/core/config/features.dart +18 -0
  53. package/templates/firebase/lib/core/dev_inspector/dev_inspector.dart +21 -0
  54. package/templates/firebase/lib/core/rating/widgets/rate_banner.dart +1 -1
  55. package/templates/firebase/lib/core/rating/widgets/review_popup.dart +46 -124
  56. package/templates/firebase/lib/core/theme/icon_sizes.dart +47 -0
  57. package/templates/firebase/lib/core/theme/shadows.dart +13 -0
  58. package/templates/firebase/lib/core/theme/texts.dart +32 -0
  59. package/templates/firebase/lib/core/theme/theme.dart +2 -0
  60. package/templates/firebase/lib/core/web_device_preview/web_device_preview.dart +3 -0
  61. package/templates/firebase/lib/core/web_viewport_scale.dart +23 -4
  62. package/templates/firebase/lib/core/widgets/update_bottom_sheet.dart +29 -126
  63. package/templates/firebase/lib/features/ai_chat/ai_chat_page.dart +11 -7
  64. package/templates/firebase/lib/features/ai_chat/ui/widgets/ai_chat_composer.dart +21 -0
  65. package/templates/firebase/lib/features/ai_chat/ui/widgets/ai_conversation_list.dart +1 -1
  66. package/templates/firebase/lib/features/ai_chat/ui/widgets/ai_conversation_tile.dart +1 -1
  67. package/templates/firebase/lib/features/authentication/api/authentication_api.dart +61 -0
  68. package/templates/firebase/lib/features/authentication/ui/components/otp_verification.dart +1 -1
  69. package/templates/firebase/lib/features/authentication/ui/components/phone_input.dart +2 -1
  70. package/templates/firebase/lib/features/authentication/ui/recover_password_page.dart +3 -1
  71. package/templates/firebase/lib/features/authentication/ui/signin_page.dart +57 -29
  72. package/templates/firebase/lib/features/authentication/ui/signup_page.dart +47 -25
  73. package/templates/firebase/lib/features/authentication/ui/widgets/recover_password_result.dart +1 -1
  74. package/templates/firebase/lib/features/feedbacks/ui/feedback_page.dart +1 -1
  75. package/templates/firebase/lib/features/feedbacks/ui/widgets/add_feature_button.dart +1 -1
  76. package/templates/firebase/lib/features/feedbacks/ui/widgets/feature_card.dart +2 -3
  77. package/templates/firebase/lib/features/home/home_components_page.dart +7 -1
  78. package/templates/firebase/lib/features/home/home_components_preview_registry.dart +54 -3
  79. package/templates/firebase/lib/features/home/home_image_grid.dart +1 -1
  80. package/templates/firebase/lib/features/local_reminders/ui/reminder_page.dart +165 -209
  81. package/templates/firebase/lib/features/notifications/ui/components/notification_settings_sheet.dart +2 -2
  82. package/templates/firebase/lib/features/notifications/ui/components/notification_tile.dart +21 -8
  83. package/templates/firebase/lib/features/notifications/ui/components/push_notification_switcher.dart +2 -2
  84. package/templates/firebase/lib/features/notifications/ui/notifications_page.dart +3 -6
  85. package/templates/firebase/lib/features/notifications/ui/widgets/empty_notifications.dart +6 -1
  86. package/templates/firebase/lib/features/notifications/ui/widgets/notification_tile.dart +104 -156
  87. package/templates/firebase/lib/features/notifications/ui/widgets/permission_request_view.dart +1 -1
  88. package/templates/firebase/lib/features/onboarding/ui/components/onboarding_loader.dart +1 -1
  89. package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_illustration_scaffold.dart +3 -4
  90. package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_module_mockups.dart +3 -3
  91. package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_radio_question.dart +2 -4
  92. package/templates/firebase/lib/features/onboarding/ui/widgets/selectable_row_tile.dart +3 -2
  93. package/templates/firebase/lib/features/settings/settings_page.dart +264 -307
  94. package/templates/firebase/lib/features/settings/ui/components/admin/admin_page.dart +17 -8
  95. package/templates/firebase/lib/features/settings/ui/components/avatar_component.dart +4 -4
  96. package/templates/firebase/lib/features/settings/ui/components/edit_name_sheet.dart +115 -0
  97. package/templates/firebase/lib/features/settings/ui/components/language_switcher.dart +2 -2
  98. package/templates/firebase/lib/features/settings/ui/widgets/settings_bottom_sheet_option_tile.dart +1 -1
  99. package/templates/firebase/lib/features/settings/ui/widgets/settings_tile.dart +13 -5
  100. package/templates/firebase/lib/features/subscriptions/api/stripe_backend_api.dart +12 -2
  101. package/templates/firebase/lib/features/subscriptions/api/stripe_payment_api.dart +7 -1
  102. package/templates/firebase/lib/features/subscriptions/providers/premium_page_provider.dart +11 -3
  103. package/templates/firebase/lib/features/subscriptions/ui/component/paywall_row.dart +1 -1
  104. package/templates/firebase/lib/features/subscriptions/ui/widgets/comparison_table.dart +1 -1
  105. package/templates/firebase/lib/features/subscriptions/ui/widgets/feature_line.dart +2 -2
  106. package/templates/firebase/lib/features/subscriptions/ui/widgets/premium_close_button.dart +1 -1
  107. package/templates/firebase/lib/features/subscriptions/ui/widgets/premium_feature.dart +1 -1
  108. package/templates/firebase/lib/features/subscriptions/ui/widgets/selectable_col.dart +3 -3
  109. package/templates/firebase/lib/features/subscriptions/ui/widgets/selectable_row.dart +1 -1
  110. package/templates/firebase/lib/i18n/en.i18n.json +13 -4
  111. package/templates/firebase/lib/i18n/es.i18n.json +13 -4
  112. package/templates/firebase/lib/i18n/pt.i18n.json +13 -4
  113. package/templates/firebase/lib/router.dart +2 -0
  114. package/templates/firebase/pubspec.yaml +1 -2
  115. package/templates/firebase/tool/design_check.dart +152 -0
  116. package/templates/firebase/web/stripe_success.html +64 -26
  117. package/lib/scaffold/backends/api/patch/lib/features/onboarding/ui/animations/movefade_anim.dart +0 -34
  118. package/lib/scaffold/backends/api/patch/lib/features/onboarding/ui/components/onboarding_att_setup.dart +0 -67
  119. package/lib/scaffold/backends/api/patch/lib/features/onboarding/ui/widgets/onboarding_radio_question.dart +0 -183
  120. package/lib/scaffold/backends/supabase/patch/lib/features/onboarding/ui/animations/movefade_anim.dart +0 -34
  121. package/lib/scaffold/backends/supabase/patch/lib/features/onboarding/ui/components/onboarding_att_setup.dart +0 -67
  122. package/lib/scaffold/backends/supabase/patch/lib/features/onboarding/ui/widgets/onboarding_radio_question.dart +0 -183
  123. package/templates/firebase/assets/images/review.png +0 -0
  124. package/templates/firebase/assets/images/update.png +0 -0
  125. package/templates/firebase/lib/features/authentication/ui/components/facebook_signin.dart +0 -19
  126. package/templates/firebase/lib/features/notifications/ui/components/notifications_header.dart +0 -32
  127. package/templates/firebase/login-redesign-preview.png +0 -0
@@ -1,9 +1,11 @@
1
1
  import 'dart:ui';
2
2
 
3
+ import 'package:flutter/foundation.dart';
3
4
  import 'package:flutter/material.dart';
4
5
  import 'package:flutter_riverpod/flutter_riverpod.dart';
5
6
  import 'package:go_router/go_router.dart';
6
7
  import 'package:kasy_kit/components/components.dart';
8
+ import 'package:kasy_kit/core/config/features.dart';
7
9
  import 'package:kasy_kit/core/data/models/user.dart';
8
10
  import 'package:kasy_kit/core/haptics/kasy_haptics.dart';
9
11
  import 'package:kasy_kit/core/states/user_state_notifier.dart';
@@ -60,6 +62,7 @@ class SignupPage extends ConsumerWidget {
60
62
  subtitle: t.auth.signup.subtitle,
61
63
  children: [
62
64
  KasyTextField(
65
+ variant: KasyTextFieldVariant.flat,
63
66
  key: const Key('email_input'),
64
67
  onChanged: (value) => ref
65
68
  .read(signupStateProvider.notifier)
@@ -79,6 +82,7 @@ class SignupPage extends ConsumerWidget {
79
82
  ),
80
83
  const SizedBox(height: _authFieldSpacing),
81
84
  KasyTextField(
85
+ variant: KasyTextFieldVariant.flat,
82
86
  key: const Key('password_input'),
83
87
  onChanged: (newValue) => ref
84
88
  .read(signupStateProvider.notifier)
@@ -180,7 +184,8 @@ class _SigninPrompt extends StatelessWidget {
180
184
  KasyPressableDepth(
181
185
  semanticLabel: t.auth.signup.signin_link,
182
186
  onPressed: () => context.pushReplacement('/signin'),
183
- focusable: true,
187
+ // Secondary link: kept out of Tab traversal (focusable defaults to
188
+ // false) so keyboard/next jumps straight to the social buttons.
184
189
  child: Text(
185
190
  t.auth.signup.signin_link,
186
191
  style: context.textTheme.bodyMedium?.copyWith(
@@ -203,6 +208,18 @@ class _SocialSignupRow extends ConsumerWidget {
203
208
  Widget build(BuildContext context, WidgetRef ref) {
204
209
  final state = ref.watch(signinStateProvider);
205
210
  final isSending = state is SigninStateSending;
211
+ // Apple sign-in is reliable only on Apple-native platforms (iOS/macOS). On web
212
+ // it needs a paid Apple Service ID + manual console setup (see auth docs), gated
213
+ // by withAppleWebSignin (off by default). On Android it needs the same Service ID
214
+ // and the Supabase/API native flow throws, so Apple is hidden there.
215
+ final bool showApple = kIsWeb
216
+ ? withAppleWebSignin
217
+ : (defaultTargetPlatform == TargetPlatform.iOS ||
218
+ defaultTargetPlatform == TargetPlatform.macOS);
219
+ // Facebook on web works on the Firebase backend (signInWithPopup); on Supabase
220
+ // the web flow isn't wired yet (roadmap), so withFacebookWebSignin ships false
221
+ // there. Native (iOS/Android) always shows it.
222
+ const bool showFacebook = !kIsWeb || withFacebookWebSignin;
206
223
  return Row(
207
224
  children: [
208
225
  Expanded(
@@ -215,33 +232,38 @@ class _SocialSignupRow extends ConsumerWidget {
215
232
  ref.read(signinStateProvider.notifier).signinWithGoogle(),
216
233
  ),
217
234
  ),
218
- const SizedBox(width: KasySpacing.sm),
219
- Expanded(
220
- child: _SocialSignupTile(
221
- label: t.auth.signin.apple,
222
- icon: Image.asset('assets/icons/apple.png', width: 20, height: 20),
223
- onPressed: isSending
224
- ? null
225
- : () =>
226
- ref.read(signinStateProvider.notifier).signinWithApple(),
235
+ if (showApple) ...[
236
+ const SizedBox(width: KasySpacing.sm),
237
+ Expanded(
238
+ child: _SocialSignupTile(
239
+ label: t.auth.signin.apple,
240
+ icon: Image.asset('assets/icons/apple.png', width: 20, height: 20),
241
+ onPressed: isSending
242
+ ? null
243
+ : () => ref
244
+ .read(signinStateProvider.notifier)
245
+ .signinWithApple(),
246
+ ),
227
247
  ),
228
- ),
229
- const SizedBox(width: KasySpacing.sm),
230
- Expanded(
231
- child: _SocialSignupTile(
232
- label: t.auth.signin.facebook,
233
- icon: Image.asset(
234
- 'assets/icons/facebook.png',
235
- width: 20,
236
- height: 20,
248
+ ],
249
+ if (showFacebook) ...[
250
+ const SizedBox(width: KasySpacing.sm),
251
+ Expanded(
252
+ child: _SocialSignupTile(
253
+ label: t.auth.signin.facebook,
254
+ icon: Image.asset(
255
+ 'assets/icons/facebook.png',
256
+ width: 20,
257
+ height: 20,
258
+ ),
259
+ onPressed: isSending
260
+ ? null
261
+ : () => ref
262
+ .read(signinStateProvider.notifier)
263
+ .signinWithFacebook(),
237
264
  ),
238
- onPressed: isSending
239
- ? null
240
- : () => ref
241
- .read(signinStateProvider.notifier)
242
- .signinWithFacebook(),
243
265
  ),
244
- ),
266
+ ],
245
267
  ],
246
268
  );
247
269
  }
@@ -28,7 +28,7 @@ class RecoverPasswordSent extends StatelessWidget {
28
28
  KasyBrandBadge(
29
29
  icon: KasyIcons.checkCircle,
30
30
  size: 72,
31
- glyphSize: 36,
31
+ glyphSize: KasyIconSize.display,
32
32
  gradient: LinearGradient(
33
33
  begin: Alignment.topLeft,
34
34
  end: Alignment.bottomRight,
@@ -167,7 +167,7 @@ class _AddChipButton extends StatelessWidget {
167
167
  child: Row(
168
168
  mainAxisSize: MainAxisSize.min,
169
169
  children: [
170
- Icon(KasyIcons.add, size: 14, color: context.colors.primary),
170
+ Icon(KasyIcons.add, size: KasyIconSize.xs, color: context.colors.primary),
171
171
  const SizedBox(width: KasySpacing.xs),
172
172
  Text(
173
173
  label,
@@ -56,7 +56,7 @@ class AddFeatureButton extends StatelessWidget {
56
56
  const SizedBox(width: KasySpacing.smd),
57
57
  Icon(
58
58
  KasyIcons.northEast,
59
- size: 16,
59
+ size: KasyIconSize.rowTrailing,
60
60
  color: context.colors.onPrimary.withValues(alpha: 0.55),
61
61
  ),
62
62
  ],
@@ -60,7 +60,6 @@ class _FeatureCardState extends State<FeatureCard> {
60
60
  Text(
61
61
  widget.title,
62
62
  style: context.textTheme.titleMedium?.copyWith(
63
- fontSize: 16,
64
63
  fontWeight: FontWeight.w700,
65
64
  ),
66
65
  ),
@@ -220,7 +219,7 @@ class _VoteCardState extends State<VoteCard>
220
219
  children: [
221
220
  Icon(
222
221
  KasyIcons.voteUp,
223
- size: 22,
222
+ size: KasyIconSize.lg,
224
223
  color: widget.textColor,
225
224
  ),
226
225
  ClipRect(
@@ -251,7 +250,7 @@ class _VoteCardState extends State<VoteCard>
251
250
  key: ValueKey('votes-${widget.id}-${widget.votes}'),
252
251
  widget.votes.toString(),
253
252
  style: context.textTheme.labelLarge?.copyWith(
254
- fontSize: 15,
253
+ fontSize: 15, // design-check: ignore — vote-count badge
255
254
  height: 1,
256
255
  fontWeight: FontWeight.w800,
257
256
  color: widget.textColor,
@@ -91,7 +91,13 @@ class HomeComponentsPage extends StatelessWidget {
91
91
  Flexible(
92
92
  child: Text(
93
93
  row.name,
94
- style: context.textTheme.titleMedium,
94
+ // Lighter weight (w500) to match the
95
+ // app's row/list scale instead of the
96
+ // heavier heading weight.
97
+ style: context.textTheme.titleMedium
98
+ ?.copyWith(
99
+ fontWeight: FontWeight.w500,
100
+ ),
95
101
  ),
96
102
  ),
97
103
  if (_kReadyComponents.contains(
@@ -397,6 +397,10 @@ ComponentPreviewDefinition? getComponentPreviewDefinition(
397
397
  label: 'With Label & Description',
398
398
  builder: _buildTextAreaWithLabelDescription,
399
399
  ),
400
+ ComponentPreviewVariant(
401
+ label: 'Variants',
402
+ builder: _buildTextAreaVariants,
403
+ ),
400
404
  ComponentPreviewVariant(
401
405
  label: 'States',
402
406
  builder: _buildTextAreaStates,
@@ -2714,18 +2718,26 @@ Widget _buildTextFieldVariantsVariant(BuildContext context) {
2714
2718
  children: [
2715
2719
  KasyTextField(
2716
2720
  label: 'Primary Variant',
2717
- hint: 'Primary style input',
2721
+ hint: 'Primary style text field',
2718
2722
  description: 'Default variant with primary styling',
2719
2723
  contentType: KasyTextFieldContentType.email,
2720
2724
  ),
2721
2725
  SizedBox(height: KasySpacing.lg),
2722
2726
  KasyTextField(
2723
2727
  label: 'Secondary Variant',
2724
- hint: 'Secondary style input',
2728
+ hint: 'Secondary style text field',
2725
2729
  description: 'Secondary variant for surfaces',
2726
2730
  variant: KasyTextFieldVariant.secondary,
2727
2731
  contentType: KasyTextFieldContentType.email,
2728
2732
  ),
2733
+ SizedBox(height: KasySpacing.lg),
2734
+ KasyTextField(
2735
+ label: 'Flat Variant',
2736
+ hint: 'Flat style text field',
2737
+ description: 'Primary fill, hairline border, no shadow',
2738
+ variant: KasyTextFieldVariant.flat,
2739
+ contentType: KasyTextFieldContentType.email,
2740
+ ),
2729
2741
  ],
2730
2742
  );
2731
2743
  }
@@ -2738,7 +2750,7 @@ Widget _buildTextFieldStates(BuildContext context) {
2738
2750
  KasyTextField(
2739
2751
  label: 'Default State',
2740
2752
  hint: 'Enter your email',
2741
- description: 'Normal input state',
2753
+ description: 'Normal text field state',
2742
2754
  contentType: KasyTextFieldContentType.email,
2743
2755
  ),
2744
2756
  SizedBox(height: KasySpacing.lg),
@@ -2777,6 +2789,34 @@ Widget _buildTextAreaWithLabelDescription(BuildContext context) {
2777
2789
  return const _TextAreaWithLabelDescriptionContent();
2778
2790
  }
2779
2791
 
2792
+ Widget _buildTextAreaVariants(BuildContext context) {
2793
+ return const Column(
2794
+ mainAxisSize: MainAxisSize.min,
2795
+ crossAxisAlignment: CrossAxisAlignment.stretch,
2796
+ children: [
2797
+ KasyTextArea(
2798
+ label: 'Primary Variant',
2799
+ hint: 'Primary style text area',
2800
+ description: 'Default variant with primary styling',
2801
+ ),
2802
+ SizedBox(height: KasySpacing.lg),
2803
+ KasyTextArea(
2804
+ label: 'Secondary Variant',
2805
+ hint: 'Secondary style text area',
2806
+ description: 'Secondary variant for surfaces',
2807
+ variant: KasyTextFieldVariant.secondary,
2808
+ ),
2809
+ SizedBox(height: KasySpacing.lg),
2810
+ KasyTextArea(
2811
+ label: 'Flat Variant',
2812
+ hint: 'Flat style text area',
2813
+ description: 'Primary fill, hairline border, no shadow',
2814
+ variant: KasyTextFieldVariant.flat,
2815
+ ),
2816
+ ],
2817
+ );
2818
+ }
2819
+
2780
2820
  Widget _buildTextAreaStates(BuildContext context) {
2781
2821
  return const Column(
2782
2822
  mainAxisSize: MainAxisSize.min,
@@ -9013,6 +9053,7 @@ class _DatePickerVariantsPreview extends StatefulWidget {
9013
9053
  class _DatePickerVariantsPreviewState
9014
9054
  extends State<_DatePickerVariantsPreview> {
9015
9055
  DateTime? _filledDate;
9056
+ DateTime? _flatDate;
9016
9057
  DateTime? _noBarrierDate;
9017
9058
  DateTime? _noSuffixDate;
9018
9059
  DateTime? _noFocusDate;
@@ -9035,6 +9076,16 @@ class _DatePickerVariantsPreviewState
9035
9076
  locale: locale,
9036
9077
  ),
9037
9078
  const SizedBox(height: KasySpacing.lg),
9079
+ // Flat — surface fill + hairline border, no shadow (KasyTextField.flat).
9080
+ KasyDatePicker(
9081
+ label: 'Flat (no shadow)',
9082
+ placeholder: 'Choose a date',
9083
+ value: _flatDate,
9084
+ onChanged: (d) => setState(() => _flatDate = d),
9085
+ variant: KasyTextFieldVariant.flat,
9086
+ locale: locale,
9087
+ ),
9088
+ const SizedBox(height: KasySpacing.lg),
9038
9089
  // Popover without the dimmed backdrop — feels lighter / tooltip-like.
9039
9090
  KasyDatePicker(
9040
9091
  label: 'No backdrop',
@@ -396,7 +396,7 @@ class _LikeButtonState extends State<_LikeButton>
396
396
  scale: _scale,
397
397
  child: Icon(
398
398
  widget.liked ? KasyIcons.favoriteFilled : KasyIcons.favorite,
399
- size: 18,
399
+ size: KasyIconSize.md,
400
400
  color: heart,
401
401
  ),
402
402
  ),