@vadimcomanescu/nadicode-design-system 2.0.9 → 4.0.1

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 (154) hide show
  1. package/.agents/skills/seed/SKILL.md +24 -14
  2. package/.agents/skills/seed/contract.md +19 -6
  3. package/.agents/skills/seed/recipes/agency-home.md +5 -5
  4. package/.agents/skills/seed/recipes/auth.md +3 -3
  5. package/.agents/skills/seed/recipes/blog-content.md +2 -2
  6. package/.agents/skills/seed/recipes/company-about.md +3 -3
  7. package/.agents/skills/seed/recipes/company-contact.md +3 -3
  8. package/.agents/skills/seed/recipes/digital-workers.md +3 -3
  9. package/.agents/skills/seed/recipes/marketing-landing.md +8 -8
  10. package/.agents/skills/seed/recipes/marketing-shell.md +4 -4
  11. package/.agents/skills/seed/recipes/navigation-shell.md +3 -2
  12. package/.agents/skills/seed/recipes/pricing.md +4 -4
  13. package/.agents/skills/seed/recipes/service-detail.md +3 -3
  14. package/.agents/skills/seed/references/blocks.md +5 -5
  15. package/.agents/skills/seed/references/components.md +2 -2
  16. package/.agents/skills/seed/references/nextjs.md +2 -2
  17. package/README.md +3 -3
  18. package/contracts/consumer-intent-map.json +1 -2
  19. package/contracts/release-governance-baseline.json +3 -37
  20. package/dist/catalog/catalog.d.ts +2220 -0
  21. package/dist/catalog/catalog.js +1913 -0
  22. package/dist/catalog/components.d.ts +201 -0
  23. package/dist/catalog/components.js +407 -0
  24. package/dist/catalog/types.d.ts +4 -0
  25. package/dist/catalog/types.js +1 -0
  26. package/dist/chunk-224KPIOG.js +60 -0
  27. package/dist/chunk-25BOZMXA.js +169 -0
  28. package/dist/chunk-32OLQ7FC.js +130 -0
  29. package/dist/chunk-3JJBJ4VR.js +47 -0
  30. package/dist/chunk-3U56FXYC.js +30 -0
  31. package/dist/chunk-4MWKE6F5.js +86 -0
  32. package/dist/chunk-6HGSU24S.js +94 -0
  33. package/dist/chunk-7IADIXDV.js +168 -0
  34. package/dist/chunk-7NS3VFD7.js +86 -0
  35. package/dist/chunk-ALA6OM7K.js +134 -0
  36. package/dist/chunk-AN5TW4AL.js +50 -0
  37. package/dist/chunk-AWZFQQGN.js +167 -0
  38. package/dist/chunk-BRCBJ3S4.js +42 -0
  39. package/dist/chunk-BRICSLHJ.js +30 -0
  40. package/dist/chunk-BYEHHZZN.js +115 -0
  41. package/dist/chunk-C33GUEDY.js +149 -0
  42. package/dist/chunk-CUDMDYKE.js +150 -0
  43. package/dist/chunk-CVTMWSNS.js +145 -0
  44. package/dist/chunk-DEZXWNYF.js +165 -0
  45. package/dist/chunk-DNJEVMDY.js +40 -0
  46. package/dist/chunk-DNJOBML6.js +66 -0
  47. package/dist/chunk-FTGFOK6T.js +69 -0
  48. package/dist/{chunk-7A2RXKGH.js → chunk-GJ557DGH.js} +1 -1
  49. package/dist/chunk-HFBJ6L6O.js +104 -0
  50. package/dist/chunk-HPTHS7SX.js +52 -0
  51. package/dist/chunk-K4U67BVG.js +175 -0
  52. package/dist/chunk-KNR3WB5C.js +147 -0
  53. package/dist/chunk-KQ7ZC6EM.js +66 -0
  54. package/dist/chunk-LGW7FVG5.js +83 -0
  55. package/dist/chunk-LK2L3C7D.js +72 -0
  56. package/dist/chunk-LP6ZZYOQ.js +36 -0
  57. package/dist/chunk-LV4P7WVM.js +54 -0
  58. package/dist/chunk-MGSGCARB.js +164 -0
  59. package/dist/chunk-N3YFYMNZ.js +73 -0
  60. package/dist/{chunk-DSMGCFMJ.js → chunk-POFFOUQW.js} +2 -5
  61. package/dist/chunk-Q5IYBNA7.js +56 -0
  62. package/dist/chunk-QJCE7NZF.js +85 -0
  63. package/dist/chunk-QW5II6YK.js +96 -0
  64. package/dist/chunk-RMGDDOCD.js +138 -0
  65. package/dist/chunk-RNCX4JIE.js +70 -0
  66. package/dist/chunk-RWCL5OPX.js +112 -0
  67. package/dist/chunk-S5OY2B63.js +28 -0
  68. package/dist/chunk-SIQNG72C.js +257 -0
  69. package/dist/chunk-SP7NIZFP.js +117 -0
  70. package/dist/chunk-SWRJWMGG.js +30 -0
  71. package/dist/chunk-TCQIJ3DO.js +85 -0
  72. package/dist/chunk-TPJ6JJ2F.js +290 -0
  73. package/dist/chunk-UR43ANYS.js +159 -0
  74. package/dist/chunk-VRGPG2YN.js +79 -0
  75. package/dist/chunk-WSBLCWY7.js +126 -0
  76. package/dist/chunk-XKKFSFYO.js +93 -0
  77. package/dist/chunk-XO7TBM47.js +32 -0
  78. package/dist/chunk-YDYDGG5K.js +132 -0
  79. package/dist/chunk-YMJOUYMT.js +171 -0
  80. package/dist/chunk-Z2WION42.js +32 -0
  81. package/dist/chunk-ZFKSVEYW.js +35 -0
  82. package/dist/components/blocks/AgentProfileGridBlock.js +8 -86
  83. package/dist/components/blocks/AgentRunOverviewBlock.js +8 -147
  84. package/dist/components/blocks/AgentWorkbenchBlock.js +15 -257
  85. package/dist/components/blocks/AudioVisualizerBlock.js +2 -50
  86. package/dist/components/blocks/AuthLayout.js +9 -73
  87. package/dist/components/blocks/BannerBlock.js +8 -66
  88. package/dist/components/blocks/BarChartBlock.js +5 -47
  89. package/dist/components/blocks/ChartBlock.js +7 -54
  90. package/dist/components/blocks/ChartCollectionBlock.js +11 -171
  91. package/dist/components/blocks/ChatLayout.js +12 -126
  92. package/dist/components/blocks/CreateBlock.js +9 -104
  93. package/dist/components/blocks/DataGridBlock.js +9 -117
  94. package/dist/components/blocks/DirectoryBlock.js +12 -85
  95. package/dist/components/blocks/FeatureGridBlock.js +6 -56
  96. package/dist/components/blocks/GalleryBlock.js +6 -69
  97. package/dist/components/blocks/HeroBlock.js +2 -2
  98. package/dist/components/blocks/HeroSectionBlock.js +10 -134
  99. package/dist/components/blocks/IntegrationsBlock.js +13 -94
  100. package/dist/components/blocks/InteractiveAreaChartBlock.js +5 -290
  101. package/dist/components/blocks/KanbanDemoBlock.js +8 -145
  102. package/dist/components/blocks/LogoCloud.js +4 -35
  103. package/dist/components/blocks/NavUser.js +5 -85
  104. package/dist/components/blocks/NotFoundBlock.js +8 -32
  105. package/dist/components/blocks/OnboardingBlock.js +7 -66
  106. package/dist/components/blocks/SettingsLayout.js +13 -86
  107. package/dist/components/blocks/SignUpBlock.js +8 -168
  108. package/dist/components/blocks/SolutionShowcaseBlock.js +11 -112
  109. package/dist/components/blocks/StatsBlock.js +6 -60
  110. package/dist/components/blocks/UsageDonutBlock.js +5 -79
  111. package/dist/components/blocks/WizardBlock.js +12 -93
  112. package/dist/components/blocks/user/InviteUserModal.js +10 -132
  113. package/dist/components/page-kits/AccountLockedPageKit.js +3 -40
  114. package/dist/components/page-kits/AgentsChatPageKit.js +11 -159
  115. package/dist/components/page-kits/AnalyticsPageKit.js +12 -150
  116. package/dist/components/page-kits/BlogContentPageKit.js +12 -167
  117. package/dist/components/page-kits/CheckoutPageKit.js +9 -83
  118. package/dist/components/page-kits/CompanySuitePageKit.js +9 -96
  119. package/dist/components/page-kits/DashboardPageKit.js +11 -149
  120. package/dist/components/page-kits/ErrorPageKit.js +5 -52
  121. package/dist/components/page-kits/KanbanBoardPageKit.js +7 -169
  122. package/dist/components/page-kits/LandingPageKit.js +12 -73
  123. package/dist/components/page-kits/LoginPageKit.js +3 -32
  124. package/dist/components/page-kits/OnboardingPageKit.js +6 -115
  125. package/dist/components/page-kits/PricingPageKit.js +12 -138
  126. package/dist/components/page-kits/ProfileSettingsPageKit.js +10 -164
  127. package/dist/components/page-kits/RecoveryPageKit.js +3 -42
  128. package/dist/components/page-kits/ResetPageKit.js +3 -36
  129. package/dist/components/page-kits/ServiceSuitePageKit.js +11 -176
  130. package/dist/components/page-kits/SignupPageKit.js +3 -30
  131. package/dist/components/page-kits/SuccessPageKit.js +4 -30
  132. package/dist/components/page-kits/TeamSettingsPageKit.js +9 -165
  133. package/dist/components/page-kits/TwoFactorPageKit.js +4 -28
  134. package/dist/components/page-kits/VerifyEmailPageKit.js +4 -30
  135. package/dist/components/page-kits/VoiceAgentsPageKit.js +13 -130
  136. package/dist/components/ui/AvatarUpload.js +1 -1
  137. package/dist/components/ui/CheckoutForm.js +5 -70
  138. package/dist/components/ui/MouseEffect.js +1 -1
  139. package/eslint-rules/nadicode/config.js +2 -0
  140. package/eslint-rules/nadicode/data/catalog-names.json +93 -0
  141. package/eslint-rules/nadicode/index.js +4 -0
  142. package/eslint-rules/nadicode/rules/__tests__/require-catalog-component.test.js +77 -0
  143. package/eslint-rules/nadicode/rules/__tests__/require-catalog-import.test.js +111 -0
  144. package/eslint-rules/nadicode/rules/require-catalog-component.js +79 -0
  145. package/eslint-rules/nadicode/rules/require-catalog-import.js +59 -0
  146. package/package.json +15 -358
  147. package/contracts/block-props-schemas.json +0 -2186
  148. package/contracts/component-props-schemas.json +0 -8322
  149. package/contracts/consumer-contract.json +0 -178
  150. package/contracts/page-kit-props-schemas.json +0 -1894
  151. package/contracts/public-surface-registry.json +0 -5822
  152. package/contracts/public-surface-registry.schema.json +0 -219
  153. package/contracts/spec-manifest.json +0 -46
  154. package/dist/catalog.json +0 -5221
@@ -0,0 +1,164 @@
1
+ import { SettingsPageKit } from './chunk-RKQPU75I.js';
2
+ import { Typography } from './chunk-N53OMWW2.js';
3
+ import { Switch } from './chunk-R7N7YLFT.js';
4
+ import { Field, FieldLabel } from './chunk-RX5EUODB.js';
5
+ import { Input } from './chunk-AP3XXYAY.js';
6
+ import { Label } from './chunk-LIBXYD5Q.js';
7
+ import { Card, CardHeader, CardTitle, CardDescription, CardContent } from './chunk-AH6YSYYT.js';
8
+ import { Avatar, AvatarImage, AvatarFallback } from './chunk-NAAU5IWU.js';
9
+ import { Button } from './chunk-7KIDDF3I.js';
10
+ import { jsx, jsxs } from 'react/jsx-runtime';
11
+
12
+ var DEFAULT_SECTIONS = [{ id: "profile", label: "Profile" }];
13
+ var EMPTY_VALIDATION_ERRORS = {};
14
+ function renderProfileSection({
15
+ profileFields,
16
+ notificationPreferences,
17
+ avatar,
18
+ mode,
19
+ validationErrors,
20
+ onFieldChange,
21
+ onNotificationChange
22
+ }) {
23
+ const readOnlyMode = mode === "view";
24
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
25
+ /* @__PURE__ */ jsxs(Card, { children: [
26
+ /* @__PURE__ */ jsxs(CardHeader, { children: [
27
+ /* @__PURE__ */ jsx(CardTitle, { children: "Avatar" }),
28
+ /* @__PURE__ */ jsx(CardDescription, { children: "Upload a profile image visible to your workspace." })
29
+ ] }),
30
+ /* @__PURE__ */ jsxs(CardContent, { className: "flex flex-wrap items-center gap-4", children: [
31
+ /* @__PURE__ */ jsxs(Avatar, { className: "h-14 w-14", children: [
32
+ /* @__PURE__ */ jsx(AvatarImage, { src: avatar?.src, alt: "Profile avatar" }),
33
+ /* @__PURE__ */ jsx(AvatarFallback, { children: avatar?.fallback ?? "U" })
34
+ ] }),
35
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-2", children: [
36
+ /* @__PURE__ */ jsx(
37
+ Button,
38
+ {
39
+ variant: "secondary",
40
+ onClick: avatar?.onUpload,
41
+ disabled: readOnlyMode || avatar?.status === "uploading",
42
+ children: avatar?.status === "uploading" ? "Uploading\u2026" : "Upload avatar"
43
+ }
44
+ ),
45
+ /* @__PURE__ */ jsx(Button, { variant: "ghost", onClick: avatar?.onRemove, disabled: readOnlyMode, children: "Remove" })
46
+ ] })
47
+ ] }),
48
+ avatar?.errorMessage ? /* @__PURE__ */ jsx(CardContent, { children: /* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-destructive", children: avatar.errorMessage }) }) : null
49
+ ] }),
50
+ /* @__PURE__ */ jsxs(Card, { children: [
51
+ /* @__PURE__ */ jsxs(CardHeader, { children: [
52
+ /* @__PURE__ */ jsx(CardTitle, { children: "Personal information" }),
53
+ /* @__PURE__ */ jsx(CardDescription, { children: "Control profile details used across your account." })
54
+ ] }),
55
+ /* @__PURE__ */ jsx(CardContent, { className: "space-y-4", children: profileFields.map((field) => {
56
+ const inputId = `profile-settings-field-${field.id}`;
57
+ const fieldError = validationErrors[field.id];
58
+ return /* @__PURE__ */ jsxs(Field, { children: [
59
+ /* @__PURE__ */ jsxs(FieldLabel, { htmlFor: inputId, children: [
60
+ field.label,
61
+ field.required ? " *" : ""
62
+ ] }),
63
+ /* @__PURE__ */ jsx(
64
+ Input,
65
+ {
66
+ id: inputId,
67
+ type: field.type ?? "text",
68
+ value: field.value,
69
+ placeholder: field.placeholder,
70
+ readOnly: readOnlyMode || field.readOnly,
71
+ disabled: readOnlyMode || field.readOnly,
72
+ onChange: (event) => onFieldChange?.(field.id, event.target.value)
73
+ }
74
+ ),
75
+ field.helperText ? /* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-text-tertiary", children: field.helperText }) : null,
76
+ fieldError ? /* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-destructive", children: fieldError }) : null
77
+ ] }, field.id);
78
+ }) })
79
+ ] }),
80
+ /* @__PURE__ */ jsxs(Card, { children: [
81
+ /* @__PURE__ */ jsxs(CardHeader, { children: [
82
+ /* @__PURE__ */ jsx(CardTitle, { children: "Notification preferences" }),
83
+ /* @__PURE__ */ jsx(CardDescription, { children: "Set communication and security notification behavior." })
84
+ ] }),
85
+ /* @__PURE__ */ jsx(CardContent, { className: "space-y-4", children: notificationPreferences.map((preference) => /* @__PURE__ */ jsxs(
86
+ "div",
87
+ {
88
+ className: "flex flex-wrap items-center justify-between gap-3 rounded-lg border border-border-subtle bg-surface-hover p-4",
89
+ children: [
90
+ /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
91
+ /* @__PURE__ */ jsx(Label, { htmlFor: `profile-settings-pref-${preference.id}`, children: preference.label }),
92
+ preference.description ? /* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-text-secondary", children: preference.description }) : null
93
+ ] }),
94
+ /* @__PURE__ */ jsx(
95
+ Switch,
96
+ {
97
+ id: `profile-settings-pref-${preference.id}`,
98
+ checked: preference.enabled,
99
+ disabled: readOnlyMode || preference.disabled,
100
+ onCheckedChange: (checked) => onNotificationChange?.(preference.id, checked),
101
+ "aria-label": preference.label
102
+ }
103
+ )
104
+ ]
105
+ },
106
+ preference.id
107
+ )) })
108
+ ] })
109
+ ] });
110
+ }
111
+ function ProfileSettingsPageKit({
112
+ title = "Profile settings",
113
+ description = "Manage profile details, avatar controls, and personal notification preferences.",
114
+ sections = DEFAULT_SECTIONS,
115
+ activeSectionId,
116
+ onSectionChange,
117
+ profileFields,
118
+ notificationPreferences,
119
+ avatar,
120
+ mode = "edit",
121
+ saveState = "default",
122
+ validationErrors = EMPTY_VALIDATION_ERRORS,
123
+ validationMessage,
124
+ fatalErrorMessage,
125
+ onFieldChange,
126
+ onNotificationChange,
127
+ onSave,
128
+ onDiscard,
129
+ renderAdditionalSection
130
+ }) {
131
+ const firstSectionId = sections[0]?.id ?? "profile";
132
+ const resolvedActiveSectionId = activeSectionId ?? firstSectionId;
133
+ return /* @__PURE__ */ jsx(
134
+ SettingsPageKit,
135
+ {
136
+ title,
137
+ description,
138
+ sections,
139
+ activeSectionId: resolvedActiveSectionId,
140
+ onSectionChange,
141
+ saveState,
142
+ validationMessage,
143
+ fatalErrorMessage,
144
+ onSave,
145
+ onDiscard,
146
+ renderSection: (section) => {
147
+ if (section.id === "profile") {
148
+ return renderProfileSection({
149
+ profileFields,
150
+ notificationPreferences,
151
+ avatar,
152
+ mode,
153
+ validationErrors,
154
+ onFieldChange,
155
+ onNotificationChange
156
+ });
157
+ }
158
+ return renderAdditionalSection ? renderAdditionalSection(section) : null;
159
+ }
160
+ }
161
+ );
162
+ }
163
+
164
+ export { ProfileSettingsPageKit };
@@ -0,0 +1,73 @@
1
+ import { LoginBlock } from './chunk-RGE5OQMZ.js';
2
+ import { StaggerChildren } from './chunk-DQPK2XRL.js';
3
+ import { Heading } from './chunk-WI547C47.js';
4
+ import { siteConfig } from './chunk-A7NUWD76.js';
5
+ import { AnimatedBackground } from './chunk-4GSFNJAJ.js';
6
+ import { useMotionConfig, m, motionSpring } from './chunk-PD2YEH3H.js';
7
+ import { SparklesIcon } from './chunk-CGUCH322.js';
8
+ import { cn } from './chunk-QYZT24TS.js';
9
+ import { jsxs, jsx } from 'react/jsx-runtime';
10
+
11
+ var FORM_ENTRANCE_Y = 12;
12
+ var VISUAL_STAGGER_MS = 100;
13
+ var defaultLabels = {
14
+ headline: "Build the future, faster.",
15
+ quote: "This library has saved me countless hours of work and helped me deliver stunning designs to my clients faster than ever before.",
16
+ quoteAttribution: "Sofia Davis, Lead Engineer"
17
+ };
18
+ function AuthLayout({
19
+ mode = "login",
20
+ action,
21
+ error,
22
+ googleAction,
23
+ labels: userLabels,
24
+ className
25
+ }) {
26
+ const motionConfig = useMotionConfig();
27
+ const labels = { ...defaultLabels, ...userLabels };
28
+ return /* @__PURE__ */ jsxs("div", { className: cn("w-full min-h-dvh lg:h-dvh lg:min-h-[800px] grid lg:grid-cols-2 overflow-hidden bg-background", className), children: [
29
+ /* @__PURE__ */ jsxs("div", { className: "hidden lg:flex relative h-full w-full flex-col bg-muted text-overlay-foreground dark:border-r border-border/50", children: [
30
+ /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-surface-active" }),
31
+ /* @__PURE__ */ jsx("div", { className: "absolute inset-0", children: /* @__PURE__ */ jsx(AnimatedBackground, {}) }),
32
+ /* @__PURE__ */ jsxs("div", { className: "relative z-20 flex items-center text-lg font-medium p-8", children: [
33
+ /* @__PURE__ */ jsx(SparklesIcon, { size: 24, className: "mr-2 text-accent" }),
34
+ siteConfig.name
35
+ ] }),
36
+ /* @__PURE__ */ jsxs(StaggerChildren, { staggerMs: VISUAL_STAGGER_MS, className: "relative z-20 m-auto max-w-lg text-center space-y-4", children: [
37
+ /* @__PURE__ */ jsx(Heading, { level: 2, size: "display", className: "font-bold bg-clip-text text-transparent bg-gradient-to-b from-overlay-foreground to-overlay-foreground/60 relative", children: labels.headline }),
38
+ /* @__PURE__ */ jsxs("blockquote", { className: "text-lg text-text-tertiary relative", children: [
39
+ /* @__PURE__ */ jsxs("p", { children: [
40
+ '"',
41
+ labels.quote,
42
+ '"'
43
+ ] }),
44
+ /* @__PURE__ */ jsx("footer", { className: "mt-2 text-sm", children: labels.quoteAttribution })
45
+ ] })
46
+ ] })
47
+ ] }),
48
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center p-8 bg-background relative overflow-y-auto", children: [
49
+ /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-background via-background to-accent/5 pointer-events-none" }),
50
+ /* @__PURE__ */ jsx(
51
+ m.div,
52
+ {
53
+ initial: { opacity: 0, y: FORM_ENTRANCE_Y },
54
+ animate: { opacity: 1, y: 0 },
55
+ transition: { ...motionSpring.gentle, ...motionConfig },
56
+ className: "relative z-10 w-full max-w-sm",
57
+ children: /* @__PURE__ */ jsx(
58
+ LoginBlock,
59
+ {
60
+ className: "w-full",
61
+ type: mode === "signup" ? "signup" : "login",
62
+ action,
63
+ error,
64
+ googleAction
65
+ }
66
+ )
67
+ }
68
+ )
69
+ ] })
70
+ ] });
71
+ }
72
+
73
+ export { AuthLayout };
@@ -5,10 +5,7 @@ import { createPortal } from 'react-dom';
5
5
  import { useReducedMotion, useMotionValue, useMotionTemplate } from 'motion/react';
6
6
  import { jsxs, jsx } from 'react/jsx-runtime';
7
7
 
8
- function getAccentColor() {
9
- if (typeof window === "undefined") return "10 158 111";
10
- return getComputedStyle(document.documentElement).getPropertyValue("--color-accent").trim() || "10 158 111";
11
- }
8
+ var CSS_ACCENT_095 = "rgb(var(--color-accent) / 0.95)";
12
9
  function MouseGlow({
13
10
  className,
14
11
  dotColor = "rgba(255, 255, 255, 0.5)",
@@ -20,7 +17,7 @@ function MouseGlow({
20
17
  const containerRef = React.useRef(null);
21
18
  const overlayRef = React.useRef(null);
22
19
  const [mounted, setMounted] = React.useState(false);
23
- const resolvedOverlayColor = overlayColor ?? `rgba(${getAccentColor().replace(/ /g, ", ")}, 0.95)`;
20
+ const resolvedOverlayColor = overlayColor ?? CSS_ACCENT_095;
24
21
  React.useEffect(() => {
25
22
  setMounted(true);
26
23
  const handleMouseMove = (e) => {
@@ -0,0 +1,56 @@
1
+ import { Heading } from './chunk-WI547C47.js';
2
+ import { Card, CardHeader, CardContent } from './chunk-AH6YSYYT.js';
3
+ import { ZapIcon } from './chunk-FLF5AMNO.js';
4
+ import { SparklesIcon } from './chunk-CGUCH322.js';
5
+ import { SettingsIcon } from './chunk-OITJWGFV.js';
6
+ import { jsx, jsxs } from 'react/jsx-runtime';
7
+
8
+ var defaultFeatures = [
9
+ {
10
+ title: "Customizable",
11
+ description: "Extensive customization options, allowing you to tailor every aspect to meet your specific needs.",
12
+ icon: /* @__PURE__ */ jsx(ZapIcon, { size: 24, "aria-hidden": true })
13
+ },
14
+ {
15
+ title: "You have full control",
16
+ description: "From design elements to functionality, you have complete control to create a unique and personalized experience.",
17
+ icon: /* @__PURE__ */ jsx(SettingsIcon, { size: 24, "aria-hidden": true })
18
+ },
19
+ {
20
+ title: "Powered By AI",
21
+ description: "Elements to functionality, you have complete control to create a unique experience.",
22
+ icon: /* @__PURE__ */ jsx(SparklesIcon, { size: 24, "aria-hidden": true })
23
+ }
24
+ ];
25
+ function FeatureGridBlock({
26
+ title = "Built to cover your needs",
27
+ description = "Libero sapiente aliquam quibusdam aspernatur, praesentium iusto repellendus.",
28
+ features = defaultFeatures,
29
+ className
30
+ } = {}) {
31
+ return /* @__PURE__ */ jsx("section", { className: className ?? "bg-background py-16 md:py-32 dark:bg-transparent", children: /* @__PURE__ */ jsxs("div", { className: "@container mx-auto max-w-5xl px-6", children: [
32
+ /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
33
+ /* @__PURE__ */ jsx(Heading, { level: 2, size: "section", className: "text-4xl lg:text-5xl", children: title }),
34
+ /* @__PURE__ */ jsx("p", { className: "mt-4", children: description })
35
+ ] }),
36
+ /* @__PURE__ */ jsx(Card, { className: "lg:max-w-full lg:grid-cols-3 lg:divide-x lg:divide-y-0 mx-auto mt-8 grid max-w-sm divide-y overflow-hidden shadow-sm *:text-center md:mt-16", children: features.map((feature, i) => /* @__PURE__ */ jsxs("div", { className: "group shadow-sm", children: [
37
+ /* @__PURE__ */ jsxs(CardHeader, { className: "pb-4", children: [
38
+ /* @__PURE__ */ jsx(CardDecorator, { children: feature.icon }),
39
+ /* @__PURE__ */ jsx(Heading, { level: 3, size: "title", className: "mt-6 font-medium", children: feature.title })
40
+ ] }),
41
+ /* @__PURE__ */ jsx(CardContent, { children: /* @__PURE__ */ jsx("p", { className: "mt-4 text-sm", children: feature.description }) })
42
+ ] }, i)) })
43
+ ] }) });
44
+ }
45
+ var CardDecorator = ({ children }) => /* @__PURE__ */ jsxs("div", { className: "mask-radial-from-40% mask-radial-to-60% relative mx-auto size-36 duration-200 [--color-border:color-mix(in_oklab,var(--color-text-primary)10%,transparent)] group-hover:[--color-border:color-mix(in_oklab,var(--color-text-primary)20%,transparent)] dark:[--color-border:color-mix(in_oklab,var(--color-text-primary)15%,transparent)] dark:group-hover:[--color-border:color-mix(in_oklab,var(--color-text-primary)20%,transparent)]", children: [
46
+ /* @__PURE__ */ jsx(
47
+ "div",
48
+ {
49
+ "aria-hidden": true,
50
+ className: "absolute inset-0 bg-[linear-gradient(to_right,var(--color-border)_1px,transparent_1px),linear-gradient(to_bottom,var(--color-border)_1px,transparent_1px)] bg-[size:24px_24px] dark:opacity-50"
51
+ }
52
+ ),
53
+ /* @__PURE__ */ jsx("div", { className: "bg-background absolute inset-0 m-auto flex size-12 items-center justify-center border-l border-t", children })
54
+ ] });
55
+
56
+ export { FeatureGridBlock };
@@ -0,0 +1,85 @@
1
+ import { useSidebar, SidebarMenu, SidebarMenuItem, SidebarMenuButton } from './chunk-J2DCQDXO.js';
2
+ import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuGroup, DropdownMenuItem } from './chunk-CQEUNASC.js';
3
+ import { Avatar, AvatarImage, AvatarFallback } from './chunk-NAAU5IWU.js';
4
+ import { ChevronsUpDownIcon } from './chunk-SW6QPJM4.js';
5
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
6
+
7
+ function getInitials(name) {
8
+ return name.split(" ").map((n) => n[0]).join("").toUpperCase().slice(0, 2);
9
+ }
10
+ var EMPTY_ITEMS = [];
11
+ function NavUser({ user, items = EMPTY_ITEMS, footer }) {
12
+ const { isMobile } = useSidebar();
13
+ const initials = getInitials(user.name);
14
+ return /* @__PURE__ */ jsx(SidebarMenu, { children: /* @__PURE__ */ jsx(SidebarMenuItem, { children: /* @__PURE__ */ jsxs(DropdownMenu, { children: [
15
+ /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
16
+ SidebarMenuButton,
17
+ {
18
+ size: "lg",
19
+ className: "data-[state=open]:bg-surface-hover",
20
+ children: [
21
+ /* @__PURE__ */ jsxs(Avatar, { className: "h-8 w-8 rounded-lg", children: [
22
+ user.avatar && /* @__PURE__ */ jsx(AvatarImage, { src: user.avatar, alt: user.name }),
23
+ /* @__PURE__ */ jsx(AvatarFallback, { className: "rounded-lg text-xs", children: initials })
24
+ ] }),
25
+ /* @__PURE__ */ jsxs("div", { className: "grid flex-1 text-left text-sm leading-tight min-w-0", children: [
26
+ /* @__PURE__ */ jsx("span", { className: "truncate font-medium text-text-primary", children: user.name }),
27
+ /* @__PURE__ */ jsx("span", { className: "truncate text-xs text-text-tertiary", children: user.email })
28
+ ] }),
29
+ /* @__PURE__ */ jsx(
30
+ ChevronsUpDownIcon,
31
+ {
32
+ size: 16,
33
+ className: "ml-auto text-text-tertiary"
34
+ }
35
+ )
36
+ ]
37
+ }
38
+ ) }),
39
+ /* @__PURE__ */ jsxs(
40
+ DropdownMenuContent,
41
+ {
42
+ className: "w-[var(--radix-dropdown-menu-trigger-width)] min-w-56 rounded-lg",
43
+ side: isMobile ? "bottom" : "right",
44
+ align: "end",
45
+ sideOffset: 4,
46
+ children: [
47
+ /* @__PURE__ */ jsx(DropdownMenuLabel, { className: "p-0 font-normal", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 px-1.5 py-1.5", children: [
48
+ /* @__PURE__ */ jsxs(Avatar, { className: "h-8 w-8 rounded-lg", children: [
49
+ user.avatar && /* @__PURE__ */ jsx(AvatarImage, { src: user.avatar, alt: user.name }),
50
+ /* @__PURE__ */ jsx(AvatarFallback, { className: "rounded-lg text-xs", children: initials })
51
+ ] }),
52
+ /* @__PURE__ */ jsxs("div", { className: "grid flex-1 text-left text-sm leading-tight min-w-0", children: [
53
+ /* @__PURE__ */ jsx("span", { className: "truncate font-medium text-text-primary", children: user.name }),
54
+ /* @__PURE__ */ jsx("span", { className: "truncate text-xs text-text-tertiary", children: user.email })
55
+ ] })
56
+ ] }) }),
57
+ items.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
58
+ /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
59
+ /* @__PURE__ */ jsx(DropdownMenuGroup, { children: items.map((item) => /* @__PURE__ */ jsx(
60
+ DropdownMenuItem,
61
+ {
62
+ asChild: !!item.href,
63
+ onClick: item.onClick,
64
+ children: item.href ? /* @__PURE__ */ jsxs("a", { href: item.href, children: [
65
+ item.icon,
66
+ item.label
67
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
68
+ item.icon,
69
+ item.label
70
+ ] })
71
+ },
72
+ item.label
73
+ )) })
74
+ ] }),
75
+ !!footer && /* @__PURE__ */ jsxs(Fragment, { children: [
76
+ /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
77
+ footer
78
+ ] })
79
+ ]
80
+ }
81
+ )
82
+ ] }) }) });
83
+ }
84
+
85
+ export { NavUser };
@@ -0,0 +1,96 @@
1
+ import { MarketingShellPageKit } from './chunk-Z233ZQZE.js';
2
+ import { TeamBlock } from './chunk-VBZQ4DBE.js';
3
+ import { ContactBlock } from './chunk-U4GYSYGN.js';
4
+ import { FAQBlock } from './chunk-NEHCPO53.js';
5
+ import { CallToActionBlock } from './chunk-GJPTPLCQ.js';
6
+ import { Typography } from './chunk-N53OMWW2.js';
7
+ import { Card, CardHeader, CardTitle, CardContent } from './chunk-AH6YSYYT.js';
8
+ import { cn } from './chunk-QYZT24TS.js';
9
+ import React from 'react';
10
+ import { jsx, jsxs } from 'react/jsx-runtime';
11
+
12
+ var DEFAULT_SECTION_ORDER = [
13
+ "narrative",
14
+ "team",
15
+ "contact",
16
+ "faq",
17
+ "cta"
18
+ ];
19
+ var DEFAULTS_BY_VARIANT = {
20
+ "company-about": {
21
+ narrative: {
22
+ title: "Built by practitioners who ship with contracts first.",
23
+ description: "We partner with teams that need high-quality interfaces and predictable release confidence."
24
+ },
25
+ team: {
26
+ title: "Leadership team"
27
+ },
28
+ contact: null,
29
+ faq: {},
30
+ cta: {
31
+ title: "Interested in working together?",
32
+ description: "Share your route goals and we will propose a rollout plan.",
33
+ primaryAction: { label: "Talk to us", href: "/contact" }
34
+ }
35
+ },
36
+ "company-contact": {
37
+ narrative: {
38
+ title: "Talk to our delivery team",
39
+ description: "Tell us what you are building, we will recommend an implementation path."
40
+ },
41
+ team: null,
42
+ contact: {
43
+ title: "Contact request",
44
+ description: "We respond within one business day.",
45
+ submitLabel: "Send request"
46
+ },
47
+ faq: {},
48
+ cta: {
49
+ title: "Prefer self-serve?",
50
+ description: "Start with our templates and scale with support as needed.",
51
+ primaryAction: { label: "View templates", href: "/templates" }
52
+ }
53
+ }
54
+ };
55
+ var SECTION_CLASS = "mx-auto w-full max-w-6xl px-6";
56
+ function normalizeSectionOrder(sectionOrder) {
57
+ if (!sectionOrder || sectionOrder.length === 0) {
58
+ return DEFAULT_SECTION_ORDER;
59
+ }
60
+ return [...new Set(sectionOrder)];
61
+ }
62
+ function CompanySuitePageKit({
63
+ shell,
64
+ variant = "company-about",
65
+ sectionOrder,
66
+ narrative,
67
+ team,
68
+ contact,
69
+ faq,
70
+ cta,
71
+ className
72
+ }) {
73
+ const defaults = DEFAULTS_BY_VARIANT[variant];
74
+ const resolvedNarrative = narrative ?? defaults.narrative ?? { title: "Company overview" };
75
+ const resolvedTeam = team === void 0 ? defaults.team : team;
76
+ const resolvedContact = contact === void 0 ? defaults.contact : contact;
77
+ const resolvedFaq = faq === void 0 ? defaults.faq : faq;
78
+ const resolvedCta = cta === void 0 ? defaults.cta : cta;
79
+ const orderedSections = normalizeSectionOrder(sectionOrder);
80
+ const sectionById = {
81
+ narrative: resolvedNarrative === null ? null : /* @__PURE__ */ jsx("section", { "data-testid": "company-section-narrative", className: SECTION_CLASS, children: /* @__PURE__ */ jsxs(Card, { children: [
82
+ /* @__PURE__ */ jsx(CardHeader, { children: /* @__PURE__ */ jsx(CardTitle, { children: resolvedNarrative.title }) }),
83
+ /* @__PURE__ */ jsxs(CardContent, { className: "space-y-3", children: [
84
+ resolvedNarrative.description ? /* @__PURE__ */ jsx(Typography, { variant: "muted", children: resolvedNarrative.description }) : null,
85
+ resolvedNarrative.content ? /* @__PURE__ */ jsx("div", { children: resolvedNarrative.content }) : null
86
+ ] })
87
+ ] }) }),
88
+ team: resolvedTeam === null ? null : /* @__PURE__ */ jsx("section", { "data-testid": "company-section-team", className: SECTION_CLASS, children: /* @__PURE__ */ jsx(TeamBlock, { ...resolvedTeam }) }),
89
+ contact: resolvedContact === null ? null : /* @__PURE__ */ jsx("section", { "data-testid": "company-section-contact", className: SECTION_CLASS, children: /* @__PURE__ */ jsx(ContactBlock, { ...resolvedContact }) }),
90
+ faq: resolvedFaq === null ? null : /* @__PURE__ */ jsx("section", { "data-testid": "company-section-faq", className: SECTION_CLASS, children: /* @__PURE__ */ jsx(FAQBlock, { ...resolvedFaq }) }),
91
+ cta: resolvedCta === null ? null : /* @__PURE__ */ jsx("section", { "data-testid": "company-section-cta", className: cn(SECTION_CLASS, "pb-16"), children: /* @__PURE__ */ jsx(CallToActionBlock, { ...resolvedCta }) })
92
+ };
93
+ return /* @__PURE__ */ jsx(MarketingShellPageKit, { ...shell, children: /* @__PURE__ */ jsx("div", { className: cn("space-y-10 pb-10", className), children: orderedSections.map((sectionId) => /* @__PURE__ */ jsx(React.Fragment, { children: sectionById[sectionId] }, sectionId)) }) });
94
+ }
95
+
96
+ export { CompanySuitePageKit };
@@ -0,0 +1,138 @@
1
+ import { MarketingShellPageKit } from './chunk-Z233ZQZE.js';
2
+ import { PricingBlock } from './chunk-VNNAL4A6.js';
3
+ import { FAQBlock } from './chunk-NEHCPO53.js';
4
+ import { CallToActionBlock } from './chunk-GJPTPLCQ.js';
5
+ import { ComparisonBlock } from './chunk-VZCB4APK.js';
6
+ import { Typography } from './chunk-N53OMWW2.js';
7
+ import { Heading } from './chunk-WI547C47.js';
8
+ import { Card, CardHeader, CardTitle, CardContent } from './chunk-AH6YSYYT.js';
9
+ import { Button } from './chunk-7KIDDF3I.js';
10
+ import { Badge } from './chunk-S4JAHKOP.js';
11
+ import { cn } from './chunk-QYZT24TS.js';
12
+ import React from 'react';
13
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
14
+
15
+ var STATE_BADGE_LABELS = {
16
+ "billing-toggle": "Billing toggle",
17
+ "loading-action": "Loading actions",
18
+ "empty-plan": "Empty plan state"
19
+ };
20
+ var EMPTY_PLAN_ACTIONS = [];
21
+ var EMPTY_PLANS = [];
22
+ var DEFAULT_COMPARISON = {};
23
+ var DEFAULT_FAQ = {};
24
+ var DEFAULT_CTA = {
25
+ title: "Need a custom rollout?",
26
+ description: "Talk to our team for multi-team migration and governance support.",
27
+ primaryAction: { label: "Contact sales", href: "/contact" }
28
+ };
29
+ var DEFAULT_EMPTY_STATE = {
30
+ title: "No plans available",
31
+ description: "Configure at least one plan to render pricing actions."
32
+ };
33
+ function PricingPageKit({
34
+ shell,
35
+ state = "default",
36
+ title = "Choose the plan that fits your team.",
37
+ description = "Use stable pricing blocks while keeping plan copy, links, and billing behavior app-owned.",
38
+ plans = EMPTY_PLANS,
39
+ billing,
40
+ comparison = DEFAULT_COMPARISON,
41
+ faq = DEFAULT_FAQ,
42
+ cta = DEFAULT_CTA,
43
+ planActions = EMPTY_PLAN_ACTIONS,
44
+ emptyState = DEFAULT_EMPTY_STATE,
45
+ loadingMessage = "Preparing checkout actions...",
46
+ className
47
+ }) {
48
+ const [selectedBilling, setSelectedBilling] = React.useState("monthly");
49
+ const supportsYearly = billing?.supportsYearly ?? true;
50
+ const monthlyLabel = billing?.monthlyLabel ?? "Monthly";
51
+ const yearlyLabel = billing?.yearlyLabel ?? "Yearly";
52
+ const yearlyBadgeLabel = billing?.yearlyBadgeLabel ?? "Save";
53
+ const isLoadingActions = state === "loading-action";
54
+ const shouldRenderEmpty = state === "empty-plan" || plans.length === 0;
55
+ return /* @__PURE__ */ jsx(MarketingShellPageKit, { ...shell, children: /* @__PURE__ */ jsxs("section", { className: cn("mx-auto w-full max-w-6xl space-y-8 px-6 pb-16", className), children: [
56
+ /* @__PURE__ */ jsxs("header", { className: "space-y-4", children: [
57
+ /* @__PURE__ */ jsx(Heading, { level: 2, children: title }),
58
+ /* @__PURE__ */ jsx(Typography, { variant: "muted", children: description }),
59
+ state !== "default" ? /* @__PURE__ */ jsx("div", { className: "flex flex-wrap items-center gap-2", children: /* @__PURE__ */ jsx(Badge, { variant: "outline", children: STATE_BADGE_LABELS[state] }) }) : null
60
+ ] }),
61
+ state === "billing-toggle" ? /* @__PURE__ */ jsxs(Card, { "data-testid": "pricing-billing-controls", children: [
62
+ /* @__PURE__ */ jsx(CardHeader, { children: /* @__PURE__ */ jsx(CardTitle, { children: "Billing interval" }) }),
63
+ /* @__PURE__ */ jsxs(CardContent, { className: "space-y-3", children: [
64
+ /* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-2 rounded-md border border-border/70 bg-surface/60 p-1", children: [
65
+ /* @__PURE__ */ jsx(
66
+ Button,
67
+ {
68
+ type: "button",
69
+ size: "sm",
70
+ variant: selectedBilling === "monthly" ? "primary" : "ghost",
71
+ onClick: () => setSelectedBilling("monthly"),
72
+ children: monthlyLabel
73
+ }
74
+ ),
75
+ supportsYearly ? /* @__PURE__ */ jsxs(Fragment, { children: [
76
+ /* @__PURE__ */ jsx(
77
+ Button,
78
+ {
79
+ type: "button",
80
+ size: "sm",
81
+ variant: selectedBilling === "yearly" ? "primary" : "ghost",
82
+ onClick: () => setSelectedBilling("yearly"),
83
+ children: yearlyLabel
84
+ }
85
+ ),
86
+ /* @__PURE__ */ jsx(Badge, { variant: "accent", children: yearlyBadgeLabel })
87
+ ] }) : null
88
+ ] }),
89
+ billing?.note ? /* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-text-secondary", children: billing.note }) : null
90
+ ] })
91
+ ] }) : null,
92
+ isLoadingActions ? /* @__PURE__ */ jsx(
93
+ "div",
94
+ {
95
+ "data-testid": "pricing-loading-action",
96
+ role: "status",
97
+ className: "rounded-md border border-border/70 bg-surface/70 px-4 py-3 text-sm text-text-secondary",
98
+ children: loadingMessage
99
+ }
100
+ ) : null,
101
+ shouldRenderEmpty ? /* @__PURE__ */ jsxs(Card, { "data-testid": "pricing-empty-state", children: [
102
+ /* @__PURE__ */ jsx(CardHeader, { children: /* @__PURE__ */ jsx(CardTitle, { children: emptyState.title }) }),
103
+ /* @__PURE__ */ jsx(CardContent, { children: /* @__PURE__ */ jsx(Typography, { variant: "muted", children: emptyState.description }) })
104
+ ] }) : /* @__PURE__ */ jsx(
105
+ PricingBlock,
106
+ {
107
+ title: "Pricing plans",
108
+ description: "All plans are rendered from declared data inputs.",
109
+ plans,
110
+ showBillingToggle: state === "billing-toggle" && supportsYearly
111
+ }
112
+ ),
113
+ planActions.length > 0 ? /* @__PURE__ */ jsxs(Card, { "data-testid": "pricing-plan-actions", children: [
114
+ /* @__PURE__ */ jsx(CardHeader, { children: /* @__PURE__ */ jsx(CardTitle, { children: "Checkout actions" }) }),
115
+ /* @__PURE__ */ jsx(CardContent, { className: "grid gap-3 sm:grid-cols-2", children: planActions.map((action) => {
116
+ const isDisabled = isLoadingActions || action.disabled;
117
+ return /* @__PURE__ */ jsxs("div", { className: "rounded-md border border-border/70 p-3", children: [
118
+ /* @__PURE__ */ jsx(
119
+ Button,
120
+ {
121
+ type: "button",
122
+ disabled: isDisabled,
123
+ onClick: action.onAction,
124
+ className: "w-full",
125
+ children: action.label
126
+ }
127
+ ),
128
+ /* @__PURE__ */ jsx(Typography, { variant: "small", className: "mt-2 break-all text-text-tertiary", children: action.href })
129
+ ] }, action.id);
130
+ }) })
131
+ ] }) : null,
132
+ comparison === null ? null : /* @__PURE__ */ jsx("section", { children: /* @__PURE__ */ jsx(ComparisonBlock, { ...comparison }) }),
133
+ faq === null ? null : /* @__PURE__ */ jsx("section", { children: /* @__PURE__ */ jsx(FAQBlock, { ...faq }) }),
134
+ cta === null ? null : /* @__PURE__ */ jsx("section", { children: /* @__PURE__ */ jsx(CallToActionBlock, { ...cta }) })
135
+ ] }) });
136
+ }
137
+
138
+ export { PricingPageKit };