nextworks 0.2.0-alpha.2 → 0.2.0-alpha.21

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
@@ -1,90 +1,90 @@
1
- "use client";
2
-
3
- import { Pricing as SharedPricing } from "@/components/sections/Pricing";
4
- import { cn } from "@/lib/utils";
5
-
6
- const DefaultPricingData = [
7
- {
8
- pricingPlanHeaderText: "Starter Plan",
9
- pricingPlanPrice: "$29/month",
10
- pricingPlanFeatures: [
11
- "Up to 5 users",
12
- "3 projects",
13
- "Basic analytics",
14
- "email support",
15
- ],
16
- pricingPlanCTALabel: "Select Plan",
17
- pricingPlanCTAHref: "#contact",
18
- },
19
- {
20
- pricingPlanHeaderText: "Professional Plan",
21
- pricingPlanPrice: "$79.99/month",
22
- pricingPlanFeatures: [
23
- "Up to 25 users",
24
- "Unlimited projects",
25
- "Advanced analytics",
26
- "Priority support",
27
- "Api access",
28
- ],
29
- pricingPlanCTALabel: "Select Plan",
30
- pricingPlanCTAHref: "#contact",
31
- isPopular: true,
32
- },
33
- {
34
- pricingPlanHeaderText: "Enterprise Plan",
35
- pricingPlanPrice: "$199.99/month",
36
- pricingPlanFeatures: [
37
- "Unlimited users",
38
- "Custom integrations",
39
- "Dedicated account manager",
40
- "SLA guarantee",
41
- ],
42
- pricingPlanCTALabel: "Select Plan",
43
- pricingPlanCTAHref: "#contact",
44
- },
45
- ];
46
-
47
- export function Pricing() {
48
- return (
49
- <SharedPricing
50
- pricingPlans={DefaultPricingData}
51
- pricingHeadingText="Simple Pricing That Scales With You"
52
- className={cn("relative")}
53
- section={{
54
- className:
55
- "pt-20 pb-5 bg-[var(--section-bg,theme(colors.white))] dark:bg-[var(--section-bg,theme(colors.gray.900))]",
56
- }}
57
- heading={{
58
- className:
59
- "text-3xl font-bold font-inter text-center mb-8 text-[var(--heading-fg)]",
60
- }}
61
- card={{
62
- className:
63
- "relative rounded-lg transition-all duration-300 will-change-transform hover:-translate-y-1 bg-[var(--card-bg)] text-[var(--card-fg)] border-[var(--card-border)] shadow-[var(--card-shadow)]",
64
- }}
65
- title={{
66
- className:
67
- "text-xl font-bold font-inter mb-2 text-[var(--card-title-fg)]",
68
- }}
69
- price={{
70
- className:
71
- "text-2xl font-bold font-inter mb-4 text-[var(--card-title-fg)]",
72
- }}
73
- featureItem={{
74
- className:
75
- "flex items-center text-base font-inter text-[var(--card-muted-fg)]",
76
- }}
77
- cta={{
78
- variant: "default",
79
- size: "lg",
80
- className:
81
- "w-full font-semibold font-inter shadow-md hover:shadow-lg transition-all duration-200 hover:-translate-y-0.5 [--btn-bg:theme(colors.sky.600)] hover:[--btn-hover-bg:theme(colors.sky.700)] [--btn-fg:theme(colors.white)] hover:[--btn-hover-fg:theme(colors.white)] border-[var(--btn-border)] focus-visible:ring-[var(--btn-ring)]",
82
- }}
83
- popularBadge={{
84
- className:
85
- "absolute -top-3 left-1/2 -translate-x-1/2 px-4 py-1 rounded-full text-xs font-semibold bg-[var(--badge-active-bg)] text-[var(--badge-active-fg)] border-[var(--badge-active-border)]",
86
- }}
87
- ariaLabel="Pricing section"
88
- />
89
- );
90
- }
1
+ "use client";
2
+
3
+ import { Pricing as SharedPricing } from "@/components/sections/Pricing";
4
+ import { cn } from "@/lib/utils";
5
+
6
+ const DefaultPricingData = [
7
+ {
8
+ pricingPlanHeaderText: "Starter Plan",
9
+ pricingPlanPrice: "$29/month",
10
+ pricingPlanFeatures: [
11
+ "Up to 5 users",
12
+ "3 projects",
13
+ "Basic analytics",
14
+ "email support",
15
+ ],
16
+ pricingPlanCTALabel: "Select Plan",
17
+ pricingPlanCTAHref: "#contact",
18
+ },
19
+ {
20
+ pricingPlanHeaderText: "Professional Plan",
21
+ pricingPlanPrice: "$79.99/month",
22
+ pricingPlanFeatures: [
23
+ "Up to 25 users",
24
+ "Unlimited projects",
25
+ "Advanced analytics",
26
+ "Priority support",
27
+ "Api access",
28
+ ],
29
+ pricingPlanCTALabel: "Select Plan",
30
+ pricingPlanCTAHref: "#contact",
31
+ isPopular: true,
32
+ },
33
+ {
34
+ pricingPlanHeaderText: "Enterprise Plan",
35
+ pricingPlanPrice: "$199.99/month",
36
+ pricingPlanFeatures: [
37
+ "Unlimited users",
38
+ "Custom integrations",
39
+ "Dedicated account manager",
40
+ "SLA guarantee",
41
+ ],
42
+ pricingPlanCTALabel: "Select Plan",
43
+ pricingPlanCTAHref: "#contact",
44
+ },
45
+ ];
46
+
47
+ export function Pricing() {
48
+ return (
49
+ <SharedPricing
50
+ pricingPlans={DefaultPricingData}
51
+ pricingHeadingText="Simple Pricing That Scales With You"
52
+ className={cn("relative")}
53
+ section={{
54
+ className:
55
+ "pt-20 pb-5 bg-[var(--section-bg,theme(colors.white))] dark:bg-[var(--section-bg,theme(colors.gray.900))]",
56
+ }}
57
+ heading={{
58
+ className:
59
+ "text-3xl font-bold font-inter text-center mb-8 text-[var(--heading-fg)]",
60
+ }}
61
+ card={{
62
+ className:
63
+ "relative rounded-lg transition-all duration-300 will-change-transform hover:-translate-y-1 bg-[var(--card-bg)] text-[var(--card-fg)] border-[var(--card-border)] shadow-[var(--card-shadow)]",
64
+ }}
65
+ title={{
66
+ className:
67
+ "text-xl font-bold font-inter mb-2 text-[var(--card-title-fg)]",
68
+ }}
69
+ price={{
70
+ className:
71
+ "text-2xl font-bold font-inter mb-4 text-[var(--card-title-fg)]",
72
+ }}
73
+ featureItem={{
74
+ className:
75
+ "flex items-center text-base font-inter text-[var(--card-muted-fg)]",
76
+ }}
77
+ cta={{
78
+ variant: "default",
79
+ size: "lg",
80
+ className:
81
+ "w-full font-semibold font-inter shadow-md hover:shadow-lg transition-all duration-200 hover:-translate-y-0.5 [--btn-bg:theme(colors.sky.600)] hover:[--btn-hover-bg:theme(colors.sky.700)] [--btn-fg:theme(colors.white)] hover:[--btn-hover-fg:theme(colors.white)] border-[var(--btn-border)] focus-visible:ring-[var(--btn-ring)]",
82
+ }}
83
+ popularBadge={{
84
+ className:
85
+ "absolute -top-3 left-1/2 -translate-x-1/2 px-4 py-1 rounded-full text-xs font-semibold bg-[var(--badge-active-bg)] text-[var(--badge-active-fg)] border-[var(--badge-active-border)]",
86
+ }}
87
+ ariaLabel="Pricing section"
88
+ />
89
+ );
90
+ }
@@ -1,97 +1,96 @@
1
- "use client";
2
-
3
- import { useEffect } from "react";
4
-
5
- // Smoothly scrolls to hash targets with a custom, faster duration (~300ms)
6
- export function SmoothScroll() {
7
- useEffect(() => {
8
- let suppressClick = false;
9
-
10
- const animateTo = (href: string) => {
11
- const el = document.querySelector(href) as HTMLElement | null;
12
- if (!el) return;
13
-
14
- const navbarOffsetPx = 64; // matches h-16 sticky navbar
15
- const start = window.scrollY;
16
- const targetTop =
17
- el.getBoundingClientRect().top + window.scrollY - navbarOffsetPx;
18
- const distance = targetTop - start;
19
- const duration = 300; // ms
20
- const startTime = performance.now();
21
-
22
- // iOS-like easing
23
- const easeOutQuart = (t: number) => 1 - Math.pow(1 - t, 4);
24
-
25
- const step = (now: number) => {
26
- const elapsed = now - startTime;
27
- const t = Math.min(1, elapsed / duration);
28
- const eased = easeOutQuart(t);
29
- window.scrollTo(0, start + distance * eased);
30
- if (t < 1) requestAnimationFrame(step);
31
- else history.replaceState(null, "", href);
32
- };
33
-
34
- requestAnimationFrame(step);
35
- };
36
-
37
- const onPointerDown = (e: Event) => {
38
- const ev = e as PointerEvent;
39
- const target = e.currentTarget as HTMLAnchorElement;
40
- const href = target.getAttribute("href");
41
- if (!href || !href.startsWith("#")) return;
42
- // Only primary button, no modifiers
43
- if (
44
- ev.button !== 0 ||
45
- ev.metaKey ||
46
- ev.ctrlKey ||
47
- ev.altKey ||
48
- ev.shiftKey
49
- )
50
- return;
51
- e.preventDefault();
52
- suppressClick = true;
53
- animateTo(href);
54
- };
55
-
56
- const onClick = (e: Event) => {
57
- const target = e.currentTarget as HTMLAnchorElement;
58
- const href = target.getAttribute("href");
59
- if (!href || !href.startsWith("#")) return;
60
- if (suppressClick) {
61
- e.preventDefault();
62
- suppressClick = false;
63
- return;
64
- }
65
- e.preventDefault();
66
- animateTo(href);
67
- };
68
-
69
- const onKeyDown = (e: Event) => {
70
- const ev = e as KeyboardEvent;
71
- if (ev.key !== "Enter" && ev.key !== " ") return;
72
- const target = e.currentTarget as HTMLAnchorElement;
73
- const href = target.getAttribute("href");
74
- if (!href || !href.startsWith("#")) return;
75
- e.preventDefault();
76
- animateTo(href);
77
- };
78
-
79
- const links = Array.from(
80
- document.querySelectorAll('a[href^="#"]'),
81
- ) as HTMLAnchorElement[];
82
- links.forEach((a) => {
83
- a.addEventListener("pointerdown", onPointerDown);
84
- a.addEventListener("click", onClick);
85
- a.addEventListener("keydown", onKeyDown);
86
- });
87
- return () => {
88
- links.forEach((a) => {
89
- a.removeEventListener("pointerdown", onPointerDown);
90
- a.removeEventListener("click", onClick);
91
- a.removeEventListener("keydown", onKeyDown);
92
- });
93
- };
94
- }, []);
95
-
96
- return null;
97
- }
1
+ "use client";
2
+
3
+ import { useEffect } from "react";
4
+
5
+ // Smoothly scrolls to section links with a faster duration
6
+ export function SmoothScroll() {
7
+ useEffect(() => {
8
+ let suppressClick = false;
9
+
10
+ const animateTo = (href: string) => {
11
+ const el = document.querySelector(href) as HTMLElement | null;
12
+ if (!el) return;
13
+
14
+ const navbarOffsetPx = 64;
15
+ const start = window.scrollY;
16
+ const targetTop =
17
+ el.getBoundingClientRect().top + window.scrollY - navbarOffsetPx;
18
+ const distance = targetTop - start;
19
+ const duration = 300; // ms
20
+ const startTime = performance.now();
21
+
22
+ const easeOutQuart = (t: number) => 1 - Math.pow(1 - t, 4);
23
+
24
+ const step = (now: number) => {
25
+ const elapsed = now - startTime;
26
+ const t = Math.min(1, elapsed / duration);
27
+ const eased = easeOutQuart(t);
28
+ window.scrollTo(0, start + distance * eased);
29
+ if (t < 1) requestAnimationFrame(step);
30
+ else history.replaceState(null, "", href);
31
+ };
32
+
33
+ requestAnimationFrame(step);
34
+ };
35
+
36
+ const onPointerDown = (e: Event) => {
37
+ const ev = e as PointerEvent;
38
+ const target = e.currentTarget as HTMLAnchorElement;
39
+ const href = target.getAttribute("href");
40
+ if (!href || !href.startsWith("#")) return;
41
+
42
+ if (
43
+ ev.button !== 0 ||
44
+ ev.metaKey ||
45
+ ev.ctrlKey ||
46
+ ev.altKey ||
47
+ ev.shiftKey
48
+ )
49
+ return;
50
+ e.preventDefault();
51
+ suppressClick = true;
52
+ animateTo(href);
53
+ };
54
+
55
+ const onClick = (e: Event) => {
56
+ const target = e.currentTarget as HTMLAnchorElement;
57
+ const href = target.getAttribute("href");
58
+ if (!href || !href.startsWith("#")) return;
59
+ if (suppressClick) {
60
+ e.preventDefault();
61
+ suppressClick = false;
62
+ return;
63
+ }
64
+ e.preventDefault();
65
+ animateTo(href);
66
+ };
67
+
68
+ const onKeyDown = (e: Event) => {
69
+ const ev = e as KeyboardEvent;
70
+ if (ev.key !== "Enter" && ev.key !== " ") return;
71
+ const target = e.currentTarget as HTMLAnchorElement;
72
+ const href = target.getAttribute("href");
73
+ if (!href || !href.startsWith("#")) return;
74
+ e.preventDefault();
75
+ animateTo(href);
76
+ };
77
+
78
+ const links = Array.from(
79
+ document.querySelectorAll('a[href^="#"]'),
80
+ ) as HTMLAnchorElement[];
81
+ links.forEach((a) => {
82
+ a.addEventListener("pointerdown", onPointerDown);
83
+ a.addEventListener("click", onClick);
84
+ a.addEventListener("keydown", onKeyDown);
85
+ });
86
+ return () => {
87
+ links.forEach((a) => {
88
+ a.removeEventListener("pointerdown", onPointerDown);
89
+ a.removeEventListener("click", onClick);
90
+ a.removeEventListener("keydown", onKeyDown);
91
+ });
92
+ };
93
+ }, []);
94
+
95
+ return null;
96
+ }
@@ -1,72 +1,72 @@
1
- "use client";
2
-
3
- import { Testimonials as SharedTestimonials } from "@/components/sections/Testimonials";
4
- import { cn } from "@/lib/utils";
5
-
6
- export function Testimonials() {
7
- return (
8
- <div className="relative">
9
- {/* Gradient mesh + fine noise overlays for depth */}
10
- <div
11
- aria-hidden
12
- className="pointer-events-none absolute inset-0 -z-10 [background-image:radial-gradient(60rem_60rem_at_0%_0%,rgba(59,130,246,0.08),transparent_40%),radial-gradient(50rem_50rem_at_100%_100%,rgba(168,85,247,0.06),transparent_40%)] opacity-20"
13
- />
14
- <div
15
- aria-hidden
16
- className="pointer-events-none absolute inset-0 -z-10 [background-image:radial-gradient(rgba(255,255,255,0.07)_1px,transparent_1px)] [background-size:14px_14px] opacity-[0.05]"
17
- />
18
- <SharedTestimonials
19
- testimonials={[
20
- {
21
- testimonialText:
22
- "DashFlow replaced 6 different tools for us. Our team productivity increased 40% in the first month.",
23
- testimonialAuthor: "- Sarah Chen, Marketing Director at TechStart",
24
- testimonialAuthorInitials: "SC",
25
- },
26
- {
27
- testimonialText:
28
- "Finally, a dashboard that actually makes sense. Setup took 10 minutes, not 10 hours.",
29
- testimonialAuthor: "- Mike Rodriguez, Operations Manager",
30
- testimonialAuthorInitials: "MR",
31
- },
32
- {
33
- testimonialText:
34
- "The analytics alone pay for the subscription. We spot trends weeks earlier now.",
35
- testimonialAuthor: "- Lisa Park, CEO of GrowthCo",
36
- testimonialAuthorInitials: "LP",
37
- },
38
- ]}
39
- testimonialSectionHeader="What Our Customers Say"
40
- className={cn("relative")}
41
- section={{ className: "py-16 px-6 bg-background" }}
42
- container={{ className: "max-w-7xl mx-auto" }}
43
- header={{ className: "text-center mb-12" }}
44
- heading={{
45
- className:
46
- "text-3xl md:text-4xl font-bold font-inter text-[var(--heading-fg)]",
47
- }}
48
- grid={{
49
- className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8",
50
- }}
51
- card={{
52
- className:
53
- "p-6 rounded-lg transition-transform duration-200 hover:-translate-y-1 bg-[var(--card-bg)] text-[var(--card-fg)] border-[var(--card-border)] shadow-[var(--card-shadow)]",
54
- }}
55
- text={{
56
- className:
57
- "italic font-inter font-normal text-base text-[var(--card-fg)]",
58
- }}
59
- author={{
60
- className:
61
- "text-sm font-medium font-inter text-[var(--card-muted-fg)]",
62
- }}
63
- avatar={{
64
- className:
65
- "w-12 h-12 rounded-full flex items-center justify-center text-lg font-bold bg-[var(--badge-bg)] text-[var(--badge-fg)] border-[var(--badge-border)]",
66
- }}
67
- avatarText={{ className: "font-bold" }}
68
- ariaLabel="Customer testimonials"
69
- />
70
- </div>
71
- );
72
- }
1
+ "use client";
2
+
3
+ import { Testimonials as SharedTestimonials } from "@/components/sections/Testimonials";
4
+ import { cn } from "@/lib/utils";
5
+
6
+ export function Testimonials() {
7
+ return (
8
+ <div className="relative">
9
+ {/* Gradient mesh and fine noise overlays for depth */}
10
+ <div
11
+ aria-hidden
12
+ className="pointer-events-none absolute inset-0 -z-10 [background-image:radial-gradient(60rem_60rem_at_0%_0%,rgba(59,130,246,0.08),transparent_40%),radial-gradient(50rem_50rem_at_100%_100%,rgba(168,85,247,0.06),transparent_40%)] opacity-20"
13
+ />
14
+ <div
15
+ aria-hidden
16
+ className="pointer-events-none absolute inset-0 -z-10 [background-image:radial-gradient(rgba(255,255,255,0.07)_1px,transparent_1px)] [background-size:14px_14px] opacity-[0.05]"
17
+ />
18
+ <SharedTestimonials
19
+ testimonials={[
20
+ {
21
+ testimonialText:
22
+ "DashFlow replaced 6 different tools for us. Our team productivity increased 40% in the first month.",
23
+ testimonialAuthor: "- Sarah Chen, Marketing Director at TechStart",
24
+ testimonialAuthorInitials: "SC",
25
+ },
26
+ {
27
+ testimonialText:
28
+ "Finally, a dashboard that actually makes sense. Setup took 10 minutes, not 10 hours.",
29
+ testimonialAuthor: "- Mike Rodriguez, Operations Manager",
30
+ testimonialAuthorInitials: "MR",
31
+ },
32
+ {
33
+ testimonialText:
34
+ "The analytics alone pay for the subscription. We spot trends weeks earlier now.",
35
+ testimonialAuthor: "- Lisa Park, CEO of GrowthCo",
36
+ testimonialAuthorInitials: "LP",
37
+ },
38
+ ]}
39
+ testimonialSectionHeader="What Our Customers Say"
40
+ className={cn("relative")}
41
+ section={{ className: "py-16 px-6 bg-background" }}
42
+ container={{ className: "max-w-7xl mx-auto" }}
43
+ header={{ className: "text-center mb-12" }}
44
+ heading={{
45
+ className:
46
+ "text-3xl md:text-4xl font-bold font-inter text-[var(--heading-fg)]",
47
+ }}
48
+ grid={{
49
+ className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8",
50
+ }}
51
+ card={{
52
+ className:
53
+ "p-6 rounded-lg transition-transform duration-200 hover:-translate-y-1 bg-[var(--card-bg)] text-[var(--card-fg)] border-[var(--card-border)] shadow-[var(--card-shadow)]",
54
+ }}
55
+ text={{
56
+ className:
57
+ "italic font-inter font-normal text-base text-[var(--card-fg)]",
58
+ }}
59
+ author={{
60
+ className:
61
+ "text-sm font-medium font-inter text-[var(--card-muted-fg)]",
62
+ }}
63
+ avatar={{
64
+ className:
65
+ "w-12 h-12 rounded-full flex items-center justify-center text-lg font-bold bg-[var(--badge-bg)] text-[var(--badge-fg)] border-[var(--badge-border)]",
66
+ }}
67
+ avatarText={{ className: "font-bold" }}
68
+ ariaLabel="Customer testimonials"
69
+ />
70
+ </div>
71
+ );
72
+ }
@@ -1,53 +1,53 @@
1
- "use client";
2
-
3
- import { TrustBadges as SharedTrustBadges } from "@/components/sections/TrustBadges";
4
- import { cn } from "@/lib/utils";
5
-
6
- const defaultBadgesInfo = [
7
- {
8
- badgeText: "10,000+ businesses",
9
- badgeDescription: "Trusted by",
10
- badgeIcon: "📊",
11
- },
12
- {
13
- badgeText: "SOC 2 Compliant",
14
- badgeDescription: "Enterprise security",
15
- badgeIcon: "🔒",
16
- },
17
- {
18
- badgeText: "99.9% Uptime",
19
- badgeDescription: "Reliable service",
20
- badgeIcon: "⚡",
21
- },
22
- {
23
- badgeText: "4.9/5 Rating",
24
- badgeDescription: "Customer satisfaction",
25
- badgeIcon: "⭐",
26
- },
27
- ];
28
-
29
- export function TrustBadges() {
30
- return (
31
- <SharedTrustBadges
32
- badges={defaultBadgesInfo}
33
- className={cn("relative")}
34
- section={{ className: "py-8 px-6 bg-blue-950/10 dark:bg-blue-950" }}
35
- heading={{
36
- className:
37
- "text-2xl font-bold font-inter text-gray-700 dark:text-gray-200",
38
- }}
39
- badgesContainer={{
40
- className: "flex flex-wrap items-center justify-center gap-8",
41
- }}
42
- badge={{
43
- className:
44
- "transition-all duration-200 grayscale hover:grayscale-0 hover:-translate-y-0.5",
45
- }}
46
- text={{
47
- className:
48
- "text-base font-medium font-inter text-gray-900 dark:text-white",
49
- }}
50
- ariaLabel="Trust badges section"
51
- />
52
- );
53
- }
1
+ "use client";
2
+
3
+ import { TrustBadges as SharedTrustBadges } from "@/components/sections/TrustBadges";
4
+ import { cn } from "@/lib/utils";
5
+
6
+ const defaultBadgesInfo = [
7
+ {
8
+ badgeText: "10,000+ businesses",
9
+ badgeDescription: "Trusted by",
10
+ badgeIcon: "📊",
11
+ },
12
+ {
13
+ badgeText: "SOC 2 Compliant",
14
+ badgeDescription: "Enterprise security",
15
+ badgeIcon: "🔒",
16
+ },
17
+ {
18
+ badgeText: "99.9% Uptime",
19
+ badgeDescription: "Reliable service",
20
+ badgeIcon: "⚡",
21
+ },
22
+ {
23
+ badgeText: "4.9/5 Rating",
24
+ badgeDescription: "Customer satisfaction",
25
+ badgeIcon: "⭐",
26
+ },
27
+ ];
28
+
29
+ export function TrustBadges() {
30
+ return (
31
+ <SharedTrustBadges
32
+ badges={defaultBadgesInfo}
33
+ className={cn("relative")}
34
+ section={{ className: "py-8 px-6 bg-blue-950/10 dark:bg-blue-950" }}
35
+ heading={{
36
+ className:
37
+ "text-2xl font-bold font-inter text-gray-700 dark:text-gray-200",
38
+ }}
39
+ badgesContainer={{
40
+ className: "flex flex-wrap items-center justify-center gap-8",
41
+ }}
42
+ badge={{
43
+ className:
44
+ "transition-all duration-200 grayscale hover:grayscale-0 hover:-translate-y-0.5",
45
+ }}
46
+ text={{
47
+ className:
48
+ "text-base font-medium font-inter text-gray-900 dark:text-white",
49
+ }}
50
+ ariaLabel="Trust badges section"
51
+ />
52
+ );
53
+ }