@carlonicora/nextjs-jsonapi 1.129.1 → 1.130.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 (115) hide show
  1. package/dist/{BlockNoteEditor-RG2YQDMQ.js → BlockNoteEditor-AI5C4PBZ.js} +11 -11
  2. package/dist/BlockNoteEditor-AI5C4PBZ.js.map +1 -0
  3. package/dist/{BlockNoteEditor-WIAQJ5HM.mjs → BlockNoteEditor-KARBUMFE.mjs} +4 -4
  4. package/dist/BlockNoteEditor-KARBUMFE.mjs.map +1 -0
  5. package/dist/billing/index.js +398 -389
  6. package/dist/billing/index.js.map +1 -1
  7. package/dist/billing/index.mjs +131 -122
  8. package/dist/billing/index.mjs.map +1 -1
  9. package/dist/{chunk-YQTMNZQB.js → chunk-BHZVFSDR.js} +158 -89
  10. package/dist/chunk-BHZVFSDR.js.map +1 -0
  11. package/dist/{chunk-F54XZKPY.mjs → chunk-NXHNJCY2.mjs} +2119 -2050
  12. package/dist/chunk-NXHNJCY2.mjs.map +1 -0
  13. package/dist/client/index.js +2 -2
  14. package/dist/client/index.mjs +1 -1
  15. package/dist/components/index.d.mts +20 -2
  16. package/dist/components/index.d.ts +20 -2
  17. package/dist/components/index.js +8 -2
  18. package/dist/components/index.js.map +1 -1
  19. package/dist/components/index.mjs +7 -1
  20. package/dist/contexts/index.js +2 -2
  21. package/dist/contexts/index.mjs +1 -1
  22. package/dist/features/help/index.js +32 -31
  23. package/dist/features/help/index.js.map +1 -1
  24. package/dist/features/help/index.mjs +3 -2
  25. package/dist/features/help/index.mjs.map +1 -1
  26. package/package.json +1 -1
  27. package/src/components/containers/ReactMarkdownContainer.tsx +2 -2
  28. package/src/components/editors/BlockNoteDiffInlineContent.tsx +10 -10
  29. package/src/components/editors/BlockNoteEditor.tsx +2 -2
  30. package/src/components/forms/FormCheckbox.tsx +2 -2
  31. package/src/components/forms/FormFieldWrapper.tsx +1 -1
  32. package/src/components/forms/FormSlider.tsx +1 -1
  33. package/src/components/forms/GdprConsentCheckbox.tsx +1 -1
  34. package/src/components/hero/EntitySection.tsx +2 -1
  35. package/src/components/index.ts +1 -0
  36. package/src/components/typography/DetailField.tsx +35 -0
  37. package/src/components/typography/MicroLabel.tsx +21 -0
  38. package/src/components/typography/SectionHeader.tsx +18 -0
  39. package/src/components/typography/index.ts +6 -0
  40. package/src/features/assistant/components/parts/AssistantEmptyState.tsx +2 -1
  41. package/src/features/assistant/components/parts/AssistantSidebar.tsx +2 -1
  42. package/src/features/auth/components/buttons/GoogleSignInButton.tsx +1 -1
  43. package/src/features/auth/components/forms/Register.tsx +1 -1
  44. package/src/features/auth/components/forms/TwoFactorChallenge.tsx +3 -3
  45. package/src/features/auth/components/two-factor/BackupCodesDialog.tsx +1 -1
  46. package/src/features/auth/components/two-factor/TotpInput.tsx +2 -2
  47. package/src/features/auth/components/two-factor/TwoFactorSettings.tsx +3 -3
  48. package/src/features/billing/components/cards/BillingUsageSummaryCard.tsx +4 -4
  49. package/src/features/billing/components/cards/CustomerInfoCard.tsx +6 -6
  50. package/src/features/billing/components/cards/InvoicesSummaryCard.tsx +5 -5
  51. package/src/features/billing/components/cards/PaymentMethodSummaryCard.tsx +4 -4
  52. package/src/features/billing/components/cards/SubscriptionSummaryCard.tsx +4 -4
  53. package/src/features/billing/components/containers/BillingDashboardContainer.tsx +2 -2
  54. package/src/features/billing/components/widgets/BillingAlertBanner.tsx +8 -8
  55. package/src/features/billing/stripe-customer/components/containers/PaymentMethodsContainer.tsx +2 -2
  56. package/src/features/billing/stripe-customer/components/details/PaymentMethodCard.tsx +8 -2
  57. package/src/features/billing/stripe-customer/components/forms/PaymentMethodForm.tsx +1 -1
  58. package/src/features/billing/stripe-invoice/components/details/InvoiceDetails.tsx +16 -18
  59. package/src/features/billing/stripe-invoice/components/lists/InvoicesList.tsx +2 -2
  60. package/src/features/billing/stripe-invoice/components/widgets/InvoiceStatusBadge.tsx +8 -7
  61. package/src/features/billing/stripe-price/components/lists/PricesList.tsx +6 -13
  62. package/src/features/billing/stripe-product/components/containers/ProductsAdminContainer.tsx +3 -3
  63. package/src/features/billing/stripe-product/components/lists/ProductsList.tsx +4 -7
  64. package/src/features/billing/stripe-promotion-code/components/PromoCodeInput.tsx +6 -6
  65. package/src/features/billing/stripe-subscription/components/containers/SubscriptionsContainer.tsx +2 -2
  66. package/src/features/billing/stripe-subscription/components/details/SubscriptionDetails.tsx +10 -10
  67. package/src/features/billing/stripe-subscription/components/widgets/PricingCard.tsx +2 -2
  68. package/src/features/billing/stripe-subscription/components/widgets/ProductPricingRow.tsx +2 -1
  69. package/src/features/billing/stripe-subscription/components/widgets/ProrationPreview.tsx +1 -1
  70. package/src/features/billing/stripe-subscription/components/widgets/SubscriptionStatusBadge.tsx +12 -11
  71. package/src/features/billing/stripe-subscription/components/wizards/WizardStepPaymentMethod.tsx +2 -1
  72. package/src/features/billing/stripe-subscription/components/wizards/WizardStepReview.tsx +10 -13
  73. package/src/features/billing/stripe-usage/components/containers/UsageContainer.tsx +2 -2
  74. package/src/features/billing/stripe-usage/components/details/UsageSummaryCard.tsx +6 -6
  75. package/src/features/billing/stripe-usage/components/lists/UsageHistoryTable.tsx +3 -2
  76. package/src/features/company/components/details/CompanyContent.tsx +4 -7
  77. package/src/features/company/components/details/TokenStatusIndicator.tsx +5 -5
  78. package/src/features/company/components/forms/CompanyDeleter.tsx +1 -1
  79. package/src/features/company/components/forms/CompanyEditor.tsx +3 -2
  80. package/src/features/content/components/lists/ContentsList.tsx +2 -1
  81. package/src/features/feature/components/forms/FormFeatures.tsx +6 -1
  82. package/src/features/help/components/HelpTOC.tsx +2 -3
  83. package/src/features/how-to/components/containers/HowToCommand.tsx +3 -3
  84. package/src/features/how-to/components/containers/HowToCommandViewer.tsx +4 -1
  85. package/src/features/notification/components/containers/NotificationsListContainer.tsx +1 -1
  86. package/src/features/notification/components/modals/NotificationModal.tsx +2 -2
  87. package/src/features/oauth/components/OAuthClientCard.tsx +1 -1
  88. package/src/features/oauth/components/OAuthClientDetail.tsx +5 -9
  89. package/src/features/oauth/components/OAuthClientForm.tsx +3 -3
  90. package/src/features/oauth/components/OAuthClientList.tsx +5 -4
  91. package/src/features/oauth/components/OAuthClientSecretDisplay.tsx +3 -3
  92. package/src/features/oauth/components/OAuthRedirectUriInput.tsx +1 -1
  93. package/src/features/oauth/components/OAuthScopeSelector.tsx +2 -2
  94. package/src/features/oauth/components/consent/OAuthConsentHeader.tsx +1 -1
  95. package/src/features/oauth/components/consent/OAuthConsentScreen.tsx +1 -1
  96. package/src/features/oauth/components/consent/OAuthScopeList.tsx +2 -3
  97. package/src/features/rbac/components/RbacContainer.tsx +1 -1
  98. package/src/features/rbac/components/RbacPermissionCell.tsx +2 -2
  99. package/src/features/rbac/components/RbacPermissionPicker.tsx +3 -3
  100. package/src/features/referral/components/ReferralWidget.tsx +7 -6
  101. package/src/features/waitlist/components/forms/WaitlistForm.tsx +3 -2
  102. package/src/features/waitlist/components/forms/WaitlistQuestionnaireRenderer.tsx +1 -1
  103. package/src/features/waitlist/components/lists/WaitlistList.tsx +2 -1
  104. package/src/features/waitlist/components/sections/WaitlistConfirmation.tsx +3 -2
  105. package/src/features/waitlist/components/sections/WaitlistSuccessState.tsx +2 -1
  106. package/src/features/waitlist/hooks/useWaitlistTableStructure.tsx +1 -1
  107. package/src/shadcnui/custom/link.tsx +7 -1
  108. package/src/shadcnui/ui/alert.tsx +1 -1
  109. package/src/shadcnui/ui/badge.tsx +7 -0
  110. package/src/shadcnui/ui/button.tsx +1 -1
  111. package/src/shadcnui/ui/chart.tsx +1 -3
  112. package/dist/BlockNoteEditor-RG2YQDMQ.js.map +0 -1
  113. package/dist/BlockNoteEditor-WIAQJ5HM.mjs.map +0 -1
  114. package/dist/chunk-F54XZKPY.mjs.map +0 -1
  115. package/dist/chunk-YQTMNZQB.js.map +0 -1
@@ -70,7 +70,7 @@ export function ReactMarkdownContainer({
70
70
  <ol className={`list-decimal ${size === "small" ? "pl-3" : "pl-4"}`}>{children}</ol>
71
71
  ),
72
72
  h1: ({ children }) => (
73
- <h1 className={size === "small" ? "my-1 mt-2 text-sm font-bold" : "my-2 mt-4 text-3xl font-medium"}>
73
+ <h1 className={size === "small" ? "my-1 mt-2 text-sm font-bold" : "my-2 mt-4 text-3xl font-semibold"}>
74
74
  {children}
75
75
  </h1>
76
76
  ),
@@ -106,7 +106,7 @@ export function ReactMarkdownContainer({
106
106
  <div className="mt-2 flex justify-end">
107
107
  <button
108
108
  onClick={handleToggle}
109
- className="flex items-center gap-1 rounded-md px-3 py-1.5 text-sm text-gray-600 transition-colors hover:bg-gray-100 hover:text-gray-900"
109
+ className="text-primary flex items-center gap-1 rounded-md px-3 py-1.5 text-sm font-medium transition-colors hover:bg-gray-100 hover:underline"
110
110
  aria-label={isExpanded ? t("show_less") : t("show_more")}
111
111
  >
112
112
  <span>{isExpanded ? t("show_less") : t("show_more")}</span>
@@ -55,7 +55,7 @@ export const diffWordInlineContentSpec = createReactInlineContentSpec(
55
55
  <Button
56
56
  size="sm"
57
57
  variant="ghost"
58
- className="m-0 h-6 w-6 p-0 text-green-600 hover:bg-green-50 hover:text-green-700"
58
+ className="text-success m-0 h-6 w-6 p-0 hover:bg-green-50 hover:text-success"
59
59
  onClick={(e) => {
60
60
  e.preventDefault();
61
61
  e.stopPropagation();
@@ -70,7 +70,7 @@ export const diffWordInlineContentSpec = createReactInlineContentSpec(
70
70
  <Button
71
71
  size="sm"
72
72
  variant="ghost"
73
- className="m-0 h-6 w-6 p-0 text-red-600 hover:bg-red-50 hover:text-red-700"
73
+ className="text-destructive m-0 h-6 w-6 p-0 hover:bg-red-50 hover:text-destructive"
74
74
  onClick={(e) => {
75
75
  e.preventDefault();
76
76
  e.stopPropagation();
@@ -93,15 +93,15 @@ export const diffWordInlineContentSpec = createReactInlineContentSpec(
93
93
  <span className="group relative inline-flex items-center">
94
94
  <span
95
95
  className={cn("rounded-sm px-1 transition-all duration-200", {
96
- "border border-green-300 bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-300":
96
+ "text-success border border-green-300 bg-green-100 dark:bg-green-900/30 dark:text-success":
97
97
  isAddition && !accepted && !rejected,
98
- "border border-green-400 bg-green-200 text-green-900": isAddition && accepted,
99
- "border border-gray-300 bg-gray-100 text-gray-500 line-through": isAddition && rejected,
98
+ "text-success border border-green-400 bg-green-200": isAddition && accepted,
99
+ "text-muted-foreground border border-gray-300 bg-gray-100 line-through": isAddition && rejected,
100
100
 
101
- "border border-red-300 bg-red-100 text-red-800 line-through dark:bg-red-900/30 dark:text-red-300":
101
+ "text-destructive border border-red-300 bg-red-100 line-through dark:bg-red-900/30 dark:text-destructive":
102
102
  isRemoval && !accepted && !rejected,
103
- "border border-gray-400 bg-gray-200 text-gray-600 line-through": isRemoval && accepted,
104
- "border border-red-400 bg-red-200 text-red-900 line-through": isRemoval && rejected,
103
+ "text-muted-foreground border border-gray-400 bg-gray-200 line-through": isRemoval && accepted,
104
+ "text-destructive border border-red-400 bg-red-200 line-through": isRemoval && rejected,
105
105
  })}
106
106
  >
107
107
  {text}
@@ -112,7 +112,7 @@ export const diffWordInlineContentSpec = createReactInlineContentSpec(
112
112
  <Button
113
113
  size="sm"
114
114
  variant="ghost"
115
- className="m-0 h-6 w-6 p-0 text-green-600 hover:bg-green-50 hover:text-green-700"
115
+ className="text-success m-0 h-6 w-6 p-0 hover:bg-green-50 hover:text-success"
116
116
  onClick={(e) => {
117
117
  e.preventDefault();
118
118
  e.stopPropagation();
@@ -127,7 +127,7 @@ export const diffWordInlineContentSpec = createReactInlineContentSpec(
127
127
  <Button
128
128
  size="sm"
129
129
  variant="ghost"
130
- className="m-0 h-6 w-6 p-0 text-red-600 hover:bg-red-50 hover:text-red-700"
130
+ className="text-destructive m-0 h-6 w-6 p-0 hover:bg-red-50 hover:text-destructive"
131
131
  onClick={(e) => {
132
132
  e.preventDefault();
133
133
  e.stopPropagation();
@@ -148,7 +148,7 @@ const createDiffActionsInlineContentSpec = (
148
148
  diffIds.split(",").forEach((id: string) => handleAcceptChange(id.trim()));
149
149
  }}
150
150
  >
151
- <CheckIcon className="h-3 w-3 text-green-600" />
151
+ <CheckIcon className="text-success h-3 w-3" />
152
152
  </Button>
153
153
  <Button
154
154
  title="Reject change"
@@ -159,7 +159,7 @@ const createDiffActionsInlineContentSpec = (
159
159
  diffIds.split(",").forEach((id: string) => handleRejectChange(id.trim()));
160
160
  }}
161
161
  >
162
- <XIcon className="h-3 w-3 text-red-600" />
162
+ <XIcon className="text-destructive h-3 w-3" />
163
163
  </Button>
164
164
  </span>
165
165
  );
@@ -38,10 +38,10 @@ export function FormCheckbox({ form, id, name, labelBefore, description, isRequi
38
38
  {(field) => (
39
39
  <div className="flex gap-x-4">
40
40
  {labelBefore && label()}
41
- {labelBefore && isRequired && <span className="text-destructive ml-2 font-semibold">*</span>}
41
+ {labelBefore && isRequired && <span className="ml-1 text-destructive">*</span>}
42
42
  <Checkbox id={id} checked={field.value ?? false} onCheckedChange={field.onChange} />
43
43
  {!labelBefore && label()}
44
- {!labelBefore && isRequired && <span className="text-destructive ml-2 font-semibold">*</span>}
44
+ {!labelBefore && isRequired && <span className="ml-1 text-destructive">*</span>}
45
45
  </div>
46
46
  )}
47
47
  </FormFieldWrapper>
@@ -43,7 +43,7 @@ export function FormFieldWrapper<T extends FieldValues>({
43
43
  {label && (
44
44
  <FieldLabel>
45
45
  {label}
46
- {isRequired && <span className="text-destructive ml-1 font-semibold">*</span>}
46
+ {isRequired && <span className="ml-1 text-destructive">*</span>}
47
47
  </FieldLabel>
48
48
  )}
49
49
  {children(field, fieldState)}
@@ -28,7 +28,7 @@ export function FormSlider({
28
28
  {() => (
29
29
  <div>
30
30
  {showPercentage && (
31
- <div className="text-muted-foreground mb-2 flex w-full justify-center text-xs">{`${value}%`}</div>
31
+ <div className="text-muted-foreground mb-2 flex w-full justify-center text-xs/relaxed">{`${value}%`}</div>
32
32
  )}
33
33
  <Slider
34
34
  onValueChange={(val) => {
@@ -28,7 +28,7 @@ export function GdprConsentCheckbox<T extends FieldValues>({
28
28
  <div className="space-y-1 leading-none">
29
29
  <span className="text-sm font-normal">
30
30
  {label}
31
- {required && <span className="text-destructive ml-1">*</span>}
31
+ {required && <span className="ml-1 text-destructive">*</span>}
32
32
  </span>
33
33
  {description && <FieldDescription className="text-xs">{description}</FieldDescription>}
34
34
  </div>
@@ -2,6 +2,7 @@
2
2
 
3
3
  import { ReactNode } from "react";
4
4
  import { cn } from "../../utils";
5
+ import { MicroLabel } from "../typography";
5
6
 
6
7
  type EntitySectionProps = {
7
8
  title: string;
@@ -13,7 +14,7 @@ type EntitySectionProps = {
13
14
  export function EntitySection({ title, columns, children, className }: EntitySectionProps) {
14
15
  return (
15
16
  <div className={cn("flex w-full flex-col gap-y-3", className)}>
16
- <h3 className="text-muted-foreground text-xs font-semibold tracking-wider uppercase">{title}</h3>
17
+ <MicroLabel as="h3">{title}</MicroLabel>
17
18
  {columns ? (
18
19
  <div
19
20
  className={cn(
@@ -12,6 +12,7 @@ export * from "./forms";
12
12
  export * from "./navigations";
13
13
  export * from "./pages";
14
14
  export * from "./tables";
15
+ export * from "./typography";
15
16
  export * from "./grids";
16
17
  export * from "./fiscal";
17
18
  export * from "./hero";
@@ -0,0 +1,35 @@
1
+ import * as React from "react";
2
+ import { cn } from "../../utils/cn";
3
+
4
+ type DetailFieldProps = React.ComponentProps<"div"> & {
5
+ label: string;
6
+ value?: React.ReactNode;
7
+ horizontal?: boolean;
8
+ labelWidth?: string;
9
+ };
10
+
11
+ function DetailField({
12
+ label,
13
+ value,
14
+ horizontal = false,
15
+ labelWidth,
16
+ className,
17
+ children,
18
+ ...props
19
+ }: DetailFieldProps) {
20
+ return (
21
+ <div
22
+ data-slot="detail-field"
23
+ className={cn(horizontal ? "flex items-baseline gap-2" : "flex flex-col gap-0.5", className)}
24
+ {...props}
25
+ >
26
+ <span className={cn("text-muted-foreground text-xs", horizontal && labelWidth && cn("shrink-0", labelWidth))}>
27
+ {label}
28
+ </span>
29
+ <div className="text-sm">{value ?? children}</div>
30
+ </div>
31
+ );
32
+ }
33
+
34
+ export { DetailField };
35
+ export type { DetailFieldProps };
@@ -0,0 +1,21 @@
1
+ import * as React from "react";
2
+ import { cn } from "../../utils/cn";
3
+
4
+ type MicroLabelProps = React.ComponentProps<"h4"> & {
5
+ as?: "h3" | "h4" | "span";
6
+ };
7
+
8
+ function MicroLabel({ as: Tag = "h4", className, children, ...props }: MicroLabelProps) {
9
+ return (
10
+ <Tag
11
+ data-slot="micro-label"
12
+ className={cn("text-muted-foreground text-xs font-semibold tracking-wider uppercase", className)}
13
+ {...props}
14
+ >
15
+ {children}
16
+ </Tag>
17
+ );
18
+ }
19
+
20
+ export { MicroLabel };
21
+ export type { MicroLabelProps };
@@ -0,0 +1,18 @@
1
+ import * as React from "react";
2
+ import { cn } from "../../utils/cn";
3
+
4
+ type SectionHeaderProps = React.ComponentProps<"h3"> & {
5
+ level?: 2 | 3;
6
+ };
7
+
8
+ function SectionHeader({ level = 3, className, children, ...props }: SectionHeaderProps) {
9
+ const Tag = level === 2 ? "h2" : "h3";
10
+ return (
11
+ <Tag data-slot="section-header" className={cn("text-lg font-semibold", className)} {...props}>
12
+ {children}
13
+ </Tag>
14
+ );
15
+ }
16
+
17
+ export { SectionHeader };
18
+ export type { SectionHeaderProps };
@@ -0,0 +1,6 @@
1
+ export { SectionHeader } from "./SectionHeader";
2
+ export type { SectionHeaderProps } from "./SectionHeader";
3
+ export { MicroLabel } from "./MicroLabel";
4
+ export type { MicroLabelProps } from "./MicroLabel";
5
+ export { DetailField } from "./DetailField";
6
+ export type { DetailFieldProps } from "./DetailField";
@@ -4,6 +4,7 @@ import { useState } from "react";
4
4
  import { useTranslations } from "next-intl";
5
5
  import { Sparkles } from "lucide-react";
6
6
  import { Label, Switch } from "../../../../shadcnui";
7
+ import { SectionHeader } from "../../../../components/typography";
7
8
  import { AssistantComposer } from "./AssistantComposer";
8
9
 
9
10
  interface Props {
@@ -30,7 +31,7 @@ export function AssistantEmptyState({ onSend, operatorMode = false, onOperatorMo
30
31
  <div className="mx-auto mb-3 flex h-10 w-10 items-center justify-center rounded-full bg-gradient-to-br from-blue-400 to-violet-500 text-white">
31
32
  <Sparkles className="h-5 w-5" />
32
33
  </div>
33
- <h3 className="text-foreground text-xl font-semibold">{t("features.assistant.empty_state.title")}</h3>
34
+ <SectionHeader>{t("features.assistant.empty_state.title")}</SectionHeader>
34
35
  <p className="text-muted-foreground mt-1 text-sm">{t("features.assistant.empty_state.subtitle")}</p>
35
36
  </div>
36
37
  <AssistantComposer value={draft} onValueChange={setDraft} onSend={onSend} />
@@ -3,6 +3,7 @@
3
3
  import { useTranslations } from "next-intl";
4
4
  import { Plus } from "lucide-react";
5
5
  import { Button } from "../../../../shadcnui";
6
+ import { MicroLabel } from "../../../../components/typography";
6
7
  import type { AssistantInterface } from "../../data/AssistantInterface";
7
8
  import { groupThreadsByBucket } from "../../utils/groupThreadsByBucket";
8
9
 
@@ -21,7 +22,7 @@ export function AssistantSidebar({ threads, activeId, onSelect, onNew }: Props)
21
22
  if (items.length === 0) return null;
22
23
  return (
23
24
  <div className="mb-2">
24
- <div className="text-muted-foreground px-2 py-1 text-xs font-semibold uppercase tracking-wider">{label}</div>
25
+ <MicroLabel className="px-2 py-1">{label}</MicroLabel>
25
26
  {items.map((thread) => (
26
27
  <button
27
28
  key={thread.id}
@@ -23,7 +23,7 @@ export function GoogleSignInButton({ referralCode }: GoogleSignInButtonProps) {
23
23
  return (
24
24
  <Link href={buildGoogleOAuthUrl()} className="flex w-full justify-end">
25
25
  <Button
26
- className="w-full bg-white hover:bg-gray-50 text-gray-700 border border-gray-300"
26
+ className="text-muted-foreground w-full border border-gray-300 bg-white hover:bg-gray-50"
27
27
  variant="outline"
28
28
  data-testid="page-login-button-google"
29
29
  >
@@ -300,7 +300,7 @@ export default function Register() {
300
300
  className="flex w-full"
301
301
  >
302
302
  <Button
303
- className="w-full bg-white hover:bg-gray-50 text-gray-700 border border-gray-300"
303
+ className="text-muted-foreground w-full border border-gray-300 bg-white hover:bg-gray-50"
304
304
  variant="outline"
305
305
  type="button"
306
306
  >
@@ -120,7 +120,7 @@ export function TwoFactorChallenge() {
120
120
  return (
121
121
  <>
122
122
  <CardHeader data-testid="page-2fa-challenge">
123
- <CardTitle className="text-primary text-2xl">{t("auth.two_factor.verification_required")}</CardTitle>
123
+ <CardTitle className="text-primary">{t("auth.two_factor.verification_required")}</CardTitle>
124
124
  <CardDescription>{t("auth.two_factor.enter_verification_code")}</CardDescription>
125
125
  </CardHeader>
126
126
  <CardContent>
@@ -180,11 +180,11 @@ export function TwoFactorChallenge() {
180
180
  onChange={(e) => setBackupCode(e.target.value.toUpperCase())}
181
181
  placeholder="XXXXXXXX"
182
182
  maxLength={8}
183
- className={`w-48 text-center font-mono uppercase ${backupError ? "border-destructive" : ""}`}
183
+ className={`w-48 text-center tabular-nums uppercase ${backupError ? "border-destructive" : ""}`}
184
184
  disabled={isVerifying}
185
185
  data-testid="backup-code-input"
186
186
  />
187
- {backupError && <p className="text-sm text-destructive">{backupError}</p>}
187
+ {backupError && <p className="text-destructive text-xs/relaxed">{backupError}</p>}
188
188
  <Button
189
189
  onClick={handleBackupSubmit}
190
190
  disabled={isVerifying || backupCode.length < 8}
@@ -122,7 +122,7 @@ export function BackupCodesDialog({ remainingCodes, onRegenerate, trigger }: Bac
122
122
  </div>
123
123
  ) : (
124
124
  <div className="flex flex-col gap-4">
125
- <div className="grid grid-cols-2 gap-2 p-4 bg-muted rounded-lg font-mono text-sm">
125
+ <div className="grid grid-cols-2 gap-2 p-4 bg-muted rounded-lg tabular-nums text-sm">
126
126
  {codes.map((code, index) => (
127
127
  <div key={index} className="text-center" data-testid={`backup-code-${index}`}>
128
128
  {code}
@@ -75,13 +75,13 @@ export function TotpInput({ onComplete, disabled = false, autoFocus = true, erro
75
75
  onKeyDown={(e) => handleKeyDown(index, e)}
76
76
  onPaste={handlePaste}
77
77
  disabled={disabled}
78
- className={`w-12 h-14 text-center text-2xl font-mono ${error ? "border-destructive" : ""}`}
78
+ className={`w-12 h-14 text-center text-2xl tabular-nums ${error ? "border-destructive" : ""}`}
79
79
  data-testid={`totp-input-${index}`}
80
80
  />
81
81
  ))}
82
82
  </div>
83
83
  {error && (
84
- <p className="text-sm text-destructive" data-testid="totp-error">
84
+ <p className="text-destructive text-xs/relaxed" data-testid="totp-error">
85
85
  {error}
86
86
  </p>
87
87
  )}
@@ -84,9 +84,9 @@ export function TwoFactorSettings() {
84
84
  <CardHeader>
85
85
  <div className="flex items-center gap-2">
86
86
  {isEnabled ? (
87
- <ShieldCheck className="h-6 w-6 text-green-600" />
87
+ <ShieldCheck className="text-success h-6 w-6" />
88
88
  ) : (
89
- <ShieldAlert className="h-6 w-6 text-yellow-600" />
89
+ <ShieldAlert className="text-warning h-6 w-6" />
90
90
  )}
91
91
  <div>
92
92
  <CardTitle>{t("auth.two_factor.title")}</CardTitle>
@@ -146,7 +146,7 @@ export function TwoFactorSettings() {
146
146
  <Separator />
147
147
  <div className="flex items-center justify-between">
148
148
  <div>
149
- <h3 className="font-medium text-green-600">{t("auth.two_factor.enable_2fa")}</h3>
149
+ <h3 className="text-success font-medium">{t("auth.two_factor.enable_2fa")}</h3>
150
150
  <p className="text-sm text-muted-foreground">{t("auth.two_factor.enable_description")}</p>
151
151
  </div>
152
152
  <Button onClick={handleEnable2FA} disabled={isEnabling}>
@@ -30,7 +30,7 @@ export function BillingUsageSummaryCard({
30
30
  return (
31
31
  <Card>
32
32
  <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
33
- <CardTitle className="text-sm font-medium">Usage This Month</CardTitle>
33
+ <CardTitle>Usage This Month</CardTitle>
34
34
  <Activity className="h-4 w-4 text-muted-foreground" />
35
35
  </CardHeader>
36
36
  <CardContent>
@@ -45,11 +45,11 @@ export function BillingUsageSummaryCard({
45
45
  return (
46
46
  <Card>
47
47
  <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
48
- <CardTitle className="text-sm font-medium">Usage This Month</CardTitle>
48
+ <CardTitle>Usage This Month</CardTitle>
49
49
  <Activity className="h-4 w-4 text-muted-foreground" />
50
50
  </CardHeader>
51
51
  <CardContent>
52
- <p className="text-sm text-destructive">{error}</p>
52
+ <p className="text-destructive text-xs/relaxed">{error}</p>
53
53
  </CardContent>
54
54
  </Card>
55
55
  );
@@ -67,7 +67,7 @@ export function BillingUsageSummaryCard({
67
67
  return (
68
68
  <Card className="cursor-pointer hover:bg-accent/50 transition-colors" onClick={onViewDetailsClick}>
69
69
  <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
70
- <CardTitle className="text-sm font-medium">Usage This Month</CardTitle>
70
+ <CardTitle>Usage This Month</CardTitle>
71
71
  <Activity className="h-4 w-4 text-muted-foreground" />
72
72
  </CardHeader>
73
73
  <CardContent>
@@ -42,7 +42,7 @@ export function CustomerInfoCard({ customer, loading, error }: CustomerInfoCardP
42
42
  return (
43
43
  <Card>
44
44
  <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
45
- <CardTitle className="text-sm font-medium">Billing Account</CardTitle>
45
+ <CardTitle>Billing Account</CardTitle>
46
46
  <User className="h-4 w-4 text-muted-foreground" />
47
47
  </CardHeader>
48
48
  <CardContent>
@@ -58,11 +58,11 @@ export function CustomerInfoCard({ customer, loading, error }: CustomerInfoCardP
58
58
  return (
59
59
  <Card>
60
60
  <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
61
- <CardTitle className="text-sm font-medium">Billing Account</CardTitle>
61
+ <CardTitle>Billing Account</CardTitle>
62
62
  <User className="h-4 w-4 text-muted-foreground" />
63
63
  </CardHeader>
64
64
  <CardContent>
65
- <p className="text-sm text-destructive">{error}</p>
65
+ <p className="text-destructive text-xs/relaxed">{error}</p>
66
66
  </CardContent>
67
67
  </Card>
68
68
  );
@@ -72,7 +72,7 @@ export function CustomerInfoCard({ customer, loading, error }: CustomerInfoCardP
72
72
  return (
73
73
  <Card>
74
74
  <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
75
- <CardTitle className="text-sm font-medium">Billing Account</CardTitle>
75
+ <CardTitle>Billing Account</CardTitle>
76
76
  <User className="h-4 w-4 text-muted-foreground" />
77
77
  </CardHeader>
78
78
  <CardContent>
@@ -86,7 +86,7 @@ export function CustomerInfoCard({ customer, loading, error }: CustomerInfoCardP
86
86
  return (
87
87
  <Card>
88
88
  <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
89
- <CardTitle className="text-sm font-medium">Billing Account</CardTitle>
89
+ <CardTitle>Billing Account</CardTitle>
90
90
  <User className="h-4 w-4 text-muted-foreground" />
91
91
  </CardHeader>
92
92
  <CardContent>
@@ -96,7 +96,7 @@ export function CustomerInfoCard({ customer, loading, error }: CustomerInfoCardP
96
96
  {customer.balance !== undefined && customer.balance !== 0 && (
97
97
  <p className="text-sm">
98
98
  <span className="text-muted-foreground">Credit Balance: </span>
99
- <span className={customer.balance < 0 ? "text-green-600" : "text-destructive"}>
99
+ <span className={customer.balance < 0 ? "text-success" : "text-destructive"}>
100
100
  {formatBalance(customer.balance, customer.currency)}
101
101
  </span>
102
102
  </p>
@@ -46,7 +46,7 @@ export function InvoicesSummaryCard({ invoices, loading, error, onViewAllClick }
46
46
  return (
47
47
  <Card>
48
48
  <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
49
- <CardTitle className="text-sm font-medium">Recent Invoices</CardTitle>
49
+ <CardTitle>Recent Invoices</CardTitle>
50
50
  <ReceiptIcon className="h-4 w-4 text-muted-foreground" />
51
51
  </CardHeader>
52
52
  <CardContent>
@@ -62,11 +62,11 @@ export function InvoicesSummaryCard({ invoices, loading, error, onViewAllClick }
62
62
  return (
63
63
  <Card>
64
64
  <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
65
- <CardTitle className="text-sm font-medium">Recent Invoices</CardTitle>
65
+ <CardTitle>Recent Invoices</CardTitle>
66
66
  <ReceiptIcon className="h-4 w-4 text-muted-foreground" />
67
67
  </CardHeader>
68
68
  <CardContent>
69
- <p className="text-sm text-destructive">{error}</p>
69
+ <p className="text-destructive text-xs/relaxed">{error}</p>
70
70
  </CardContent>
71
71
  </Card>
72
72
  );
@@ -80,7 +80,7 @@ export function InvoicesSummaryCard({ invoices, loading, error, onViewAllClick }
80
80
  return (
81
81
  <Card className="cursor-pointer hover:bg-accent/50 transition-colors" onClick={onViewAllClick}>
82
82
  <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
83
- <CardTitle className="text-sm font-medium">Recent Invoices</CardTitle>
83
+ <CardTitle>Recent Invoices</CardTitle>
84
84
  <ReceiptIcon className="h-4 w-4 text-muted-foreground" />
85
85
  </CardHeader>
86
86
  <CardContent>
@@ -100,7 +100,7 @@ export function InvoicesSummaryCard({ invoices, loading, error, onViewAllClick }
100
100
  </p>
101
101
  <div className="flex items-center gap-4 text-xs text-muted-foreground">
102
102
  {paidInvoices.length > 0 && <span>{paidInvoices.length} paid</span>}
103
- {openInvoices.length > 0 && <span className="text-orange-600">{openInvoices.length} open</span>}
103
+ {openInvoices.length > 0 && <span className="text-warning">{openInvoices.length} open</span>}
104
104
  <span className="flex items-center">
105
105
  View all
106
106
  <ChevronRight className="h-3 w-3 ml-1" />
@@ -36,7 +36,7 @@ export function PaymentMethodSummaryCard({
36
36
  return (
37
37
  <Card>
38
38
  <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
39
- <CardTitle className="text-sm font-medium">Payment Method</CardTitle>
39
+ <CardTitle>Payment Method</CardTitle>
40
40
  <Wallet className="h-4 w-4 text-muted-foreground" />
41
41
  </CardHeader>
42
42
  <CardContent>
@@ -51,11 +51,11 @@ export function PaymentMethodSummaryCard({
51
51
  return (
52
52
  <Card>
53
53
  <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
54
- <CardTitle className="text-sm font-medium">Payment Method</CardTitle>
54
+ <CardTitle>Payment Method</CardTitle>
55
55
  <Wallet className="h-4 w-4 text-muted-foreground" />
56
56
  </CardHeader>
57
57
  <CardContent>
58
- <p className="text-sm text-destructive">{error}</p>
58
+ <p className="text-destructive text-xs/relaxed">{error}</p>
59
59
  </CardContent>
60
60
  </Card>
61
61
  );
@@ -67,7 +67,7 @@ export function PaymentMethodSummaryCard({
67
67
  return (
68
68
  <Card className="cursor-pointer hover:bg-accent/50 transition-colors" onClick={onManageClick}>
69
69
  <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
70
- <CardTitle className="text-sm font-medium">Payment Method</CardTitle>
70
+ <CardTitle>Payment Method</CardTitle>
71
71
  <Wallet className="h-4 w-4 text-muted-foreground" />
72
72
  </CardHeader>
73
73
  <CardContent>
@@ -54,7 +54,7 @@ export function SubscriptionSummaryCard({
54
54
  return (
55
55
  <Card>
56
56
  <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
57
- <CardTitle className="text-sm font-medium">Subscriptions</CardTitle>
57
+ <CardTitle>Subscriptions</CardTitle>
58
58
  <CreditCard className="h-4 w-4 text-muted-foreground" />
59
59
  </CardHeader>
60
60
  <CardContent>
@@ -70,11 +70,11 @@ export function SubscriptionSummaryCard({
70
70
  return (
71
71
  <Card>
72
72
  <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
73
- <CardTitle className="text-sm font-medium">Subscriptions</CardTitle>
73
+ <CardTitle>Subscriptions</CardTitle>
74
74
  <CreditCard className="h-4 w-4 text-muted-foreground" />
75
75
  </CardHeader>
76
76
  <CardContent>
77
- <p className="text-sm text-destructive">{error}</p>
77
+ <p className="text-destructive text-xs/relaxed">{error}</p>
78
78
  </CardContent>
79
79
  </Card>
80
80
  );
@@ -88,7 +88,7 @@ export function SubscriptionSummaryCard({
88
88
  return (
89
89
  <Card className="cursor-pointer hover:bg-accent/50 transition-colors" onClick={onManageClick}>
90
90
  <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
91
- <CardTitle className="text-sm font-medium">Subscriptions</CardTitle>
91
+ <CardTitle>Subscriptions</CardTitle>
92
92
  <CreditCard className="h-4 w-4 text-muted-foreground" />
93
93
  </CardHeader>
94
94
  <CardContent>
@@ -328,7 +328,7 @@ export function BillingDashboardContainer() {
328
328
  {/* Header */}
329
329
  <div className="flex items-center gap-x-3">
330
330
  <Wallet className="h-8 w-8" />
331
- <h1 className="text-3xl font-bold">Billing</h1>
331
+ <h1 className="text-primary text-3xl font-semibold">Billing</h1>
332
332
  </div>
333
333
 
334
334
  {/* Initial Loading State */}
@@ -367,7 +367,7 @@ export function BillingDashboardContainer() {
367
367
  </CardContent>
368
368
  {errors.customer && (
369
369
  <CardContent className="pt-0">
370
- <p className="text-center text-sm text-destructive">{errors.customer}</p>
370
+ <p className="text-center text-destructive text-xs/relaxed">{errors.customer}</p>
371
371
  </CardContent>
372
372
  )}
373
373
  </Card>