blocks-dusted 0.1.9 → 0.1.11

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 (248) hide show
  1. package/README.md +35 -0
  2. package/package.json +1 -1
  3. package/src/utils/paths.js +13 -13
  4. package/templates/blocks/DD-Accordion/Component.tsx +229 -0
  5. package/templates/blocks/DD-Accordion/README.md +3 -0
  6. package/templates/blocks/DD-Accordion/config.ts +73 -0
  7. package/templates/blocks/DD-Accordion/manifest.json +75 -0
  8. package/templates/blocks/DD-AnimText/Component.tsx +788 -0
  9. package/templates/blocks/DD-AnimText/README.md +3 -0
  10. package/templates/blocks/DD-AnimText/config.ts +295 -0
  11. package/templates/blocks/DD-AnimText/manifest.json +85 -0
  12. package/templates/blocks/DD-AsideNav/Component.tsx +321 -0
  13. package/templates/blocks/DD-AsideNav/config.ts +204 -0
  14. package/templates/blocks/DD-AsideNav/manifest.json +80 -0
  15. package/templates/blocks/DD-Banner/Component.tsx +51 -0
  16. package/templates/blocks/DD-Banner/config.ts +57 -0
  17. package/templates/blocks/DD-Banner/manifest.json +72 -0
  18. package/templates/blocks/DD-BgLightning/Component.tsx +44 -0
  19. package/templates/blocks/DD-BgLightning/README.md +3 -0
  20. package/templates/blocks/DD-BgLightning/config.ts +97 -0
  21. package/templates/blocks/DD-BgLightning/manifest.json +79 -0
  22. package/templates/blocks/DD-BookCall/Component.tsx +10 -11
  23. package/templates/blocks/DD-BookCall/config.ts +238 -238
  24. package/templates/blocks/DD-ButtonPop/Component.tsx +117 -0
  25. package/templates/blocks/DD-ButtonPop/config.ts +105 -0
  26. package/templates/blocks/DD-ButtonPop/manifest.json +88 -0
  27. package/templates/blocks/DD-ButtonPop/svg-icons/Dust2.tsx +167 -0
  28. package/templates/blocks/DD-Card/Component.tsx +251 -0
  29. package/templates/blocks/DD-Card/README.md +4 -0
  30. package/templates/blocks/DD-Card/config.ts +154 -0
  31. package/templates/blocks/DD-Card/manifest.json +82 -0
  32. package/templates/blocks/DD-CardTemplate01/Component.tsx +5 -6
  33. package/templates/blocks/DD-CardTemplate01/config.ts +106 -106
  34. package/templates/blocks/DD-Carousel-A/Component.tsx +249 -249
  35. package/templates/blocks/DD-Carousel-B/Component.tsx +403 -403
  36. package/templates/blocks/DD-Chip/Component.tsx +250 -0
  37. package/templates/blocks/DD-Chip/EXAMPLES.md +313 -0
  38. package/templates/blocks/DD-Chip/README.md +202 -0
  39. package/templates/blocks/DD-Chip/config.ts +369 -0
  40. package/templates/blocks/DD-Chip/manifest.json +74 -0
  41. package/templates/blocks/DD-ComparisonTable/Component.tsx +256 -256
  42. package/templates/blocks/DD-Contact/Component.tsx +434 -434
  43. package/templates/blocks/DD-Contact/config.ts +22 -22
  44. package/templates/blocks/DD-Counter/Component.tsx +190 -0
  45. package/templates/blocks/DD-Counter/README.md +4 -0
  46. package/templates/blocks/DD-Counter/config.ts +291 -0
  47. package/templates/blocks/DD-Counter/manifest.json +74 -0
  48. package/templates/blocks/DD-CustomCSS/Component.tsx +8 -0
  49. package/templates/blocks/DD-CustomCSS/README.md +4 -0
  50. package/templates/blocks/DD-CustomCSS/addToLayout.md +5 -0
  51. package/templates/blocks/DD-CustomCSS/config.ts +22 -0
  52. package/templates/blocks/DD-CustomCSS/manifest.json +72 -0
  53. package/templates/blocks/DD-CustomCSS/renderCustomCSS.md +7 -0
  54. package/templates/blocks/DD-FeatCat/Component.tsx +302 -302
  55. package/templates/blocks/DD-FeatCat/config.ts +201 -201
  56. package/templates/blocks/DD-FeatStrip/Component.tsx +585 -585
  57. package/templates/blocks/DD-FeatStrip/config.ts +134 -134
  58. package/templates/blocks/DD-FluidBtn/ButtonsEyeCatching.tsx +628 -0
  59. package/templates/blocks/DD-FluidBtn/Component.tsx +43 -0
  60. package/templates/blocks/DD-FluidBtn/README.md +6 -0
  61. package/templates/blocks/DD-FluidBtn/config.ts +102 -0
  62. package/templates/blocks/DD-FluidBtn/manifest.json +86 -0
  63. package/templates/blocks/DD-GooeyInfo/Component.tsx +149 -0
  64. package/templates/blocks/DD-GooeyInfo/config.ts +135 -0
  65. package/templates/blocks/DD-GooeyInfo/manifest.json +72 -0
  66. package/templates/blocks/DD-Hero/Component.tsx +40 -17
  67. package/templates/blocks/DD-Hero/config.ts +267 -267
  68. package/templates/blocks/DD-HorizontalScroll/Component.tsx +4 -2
  69. package/templates/blocks/DD-HorizontalScroll/config.ts +231 -231
  70. package/templates/blocks/DD-Icon/Component.tsx +287 -0
  71. package/templates/blocks/DD-Icon/README.md +4 -0
  72. package/templates/blocks/DD-Icon/config.ts +258 -0
  73. package/templates/blocks/DD-Icon/hooks/revalidateBlockIds.ts +66 -0
  74. package/templates/blocks/DD-Icon/manifest.json +82 -0
  75. package/templates/blocks/DD-IconButton/Component.tsx +455 -0
  76. package/templates/blocks/DD-IconButton/README.md +326 -0
  77. package/templates/blocks/DD-IconButton/config.ts +239 -0
  78. package/templates/blocks/DD-IconButton/manifest.json +85 -0
  79. package/templates/blocks/DD-IdTag/Component.tsx +21 -0
  80. package/templates/blocks/DD-IdTag/README.md +4 -0
  81. package/templates/blocks/DD-IdTag/config.ts +41 -0
  82. package/templates/blocks/DD-IdTag/manifest.json +72 -0
  83. package/templates/blocks/DD-Iframe/Component.tsx +45 -0
  84. package/templates/blocks/DD-Iframe/README.md +4 -0
  85. package/templates/blocks/DD-Iframe/config.ts +47 -0
  86. package/templates/blocks/DD-Iframe/manifest.json +72 -0
  87. package/templates/blocks/DD-IframeMedia/Component.tsx +129 -0
  88. package/templates/blocks/DD-IframeMedia/README.md +4 -0
  89. package/templates/blocks/DD-IframeMedia/config.ts +79 -0
  90. package/templates/blocks/DD-IframeMedia/manifest.json +72 -0
  91. package/templates/blocks/DD-LineAnim/Component.tsx +36 -0
  92. package/templates/blocks/DD-LineAnim/README.md +4 -0
  93. package/templates/blocks/DD-LineAnim/config.ts +90 -0
  94. package/templates/blocks/DD-LineAnim/manifest.json +80 -0
  95. package/templates/blocks/DD-LinkGrid/Component.tsx +119 -0
  96. package/templates/blocks/DD-LinkGrid/README.md +4 -0
  97. package/templates/blocks/DD-LinkGrid/config.ts +51 -0
  98. package/templates/blocks/DD-LinkGrid/manifest.json +74 -0
  99. package/templates/blocks/DD-LogoMarq/Component.tsx +132 -0
  100. package/templates/blocks/DD-LogoMarq/README.md +4 -0
  101. package/templates/blocks/DD-LogoMarq/config.ts +264 -0
  102. package/templates/blocks/DD-LogoMarq/manifest.json +82 -0
  103. package/templates/blocks/DD-Lottie/Component.tsx +459 -0
  104. package/templates/blocks/DD-Lottie/README.md +4 -0
  105. package/templates/blocks/DD-Lottie/config.ts +379 -0
  106. package/templates/blocks/DD-Lottie/index.tsx +28 -0
  107. package/templates/blocks/DD-Lottie/manifest.json +83 -0
  108. package/templates/blocks/DD-MagicBento/Component.tsx +777 -0
  109. package/templates/blocks/DD-MagicBento/README.md +4 -0
  110. package/templates/blocks/DD-MagicBento/config.ts +264 -0
  111. package/templates/blocks/DD-MagicBento/manifest.json +74 -0
  112. package/templates/blocks/DD-MasonaryMedia/Component.tsx +547 -545
  113. package/templates/blocks/DD-MasonaryMedia/config.ts +2 -2
  114. package/templates/blocks/DD-MasonaryMedia/vendor.d.ts +2 -2
  115. package/templates/blocks/DD-Masonry/Component.tsx +645 -0
  116. package/templates/blocks/DD-Masonry/README.md +4 -0
  117. package/templates/blocks/DD-Masonry/config.ts +475 -0
  118. package/templates/blocks/DD-Masonry/manifest.json +82 -0
  119. package/templates/blocks/DD-Pricing/Component.tsx +372 -372
  120. package/templates/blocks/DD-Process/Component.tsx +149 -149
  121. package/templates/blocks/DD-Process/config.ts +150 -150
  122. package/templates/blocks/DD-Progress/Component.tsx +141 -0
  123. package/templates/blocks/DD-Progress/README.md +4 -0
  124. package/templates/blocks/DD-Progress/config.ts +175 -0
  125. package/templates/blocks/DD-Progress/manifest.json +74 -0
  126. package/templates/blocks/DD-ProjHeader/Component.tsx +91 -0
  127. package/templates/blocks/DD-ProjHeader/README.md +4 -0
  128. package/templates/blocks/DD-ProjHeader/config.ts +96 -0
  129. package/templates/blocks/DD-ProjHeader/manifest.json +72 -0
  130. package/templates/blocks/DD-ProjSlider/Component.tsx +123 -0
  131. package/templates/blocks/DD-ProjSlider/README.md +4 -0
  132. package/templates/blocks/DD-ProjSlider/config.ts +64 -0
  133. package/templates/blocks/DD-ProjSlider/manifest.json +72 -0
  134. package/templates/blocks/DD-ScrollText/Component.tsx +114 -0
  135. package/templates/blocks/DD-ScrollText/README.md +4 -0
  136. package/templates/blocks/DD-ScrollText/config.ts +58 -0
  137. package/templates/blocks/DD-ScrollText/manifest.json +72 -0
  138. package/templates/blocks/DD-Section/Component.tsx +266 -266
  139. package/templates/blocks/DD-Separator/Component.tsx +66 -0
  140. package/templates/blocks/DD-Separator/README.md +4 -0
  141. package/templates/blocks/DD-Separator/config.ts +58 -0
  142. package/templates/blocks/DD-Separator/manifest.json +72 -0
  143. package/templates/blocks/DD-Services/Component.tsx +176 -176
  144. package/templates/blocks/DD-Services/config.ts +149 -149
  145. package/templates/blocks/DD-ShowcaseGrid/Component.tsx +307 -307
  146. package/templates/blocks/DD-Slider-A/Component.tsx +237 -237
  147. package/templates/blocks/DD-StackCards/Component.tsx +473 -473
  148. package/templates/blocks/DD-StackCards/config.ts +399 -399
  149. package/templates/blocks/DD-Team/Component.tsx +247 -247
  150. package/templates/blocks/DD-Team/config.ts +173 -173
  151. package/templates/blocks/DD-TeamCards/Component.tsx +251 -0
  152. package/templates/blocks/DD-TeamCards/README.md +4 -0
  153. package/templates/blocks/DD-TeamCards/config.ts +302 -0
  154. package/templates/blocks/DD-TeamCards/manifest.json +74 -0
  155. package/templates/blocks/DD-TechStack/Component.tsx +168 -162
  156. package/templates/blocks/DD-TechStack/config.ts +153 -153
  157. package/templates/blocks/DD-TestMarq/Component.tsx +132 -0
  158. package/templates/blocks/DD-TestMarq/README.md +4 -0
  159. package/templates/blocks/DD-TestMarq/RowLabel.tsx +9 -0
  160. package/templates/blocks/DD-TestMarq/config.ts +88 -0
  161. package/templates/blocks/DD-TestMarq/manifest.json +72 -0
  162. package/templates/blocks/DD-Testim/Component.tsx +247 -0
  163. package/templates/blocks/DD-Testim/README.md +4 -0
  164. package/templates/blocks/DD-Testim/config.ts +101 -0
  165. package/templates/blocks/DD-Testim/manifest.json +75 -0
  166. package/templates/blocks/DD-Testim2/Component.tsx +256 -0
  167. package/templates/blocks/DD-Testim2/README.md +4 -0
  168. package/templates/blocks/DD-Testim2/config.ts +100 -0
  169. package/templates/blocks/DD-Testim2/manifest.json +74 -0
  170. package/templates/blocks/DD-Testimonials/Component.tsx +147 -147
  171. package/templates/blocks/DD-Testimonials/config.ts +120 -120
  172. package/templates/blocks/DD-TextMarq/Component.tsx +157 -0
  173. package/templates/blocks/DD-TextMarq/README.md +4 -0
  174. package/templates/blocks/DD-TextMarq/config.ts +237 -0
  175. package/templates/blocks/DD-TextMarq/manifest.json +82 -0
  176. package/templates/blocks/DD-Thanks/Component.tsx +500 -0
  177. package/templates/blocks/DD-Thanks/README.md +4 -0
  178. package/templates/blocks/DD-Thanks/config.ts +224 -0
  179. package/templates/blocks/DD-Thanks/manifest.json +72 -0
  180. package/templates/blocks/DD-VertMarq/Component.tsx +154 -0
  181. package/templates/blocks/DD-VertMarq/README.md +4 -0
  182. package/templates/blocks/DD-VertMarq/config.ts +236 -0
  183. package/templates/blocks/DD-VertMarq/dist/index.css +6 -0
  184. package/templates/blocks/DD-VertMarq/dist/index.min.css +1 -0
  185. package/templates/blocks/DD-VertMarq/manifest.json +74 -0
  186. package/templates/blocks/DD-Work/Component.tsx +318 -315
  187. package/templates/blocks/DD-Work/config.ts +165 -165
  188. package/templates/blocks/DD-Work-B/Component.tsx +294 -294
  189. package/templates/blocks/DDHG-CTASection2/Component.tsx +185 -0
  190. package/templates/blocks/DDHG-CTASection2/config.ts +140 -0
  191. package/templates/blocks/DDHG-CTASection2/manifest.json +45 -0
  192. package/templates/blocks/DDHG-HighlightArc/Component.tsx +243 -0
  193. package/templates/blocks/DDHG-HighlightArc/config.ts +85 -0
  194. package/templates/blocks/DDHG-HighlightArc/manifest.json +46 -0
  195. package/templates/blocks/DDHG-LogoMarquee/Component.tsx +93 -0
  196. package/templates/blocks/DDHG-LogoMarquee/config.ts +66 -0
  197. package/templates/blocks/DDHG-LogoMarquee/manifest.json +39 -0
  198. package/templates/blocks/DDHG-NavCodeGrid/Component.tsx +213 -0
  199. package/templates/blocks/DDHG-NavCodeGrid/config.ts +64 -0
  200. package/templates/blocks/DDHG-NavCodeGrid/manifest.json +45 -0
  201. package/templates/blocks/DDHG-ProcessSec/Component.tsx +575 -0
  202. package/templates/blocks/DDHG-ProcessSec/config.ts +170 -0
  203. package/templates/blocks/DDHG-ProcessSec/manifest.json +56 -0
  204. package/templates/blocks/DDHG-ServiceDetails/Component.tsx +164 -0
  205. package/templates/blocks/DDHG-ServiceDetails/ServiceDetailCard.tsx +394 -0
  206. package/templates/blocks/DDHG-ServiceDetails/config.ts +77 -0
  207. package/templates/blocks/DDHG-ServiceDetails/manifest.json +50 -0
  208. package/templates/blocks/DDHG-ServiceHero/Component.tsx +234 -0
  209. package/templates/blocks/DDHG-ServiceHero/config.ts +49 -0
  210. package/templates/blocks/DDHG-ServiceHero/manifest.json +26 -0
  211. package/templates/blocks/DDHG-ServiceOverview/Component.tsx +277 -0
  212. package/templates/blocks/DDHG-ServiceOverview/config.ts +64 -0
  213. package/templates/blocks/DDHG-ServiceOverview/manifest.json +44 -0
  214. package/templates/blocks/DDHG-StatsFAQ/Component.tsx +389 -0
  215. package/templates/blocks/DDHG-StatsFAQ/config.ts +204 -0
  216. package/templates/blocks/DDHG-StatsFAQ/manifest.json +45 -0
  217. package/templates/blocks/DDHG-TeamCards/Component.tsx +131 -0
  218. package/templates/blocks/DDHG-TeamCards/config.ts +48 -0
  219. package/templates/blocks/DDHG-TeamCards/manifest.json +29 -0
  220. package/templates/components/HeaderDD02/MobileBottomNav/index.tsx +352 -257
  221. package/templates/components/HeaderDD02/index.tsx +313 -229
  222. package/templates/shared/src/components/BgLightning/index.tsx +242 -0
  223. package/templates/shared/src/components/ui/ShareButton/index.tsx +80 -0
  224. package/templates/shared/src/components/ui/anims/FadeOnScroll.tsx +48 -0
  225. package/templates/shared/src/components/ui/anims/FadeUpOnInView.tsx +63 -0
  226. package/templates/shared/src/components/ui/anims/GlareHover.tsx +111 -0
  227. package/templates/shared/src/components/ui/anims/LineAnims.tsx +81 -0
  228. package/templates/shared/src/components/ui/anims/TitleAnims01.tsx +54 -0
  229. package/templates/shared/src/components/ui/anims/animation-container.tsx +29 -0
  230. package/templates/shared/src/components/ui/anims/blur-in.tsx +26 -0
  231. package/templates/shared/src/components/ui/anims/counter.tsx +53 -0
  232. package/templates/shared/src/components/ui/anims/fade.tsx +83 -0
  233. package/templates/shared/src/components/ui/anims/gradual-spacing.tsx +39 -0
  234. package/templates/shared/src/components/ui/anims/pull-up.tsx +93 -0
  235. package/templates/shared/src/components/ui/anims/reveal-text.tsx +76 -0
  236. package/templates/shared/src/components/ui/anims/rotate-words.tsx +43 -0
  237. package/templates/shared/src/components/ui/anims/shiny-text.tsx +58 -0
  238. package/templates/shared/src/components/ui/anims/shuffle-text.tsx +85 -0
  239. package/templates/shared/src/components/ui/anims/split-text.tsx +211 -0
  240. package/templates/shared/src/components/ui/anims/staggered-fade.tsx +133 -0
  241. package/templates/shared/src/components/ui/anims/text-scroll.tsx +111 -0
  242. package/templates/shared/src/components/ui/anims/typing-effect.tsx +112 -0
  243. package/templates/shared/src/components/ui/button-dusted-fluid/index.tsx +1521 -0
  244. package/templates/shared/src/components/ui/separator.tsx +85 -0
  245. package/templates/shared/src/hooks/useBodyScrollLock.ts +97 -0
  246. package/templates/shared/src/hooks/useClickOutside.ts +28 -0
  247. package/templates/shared/src/utilities/renderCustomCSS.ts +5 -0
  248. package/templates/shared/src/utilities/smoothScroll.ts +65 -0
@@ -0,0 +1,44 @@
1
+ {
2
+ "type": "block",
3
+ "name": "DDHG-ServiceOverview",
4
+ "label": "Service Overview",
5
+ "sourceName": "ServiceOverview",
6
+ "portableName": "DDHG-ServiceOverview",
7
+ "slug": "DDHG-ServiceOverview",
8
+ "version": "0.0.1",
9
+ "source": {
10
+ "repo": "Hadizainal/HeatherGrey2025",
11
+ "originalPath": "src/blocks/ServiceOverview",
12
+ "originalSlug": "serviceOverview",
13
+ "originalConfigExport": "ServiceOverview",
14
+ "originalComponentExport": "ServiceOverviewBlock",
15
+ "originalInterfaceName": "ServiceOverviewBlockProps"
16
+ },
17
+ "files": [
18
+ { "from": "Component.tsx", "to": "src/blocks/DDHG-ServiceOverview/Component.tsx" },
19
+ { "from": "config.ts", "to": "src/blocks/DDHG-ServiceOverview/config.ts" }
20
+ ],
21
+ "dependencies": [
22
+ { "name": "framer-motion" },
23
+ { "name": "lucide-react" }
24
+ ],
25
+ "sharedFiles": [],
26
+ "requiredProjectFiles": [
27
+ { "path": "src/utilities/ui.ts", "reason": "Component uses the cn utility." }
28
+ ],
29
+ "optionalProjectFiles": [],
30
+ "collectionRegistration": { "enabled": true, "collections": ["Pages", "Posts"] },
31
+ "renderBlocksRegistration": { "enabled": true },
32
+ "renderBlocksBehavior": { "wrapperless": false },
33
+ "pageRouteIntegration": { "required": false, "manualSteps": [] },
34
+ "manualSteps": [
35
+ "Run payload generate:types after schema changes."
36
+ ],
37
+ "notes": [
38
+ "Converted from HeatherGrey2025 ServiceOverview.",
39
+ "dbName namespaced to ddhg_svc_overview.",
40
+ "Installer must not overwrite existing target files."
41
+ ],
42
+ "exportName": "DDHGServiceOverview",
43
+ "interfaceName": "DDHGServiceOverview"
44
+ }
@@ -0,0 +1,389 @@
1
+ 'use client'
2
+
3
+ import { AnimatePresence, motion } from 'framer-motion'
4
+ import {
5
+ CalendarCheck,
6
+ ChevronDown,
7
+ ChevronUp,
8
+ ClipboardList,
9
+ FileText,
10
+ HandHeart,
11
+ RefreshCw,
12
+ ShieldCheck,
13
+ User,
14
+ UserStar
15
+ } from 'lucide-react'
16
+ import React, { useState } from 'react'
17
+
18
+ import { cn } from '@/utilities/ui'
19
+
20
+ type TrustBadge = {
21
+ icon?:
22
+ | 'shieldCheck'
23
+ | 'calendarCheck'
24
+ | 'userStar'
25
+ | 'fileText'
26
+ | 'refreshCw'
27
+ | 'handHeart'
28
+ | 'clipboardList'
29
+ | null
30
+ title?: string | null
31
+ description?: string | null
32
+ desc?: string | null
33
+ id?: string | null
34
+ }
35
+
36
+ type TestimonialItem = {
37
+ quote?: string | null
38
+ author?: string | null
39
+ role?: string | null
40
+ id?: string | null
41
+ }
42
+
43
+ type FAQItem = {
44
+ question?: string | null
45
+ q?: string | null
46
+ answer?: string | null
47
+ a?: string | null
48
+ id?: string | null
49
+ }
50
+
51
+ export type DDHGStatsFAQProps = {
52
+ sectionId?: string | null
53
+ customClassName?: string | null
54
+ customCSS?: string | null
55
+ blockId?: string | null
56
+ scrollSpeed?: string | number | null
57
+ testimonials?: TestimonialItem[] | null
58
+ commitmentLabel?: string | null
59
+ commitmentHeading?: string | null
60
+ trustBadges?: TrustBadge[] | null
61
+ faqEyebrowPrefix?: string | null
62
+ faqEyebrowEmphasis?: string | null
63
+ faqHeading?: string | null
64
+ showFaqDivider?: boolean | null
65
+ faqs?: FAQItem[] | null
66
+ }
67
+
68
+ const defaultTrustBadges: TrustBadge[] = [
69
+ {
70
+ icon: 'shieldCheck',
71
+ title: 'Transparent Pricing',
72
+ description: 'Every quote is itemized. No hidden fees, no surprise charges at the end.'
73
+ },
74
+ {
75
+ icon: 'calendarCheck',
76
+ title: 'Fixed Timeline Guarantee',
77
+ description: 'We commit to a delivery date and stick to it. If we miss it, you get a credit.'
78
+ },
79
+ {
80
+ icon: 'userStar',
81
+ title: 'Dedicated Project Lead',
82
+ description: 'One senior designer owns your project from kickoff to handover. No handoffs.'
83
+ },
84
+ {
85
+ icon: 'fileText',
86
+ title: 'Full Documentation',
87
+ description: 'Every finish, fixture, and specification is documented for future reference.'
88
+ },
89
+ {
90
+ icon: 'refreshCw',
91
+ title: 'Revision Rounds Included',
92
+ description: 'Three structured revision cycles are included in every engagement.'
93
+ },
94
+ {
95
+ icon: 'handHeart',
96
+ title: 'Post-Completion Support',
97
+ description: '30 days of complimentary support after handover. We stand by our work.'
98
+ }
99
+ ]
100
+
101
+ const defaultTestimonials: TestimonialItem[] = [
102
+ {
103
+ quote:
104
+ 'They delivered exactly what they promised, on the date they promised it, at the price they quoted. That alone is rare in this industry.',
105
+ author: 'Margaret Chen',
106
+ role: 'Director of Operations, Meridian Holdings'
107
+ },
108
+ {
109
+ quote:
110
+ 'The transparency throughout the process was remarkable. We knew exactly where we stood at every phase. No surprises.',
111
+ author: 'James Oduya',
112
+ role: 'Founder, The Atelier Collective'
113
+ }
114
+ ]
115
+
116
+ const defaultFaqs: FAQItem[] = [
117
+ {
118
+ question: 'How long does a typical project take?',
119
+ answer:
120
+ 'Project timelines vary based on scope. A residential interior typically takes 8-16 weeks from concept to completion. Commercial fit-outs range from 12-24 weeks. We provide detailed timelines during our initial consultation.'
121
+ },
122
+ {
123
+ question: 'Do you handle both design and construction?',
124
+ answer:
125
+ 'Yes, our Turn-Key Services cover the complete journey from initial concept through construction to final handover. We coordinate all contractors and trades, ensuring the design vision is executed faithfully.'
126
+ },
127
+ {
128
+ question: 'Can you work with existing furniture and art?',
129
+ answer:
130
+ 'Absolutely. Our Atmospheric Curation service specializes in integrating existing pieces into new designs. We view heirlooms and collected art as anchors of identity within the space.'
131
+ },
132
+ {
133
+ question: 'What is your fee structure?',
134
+ answer:
135
+ 'We offer both fixed-fee and percentage-based pricing depending on project type. Design Consultancy is typically fixed-fee, while Turn-Key projects use a percentage of construction cost. We provide transparent quotes upfront.'
136
+ },
137
+ {
138
+ question: 'Do you offer sustainability-focused design?',
139
+ answer:
140
+ 'Sustainability is woven into our material selection and spatial planning. We prioritize low-VOC finishes, responsibly sourced materials, energy-efficient lighting, and biophilic elements that reduce environmental impact.'
141
+ }
142
+ ]
143
+
144
+ const iconMap = {
145
+ shieldCheck: ShieldCheck,
146
+ calendarCheck: CalendarCheck,
147
+ userStar: UserStar,
148
+ fileText: FileText,
149
+ refreshCw: RefreshCw,
150
+ handHeart: HandHeart,
151
+ clipboardList: ClipboardList
152
+ }
153
+
154
+ function RevealBlock({
155
+ children,
156
+ className,
157
+ delay = 0
158
+ }: {
159
+ children: React.ReactNode
160
+ className?: string
161
+ delay?: number
162
+ }) {
163
+ return (
164
+ <motion.div
165
+ className={className}
166
+ initial={{ opacity: 0, y: 20 }}
167
+ whileInView={{ opacity: 1, y: 0 }}
168
+ viewport={{ once: true, amount: 0.18 }}
169
+ transition={{ duration: 0.9, delay, ease: [0.22, 1, 0.36, 1] }}
170
+ >
171
+ {children}
172
+ </motion.div>
173
+ )
174
+ }
175
+
176
+ const getItems = <T,>(items: T[] | null | undefined, fallback: T[]) =>
177
+ Array.isArray(items) && items.length > 0 ? items : fallback
178
+
179
+ export const DDHGStatsFAQ: React.FC<DDHGStatsFAQProps> = ({
180
+ sectionId,
181
+ customClassName,
182
+ customCSS,
183
+ blockId,
184
+ scrollSpeed,
185
+ testimonials,
186
+ commitmentLabel = 'Our Commitment',
187
+ commitmentHeading = 'Why Clients Trust Us',
188
+ trustBadges,
189
+ faqEyebrowPrefix = 'common',
190
+ faqEyebrowEmphasis = 'questions',
191
+ faqHeading = 'FAQ',
192
+ showFaqDivider = true,
193
+ faqs
194
+ }) => {
195
+ const [openFAQ, setOpenFAQ] = useState<number | null>(null)
196
+ const testimonialItems = getItems(testimonials, defaultTestimonials)
197
+ const badgeItems = getItems(trustBadges, defaultTrustBadges)
198
+ const faqItems = getItems(faqs, defaultFaqs)
199
+
200
+ return (
201
+ <div
202
+ id={sectionId ?? undefined}
203
+ data-block-id={blockId ?? undefined}
204
+ data-scroll={scrollSpeed ? true : undefined}
205
+ data-scroll-speed={scrollSpeed ? String(scrollSpeed) : undefined}
206
+ className={cn('px-5 py-16 md:px-8', customClassName)}
207
+ >
208
+ {customCSS && <style dangerouslySetInnerHTML={{ __html: customCSS }} />}
209
+ <div className="mx-auto max-w-7xl">
210
+ {testimonialItems.length > 0 && (
211
+ <RevealBlock className="testimonial-section mb-16">
212
+ <div className="grid grid-cols-1 gap-6 md:grid-cols-2">
213
+ {testimonialItems.map((testimonial, i) => (
214
+ <div
215
+ key={testimonial.id || `testimonial-${i}`}
216
+ className="z-plane-1 chamfer-accent p-6 md:p-8"
217
+ >
218
+ <div className="mb-4 h-px w-8 bg-[#C4A882]" />
219
+ {testimonial.quote && (
220
+ <p className="mb-6 text-[13px] font-light leading-relaxed text-stone-700 dark:text-stone-200">
221
+ &ldquo;{testimonial.quote}&rdquo;
222
+ </p>
223
+ )}
224
+ <div className="flex items-center gap-3">
225
+ <div
226
+ className="flex h-8 w-8 items-center justify-center bg-stone-500"
227
+ style={{ borderRadius: '2px' }}
228
+ >
229
+ <User className="h-3.5 w-3.5 text-stone-50" strokeWidth={1.6} />
230
+ </div>
231
+ <div>
232
+ {testimonial.author && (
233
+ <p className="text-[13px] font-medium text-stone-700 dark:text-stone-200">
234
+ {testimonial.author}
235
+ </p>
236
+ )}
237
+ {testimonial.role && (
238
+ <p className="text-[13px] text-stone-600 dark:text-stone-300">
239
+ {testimonial.role}
240
+ </p>
241
+ )}
242
+ </div>
243
+ </div>
244
+ </div>
245
+ ))}
246
+ </div>
247
+ </RevealBlock>
248
+ )}
249
+
250
+ {badgeItems.length > 0 && (
251
+ <RevealBlock className="whytrustus-section mb-16">
252
+ <div className="z-plane-1 p-6 md:p-8">
253
+ <div className="mb-6">
254
+ {commitmentLabel && (
255
+ <p className="mb-2 font-mono text-[13px] uppercase tracking-[0.15em] text-stone-600 dark:text-stone-300">
256
+ {commitmentLabel}
257
+ </p>
258
+ )}
259
+ {commitmentHeading && (
260
+ <h3 className="text-xl font-semibold text-purple-700 dark:text-purple-500">
261
+ {commitmentHeading}
262
+ </h3>
263
+ )}
264
+ </div>
265
+ <div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3">
266
+ {badgeItems.map((badge, i) => {
267
+ const Icon = iconMap[badge.icon || 'shieldCheck'] || ShieldCheck
268
+ const description = badge.description || badge.desc || ''
269
+ return (
270
+ <div
271
+ key={badge.id || `${badge.title || 'badge'}-${i}`}
272
+ className="arch-edge-sm flex items-start gap-3 border border-[#D9D7D1] p-4"
273
+ >
274
+ <div className="mt-0.5 flex h-6 w-6 flex-shrink-0 items-center justify-center">
275
+ <Icon className="h-4 w-4 text-[#C4A882]" strokeWidth={1.7} />
276
+ </div>
277
+ <div>
278
+ {badge.title && (
279
+ <p className="mb-1 text-[13px] font-medium text-stone-700 dark:text-stone-200">
280
+ {badge.title}
281
+ </p>
282
+ )}
283
+ {description && (
284
+ <p className="text-[10px] font-light leading-relaxed text-stone-700 dark:text-stone-200">
285
+ {description}
286
+ </p>
287
+ )}
288
+ </div>
289
+ </div>
290
+ )
291
+ })}
292
+ </div>
293
+ </div>
294
+ </RevealBlock>
295
+ )}
296
+
297
+ <RevealBlock className="faq-section max-w-4xl mx-auto mb-10">
298
+ {(faqEyebrowPrefix || faqEyebrowEmphasis) && (
299
+ <p className="mb-2 text-[10px] uppercase tracking-[0.2em] text-stone-600 dark:text-stone-300">
300
+ {faqEyebrowPrefix && <span className="font-light">{faqEyebrowPrefix} </span>}
301
+ {faqEyebrowEmphasis && <span className="font-medium">{faqEyebrowEmphasis}</span>}
302
+ </p>
303
+ )}
304
+ {faqHeading && (
305
+ <h2 className="mb-3 text-3xl font-medium leading-none tracking-tight text-purple-700 dark:text-purple-500 md:text-4xl">
306
+ {faqHeading}
307
+ </h2>
308
+ )}
309
+ {showFaqDivider && <div className="h-px w-12 bg-stone-500" />}
310
+ </RevealBlock>
311
+
312
+ {faqItems.length > 0 && (
313
+ <div className="faq-wrapper max-w-4xl mx-auto space-y-3">
314
+ {faqItems.map((faq, i) => {
315
+ const isOpen = openFAQ === i
316
+ const question = faq.question || faq.q || ''
317
+ const answer = faq.answer || faq.a || ''
318
+ const ToggleIcon = isOpen ? ChevronUp : ChevronDown
319
+ return (
320
+ <RevealBlock key={faq.id || `${question || 'faq'}-${i}`} delay={i * 0.06}>
321
+ <div
322
+ className={cn(
323
+ 'accordion-card z-plane-1 border-border border chamfer-accent transition-all duration-300',
324
+ isOpen &&
325
+ 'border-border border z-depth-hover hover:shadow-2xl hover:-translate-y-2'
326
+ )}
327
+ >
328
+ <button
329
+ type="button"
330
+ onClick={() => setOpenFAQ(isOpen ? null : i)}
331
+ className="accordion-btn flex w-full items-center justify-between p-5 text-left md:p-6"
332
+ aria-expanded={isOpen}
333
+ >
334
+ <div className="flex items-center gap-4">
335
+ <span className="font-mono text-[13px] text-stone-600 dark:text-stone-300">
336
+ {String(i + 1).padStart(2, '0')}
337
+ </span>
338
+ {question && (
339
+ <h3 className="text-sm font-medium text-purple-700 dark:text-purple-500">
340
+ {question}
341
+ </h3>
342
+ )}
343
+ </div>
344
+ <div
345
+ className={cn(
346
+ 'ml-4 flex h-6 w-6 flex-shrink-0 items-center justify-center border border-[#D9D7D1] transition-all duration-300',
347
+ isOpen && 'border-[#292524] bg-[#292524]'
348
+ )}
349
+ style={{ borderRadius: '2px' }}
350
+ >
351
+ <ToggleIcon
352
+ className={cn(
353
+ 'h-3 w-3',
354
+ isOpen ? 'text-[#F5F3EF]' : 'text-stone-600 dark:text-stone-300'
355
+ )}
356
+ strokeWidth={1.8}
357
+ />
358
+ </div>
359
+ </button>
360
+ <AnimatePresence initial={false}>
361
+ {isOpen && answer && (
362
+ <motion.div
363
+ initial={{ height: 0, opacity: 0 }}
364
+ animate={{ height: 'auto', opacity: 1 }}
365
+ exit={{ height: 0, opacity: 0 }}
366
+ transition={{ duration: 0.45, ease: [0.22, 1, 0.36, 1] }}
367
+ className="overflow-hidden"
368
+ >
369
+ <div className="px-5 pb-5 pl-14 md:px-6 md:pb-6 md:pl-16">
370
+ <div className="mb-4 h-px w-full bg-stone-500" />
371
+ <p className="text-[13px] font-light leading-relaxed text-stone-700 dark:text-stone-200">
372
+ {answer}
373
+ </p>
374
+ </div>
375
+ </motion.div>
376
+ )}
377
+ </AnimatePresence>
378
+ </div>
379
+ </RevealBlock>
380
+ )
381
+ })}
382
+ </div>
383
+ )}
384
+ </div>
385
+ </div>
386
+ )
387
+ }
388
+
389
+ export default DDHGStatsFAQ
@@ -0,0 +1,204 @@
1
+ import type { Block } from 'payload'
2
+
3
+ export const DDHGStatsFAQ: Block = {
4
+ slug: 'DDHG-StatsFAQ',
5
+ interfaceName: 'DDHGStatsFAQ',
6
+ dbName: 'ddhg_stats_faq',
7
+ labels: {
8
+ singular: 'Stats FAQ',
9
+ plural: 'Stats FAQs',
10
+ },
11
+ fields: [
12
+ {
13
+ type: 'tabs',
14
+ tabs: [
15
+ {
16
+ label: 'Testimonials',
17
+ fields: [
18
+ {
19
+ name: 'testimonials',
20
+ type: 'array',
21
+ label: 'Testimonials',
22
+ dbName: 'quotes',
23
+ labels: { singular: 'Testimonial', plural: 'Testimonials' },
24
+ fields: [
25
+ { name: 'quote', type: 'textarea', label: 'Quote', required: true },
26
+ {
27
+ type: 'row',
28
+ fields: [
29
+ {
30
+ name: 'author',
31
+ type: 'text',
32
+ label: 'Author',
33
+ required: true,
34
+ admin: { width: '50%' },
35
+ },
36
+ {
37
+ name: 'role',
38
+ type: 'text',
39
+ label: 'Role / Company',
40
+ admin: { width: '50%' },
41
+ },
42
+ ],
43
+ },
44
+ ],
45
+ },
46
+ ],
47
+ },
48
+ {
49
+ label: 'Trust Badges',
50
+ fields: [
51
+ {
52
+ type: 'row',
53
+ fields: [
54
+ {
55
+ name: 'commitmentLabel',
56
+ type: 'text',
57
+ label: 'Commitment Label',
58
+ defaultValue: 'Our Commitment',
59
+ admin: { width: '50%' },
60
+ },
61
+ {
62
+ name: 'commitmentHeading',
63
+ type: 'text',
64
+ label: 'Commitment Heading',
65
+ defaultValue: 'Why Clients Trust Us',
66
+ admin: { width: '50%' },
67
+ },
68
+ ],
69
+ },
70
+ {
71
+ name: 'trustBadges',
72
+ type: 'array',
73
+ label: 'Trust Badges',
74
+ dbName: 'badges',
75
+ labels: { singular: 'Trust Badge', plural: 'Trust Badges' },
76
+ fields: [
77
+ {
78
+ type: 'row',
79
+ fields: [
80
+ {
81
+ name: 'icon',
82
+ type: 'select',
83
+ label: 'Icon',
84
+ defaultValue: 'shieldCheck',
85
+ admin: { width: '33.33%' },
86
+ options: [
87
+ { label: 'Shield Check', value: 'shieldCheck' },
88
+ { label: 'Calendar Check', value: 'calendarCheck' },
89
+ { label: 'User Star', value: 'userStar' },
90
+ { label: 'File Text', value: 'fileText' },
91
+ { label: 'Refresh', value: 'refreshCw' },
92
+ { label: 'Hand Heart', value: 'handHeart' },
93
+ { label: 'Clipboard List', value: 'clipboardList' },
94
+ ],
95
+ },
96
+ {
97
+ name: 'title',
98
+ type: 'text',
99
+ label: 'Title',
100
+ required: true,
101
+ admin: { width: '66.66%' },
102
+ },
103
+ ],
104
+ },
105
+ { name: 'description', type: 'textarea', label: 'Description' },
106
+ ],
107
+ },
108
+ ],
109
+ },
110
+ {
111
+ label: 'FAQ',
112
+ fields: [
113
+ {
114
+ type: 'row',
115
+ fields: [
116
+ {
117
+ name: 'faqEyebrowPrefix',
118
+ type: 'text',
119
+ label: 'FAQ Eyebrow Prefix',
120
+ defaultValue: 'common',
121
+ admin: { width: '50%' },
122
+ },
123
+ {
124
+ name: 'faqEyebrowEmphasis',
125
+ type: 'text',
126
+ label: 'FAQ Eyebrow Emphasis',
127
+ defaultValue: 'questions',
128
+ admin: { width: '50%' },
129
+ },
130
+ ],
131
+ },
132
+ {
133
+ type: 'row',
134
+ fields: [
135
+ {
136
+ name: 'faqHeading',
137
+ type: 'text',
138
+ label: 'FAQ Heading',
139
+ defaultValue: 'FAQ',
140
+ admin: { width: '75%' },
141
+ },
142
+ {
143
+ name: 'showFaqDivider',
144
+ type: 'checkbox',
145
+ label: 'Show Divider',
146
+ defaultValue: true,
147
+ admin: { width: '25%' },
148
+ },
149
+ ],
150
+ },
151
+ {
152
+ name: 'faqs',
153
+ type: 'array',
154
+ label: 'FAQ Items',
155
+ dbName: 'faqs',
156
+ labels: { singular: 'FAQ Item', plural: 'FAQ Items' },
157
+ fields: [
158
+ { name: 'question', type: 'text', label: 'Question', required: true },
159
+ { name: 'answer', type: 'textarea', label: 'Answer', required: true },
160
+ ],
161
+ },
162
+ ],
163
+ },
164
+ {
165
+ label: 'Advanced',
166
+ fields: [
167
+ {
168
+ type: 'row',
169
+ fields: [
170
+ {
171
+ name: 'sectionId',
172
+ type: 'text',
173
+ label: 'Section ID',
174
+ admin: { width: '50%' },
175
+ },
176
+ {
177
+ name: 'customClassName',
178
+ type: 'text',
179
+ label: 'Custom CSS Classes',
180
+ admin: { width: '50%' },
181
+ },
182
+ ],
183
+ },
184
+ {
185
+ name: 'scrollSpeed',
186
+ type: 'text',
187
+ label: 'Scroll Speed',
188
+ admin: { description: 'Optional data-scroll-speed value.' },
189
+ },
190
+ {
191
+ name: 'customCSS',
192
+ type: 'code',
193
+ label: 'Custom CSS',
194
+ admin: {
195
+ language: 'css',
196
+ description: 'Injected as a style tag. Use with caution.',
197
+ },
198
+ },
199
+ ],
200
+ },
201
+ ],
202
+ },
203
+ ],
204
+ }
@@ -0,0 +1,45 @@
1
+ {
2
+ "type": "block",
3
+ "name": "DDHG-StatsFAQ",
4
+ "label": "Stats FAQ",
5
+ "sourceName": "StatsFAQ",
6
+ "portableName": "DDHG-StatsFAQ",
7
+ "slug": "DDHG-StatsFAQ",
8
+ "version": "0.0.1",
9
+ "source": {
10
+ "repo": "Hadizainal/HeatherGrey2025",
11
+ "originalPath": "src/blocks/StatsFAQ",
12
+ "originalSlug": "statsFAQ",
13
+ "originalConfigExport": "StatsFAQ",
14
+ "originalComponentExport": "StatsFAQBlock",
15
+ "originalInterfaceName": "StatsFAQBlockProps"
16
+ },
17
+ "files": [
18
+ { "from": "Component.tsx", "to": "src/blocks/DDHG-StatsFAQ/Component.tsx" },
19
+ { "from": "config.ts", "to": "src/blocks/DDHG-StatsFAQ/config.ts" }
20
+ ],
21
+ "dependencies": [
22
+ { "name": "framer-motion" },
23
+ { "name": "lucide-react" }
24
+ ],
25
+ "sharedFiles": [],
26
+ "requiredProjectFiles": [
27
+ { "path": "src/utilities/ui.ts", "reason": "Component uses the cn utility." }
28
+ ],
29
+ "optionalProjectFiles": [],
30
+ "collectionRegistration": { "enabled": true, "collections": ["Pages", "Posts"] },
31
+ "renderBlocksRegistration": { "enabled": true },
32
+ "renderBlocksBehavior": { "wrapperless": false },
33
+ "pageRouteIntegration": { "required": false, "manualSteps": [] },
34
+ "manualSteps": [
35
+ "Review HeatherGrey-specific utility classes such as z-plane, chamfer and arch-edge in the destination theme.",
36
+ "Run payload generate:types after schema changes."
37
+ ],
38
+ "notes": [
39
+ "Converted from HeatherGrey2025 StatsFAQ.",
40
+ "The top-level dbName was namespaced to ddhg_stats_faq for portability.",
41
+ "Installer must not overwrite existing target files."
42
+ ],
43
+ "exportName": "DDHGStatsFAQ",
44
+ "interfaceName": "DDHGStatsFAQ"
45
+ }