nextworks 0.2.0-alpha.2 → 0.2.0-alpha.20

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 (145) hide show
  1. package/README.md +280 -228
  2. package/dist/cli_manifests/blocks_manifest.json +193 -194
  3. package/dist/commands/blocks.d.ts +3 -0
  4. package/dist/commands/blocks.d.ts.map +1 -1
  5. package/dist/commands/blocks.js +128 -19
  6. package/dist/commands/blocks.js.map +1 -1
  7. package/dist/commands/doctor.d.ts +136 -0
  8. package/dist/commands/doctor.d.ts.map +1 -0
  9. package/dist/commands/doctor.js +696 -0
  10. package/dist/commands/doctor.js.map +1 -0
  11. package/dist/commands/remove-blocks.d.ts +4 -1
  12. package/dist/commands/remove-blocks.d.ts.map +1 -1
  13. package/dist/commands/remove-blocks.js +24 -6
  14. package/dist/commands/remove-blocks.js.map +1 -1
  15. package/dist/index.js +125 -4
  16. package/dist/index.js.map +1 -1
  17. package/dist/kits/blocks/.nextworks/docs/BLOCKS_QUICKSTART.md +104 -194
  18. package/dist/kits/blocks/.nextworks/docs/BLOCKS_README.md +115 -75
  19. package/dist/kits/blocks/.nextworks/docs/THEME_GUIDE.md +269 -251
  20. package/dist/kits/blocks/app/templates/digitalagency/PresetThemeVars.tsx +80 -80
  21. package/dist/kits/blocks/app/templates/digitalagency/README.md +42 -36
  22. package/dist/kits/blocks/app/templates/digitalagency/components/About.tsx +71 -99
  23. package/dist/kits/blocks/app/templates/digitalagency/components/CTA.tsx +40 -74
  24. package/dist/kits/blocks/app/templates/digitalagency/components/Contact.tsx +123 -227
  25. package/dist/kits/blocks/app/templates/digitalagency/components/Footer.tsx +89 -89
  26. package/dist/kits/blocks/app/templates/digitalagency/components/Hero.tsx +83 -90
  27. package/dist/kits/blocks/app/templates/digitalagency/components/Navbar.tsx +121 -168
  28. package/dist/kits/blocks/app/templates/digitalagency/components/NetworkPattern.tsx +288 -297
  29. package/dist/kits/blocks/app/templates/digitalagency/components/Portfolio.tsx +157 -157
  30. package/dist/kits/blocks/app/templates/digitalagency/components/Pricing.tsx +114 -114
  31. package/dist/kits/blocks/app/templates/digitalagency/components/Process.tsx +59 -59
  32. package/dist/kits/blocks/app/templates/digitalagency/components/Services.tsx +55 -55
  33. package/dist/kits/blocks/app/templates/digitalagency/components/Team.tsx +28 -28
  34. package/dist/kits/blocks/app/templates/digitalagency/components/Testimonials.tsx +65 -65
  35. package/dist/kits/blocks/app/templates/digitalagency/page.tsx +38 -38
  36. package/dist/kits/blocks/app/templates/gallery/PresetThemeVars.tsx +130 -85
  37. package/dist/kits/blocks/app/templates/gallery/page.tsx +357 -303
  38. package/dist/kits/blocks/app/templates/productlaunch/PresetThemeVars.tsx +75 -74
  39. package/dist/kits/blocks/app/templates/productlaunch/README.md +62 -55
  40. package/dist/kits/blocks/app/templates/productlaunch/components/About.tsx +84 -178
  41. package/dist/kits/blocks/app/templates/productlaunch/components/CTA.tsx +50 -93
  42. package/dist/kits/blocks/app/templates/productlaunch/components/Contact.tsx +231 -231
  43. package/dist/kits/blocks/app/templates/productlaunch/components/FAQ.tsx +86 -93
  44. package/dist/kits/blocks/app/templates/productlaunch/components/Features.tsx +83 -84
  45. package/dist/kits/blocks/app/templates/productlaunch/components/Footer.tsx +132 -132
  46. package/dist/kits/blocks/app/templates/productlaunch/components/Hero.tsx +88 -89
  47. package/dist/kits/blocks/app/templates/productlaunch/components/Navbar.tsx +116 -162
  48. package/dist/kits/blocks/app/templates/productlaunch/components/Pricing.tsx +106 -106
  49. package/dist/kits/blocks/app/templates/productlaunch/components/ProcessTimeline.tsx +110 -110
  50. package/dist/kits/blocks/app/templates/productlaunch/components/ServicesGrid.tsx +68 -68
  51. package/dist/kits/blocks/app/templates/productlaunch/components/Team.tsx +104 -104
  52. package/dist/kits/blocks/app/templates/productlaunch/components/Testimonials.tsx +90 -89
  53. package/dist/kits/blocks/app/templates/productlaunch/components/TrustBadges.tsx +76 -76
  54. package/dist/kits/blocks/app/templates/productlaunch/page.tsx +43 -43
  55. package/dist/kits/blocks/app/templates/saasdashboard/PresetThemeVars.tsx +80 -80
  56. package/dist/kits/blocks/app/templates/saasdashboard/README.md +44 -38
  57. package/dist/kits/blocks/app/templates/saasdashboard/components/Contact.tsx +129 -176
  58. package/dist/kits/blocks/app/templates/saasdashboard/components/Dashboard.tsx +293 -293
  59. package/dist/kits/blocks/app/templates/saasdashboard/components/FAQ.tsx +55 -55
  60. package/dist/kits/blocks/app/templates/saasdashboard/components/Features.tsx +90 -91
  61. package/dist/kits/blocks/app/templates/saasdashboard/components/Footer.tsx +77 -77
  62. package/dist/kits/blocks/app/templates/saasdashboard/components/Hero.tsx +104 -105
  63. package/dist/kits/blocks/app/templates/saasdashboard/components/Hero_mask.tsx +126 -127
  64. package/dist/kits/blocks/app/templates/saasdashboard/components/Navbar.tsx +117 -159
  65. package/dist/kits/blocks/app/templates/saasdashboard/components/Pricing.tsx +90 -90
  66. package/dist/kits/blocks/app/templates/saasdashboard/components/SmoothScroll.tsx +96 -97
  67. package/dist/kits/blocks/app/templates/saasdashboard/components/Testimonials.tsx +72 -72
  68. package/dist/kits/blocks/app/templates/saasdashboard/components/TrustBadges.tsx +53 -53
  69. package/dist/kits/blocks/app/templates/saasdashboard/page.tsx +39 -39
  70. package/dist/kits/blocks/components/enhanced-theme-provider.tsx +195 -183
  71. package/dist/kits/blocks/components/providers/BlocksAppProviders.tsx +27 -27
  72. package/dist/kits/blocks/components/sections/About.tsx +291 -291
  73. package/dist/kits/blocks/components/sections/CTA.tsx +257 -258
  74. package/dist/kits/blocks/components/sections/CommandShowcase.tsx +517 -0
  75. package/dist/kits/blocks/components/sections/Contact.tsx +267 -267
  76. package/dist/kits/blocks/components/sections/FAQ.tsx +214 -225
  77. package/dist/kits/blocks/components/sections/FeaturedProjectShowcase.tsx +687 -0
  78. package/dist/kits/blocks/components/sections/Features.tsx +268 -270
  79. package/dist/kits/blocks/components/sections/Footer.tsx +302 -302
  80. package/dist/kits/blocks/components/sections/HeroMotion.tsx +308 -308
  81. package/dist/kits/blocks/components/sections/HeroOverlay.tsx +358 -358
  82. package/dist/kits/blocks/components/sections/HeroProductDemo.tsx +246 -0
  83. package/dist/kits/blocks/components/sections/HeroSplit.tsx +352 -352
  84. package/dist/kits/blocks/components/sections/HeroWithVideo.tsx +495 -0
  85. package/dist/kits/blocks/components/sections/Navbar.tsx +352 -353
  86. package/dist/kits/blocks/components/sections/PortfolioSimple.tsx +549 -550
  87. package/dist/kits/blocks/components/sections/Pricing.tsx +264 -264
  88. package/dist/kits/blocks/components/sections/ProcessTimeline.tsx +325 -325
  89. package/dist/kits/blocks/components/sections/ProjectDeepDive.tsx +805 -0
  90. package/dist/kits/blocks/components/sections/SelectedWorkRail.tsx +485 -0
  91. package/dist/kits/blocks/components/sections/ServicesGrid.tsx +210 -210
  92. package/dist/kits/blocks/components/sections/Team.tsx +309 -309
  93. package/dist/kits/blocks/components/sections/Testimonials.tsx +158 -158
  94. package/dist/kits/blocks/components/sections/TrustBadges.tsx +162 -162
  95. package/dist/kits/blocks/components/sections/product-demo/ApprovalInboxPanel.tsx +128 -0
  96. package/dist/kits/blocks/components/sections/product-demo/DemoStage.tsx +519 -0
  97. package/dist/kits/blocks/components/sections/product-demo/DemoWindow.tsx +140 -0
  98. package/dist/kits/blocks/components/sections/product-demo/KnowledgePanel.tsx +130 -0
  99. package/dist/kits/blocks/components/sections/product-demo/RunConsolePanel.tsx +430 -0
  100. package/dist/kits/blocks/components/sections/product-demo/TaskListPanel.tsx +302 -0
  101. package/dist/kits/blocks/components/sections/product-demo/WorkflowStudioPanel.tsx +744 -0
  102. package/dist/kits/blocks/components/sections/product-demo/types.ts +262 -0
  103. package/dist/kits/blocks/components/theme-provider.tsx +1 -34
  104. package/dist/kits/blocks/components/ui/alert-dialog.tsx +134 -134
  105. package/dist/kits/blocks/components/ui/brand-node.tsx +121 -121
  106. package/dist/kits/blocks/components/ui/button.tsx +122 -122
  107. package/dist/kits/blocks/components/ui/card.tsx +95 -95
  108. package/dist/kits/blocks/components/ui/checkbox.tsx +30 -30
  109. package/dist/kits/blocks/components/ui/cta-button.tsx +125 -125
  110. package/dist/kits/blocks/components/ui/dropdown-menu.tsx +201 -201
  111. package/dist/kits/blocks/components/ui/feature-card.tsx +91 -91
  112. package/dist/kits/blocks/components/ui/input.tsx +27 -27
  113. package/dist/kits/blocks/components/ui/label.tsx +29 -29
  114. package/dist/kits/blocks/components/ui/pricing-card.tsx +120 -120
  115. package/dist/kits/blocks/components/ui/select.tsx +25 -25
  116. package/dist/kits/blocks/components/ui/skeleton.tsx +13 -13
  117. package/dist/kits/blocks/components/ui/table.tsx +98 -98
  118. package/dist/kits/blocks/components/ui/testimonial-card.tsx +108 -108
  119. package/dist/kits/blocks/components/ui/textarea.tsx +26 -26
  120. package/dist/kits/blocks/components/ui/theme-selector.tsx +243 -247
  121. package/dist/kits/blocks/components/ui/theme-toggle.tsx +74 -74
  122. package/dist/kits/blocks/components/ui/toaster.tsx +7 -7
  123. package/dist/kits/blocks/lib/themes.ts +400 -400
  124. package/dist/kits/blocks/lib/utils.ts +6 -9
  125. package/dist/kits/blocks/package-deps.json +40 -28
  126. package/dist/kits/blocks/tsconfig.json +11 -0
  127. package/dist/kits/blocks/tsconfig.tsbuildinfo +1 -0
  128. package/dist/utils/file-operations.d.ts +3 -1
  129. package/dist/utils/file-operations.d.ts.map +1 -1
  130. package/dist/utils/file-operations.js +84 -12
  131. package/dist/utils/file-operations.js.map +1 -1
  132. package/dist/utils/installation-tracker.d.ts +2 -2
  133. package/dist/utils/installation-tracker.d.ts.map +1 -1
  134. package/dist/utils/installation-tracker.js +11 -11
  135. package/dist/utils/installation-tracker.js.map +1 -1
  136. package/dist/utils/package-manager.d.ts +6 -0
  137. package/dist/utils/package-manager.d.ts.map +1 -0
  138. package/dist/utils/package-manager.js +58 -0
  139. package/dist/utils/package-manager.js.map +1 -0
  140. package/dist/utils/yarn-pnp.d.ts +6 -0
  141. package/dist/utils/yarn-pnp.d.ts.map +1 -0
  142. package/dist/utils/yarn-pnp.js +39 -0
  143. package/dist/utils/yarn-pnp.js.map +1 -0
  144. package/package.json +5 -2
  145. package/dist/kits/blocks/notes/THEME_GUIDE.md +0 -29
@@ -0,0 +1,495 @@
1
+ import React from "react";
2
+ import Link from "next/link";
3
+ import { Button } from "@/components/ui/button";
4
+ import { cn } from "@/lib/utils";
5
+
6
+ type ButtonVariant =
7
+ | "default"
8
+ | "destructive"
9
+ | "outline"
10
+ | "secondary"
11
+ | "ghost"
12
+ | "link";
13
+
14
+ type ButtonSize = "default" | "sm" | "lg" | "icon";
15
+
16
+ export interface HeroWithVideoCta {
17
+ label?: string;
18
+ href?: string;
19
+ ariaLabel?: string;
20
+ variant?: ButtonVariant;
21
+ size?: ButtonSize;
22
+ className?: string;
23
+ unstyled?: boolean;
24
+ style?: React.CSSProperties;
25
+ target?: string;
26
+ rel?: string;
27
+ }
28
+
29
+ export interface HeroWithVideoTextContent {
30
+ text?: React.ReactNode;
31
+ className?: string;
32
+ }
33
+
34
+ export interface HeroWithVideoTitleContent extends HeroWithVideoTextContent {
35
+ highlight?: string;
36
+ highlightClassName?: string;
37
+ }
38
+
39
+ export interface HeroWithVideoMedia {
40
+ src?: string;
41
+ poster?: string;
42
+ title?: string;
43
+ ariaLabel?: string;
44
+ className?: string;
45
+ autoPlay?: boolean;
46
+ muted?: boolean;
47
+ loop?: boolean;
48
+ playsInline?: boolean;
49
+ controls?: boolean;
50
+ preload?: "none" | "metadata" | "auto";
51
+ }
52
+
53
+ export interface HeroWithVideoClassNames {
54
+ section?: string;
55
+ backgroundGlow?: string;
56
+ container?: string;
57
+ content?: string;
58
+ eyebrow?: string;
59
+ title?: string;
60
+ titleHighlight?: string;
61
+ description?: string;
62
+ credibility?: string;
63
+ buttons?: string;
64
+ primaryCta?: string;
65
+ secondaryCta?: string;
66
+ command?: string;
67
+ videoOuter?: string;
68
+ videoFrame?: string;
69
+ videoChrome?: string;
70
+ video?: string;
71
+ videoFallback?: string;
72
+ }
73
+
74
+ export interface HeroWithVideoProps {
75
+ id?: string;
76
+ className?: string;
77
+ eyebrow?: string | HeroWithVideoTextContent;
78
+ title?: string | HeroWithVideoTitleContent;
79
+ heading?: string | HeroWithVideoTitleContent;
80
+ description?: string | HeroWithVideoTextContent;
81
+ subheading?: string | HeroWithVideoTextContent;
82
+ credibility?: string | HeroWithVideoTextContent;
83
+ command?: string | HeroWithVideoTextContent;
84
+ primaryCta?: HeroWithVideoCta;
85
+ secondaryCta?: HeroWithVideoCta;
86
+ cta1?: HeroWithVideoCta;
87
+ cta2?: HeroWithVideoCta;
88
+ video?: HeroWithVideoMedia;
89
+ embed?: React.ReactNode;
90
+ fallback?: React.ReactNode;
91
+ previewId?: string;
92
+ ariaLabel?: string;
93
+ titleId?: string;
94
+ enableMotion?: boolean;
95
+ classNames?: HeroWithVideoClassNames;
96
+ section?: { className?: string };
97
+ container?: { className?: string };
98
+ content?: { className?: string };
99
+ eyebrowSlot?: { className?: string };
100
+ titleSlot?: { className?: string };
101
+ descriptionSlot?: { className?: string };
102
+ credibilitySlot?: { className?: string };
103
+ buttonsContainer?: { className?: string };
104
+ commandSlot?: { className?: string };
105
+ videoOuter?: { className?: string };
106
+ videoFrame?: { className?: string };
107
+ videoChrome?: { className?: string };
108
+ videoSlot?: { className?: string };
109
+ }
110
+
111
+ function normalizeTextContent<T extends HeroWithVideoTextContent>(
112
+ value: string | T | undefined,
113
+ defaults: Required<HeroWithVideoTextContent>,
114
+ ): Required<HeroWithVideoTextContent> {
115
+ if (typeof value === "string") {
116
+ return { text: value, className: defaults.className };
117
+ }
118
+
119
+ return {
120
+ text: value?.text ?? defaults.text,
121
+ className: cn(defaults.className, value?.className),
122
+ };
123
+ }
124
+
125
+ function normalizeTitleContent(
126
+ value: string | HeroWithVideoTitleContent | undefined,
127
+ defaults: Required<HeroWithVideoTitleContent>,
128
+ ): Required<HeroWithVideoTitleContent> {
129
+ if (typeof value === "string") {
130
+ return {
131
+ text: value,
132
+ className: defaults.className,
133
+ highlight: defaults.highlight,
134
+ highlightClassName: defaults.highlightClassName,
135
+ };
136
+ }
137
+
138
+ return {
139
+ text: value?.text ?? defaults.text,
140
+ className: cn(defaults.className, value?.className),
141
+ highlight: value?.highlight ?? defaults.highlight,
142
+ highlightClassName: cn(
143
+ defaults.highlightClassName,
144
+ value?.highlightClassName,
145
+ ),
146
+ };
147
+ }
148
+
149
+ function renderHighlightedTitle(
150
+ title: Required<HeroWithVideoTitleContent>,
151
+ className?: string,
152
+ ) {
153
+ if (!title.highlight || typeof title.text !== "string") {
154
+ return title.text;
155
+ }
156
+
157
+ const [before, ...rest] = title.text.split(title.highlight);
158
+
159
+ if (rest.length === 0) {
160
+ return title.text;
161
+ }
162
+
163
+ return (
164
+ <>
165
+ {before}
166
+ <span className={cn(title.highlightClassName, className)}>
167
+ {title.highlight}
168
+ </span>
169
+ {rest.join(title.highlight)}
170
+ </>
171
+ );
172
+ }
173
+
174
+ function renderCta(cta: HeroWithVideoCta | undefined) {
175
+ if (!cta?.label) {
176
+ return null;
177
+ }
178
+
179
+ return (
180
+ <Button
181
+ asChild
182
+ variant={cta.variant}
183
+ size={cta.size}
184
+ className={cta.className}
185
+ unstyled={cta.unstyled}
186
+ style={cta.style}
187
+ >
188
+ <Link
189
+ href={cta.href || "#"}
190
+ aria-label={cta.ariaLabel ?? cta.label}
191
+ target={cta.target}
192
+ rel={cta.rel ?? (cta.target === "_blank" ? "noreferrer" : undefined)}
193
+ >
194
+ {cta.label}
195
+ </Link>
196
+ </Button>
197
+ );
198
+ }
199
+
200
+ export function HeroWithVideo({
201
+ id,
202
+ className,
203
+ eyebrow,
204
+ title,
205
+ heading,
206
+ description,
207
+ subheading,
208
+ credibility,
209
+ command,
210
+ primaryCta,
211
+ secondaryCta,
212
+ cta1,
213
+ cta2,
214
+ video,
215
+ embed,
216
+ fallback,
217
+ previewId,
218
+ ariaLabel = "Video hero section",
219
+ titleId,
220
+ enableMotion = true,
221
+ classNames,
222
+ section,
223
+ container,
224
+ content,
225
+ eyebrowSlot,
226
+ titleSlot,
227
+ descriptionSlot,
228
+ credibilitySlot,
229
+ buttonsContainer,
230
+ commandSlot,
231
+ videoOuter,
232
+ videoFrame,
233
+ videoChrome,
234
+ videoSlot,
235
+ }: HeroWithVideoProps) {
236
+ const normalizedEyebrow = normalizeTextContent(eyebrow, {
237
+ text: "Product demo · Launch page · Video preview",
238
+ className:
239
+ "hidden text-xs font-medium uppercase tracking-[0.28em] text-muted-foreground sm:block sm:text-sm",
240
+ });
241
+
242
+ const normalizedTitle = normalizeTitleContent(heading ?? title, {
243
+ text: "Show your product with a clear video-first hero.",
244
+ className:
245
+ "mx-auto max-w-5xl text-balance text-4xl font-semibold tracking-[-0.055em] text-foreground sm:text-6xl lg:text-7xl",
246
+ highlight: "video-first",
247
+ highlightClassName: "text-foreground",
248
+ });
249
+
250
+ const normalizedDescription = normalizeTextContent(subheading ?? description, {
251
+ text: "Introduce a product, service, or project with a focused headline, simple calls to action, and a large demo preview.",
252
+ className:
253
+ "mx-auto mt-5 max-w-2xl text-pretty text-base leading-7 text-muted-foreground sm:text-lg lg:text-xl",
254
+ });
255
+
256
+ const normalizedCredibility = normalizeTextContent(credibility, {
257
+ text: "Designed for landing pages, launches, and product walkthroughs.",
258
+ className: "mt-4 text-sm text-muted-foreground",
259
+ });
260
+
261
+ const normalizedCommand = normalizeTextContent(command, {
262
+ text: "Add a short setup command or product note here.",
263
+ className:
264
+ "mt-6 inline-flex max-w-full items-center rounded-full border border-border bg-muted/60 px-4 py-2 font-mono text-xs text-muted-foreground shadow-[inset_0_1px_0_rgba(255,255,255,0.08)] sm:text-sm dark:shadow-[inset_0_1px_0_rgba(255,255,255,0.08)]",
265
+ });
266
+
267
+ const buttonMotion = enableMotion
268
+ ? "transition-all duration-200 hover:-translate-y-0.5"
269
+ : "transition-none hover:!translate-y-0";
270
+
271
+ const resolvedPreviewId =
272
+ previewId ?? (id ? `${id}-preview` : "video-preview");
273
+
274
+ const resolvedPrimaryCta: HeroWithVideoCta = {
275
+ label: "View demo",
276
+ href: `#${resolvedPreviewId}`,
277
+ variant: "default",
278
+ size: "lg",
279
+ unstyled: true,
280
+ ...(primaryCta ?? cta1 ?? {}),
281
+ className: cn(
282
+ "h-11 rounded-full bg-primary px-6 text-sm font-medium text-primary-foreground shadow-lg hover:bg-primary/90",
283
+ buttonMotion,
284
+ classNames?.primaryCta,
285
+ primaryCta?.className ?? cta1?.className,
286
+ ),
287
+ };
288
+
289
+ const secondaryInput = secondaryCta ?? cta2;
290
+ const resolvedSecondaryCta: HeroWithVideoCta = {
291
+ label: "Learn more",
292
+ href: "#",
293
+ variant: "outline",
294
+ size: "lg",
295
+ unstyled: true,
296
+ ...(secondaryInput ?? {}),
297
+ className: cn(
298
+ "h-11 rounded-full border border-border bg-background/80 px-6 text-sm font-medium text-foreground hover:bg-muted",
299
+ buttonMotion,
300
+ classNames?.secondaryCta,
301
+ secondaryInput?.className,
302
+ ),
303
+ };
304
+
305
+ const videoMotion = enableMotion
306
+ ? "transition-transform duration-300 hover:-translate-y-1"
307
+ : "transition-none hover:!translate-y-0";
308
+
309
+ return (
310
+ <section
311
+ id={id}
312
+ className={cn(
313
+ "relative overflow-hidden bg-background px-4 py-20 text-foreground sm:px-6 lg:px-8 lg:py-24",
314
+ section?.className,
315
+ classNames?.section,
316
+ className,
317
+ )}
318
+ aria-label={ariaLabel}
319
+ aria-labelledby={titleId}
320
+ >
321
+ <div
322
+ className={cn(
323
+ "pointer-events-none absolute left-1/2 top-[34rem] h-[30rem] w-[72rem] -translate-x-1/2 rounded-full bg-[radial-gradient(circle_at_center,rgba(0,0,0,0.08)_0%,rgba(0,0,0,0.03)_24%,transparent_68%)] blur-3xl dark:bg-[radial-gradient(circle_at_center,rgba(255,255,255,0.16)_0%,rgba(255,255,255,0.08)_24%,transparent_68%)]",
324
+ classNames?.backgroundGlow,
325
+ )}
326
+ aria-hidden="true"
327
+ />
328
+ <div
329
+ className="pointer-events-none absolute inset-x-0 top-0 h-40 bg-gradient-to-b from-foreground/5 to-transparent"
330
+ aria-hidden="true"
331
+ />
332
+
333
+ <div
334
+ className={cn(
335
+ "relative z-10 mx-auto flex max-w-7xl flex-col items-center",
336
+ container?.className,
337
+ classNames?.container,
338
+ )}
339
+ >
340
+ <div
341
+ className={cn(
342
+ "mx-auto flex max-w-5xl flex-col items-center text-center",
343
+ content?.className,
344
+ classNames?.content,
345
+ )}
346
+ >
347
+ {normalizedEyebrow.text ? (
348
+ <p
349
+ className={cn(
350
+ normalizedEyebrow.className,
351
+ eyebrowSlot?.className,
352
+ classNames?.eyebrow,
353
+ )}
354
+ >
355
+ {normalizedEyebrow.text}
356
+ </p>
357
+ ) : null}
358
+
359
+ <h1
360
+ id={titleId}
361
+ className={cn(
362
+ "mt-5",
363
+ normalizedTitle.className,
364
+ titleSlot?.className,
365
+ classNames?.title,
366
+ )}
367
+ >
368
+ {renderHighlightedTitle(normalizedTitle, classNames?.titleHighlight)}
369
+ </h1>
370
+
371
+ {normalizedDescription.text ? (
372
+ <p
373
+ className={cn(
374
+ normalizedDescription.className,
375
+ descriptionSlot?.className,
376
+ classNames?.description,
377
+ )}
378
+ >
379
+ {normalizedDescription.text}
380
+ </p>
381
+ ) : null}
382
+
383
+ <div
384
+ className={cn(
385
+ "mt-8 flex w-full flex-col items-center justify-center gap-3 sm:w-auto sm:flex-row",
386
+ buttonsContainer?.className,
387
+ classNames?.buttons,
388
+ )}
389
+ >
390
+ {renderCta(resolvedPrimaryCta)}
391
+ {renderCta(resolvedSecondaryCta)}
392
+ </div>
393
+
394
+ {normalizedCredibility.text ? (
395
+ <p
396
+ className={cn(
397
+ normalizedCredibility.className,
398
+ credibilitySlot?.className,
399
+ classNames?.credibility,
400
+ )}
401
+ >
402
+ {normalizedCredibility.text}
403
+ </p>
404
+ ) : null}
405
+
406
+ {normalizedCommand.text ? (
407
+ <code
408
+ className={cn(
409
+ normalizedCommand.className,
410
+ commandSlot?.className,
411
+ classNames?.command,
412
+ )}
413
+ >
414
+ <span className="mr-2 text-muted-foreground/60" aria-hidden="true">
415
+ $
416
+ </span>
417
+ <span className="truncate">{normalizedCommand.text}</span>
418
+ </code>
419
+ ) : null}
420
+ </div>
421
+
422
+ <div
423
+ id={resolvedPreviewId}
424
+ className={cn(
425
+ "relative mt-12 w-full max-w-6xl sm:mt-14 lg:mt-16",
426
+ videoOuter?.className,
427
+ classNames?.videoOuter,
428
+ )}
429
+ >
430
+ <div
431
+ className={cn(
432
+ "relative overflow-hidden rounded-[1.75rem] border border-border bg-card/80 p-2 shadow-[0_28px_90px_rgba(0,0,0,0.12)] backdrop-blur dark:shadow-[0_28px_90px_rgba(0,0,0,0.72),0_0_0_1px_rgba(255,255,255,0.04)]",
433
+ videoMotion,
434
+ videoFrame?.className,
435
+ classNames?.videoFrame,
436
+ )}
437
+ >
438
+ <div
439
+ className={cn(
440
+ "flex h-10 items-center gap-2 border-b border-border px-4",
441
+ videoChrome?.className,
442
+ classNames?.videoChrome,
443
+ )}
444
+ aria-hidden="true"
445
+ >
446
+ <span className="size-2.5 rounded-full bg-foreground/24" />
447
+ <span className="size-2.5 rounded-full bg-foreground/16" />
448
+ <span className="size-2.5 rounded-full bg-foreground/10" />
449
+ <span className="ml-3 h-2 w-28 rounded-full bg-foreground/8" />
450
+ </div>
451
+
452
+ <div className="relative aspect-video overflow-hidden rounded-[1.25rem] bg-muted">
453
+ {embed ??
454
+ (video?.src ? (
455
+ <video
456
+ src={video.src}
457
+ poster={video.poster}
458
+ title={video.title ?? video.ariaLabel ?? "Hero video"}
459
+ aria-label={video.ariaLabel ?? video.title ?? "Hero video"}
460
+ className={cn(
461
+ "size-full object-cover",
462
+ video.className,
463
+ videoSlot?.className,
464
+ classNames?.video,
465
+ )}
466
+ autoPlay={video.autoPlay}
467
+ muted={video.muted ?? video.autoPlay ?? false}
468
+ loop={video.loop}
469
+ playsInline={video.playsInline ?? true}
470
+ controls={video.controls ?? true}
471
+ preload={video.preload ?? "metadata"}
472
+ />
473
+ ) : (
474
+ <div
475
+ className={cn(
476
+ "flex size-full items-center justify-center bg-[radial-gradient(circle_at_center,rgba(255,255,255,0.28),rgba(255,255,255,0.1)_38%,rgba(255,255,255,0)_72%)] px-6 text-center dark:bg-[radial-gradient(circle_at_center,rgba(255,255,255,0.11),rgba(255,255,255,0.035)_38%,rgba(0,0,0,1)_72%)]",
477
+ classNames?.videoFallback,
478
+ )}
479
+ >
480
+ {fallback ?? (
481
+ <p className="max-w-md text-sm leading-6 text-muted-foreground">
482
+ Add a demo video source to show a product walkthrough,
483
+ launch preview, or selected project here.
484
+ </p>
485
+ )}
486
+ </div>
487
+ ))}
488
+ </div>
489
+ </div>
490
+ </div>
491
+ </div>
492
+ </section>
493
+ );
494
+ }
495
+