nextworks 0.2.0-alpha.13 → 0.2.0-alpha.14
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.
- package/README.md +3 -1
- package/dist/kits/blocks/.nextworks/docs/BLOCKS_QUICKSTART.md +2 -0
- package/dist/kits/blocks/.nextworks/docs/BLOCKS_README.md +2 -0
- package/dist/kits/blocks/app/templates/aiworkflow/PresetThemeVars.tsx +1 -58
- package/dist/kits/blocks/app/templates/aiworkflow/README.md +2 -0
- package/dist/kits/blocks/app/templates/aiworkflow/components/CTA.tsx +9 -9
- package/dist/kits/blocks/app/templates/aiworkflow/components/Contact.tsx +12 -13
- package/dist/kits/blocks/app/templates/aiworkflow/components/FAQ.tsx +22 -19
- package/dist/kits/blocks/app/templates/aiworkflow/components/FeatureMockups.tsx +562 -0
- package/dist/kits/blocks/app/templates/aiworkflow/components/Features.tsx +18 -16
- package/dist/kits/blocks/app/templates/aiworkflow/components/Footer.tsx +13 -9
- package/dist/kits/blocks/app/templates/aiworkflow/components/Hero.tsx +883 -636
- package/dist/kits/blocks/app/templates/aiworkflow/components/Navbar.tsx +14 -15
- package/dist/kits/blocks/app/templates/aiworkflow/components/Pricing.tsx +27 -22
- package/dist/kits/blocks/app/templates/aiworkflow/components/ProcessTimeline.tsx +20 -21
- package/dist/kits/blocks/app/templates/aiworkflow/components/Testimonials.tsx +17 -13
- package/dist/kits/blocks/app/templates/aiworkflow/components/TrustBadges.tsx +15 -12
- package/dist/kits/blocks/app/templates/aiworkflow/themes/animation.tsx +151 -0
- package/dist/kits/blocks/app/templates/aiworkflow/themes/default.tsx +158 -0
- package/dist/kits/blocks/app/templates/aiworkflow/themes/test.tsx +163 -0
- package/dist/kits/blocks/app/templates/gallery/PresetThemeVars.tsx +46 -0
- package/dist/kits/blocks/app/templates/gallery/page.tsx +550 -161
- package/dist/kits/blocks/components/sections/HeroProductDemo.tsx +74 -64
- package/dist/kits/blocks/components/sections/Navbar.tsx +2 -0
- package/dist/kits/blocks/components/sections/product-demo/ApprovalInboxPanel.tsx +16 -13
- package/dist/kits/blocks/components/sections/product-demo/DemoStage.tsx +283 -162
- package/dist/kits/blocks/components/sections/product-demo/DemoWindow.tsx +65 -53
- package/dist/kits/blocks/components/sections/product-demo/KnowledgePanel.tsx +20 -17
- package/dist/kits/blocks/components/sections/product-demo/RunConsolePanel.tsx +208 -127
- package/dist/kits/blocks/components/sections/product-demo/TaskListPanel.tsx +95 -0
- package/dist/kits/blocks/components/sections/product-demo/WorkflowStudioPanel.tsx +714 -161
- package/dist/kits/blocks/components/sections/product-demo/types.ts +69 -0
- package/dist/kits/blocks/components/ui/theme-selector.tsx +1 -1
- package/dist/kits/blocks/package-deps.json +3 -3
- package/dist/kits/blocks/public/placeholders/aiworkflow/live.svg +92 -0
- package/dist/kits/blocks/public/placeholders/aiworkflow/review.svg +80 -0
- package/dist/kits/blocks/public/placeholders/aiworkflow/task.svg +71 -0
- package/dist/kits/blocks/tsconfig.json +13 -0
- package/dist/utils/file-operations.d.ts.map +1 -1
- package/dist/utils/file-operations.js +6 -1
- package/dist/utils/file-operations.js.map +1 -1
- package/package.json +1 -1
|
@@ -6,6 +6,7 @@ import { CTA } from "@/components/sections/CTA";
|
|
|
6
6
|
import { FAQ } from "@/components/sections/FAQ";
|
|
7
7
|
import { Features } from "@/components/sections/Features";
|
|
8
8
|
import { Footer } from "@/components/sections/Footer";
|
|
9
|
+
import { HeroProductDemo } from "@/components/sections/HeroProductDemo";
|
|
9
10
|
import { HeroMotion } from "@/components/sections/HeroMotion";
|
|
10
11
|
import { HeroOverlay } from "@/components/sections/HeroOverlay";
|
|
11
12
|
import { HeroSplit } from "@/components/sections/HeroSplit";
|
|
@@ -18,7 +19,9 @@ import { ServicesGrid } from "@/components/sections/ServicesGrid";
|
|
|
18
19
|
import { Team } from "@/components/sections/Team";
|
|
19
20
|
import { Testimonials } from "@/components/sections/Testimonials";
|
|
20
21
|
import { ThemeSelector } from "@/components/ui/theme-selector";
|
|
22
|
+
import type { HeroProductDemoProps } from "@/components/sections/HeroProductDemo";
|
|
21
23
|
import { TrustBadges } from "@/components/sections/TrustBadges";
|
|
24
|
+
|
|
22
25
|
import { PresetThemeVars } from "./PresetThemeVars";
|
|
23
26
|
|
|
24
27
|
export default function Gallery() {
|
|
@@ -53,6 +56,256 @@ export default function Gallery() {
|
|
|
53
56
|
},
|
|
54
57
|
];
|
|
55
58
|
|
|
59
|
+
const heroProductDemoScenarios: NonNullable<
|
|
60
|
+
HeroProductDemoProps["stage"]
|
|
61
|
+
>["scenarios"] = [
|
|
62
|
+
{
|
|
63
|
+
key: "gallery-product-demo",
|
|
64
|
+
label: "Workflow overview",
|
|
65
|
+
description:
|
|
66
|
+
"An AI-powered coding agent that plans, edits, and verifies changes across your entire codebase — without breaking your flow.",
|
|
67
|
+
activeWindow: "workflowStudio",
|
|
68
|
+
playback: {
|
|
69
|
+
workflowStudio: {
|
|
70
|
+
playbackStepDurationsMs: [820, 920, 1240, 1100, 960, 840, 1560],
|
|
71
|
+
playbackResetDelayMs: 2200,
|
|
72
|
+
},
|
|
73
|
+
runConsole: {
|
|
74
|
+
playbackStepDurationsMs: [1080, 1320, 920, 780, 700, 620, 1240],
|
|
75
|
+
playbackResetDelayMs: 2200,
|
|
76
|
+
playbackStepEntryIndices: [0, 0, 1, 1, 2, 2, 2, 3, 3],
|
|
77
|
+
playbackStepVisibleLineCounts: [2, 2, 3, 4, 6, 8, 10, 12, 12],
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
taskList: {
|
|
81
|
+
window: {
|
|
82
|
+
key: "taskList",
|
|
83
|
+
title: "Queues",
|
|
84
|
+
subtitle: "Active tasks",
|
|
85
|
+
status: { label: "Ready", tone: "info" },
|
|
86
|
+
},
|
|
87
|
+
title: "Task queues",
|
|
88
|
+
subtitle: "Switch between in-progress agent runs.",
|
|
89
|
+
activeItemId: "gallery-product-demo",
|
|
90
|
+
items: [
|
|
91
|
+
{
|
|
92
|
+
id: "gallery-product-demo",
|
|
93
|
+
title: "Refactor auth module",
|
|
94
|
+
description:
|
|
95
|
+
"Extract token logic into a dedicated service, add refresh handling, and update all call sites.",
|
|
96
|
+
meta: "in progress · 4 files",
|
|
97
|
+
},
|
|
98
|
+
],
|
|
99
|
+
},
|
|
100
|
+
workflowStudio: {
|
|
101
|
+
window: {
|
|
102
|
+
key: "workflowStudio",
|
|
103
|
+
title: "Agent console",
|
|
104
|
+
subtitle: "Live run",
|
|
105
|
+
status: { label: "Running", tone: "info" },
|
|
106
|
+
},
|
|
107
|
+
title: "Refactoring auth module",
|
|
108
|
+
subtitle:
|
|
109
|
+
"The agent reads existing logic, plans the extraction, and applies changes across all affected files.",
|
|
110
|
+
activeNodeId: "polish-layout",
|
|
111
|
+
transcript: [
|
|
112
|
+
{ id: "gallery-title", kind: "title", text: "Refactor auth module" },
|
|
113
|
+
{
|
|
114
|
+
id: "gallery-prompt",
|
|
115
|
+
kind: "prompt",
|
|
116
|
+
text: "Extract token handling into an AuthService class, add silent refresh on 401, and update every call site.",
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
id: "gallery-read-1",
|
|
120
|
+
kind: "activity",
|
|
121
|
+
text: "Read auth/session.ts and api/client.ts",
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
id: "gallery-read-2",
|
|
125
|
+
kind: "activity",
|
|
126
|
+
text: "Scan for token usage across 12 files",
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
id: "gallery-file-1",
|
|
130
|
+
kind: "file",
|
|
131
|
+
path: "src/services/auth-service.ts",
|
|
132
|
+
text: "src/services/auth-service.ts",
|
|
133
|
+
added: 74,
|
|
134
|
+
removed: 0,
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
id: "gallery-summary",
|
|
138
|
+
kind: "message",
|
|
139
|
+
text: "Done. Token logic is centralised in AuthService and silent refresh is active on every API call.",
|
|
140
|
+
},
|
|
141
|
+
],
|
|
142
|
+
composer: {
|
|
143
|
+
placeholder: "Describe your next change...",
|
|
144
|
+
modeLabel: "Agent",
|
|
145
|
+
modelLabel: "Sonnet",
|
|
146
|
+
},
|
|
147
|
+
highlights: [
|
|
148
|
+
{ id: "read-copy", label: "Read codebase", tone: "info" },
|
|
149
|
+
{ id: "polish-layout", label: "Apply changes", tone: "accent" },
|
|
150
|
+
],
|
|
151
|
+
nodes: [
|
|
152
|
+
{
|
|
153
|
+
id: "read-copy",
|
|
154
|
+
label: "Read existing auth logic",
|
|
155
|
+
description:
|
|
156
|
+
"Parse session handling and identify all token read/write paths.",
|
|
157
|
+
type: "Read",
|
|
158
|
+
status: "success",
|
|
159
|
+
metadata: "auth/session.ts · api/client.ts",
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
id: "layout-shell",
|
|
163
|
+
label: "Plan the extraction",
|
|
164
|
+
description:
|
|
165
|
+
"Decide class boundaries and map which call sites need updating.",
|
|
166
|
+
type: "Analyze",
|
|
167
|
+
status: "success",
|
|
168
|
+
metadata: "12 files affected",
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
id: "polish-layout",
|
|
172
|
+
label: "Write AuthService",
|
|
173
|
+
description:
|
|
174
|
+
"Create the service class, move token storage, and add the 401 refresh interceptor.",
|
|
175
|
+
type: "Edit",
|
|
176
|
+
status: "info",
|
|
177
|
+
active: true,
|
|
178
|
+
emphasized: true,
|
|
179
|
+
metadata: "src/services/auth-service.ts",
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
id: "review-story",
|
|
183
|
+
label: "Update call sites",
|
|
184
|
+
description:
|
|
185
|
+
"Replace direct token access with AuthService across all affected files and verify types.",
|
|
186
|
+
type: "Verify",
|
|
187
|
+
status: "neutral",
|
|
188
|
+
metadata: "final pass",
|
|
189
|
+
},
|
|
190
|
+
],
|
|
191
|
+
},
|
|
192
|
+
runConsole: {
|
|
193
|
+
window: {
|
|
194
|
+
key: "runConsole",
|
|
195
|
+
title: "Console",
|
|
196
|
+
subtitle: "Live output",
|
|
197
|
+
status: { label: "Writing", tone: "info" },
|
|
198
|
+
},
|
|
199
|
+
title: "src/services/auth-service.ts",
|
|
200
|
+
subtitle:
|
|
201
|
+
"New file — token logic extracted from session.ts and api/client.ts.",
|
|
202
|
+
statusLabel: "Writing AuthService",
|
|
203
|
+
progressLabel: "74 lines added",
|
|
204
|
+
progressPercent: 64,
|
|
205
|
+
activeEntryId: "gallery-diff-3",
|
|
206
|
+
editorTabLabel: "auth-service.ts",
|
|
207
|
+
editorLanguage: "TypeScript",
|
|
208
|
+
editorSummary:
|
|
209
|
+
"Create AuthService with token storage, silent refresh, and a fetch interceptor.",
|
|
210
|
+
entries: [
|
|
211
|
+
{
|
|
212
|
+
id: "gallery-diff-1",
|
|
213
|
+
message: "Read auth/session.ts and mapped token access patterns",
|
|
214
|
+
timestamp: "10:48",
|
|
215
|
+
source: "agent",
|
|
216
|
+
status: "success",
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
id: "gallery-diff-2",
|
|
220
|
+
message: "Identified 12 call sites that reference tokens directly",
|
|
221
|
+
timestamp: "10:49",
|
|
222
|
+
source: "analysis",
|
|
223
|
+
status: "success",
|
|
224
|
+
detail:
|
|
225
|
+
"Centralising access in AuthService will eliminate all direct imports.",
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
id: "gallery-diff-3",
|
|
229
|
+
message: "Created AuthService with refresh interceptor",
|
|
230
|
+
timestamp: "10:49",
|
|
231
|
+
source: "editor",
|
|
232
|
+
status: "info",
|
|
233
|
+
highlighted: true,
|
|
234
|
+
lineNumber: "34",
|
|
235
|
+
code: [
|
|
236
|
+
" export class AuthService {",
|
|
237
|
+
" private static token: string | null = null;",
|
|
238
|
+
" ",
|
|
239
|
+
"+ static async getToken(): Promise<string | null> {",
|
|
240
|
+
"+ if (!this.token) this.token = await storage.get('auth_token');",
|
|
241
|
+
"+ return this.token;",
|
|
242
|
+
"+ }",
|
|
243
|
+
"+ ",
|
|
244
|
+
"+ static async refreshIfExpired(): Promise<void> {",
|
|
245
|
+
"+ const exp = parseExpiry(this.token);",
|
|
246
|
+
"+ if (exp && exp < Date.now() + 60_000) {",
|
|
247
|
+
"+ this.token = await api.post('/auth/refresh');",
|
|
248
|
+
"+ }",
|
|
249
|
+
"+ }",
|
|
250
|
+
],
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
id: "gallery-diff-4",
|
|
254
|
+
message: "Queued call-site updates across 12 files",
|
|
255
|
+
timestamp: "10:50",
|
|
256
|
+
source: "preview",
|
|
257
|
+
status: "neutral",
|
|
258
|
+
},
|
|
259
|
+
],
|
|
260
|
+
metrics: [
|
|
261
|
+
{ id: "gm1", label: "Files", value: "1", tone: "success" },
|
|
262
|
+
{ id: "gm2", label: "Lines added", value: "74", tone: "info" },
|
|
263
|
+
{ id: "gm3", label: "Type errors", value: "0", tone: "success" },
|
|
264
|
+
],
|
|
265
|
+
highlights: [],
|
|
266
|
+
},
|
|
267
|
+
approvalInbox: {
|
|
268
|
+
window: {
|
|
269
|
+
key: "approvalInbox",
|
|
270
|
+
title: "Hidden",
|
|
271
|
+
},
|
|
272
|
+
items: [],
|
|
273
|
+
},
|
|
274
|
+
knowledgePanel: {
|
|
275
|
+
window: {
|
|
276
|
+
key: "knowledgePanel",
|
|
277
|
+
title: "Knowledge",
|
|
278
|
+
subtitle: "Context",
|
|
279
|
+
status: { label: "Ready", tone: "success" },
|
|
280
|
+
},
|
|
281
|
+
title: "Auth codebase context",
|
|
282
|
+
subtitle: "Relevant files and patterns surfaced for this task.",
|
|
283
|
+
query: "AuthService token refresh",
|
|
284
|
+
summary:
|
|
285
|
+
"Token storage is currently split between session.ts and api/client.ts. Centralising in AuthService removes 3 duplicate patterns and enables a single refresh intercept point.",
|
|
286
|
+
snippets: [
|
|
287
|
+
{
|
|
288
|
+
id: "gallery-snippet",
|
|
289
|
+
title: "auth/session.ts — token storage",
|
|
290
|
+
excerptLabel: "Current implementation",
|
|
291
|
+
confidence: "12 call sites",
|
|
292
|
+
highlighted: true,
|
|
293
|
+
content:
|
|
294
|
+
"getToken(): string | null { return localStorage.getItem('auth_token'); }\nsetToken(t: string): void { localStorage.setItem('auth_token', t); }\nclearToken(): void { localStorage.removeItem('auth_token'); }",
|
|
295
|
+
tags: ["auth", "token", "session"],
|
|
296
|
+
},
|
|
297
|
+
],
|
|
298
|
+
highlights: [
|
|
299
|
+
{ id: "gallery-snippet", label: "Token pattern", tone: "success" },
|
|
300
|
+
],
|
|
301
|
+
},
|
|
302
|
+
highlights: [
|
|
303
|
+
{ id: "polish-layout", label: "AuthService created", tone: "accent" },
|
|
304
|
+
{ id: "gallery-diff-3", label: "Refresh interceptor", tone: "info" },
|
|
305
|
+
],
|
|
306
|
+
},
|
|
307
|
+
];
|
|
308
|
+
|
|
56
309
|
const BrandNode = (
|
|
57
310
|
<>
|
|
58
311
|
<ThemeSelector ariaLabel="Demo: Color theme" label="" className="mr-2" />
|
|
@@ -81,7 +334,8 @@ export default function Gallery() {
|
|
|
81
334
|
brand="Nextworks"
|
|
82
335
|
brandNode={BrandNode}
|
|
83
336
|
menuItems={[
|
|
84
|
-
{ label: "Hero", href: "#hero-
|
|
337
|
+
{ label: "Hero", href: "#hero-product-demo" },
|
|
338
|
+
|
|
85
339
|
{ label: "Trust", href: "#trust" },
|
|
86
340
|
{ label: "Features", href: "#features" },
|
|
87
341
|
{ label: "About", href: "#about-process" },
|
|
@@ -99,200 +353,335 @@ export default function Gallery() {
|
|
|
99
353
|
ctaButton={null}
|
|
100
354
|
/>
|
|
101
355
|
{/* Hero Sections */}
|
|
102
|
-
<div id="hero-sections">
|
|
103
|
-
<
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
"
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
"
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
356
|
+
<div id="hero-sections" className="scroll-mt-16">
|
|
357
|
+
<div id="hero-product-demo" className="scroll-mt-16">
|
|
358
|
+
<div className="relative pt-0">
|
|
359
|
+
<HeroProductDemo
|
|
360
|
+
className="bg-transparent"
|
|
361
|
+
heading={{
|
|
362
|
+
text: "Ship faster with an agent that knows your codebase.",
|
|
363
|
+
className:
|
|
364
|
+
"max-w-4xl text-left font-outfit text-3xl font-semibold leading-none tracking-tight text-[var(--heading-fg)] sm:text-4xl lg:text-5xl",
|
|
365
|
+
}}
|
|
366
|
+
subheading={{
|
|
367
|
+
text: "Describe the change you need. The agent reads, plans, edits, and verifies — across every affected file, in one run.",
|
|
368
|
+
className:
|
|
369
|
+
"mt-3 max-w-2xl text-left font-inter text-sm leading-6 text-[var(--subheading-fg)] sm:text-base",
|
|
370
|
+
}}
|
|
371
|
+
cta1={{
|
|
372
|
+
label: "Start for free",
|
|
373
|
+
href: "#features",
|
|
374
|
+
variant: "default",
|
|
375
|
+
size: "lg",
|
|
376
|
+
className:
|
|
377
|
+
// "ml-4 px-7 py-3 text-sm font-semibold shadow-lg shadow-black/10 dark:shadow-black/30 " +
|
|
378
|
+
// "!bg-[var(--hero-cta-primary-bg)] !text-[var(--hero-cta-primary-fg)] " +
|
|
379
|
+
// "hover:!bg-[var(--hero-cta-primary-hover-bg)] hover:!text-[var(--hero-cta-primary-hover-fg)] " +
|
|
380
|
+
// "active:!bg-[var(--hero-cta-primary-bg)] active:!text-[var(--hero-cta-primary-fg)] " +
|
|
381
|
+
// "visited:!bg-[var(--hero-cta-primary-bg)] visited:!text-[var(--hero-cta-primary-fg)] " +
|
|
382
|
+
// "dark:!bg-[var(--hero-cta-primary-bg)] dark:!text-[var(--hero-cta-primary-fg)] " +
|
|
383
|
+
// "dark:hover:!bg-[var(--hero-cta-secondary-hover-bg)] dark:hover:!text-[var(--hero-cta-primary-hover-fg)] " +
|
|
384
|
+
// "dark:active:!bg-[var(--hero-cta-primary-bg)] dark:active:!text-[var(--hero-cta-primary-fg)] " +
|
|
385
|
+
// "dark:visited:!bg-[var(--hero-cta-primary-bg)] dark:visited:!text-[var(--hero-cta-primary-fg)]",
|
|
386
|
+
"ml-4 border border-transparent px-7 py-3 text-sm font-semibold shadow-lg shadow-black/10 dark:shadow-black/30 " +
|
|
387
|
+
"!bg-[var(--hero-cta-primary-bg)] !text-[var(--hero-cta-primary-fg)] " +
|
|
388
|
+
"hover:!bg-[var(--hero-cta-primary-hover-bg)] hover:!text-[var(--hero-cta-primary-hover-fg)] " +
|
|
389
|
+
"active:!bg-[var(--hero-cta-primary-bg)] active:!text-[var(--hero-cta-primary-fg)] " +
|
|
390
|
+
"visited:!bg-[var(--hero-cta-primary-bg)] visited:!text-[var(--hero-cta-primary-fg)] " +
|
|
391
|
+
"dark:!bg-[var(--hero-cta-primary-bg)] dark:!text-[var(--hero-cta-primary-fg)] " +
|
|
392
|
+
"dark:hover:!bg-[var(--hero-cta-secondary-hover-bg)] dark:hover:!text-[var(--hero-cta-primary-hover-fg)] " +
|
|
393
|
+
"dark:hover:!border-white " +
|
|
394
|
+
"dark:active:!bg-[var(--hero-cta-primary-bg)] dark:active:!text-[var(--hero-cta-primary-fg)] " +
|
|
395
|
+
"dark:visited:!bg-[var(--hero-cta-primary-bg)] dark:visited:!text-[var(--hero-cta-primary-fg)]",
|
|
396
|
+
}}
|
|
397
|
+
cta2={{
|
|
398
|
+
label: "See it in action",
|
|
399
|
+
href: "#trust",
|
|
400
|
+
variant: "outline",
|
|
401
|
+
size: "lg",
|
|
402
|
+
className:
|
|
403
|
+
"border px-7 py-3 text-sm font-semibold shadow-sm dark:shadow-black/20 " +
|
|
404
|
+
"[--btn-bg:var(--hero-cta-secondary-bg)] " +
|
|
405
|
+
"[--btn-fg:var(--hero-cta-secondary-fg)] " +
|
|
406
|
+
"[--btn-border:var(--hero-cta-secondary-border)] " +
|
|
407
|
+
"hover:[--btn-hover-bg:var(--hero-cta-secondary-hover-bg)] " +
|
|
408
|
+
"hover:[--btn-hover-fg:var(--hero-cta-secondary-hover-fg)]",
|
|
409
|
+
}}
|
|
410
|
+
stage={{
|
|
411
|
+
scenarios: heroProductDemoScenarios,
|
|
412
|
+
initialScenarioIndex: 0,
|
|
413
|
+
className: "mt-0",
|
|
414
|
+
}}
|
|
415
|
+
section={{
|
|
416
|
+
className:
|
|
417
|
+
"px-6 pt-10 pb-6 sm:px-8 lg:px-10 lg:pt-12 lg:pb-8",
|
|
418
|
+
}}
|
|
419
|
+
container={{
|
|
420
|
+
className: "relative z-10 max-w-7xl gap-8",
|
|
421
|
+
}}
|
|
422
|
+
textContainer={{
|
|
423
|
+
className: "max-w-3xl pt-6 lg:pl-4 lg:pt-8",
|
|
424
|
+
}}
|
|
425
|
+
demoContainer={{
|
|
426
|
+
className:
|
|
427
|
+
"relative mt-2 min-h-[34rem] w-full max-w-full overflow-hidden rounded-[0.5rem] border border-border/0 bg-background/90 p-3 shadow-[0_24px_80px_-44px_rgba(15,23,42,0.24)] backdrop-blur-sm lg:h-[clamp(34rem,calc(100svh-8rem),46rem)] lg:min-h-0 lg:px-4",
|
|
428
|
+
// "relative mt-2 min-h-[34rem] w-full max-w-full overflow-hidden rounded-[2rem] border border-border/70 bg-background/90 p-3 shadow-[0_24px_80px_-44px_rgba(15,23,42,0.24)] backdrop-blur-sm lg:h-[clamp(34rem,calc(100svh-8rem),46rem)] lg:min-h-0 lg:px-4",
|
|
429
|
+
}}
|
|
430
|
+
buttonsContainer={{
|
|
431
|
+
className:
|
|
432
|
+
"mt-6 flex flex-col items-start gap-3 sm:flex-row sm:items-center [--btn-ring:var(--ring)]",
|
|
433
|
+
}}
|
|
434
|
+
demoBelowText
|
|
435
|
+
ariaLabel="Gallery product demo hero section"
|
|
436
|
+
/>
|
|
437
|
+
</div>
|
|
438
|
+
</div>
|
|
439
|
+
|
|
440
|
+
<div className="relative pt-4 sm:pt-5 mb-10">
|
|
441
|
+
<HeroOverlay
|
|
442
|
+
heading="Forecast The Next Move"
|
|
443
|
+
subheading="Predict demand, personalize journeys, and scale impact with AI-guided insights your team can use today."
|
|
444
|
+
cta1={{
|
|
445
|
+
label: "Try It Free",
|
|
446
|
+
href: "#hero-sections",
|
|
447
|
+
className:
|
|
448
|
+
"[--btn-bg:var(--primary)] [--btn-fg:var(--primary-foreground)] " +
|
|
449
|
+
"hover:[--btn-hover-bg:color-mix(in_oklab,var(--primary)_88%,black)] " +
|
|
450
|
+
"hover:[--btn-hover-fg:var(--primary-foreground)]",
|
|
451
|
+
}}
|
|
452
|
+
cta2={{
|
|
453
|
+
label: "See Demo",
|
|
454
|
+
href: "#hero-sections",
|
|
455
|
+
className:
|
|
456
|
+
"border [&:where(button)]:border " +
|
|
457
|
+
"[--btn-bg:transparent] dark:[--btn-bg:transparent] " +
|
|
458
|
+
"[--btn-fg:var(--primary)] dark:[--btn-fg:var(--primary)] " +
|
|
459
|
+
"[--btn-border:var(--primary)] dark:[--btn-border:var(--primary)] " +
|
|
460
|
+
"hover:[--btn-hover-bg:color-mix(in_oklab,var(--primary)_15%,transparent)] " +
|
|
461
|
+
"dark:hover:[--btn-hover-bg:color-mix(in_oklab,var(--primary)_18%,transparent)] " +
|
|
462
|
+
"hover:[--btn-hover-fg:var(--primary)] dark:hover:[--btn-hover-fg:var(--primary)]",
|
|
463
|
+
}}
|
|
464
|
+
// Set ring color on the CTA container so both buttons share it
|
|
465
|
+
ctaContainer={{
|
|
466
|
+
className:
|
|
467
|
+
"flex flex-col sm:flex-row gap-4 mt-6 justify-center items-center [--btn-ring:var(--ring)]",
|
|
468
|
+
}}
|
|
469
|
+
image={{
|
|
470
|
+
src: "/placeholders/gallery/hero-pexels-broken-9945014.avif",
|
|
471
|
+
}}
|
|
472
|
+
/>
|
|
473
|
+
</div>
|
|
474
|
+
<div className="relative pt-3 sm:pt-4 mb-10">
|
|
475
|
+
<HeroMotion
|
|
476
|
+
actions={{
|
|
477
|
+
className:
|
|
478
|
+
"mt-8 flex items-center justify-center gap-3 [--btn-ring:var(--ring)]",
|
|
479
|
+
}}
|
|
480
|
+
primaryButtonStyle={{
|
|
481
|
+
size: "lg",
|
|
482
|
+
variant: "default",
|
|
483
|
+
className:
|
|
484
|
+
"[--btn-bg:var(--primary)] [--btn-fg:var(--primary-foreground)] " +
|
|
485
|
+
"hover:[--btn-hover-bg:color-mix(in_oklab,var(--primary)_88%,black)] " +
|
|
486
|
+
"hover:[--btn-hover-fg:var(--primary-foreground)]",
|
|
487
|
+
}}
|
|
488
|
+
secondaryButtonStyle={{
|
|
489
|
+
size: "lg",
|
|
490
|
+
variant: "outline",
|
|
491
|
+
className:
|
|
492
|
+
"border [&:where(button)]:border " +
|
|
493
|
+
"[--btn-bg:transparent] dark:[--btn-bg:transparent] " +
|
|
494
|
+
"[--btn-fg:var(--primary)] dark:[--btn-fg:var(--primary)] " +
|
|
495
|
+
"[--btn-border:var(--primary)] dark:[--btn-border:var(--primary)] " +
|
|
496
|
+
"hover:[--btn-hover-bg:color-mix(in_oklab,var(--primary)_15%,transparent)] " +
|
|
497
|
+
"dark:hover:[--btn-hover-bg:color-mix(in_oklab,var(--primary)_18%,transparent)] " +
|
|
498
|
+
"hover:[--btn-hover-fg:var(--primary)] dark:hover:[--btn-hover-fg:var(--primary)]",
|
|
499
|
+
}}
|
|
500
|
+
primaryCta={{ label: "Get Started", href: "#hero-sections" }}
|
|
501
|
+
secondaryCta={{ label: "See Demo", href: "#hero-sections" }}
|
|
502
|
+
/>
|
|
503
|
+
</div>
|
|
504
|
+
|
|
505
|
+
<div className="relative pt-4 sm:pt-5">
|
|
506
|
+
<HeroSplit
|
|
507
|
+
section={{ className: "bg-muted" }}
|
|
508
|
+
heading="Confident Decisions, On Demand"
|
|
509
|
+
subheading="Reliable data when you need it."
|
|
510
|
+
cta1={{
|
|
511
|
+
label: "Start Free Trial",
|
|
512
|
+
href: "#hero-sections",
|
|
513
|
+
className:
|
|
514
|
+
"[--btn-bg:var(--primary)] [--btn-fg:var(--primary-foreground)] " +
|
|
515
|
+
"hover:[--btn-hover-bg:color-mix(in_oklab,var(--primary)_88%,black)] " +
|
|
516
|
+
"hover:[--btn-hover-fg:var(--primary-foreground)]",
|
|
517
|
+
}}
|
|
518
|
+
cta2={{
|
|
519
|
+
label: "View Sample Report",
|
|
520
|
+
href: "#hero-sections",
|
|
521
|
+
className:
|
|
522
|
+
"border [&:where(button)]:border " +
|
|
523
|
+
"[--btn-bg:transparent] dark:[--btn-bg:transparent] " +
|
|
524
|
+
"[--btn-fg:var(--primary)] dark:[--btn-fg:var(--primary)] " +
|
|
525
|
+
"[--btn-border:var(--primary)] dark:[--btn-border:var(--primary)] " +
|
|
526
|
+
"hover:[--btn-hover-bg:color-mix(in_oklab,var(--primary)_15%,transparent)] " +
|
|
527
|
+
"dark:hover:[--btn-hover-bg:color-mix(in_oklab,var(--primary)_18%,transparent)] " +
|
|
528
|
+
"hover:[--btn-hover-fg:var(--primary)] dark:hover:[--btn-hover-fg:var(--primary)]",
|
|
529
|
+
}}
|
|
530
|
+
buttonsContainer={{
|
|
531
|
+
className:
|
|
532
|
+
"flex flex-col md:flex-row gap-4 mt-6 [--btn-ring:var(--ring)]",
|
|
533
|
+
}}
|
|
534
|
+
image={{
|
|
535
|
+
src: "/placeholders/gallery/hero-pexels-broken-9945014.avif",
|
|
536
|
+
}}
|
|
537
|
+
imageLayout="full-bleed"
|
|
538
|
+
/>
|
|
539
|
+
</div>
|
|
195
540
|
{/* */}
|
|
196
541
|
</div>
|
|
542
|
+
|
|
197
543
|
{/* Trust & Social Proof */}
|
|
198
544
|
<div id="trust" className="scroll-mt-16">
|
|
199
|
-
<
|
|
545
|
+
<div className="relative pt-0">
|
|
546
|
+
<TrustBadges
|
|
547
|
+
section={{
|
|
548
|
+
className:
|
|
549
|
+
"py-8 px-6 bg-[color-mix(in_oklab,var(--muted)_94%,black)] dark:bg-[color-mix(in_oklab,var(--muted)_90%,white)]",
|
|
550
|
+
}}
|
|
551
|
+
/>
|
|
552
|
+
</div>
|
|
200
553
|
</div>
|
|
554
|
+
|
|
201
555
|
{/* Features & Services */}
|
|
202
556
|
<div id="features" className="scroll-mt-16">
|
|
203
|
-
<
|
|
204
|
-
|
|
557
|
+
<div className="relative pt-3 sm:pt-4">
|
|
558
|
+
<Features featuresData={defaultFeaturesData}></Features>
|
|
559
|
+
</div>
|
|
560
|
+
<div className="relative pt-4 sm:pt-5 mb-0">
|
|
561
|
+
<ServicesGrid />
|
|
562
|
+
</div>
|
|
205
563
|
</div>
|
|
564
|
+
|
|
206
565
|
{/* About & Process */}
|
|
207
566
|
<div id="about-process" className="scroll-mt-16">
|
|
208
|
-
<
|
|
209
|
-
|
|
567
|
+
<div className="relative pt-0">
|
|
568
|
+
<About animateStats={false} />
|
|
569
|
+
</div>
|
|
570
|
+
<div className="relative pt-0 mb-0">
|
|
571
|
+
<ProcessTimeline />
|
|
572
|
+
</div>
|
|
210
573
|
</div>
|
|
574
|
+
|
|
211
575
|
{/* Portfolio & Team */}
|
|
212
576
|
<div id="portfolio-team" className="scroll-mt-16">
|
|
213
|
-
<
|
|
214
|
-
|
|
577
|
+
<div className="relative pt-3 sm:pt-4">
|
|
578
|
+
<PortfolioSimple />
|
|
579
|
+
</div>
|
|
580
|
+
<div className="relative pt-4 sm:pt-5 mb-0">
|
|
581
|
+
<Team />
|
|
582
|
+
</div>
|
|
215
583
|
</div>
|
|
584
|
+
|
|
216
585
|
{/* Testimonials */}
|
|
217
586
|
<div id="testimonials" className="scroll-mt-16">
|
|
218
|
-
<
|
|
587
|
+
<div className="relative pt-0 mb-0">
|
|
588
|
+
<Testimonials />
|
|
589
|
+
</div>
|
|
219
590
|
</div>
|
|
591
|
+
|
|
220
592
|
{/* Pricing */}
|
|
221
593
|
<div id="pricing" className="scroll-mt-16">
|
|
222
|
-
<
|
|
594
|
+
<div className="relative pt-3 sm:pt-4 mb-0">
|
|
595
|
+
<Pricing />
|
|
596
|
+
</div>
|
|
223
597
|
</div>
|
|
598
|
+
|
|
224
599
|
{/* FAQ */}
|
|
225
600
|
<div id="faq" className="scroll-mt-16">
|
|
226
|
-
<
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
601
|
+
<div className="relative pt-4 sm:pt-5 mb-0">
|
|
602
|
+
<FAQ
|
|
603
|
+
questionButton={{
|
|
604
|
+
className:
|
|
605
|
+
// Distinct, theme-driven gradient tile + brand ring/border
|
|
606
|
+
"bg-gradient-to-r " +
|
|
607
|
+
"from-[var(--primary)] to-[color-mix(in_oklab,var(--primary)_88%,black)] " +
|
|
608
|
+
"hover:from-[color-mix(in_oklab,var(--primary)_92%,black)] " +
|
|
609
|
+
"hover:to-[color-mix(in_oklab,var(--primary)_95%,black)] " +
|
|
610
|
+
"text-[var(--primary-foreground)] p-5 cursor-pointer rounded-lg " +
|
|
611
|
+
"transition-all duration-200 flex items-center justify-between " +
|
|
612
|
+
"shadow-lg hover:shadow-xl hover:-translate-y-0.5 " +
|
|
613
|
+
// define ring/border vars and ensure a visible border if tokens apply
|
|
614
|
+
"[--btn-ring:var(--ring)] [--btn-border:var(--primary)] border [&:where(button)]:border",
|
|
615
|
+
}}
|
|
616
|
+
answer={{
|
|
617
|
+
className:
|
|
618
|
+
"bg-gradient-to-r " +
|
|
619
|
+
"from-[var(--secondary)] to-[color-mix(in_oklab,var(--secondary)_90%,white)] ",
|
|
620
|
+
}}
|
|
621
|
+
/>
|
|
622
|
+
</div>
|
|
246
623
|
</div>
|
|
624
|
+
|
|
247
625
|
{/* Call to Action */}
|
|
248
626
|
<div id="cta" className="scroll-mt-16">
|
|
249
|
-
<
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
627
|
+
<div className="relative pt-3 sm:pt-4 mb-0">
|
|
628
|
+
<CTA
|
|
629
|
+
ctaButton={{ label: "Sign Up Now", href: "#contact" }}
|
|
630
|
+
actionsWrapper={{
|
|
631
|
+
className:
|
|
632
|
+
"mt-6 flex flex-col items-center gap-3 sm:flex-row [--btn-ring:var(--ring)]",
|
|
633
|
+
}}
|
|
634
|
+
ctaButtonStyle={{
|
|
635
|
+
variant: "default",
|
|
636
|
+
size: "default",
|
|
637
|
+
className:
|
|
638
|
+
"shadow-lg hover:shadow-xl transition-all duration-200 hover:-translate-y-0.5 " +
|
|
639
|
+
"[--btn-bg:var(--primary)] [--btn-fg:var(--primary-foreground)] " +
|
|
640
|
+
"hover:[--btn-hover-bg:color-mix(in_oklab,var(--primary)_88%,black)] " +
|
|
641
|
+
"hover:[--btn-hover-fg:var(--primary-foreground)]",
|
|
642
|
+
}}
|
|
643
|
+
/>
|
|
644
|
+
</div>
|
|
265
645
|
</div>
|
|
646
|
+
|
|
266
647
|
{/* Contact */}
|
|
267
648
|
<div id="contact" className="scroll-mt-16">
|
|
268
|
-
<
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
649
|
+
<div className="relative pt-4 sm:pt-5 mb-0">
|
|
650
|
+
<Contact
|
|
651
|
+
submitButtonStyle={{
|
|
652
|
+
variant: "default",
|
|
653
|
+
size: "lg",
|
|
654
|
+
className:
|
|
655
|
+
"w-full shadow-lg hover:shadow-xl transition-all duration-200 hover:-translate-y-0.5 " +
|
|
656
|
+
// Match FAQ question button gradient + brand ring/border
|
|
657
|
+
"bg-gradient-to-r " +
|
|
658
|
+
"from-[var(--primary)] to-[color-mix(in_oklab,var(--primary)_88%,black)] " +
|
|
659
|
+
"hover:from-[color-mix(in_oklab,var(--primary)_92%,black)] " +
|
|
660
|
+
"hover:to-[color-mix(in_oklab,var(--primary)_95%,black)] " +
|
|
661
|
+
"text-[var(--primary-foreground)] " +
|
|
662
|
+
"[--btn-ring:var(--ring)] [--btn-border:var(--primary)] border [&:where(button)]:border",
|
|
663
|
+
}}
|
|
664
|
+
/>
|
|
665
|
+
</div>
|
|
283
666
|
</div>
|
|
667
|
+
|
|
284
668
|
{/* Newsletter */}
|
|
285
669
|
<div id="newsletter" className="scroll-mt-16">
|
|
286
|
-
<
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
670
|
+
<div className="relative pt-3 sm:pt-4 mb-0">
|
|
671
|
+
<Newsletter
|
|
672
|
+
button={{
|
|
673
|
+
className:
|
|
674
|
+
"!bg-[var(--primary)] hover:!bg-[color-mix(in_oklab,var(--primary)_90%,transparent)] !text-[var(--primary-foreground)] hover:!text-[var(--primary-background)]",
|
|
675
|
+
}}
|
|
676
|
+
/>
|
|
677
|
+
</div>
|
|
292
678
|
</div>
|
|
679
|
+
|
|
293
680
|
{/* Footer */}
|
|
294
681
|
<div id="footer">
|
|
295
|
-
<
|
|
682
|
+
<div className="relative pt-3 sm:pt-4 mb-0">
|
|
683
|
+
<Footer />
|
|
684
|
+
</div>
|
|
296
685
|
</div>
|
|
297
686
|
</div>
|
|
298
687
|
</PresetThemeVars>
|