blocks-dusted 0.1.11 → 0.1.13
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/package.json +5 -2
- package/src/cli.js +39 -3
- package/src/commands/shop.js +59 -0
- package/src/commands/warehouse.js +73 -0
- package/src/installers/patchRenderBlocks.js +1 -1
- package/src/registry/validateTemplateManifest.js +2 -1
- package/templates/blocks/BannerDD790432/Component.tsx +63 -0
- package/templates/blocks/BannerDD790432/config.ts +54 -0
- package/templates/blocks/BannerDD790432/manifest.json +80 -0
- package/templates/blocks/Button47/Component.tsx +124 -0
- package/templates/blocks/Button47/config.ts +75 -0
- package/templates/blocks/Button47/link.ts +22 -0
- package/templates/blocks/Button47/manifest.json +105 -0
- package/templates/blocks/Button47/styles.module.scss +75 -0
- package/templates/blocks/DD-Accordion/Component.tsx +55 -36
- package/templates/blocks/DD-Accordion/config.ts +71 -59
- package/templates/blocks/DD-AnimText/Component.tsx +50 -32
- package/templates/blocks/DD-AnimText/config.ts +296 -295
- package/templates/blocks/DD-AsideNav/Component.tsx +323 -319
- package/templates/blocks/DD-Banner/Component.tsx +54 -51
- package/templates/blocks/DD-BookCall/Component.tsx +10 -9
- package/templates/blocks/DD-ButtonPop/Component.tsx +118 -117
- package/templates/blocks/DD-Card/Component.tsx +4 -4
- package/templates/blocks/DD-CardTemplate01/Component.tsx +5 -5
- package/templates/blocks/DD-CardsWithVariantV3/Component.tsx +472 -0
- package/templates/blocks/DD-CardsWithVariantV3/ElectricBorder/index.tsx +203 -0
- package/templates/blocks/DD-CardsWithVariantV3/ElectricBorder/styles.ts +87 -0
- package/templates/blocks/DD-CardsWithVariantV3/ElectricBorder/useInjectStyle.ts +39 -0
- package/templates/blocks/DD-CardsWithVariantV3/config.ts +326 -0
- package/templates/blocks/DD-CardsWithVariantV3/manifest.json +110 -0
- package/templates/blocks/DD-Carousel-A/Component.tsx +251 -249
- package/templates/blocks/DD-Carousel-B/Component.tsx +405 -403
- package/templates/blocks/DD-Chip/Component.tsx +14 -14
- package/templates/blocks/DD-ComparisonTable/Component.tsx +255 -256
- package/templates/blocks/DD-Contact/Component.tsx +433 -434
- package/templates/blocks/DD-Counter/Component.tsx +18 -13
- package/templates/blocks/DD-DeliCard/Component.tsx +303 -0
- package/templates/blocks/DD-DeliCard/config.ts +186 -0
- package/templates/blocks/DD-DeliCard/manifest.json +94 -0
- package/templates/blocks/DD-FeatCat/Component.tsx +302 -302
- package/templates/blocks/DD-FeatProd/CircularGallery.tsx +1179 -0
- package/templates/blocks/DD-FeatProd/Component.tsx +484 -0
- package/templates/blocks/DD-FeatProd/config.ts +173 -0
- package/templates/blocks/DD-FeatProd/manifest.json +93 -0
- package/templates/blocks/DD-FeatServ/Component.tsx +607 -0
- package/templates/blocks/DD-FeatServ/config.ts +213 -0
- package/templates/blocks/DD-FeatServ/manifest.json +113 -0
- package/templates/blocks/DD-FeatStrip/Component.tsx +584 -585
- package/templates/blocks/DD-FluidBtn/ButtonsEyeCatching.tsx +627 -628
- package/templates/blocks/DD-FluidBtn/Component.tsx +46 -43
- package/templates/blocks/DD-GooeyInfo/Component.tsx +150 -149
- package/templates/blocks/DD-GooeyInfo/config.ts +136 -135
- package/templates/blocks/DD-Hero/Component.tsx +16 -40
- package/templates/blocks/DD-HeroPlas/Component.tsx +50 -0
- package/templates/blocks/DD-HeroPlas/ThreeScene.tsx +109 -0
- package/templates/blocks/DD-HeroPlas/config.ts +33 -0
- package/templates/blocks/DD-HeroPlas/manifest.json +88 -0
- package/templates/blocks/DD-HorizontalScroll/Component.tsx +4 -5
- package/templates/blocks/DD-Icon/Component.tsx +46 -81
- package/templates/blocks/DD-IconButton/Component.tsx +13 -20
- package/templates/blocks/DD-IdTag/Component.tsx +22 -21
- package/templates/blocks/DD-IframeMedia/Component.tsx +14 -10
- package/templates/blocks/DD-LineAnim/Component.tsx +42 -36
- package/templates/blocks/DD-LogoMarq/Component.tsx +38 -48
- package/templates/blocks/DD-Lottie/Component.tsx +11 -3
- package/templates/blocks/DD-MasonaryMedia/Component.tsx +544 -547
- package/templates/blocks/DD-MasonaryMedia/config.ts +389 -389
- package/templates/blocks/DD-Masonry/Component.tsx +654 -644
- package/templates/blocks/DD-Masonry/config.ts +475 -475
- package/templates/blocks/DD-MaterialSwatches/Component.tsx +85 -0
- package/templates/blocks/DD-MaterialSwatches/config.ts +232 -0
- package/templates/blocks/DD-MaterialSwatches/manifest.json +84 -0
- package/templates/blocks/DD-MaterialSwatches/material.ts +107 -0
- package/templates/blocks/DD-NineCanvas/Component.tsx +129 -0
- package/templates/blocks/DD-NineCanvas/RenderBlocks.tsx +244 -0
- package/templates/blocks/DD-NineCanvas/allowedCanvasBlocks.ts +6 -0
- package/templates/blocks/DD-NineCanvas/blockComponents.tsx +8 -0
- package/templates/blocks/DD-NineCanvas/canvas/CanvasGrid.tsx +316 -0
- package/templates/blocks/DD-NineCanvas/canvas/RadialNav.tsx +432 -0
- package/templates/blocks/DD-NineCanvas/canvas/canvas-panels.css +889 -0
- package/templates/blocks/DD-NineCanvas/canvas/icons/custom-icons.tsx +364 -0
- package/templates/blocks/DD-NineCanvas/config.ts +61 -0
- package/templates/blocks/DD-NineCanvas/manifest.json +165 -0
- package/templates/blocks/DD-NineCanvas/styles.scss +152 -0
- package/templates/blocks/DD-NineCanvas/tooltip/get-strict-context.tsx +26 -0
- package/templates/blocks/DD-NineCanvas/tooltip/primitives.tsx +178 -0
- package/templates/blocks/DD-NineCanvas/tooltip/tooltip.tsx +71 -0
- package/templates/blocks/DD-NineCanvas/tooltip/use-controlled-state.tsx +33 -0
- package/templates/blocks/DD-NineCanvas/utilities/FadeOnScroll.tsx +68 -0
- package/templates/blocks/DD-NineCanvas/utilities/ParallaxWrapper.tsx +157 -0
- package/templates/blocks/DD-NineCanvas/utilities/renderCustomCSS.ts +5 -0
- package/templates/blocks/DD-NineCanvas/utilities/webglCleanup.ts +27 -0
- package/templates/blocks/DD-PayloadAIAssistant/Component.tsx +78 -0
- package/templates/blocks/DD-PayloadAIAssistant/DustedBot.tsx +590 -0
- package/templates/blocks/DD-PayloadAIAssistant/config.ts +37 -0
- package/templates/blocks/DD-PayloadAIAssistant/demo.css +125 -0
- package/templates/blocks/DD-PayloadAIAssistant/manifest.json +93 -0
- package/templates/blocks/DD-PayloadAIAssistant/source-defaults.ts +17 -0
- package/templates/blocks/DD-PayloadAIAssistant/styles.ts +306 -0
- package/templates/blocks/DD-Pricing/Component.tsx +368 -372
- package/templates/blocks/DD-Pricing/config.ts +215 -215
- package/templates/blocks/DD-Process/Component.tsx +147 -149
- package/templates/blocks/DD-Progress/Component.tsx +156 -141
- package/templates/blocks/DD-ProjHeader/Component.tsx +93 -91
- package/templates/blocks/DD-ProjSlider/Component.tsx +1 -1
- package/templates/blocks/DD-ProjSlider/config.ts +2 -2
- package/templates/blocks/DD-Section/Component.tsx +265 -266
- package/templates/blocks/DD-Separator/Component.tsx +66 -66
- package/templates/blocks/DD-Services/Component.tsx +176 -176
- package/templates/blocks/DD-ShowcaseGrid/Component.tsx +306 -307
- package/templates/blocks/DD-Slider-A/Component.tsx +237 -237
- package/templates/blocks/DD-StackCards/Component.tsx +474 -473
- package/templates/blocks/DD-Team/Component.tsx +247 -247
- package/templates/blocks/DD-TeamCards/Component.tsx +251 -251
- package/templates/blocks/DD-TechStack/Component.tsx +161 -168
- package/templates/blocks/DD-TestMarq/Component.tsx +158 -132
- package/templates/blocks/DD-Testim/Component.tsx +247 -247
- package/templates/blocks/DD-Testim2/Component.tsx +265 -256
- package/templates/blocks/DD-Testimonials/Component.tsx +139 -147
- package/templates/blocks/DD-TextMarq/Component.tsx +157 -157
- package/templates/blocks/DD-Thanks/Component.tsx +501 -500
- package/templates/blocks/DD-Work/Component.tsx +315 -315
- package/templates/blocks/DD-Work-B/Component.tsx +294 -294
- package/templates/blocks/DDHG-CTASection2/Component.tsx +183 -184
- package/templates/blocks/DDHG-HighlightArc/Component.tsx +246 -243
- package/templates/blocks/DDHG-LogoMarquee/Component.tsx +180 -93
- package/templates/blocks/DDHG-LogoMarquee/config.ts +154 -66
- package/templates/blocks/DDHG-NavCodeGrid/Component.tsx +225 -213
- package/templates/blocks/DDHG-ProcessSec/Component.tsx +38 -39
- package/templates/blocks/DDHG-ServiceDetails/Component.tsx +11 -11
- package/templates/blocks/DDHG-ServiceDetails/ServiceDetailCard.tsx +30 -47
- package/templates/blocks/DDHG-ServiceHero/Component.tsx +10 -10
- package/templates/blocks/DDHG-ServiceOverview/Component.tsx +23 -23
- package/templates/blocks/DDHG-StatsFAQ/Component.tsx +40 -40
- package/templates/blocks/DDHG-TeamCards/Component.tsx +140 -131
- package/templates/blocks/Form/Checkbox/index.tsx +45 -0
- package/templates/blocks/Form/Component.tsx +163 -0
- package/templates/blocks/Form/Country/index.tsx +65 -0
- package/templates/blocks/Form/Country/options.ts +982 -0
- package/templates/blocks/Form/Email/index.tsx +38 -0
- package/templates/blocks/Form/Error/index.tsx +15 -0
- package/templates/blocks/Form/Message/index.tsx +13 -0
- package/templates/blocks/Form/Number/index.tsx +36 -0
- package/templates/blocks/Form/Select/index.tsx +63 -0
- package/templates/blocks/Form/State/index.tsx +64 -0
- package/templates/blocks/Form/State/options.ts +52 -0
- package/templates/blocks/Form/Text/index.tsx +32 -0
- package/templates/blocks/Form/Textarea/index.tsx +40 -0
- package/templates/blocks/Form/Width/index.tsx +13 -0
- package/templates/blocks/Form/config.ts +51 -0
- package/templates/blocks/Form/fields.tsx +21 -0
- package/templates/blocks/Form/manifest.json +168 -0
- package/templates/blocks/MediaBlock/Component.tsx +67 -0
- package/templates/blocks/MediaBlock/config.ts +14 -0
- package/templates/blocks/MediaBlock/manifest.json +92 -0
- package/templates/blocks/TransitionsDustedShowcase/Component.tsx +9 -0
- package/templates/blocks/TransitionsDustedShowcase/config.ts +13 -0
- package/templates/blocks/TransitionsDustedShowcase/manifest.json +80 -0
- package/templates/blocks/rawHtml/Component.tsx +25 -0
- package/templates/blocks/rawHtml/config.ts +56 -0
- package/templates/blocks/rawHtml/manifest.json +80 -0
|
@@ -121,8 +121,8 @@ const defaultSteps: ProcessStep[] = [
|
|
|
121
121
|
substeps: [
|
|
122
122
|
{ label: 'Site analysis' },
|
|
123
123
|
{ label: 'User research' },
|
|
124
|
-
{ label: 'Brief definition' }
|
|
125
|
-
]
|
|
124
|
+
{ label: 'Brief definition' },
|
|
125
|
+
],
|
|
126
126
|
},
|
|
127
127
|
{
|
|
128
128
|
num: '02',
|
|
@@ -132,8 +132,8 @@ const defaultSteps: ProcessStep[] = [
|
|
|
132
132
|
substeps: [
|
|
133
133
|
{ label: 'Spatial planning' },
|
|
134
134
|
{ label: 'Material selection' },
|
|
135
|
-
{ label: 'Mood boards' }
|
|
136
|
-
]
|
|
135
|
+
{ label: 'Mood boards' },
|
|
136
|
+
],
|
|
137
137
|
},
|
|
138
138
|
{
|
|
139
139
|
num: '03',
|
|
@@ -143,8 +143,8 @@ const defaultSteps: ProcessStep[] = [
|
|
|
143
143
|
substeps: [
|
|
144
144
|
{ label: 'Technical drawings' },
|
|
145
145
|
{ label: '3D visualization' },
|
|
146
|
-
{ label: 'Specification' }
|
|
147
|
-
]
|
|
146
|
+
{ label: 'Specification' },
|
|
147
|
+
],
|
|
148
148
|
},
|
|
149
149
|
{
|
|
150
150
|
num: '04',
|
|
@@ -154,9 +154,9 @@ const defaultSteps: ProcessStep[] = [
|
|
|
154
154
|
substeps: [
|
|
155
155
|
{ label: 'Construction oversight' },
|
|
156
156
|
{ label: 'Quality assurance' },
|
|
157
|
-
{ label: 'Final handover' }
|
|
158
|
-
]
|
|
159
|
-
}
|
|
157
|
+
{ label: 'Final handover' },
|
|
158
|
+
],
|
|
159
|
+
},
|
|
160
160
|
]
|
|
161
161
|
|
|
162
162
|
let globalInstanceCounter = 0
|
|
@@ -164,7 +164,7 @@ let globalInstanceCounter = 0
|
|
|
164
164
|
function FadeUpOnInView({
|
|
165
165
|
children,
|
|
166
166
|
className = '',
|
|
167
|
-
delay = 0
|
|
167
|
+
delay = 0,
|
|
168
168
|
}: {
|
|
169
169
|
children: React.ReactNode
|
|
170
170
|
className?: string
|
|
@@ -188,7 +188,7 @@ function FadeUpOnInView({
|
|
|
188
188
|
node.style.transitionDelay = '0s'
|
|
189
189
|
}
|
|
190
190
|
},
|
|
191
|
-
{ threshold: 0.25 }
|
|
191
|
+
{ threshold: 0.25 },
|
|
192
192
|
)
|
|
193
193
|
|
|
194
194
|
observer.observe(node)
|
|
@@ -203,7 +203,7 @@ function FadeUpOnInView({
|
|
|
203
203
|
display: 'inline-block',
|
|
204
204
|
opacity: 0,
|
|
205
205
|
transform: 'translateY(24px)',
|
|
206
|
-
transition: 'opacity 700ms ease, transform 700ms ease'
|
|
206
|
+
transition: 'opacity 700ms ease, transform 700ms ease',
|
|
207
207
|
}}
|
|
208
208
|
>
|
|
209
209
|
{children}
|
|
@@ -214,7 +214,7 @@ function FadeUpOnInView({
|
|
|
214
214
|
function RevealText({
|
|
215
215
|
text,
|
|
216
216
|
className = '',
|
|
217
|
-
instanceIndex
|
|
217
|
+
instanceIndex,
|
|
218
218
|
}: {
|
|
219
219
|
text: string[]
|
|
220
220
|
className?: string
|
|
@@ -243,7 +243,7 @@ function RevealText({
|
|
|
243
243
|
setIsVisible(false)
|
|
244
244
|
}
|
|
245
245
|
},
|
|
246
|
-
{ threshold: 0.3 }
|
|
246
|
+
{ threshold: 0.3 },
|
|
247
247
|
)
|
|
248
248
|
|
|
249
249
|
observer.observe(node)
|
|
@@ -271,7 +271,7 @@ function RevealText({
|
|
|
271
271
|
ref={textRef}
|
|
272
272
|
className={cn(
|
|
273
273
|
'process-section-reveal-text reveal-text animation inline-block h-auto bg-transparent text-left font-bold uppercase leading-none tracking-[1px]',
|
|
274
|
-
className
|
|
274
|
+
className,
|
|
275
275
|
)}
|
|
276
276
|
>
|
|
277
277
|
{words.map((word, wordIndex) => {
|
|
@@ -297,7 +297,7 @@ function RevealText({
|
|
|
297
297
|
animationDuration: '1s',
|
|
298
298
|
animationFillMode: 'forwards',
|
|
299
299
|
animationDelay: `${baseDelay + index * 0.05}s`,
|
|
300
|
-
transitionTimingFunction: 'cubic-bezier(0.075, 0.82, 0.165, 1)'
|
|
300
|
+
transitionTimingFunction: 'cubic-bezier(0.075, 0.82, 0.165, 1)',
|
|
301
301
|
}}
|
|
302
302
|
>
|
|
303
303
|
{char}
|
|
@@ -321,7 +321,7 @@ function StaggerFadeUp({
|
|
|
321
321
|
className = '',
|
|
322
322
|
delay = 0,
|
|
323
323
|
as: Tag = 'div',
|
|
324
|
-
style
|
|
324
|
+
style,
|
|
325
325
|
}: {
|
|
326
326
|
children: React.ReactNode
|
|
327
327
|
className?: string
|
|
@@ -344,7 +344,7 @@ function StaggerFadeUp({
|
|
|
344
344
|
node.style.transitionDelay = `${delay}s`
|
|
345
345
|
observer.unobserve(node)
|
|
346
346
|
},
|
|
347
|
-
{ threshold: 0.18 }
|
|
347
|
+
{ threshold: 0.18 },
|
|
348
348
|
)
|
|
349
349
|
|
|
350
350
|
observer.observe(node)
|
|
@@ -361,7 +361,7 @@ function StaggerFadeUp({
|
|
|
361
361
|
filter: 'blur(6px)',
|
|
362
362
|
transition:
|
|
363
363
|
'opacity 820ms ease, transform 820ms cubic-bezier(0.22, 1, 0.36, 1), filter 820ms ease',
|
|
364
|
-
...style
|
|
364
|
+
...style,
|
|
365
365
|
}}
|
|
366
366
|
>
|
|
367
367
|
{children}
|
|
@@ -395,25 +395,24 @@ function ProcessDiagram({ label, content }: { label?: string | null; content?: a
|
|
|
395
395
|
transition={{ duration: 0.9, delay: 0.3, ease: [0.22, 1, 0.36, 1] }}
|
|
396
396
|
>
|
|
397
397
|
<div className="ProcessSectionDiagram02 z-plane-0 p-5 md:p-8">
|
|
398
|
-
<p className="ProcessSectionDiagram03 mb-4 flex items-center gap-2 font-mono text-
|
|
398
|
+
<p className="ProcessSectionDiagram03 mb-4 flex items-center gap-2 font-mono text-xs uppercase tracking-[0.15em] text-stone-600 dark:text-stone-300">
|
|
399
399
|
<Workflow className="ProcessSectionDiagram04 h-3.5 w-3.5" strokeWidth={1.5} />
|
|
400
400
|
{label || 'Process Flow Diagram'}
|
|
401
401
|
</p>
|
|
402
402
|
|
|
403
403
|
{hasRichTextContent(content) ? (
|
|
404
|
-
<div className="ProcessSectionDiagram05 relative min-h-
|
|
404
|
+
<div className="ProcessSectionDiagram05 relative min-h-75 w-full overflow-hidden">
|
|
405
405
|
<RichText
|
|
406
406
|
data={content}
|
|
407
407
|
enableGutter={false}
|
|
408
408
|
enableProse={false}
|
|
409
|
-
className="ProcessSectionDiagram06 ProcessSectionRichTextVisual h-full min-h-
|
|
409
|
+
className="ProcessSectionDiagram06 ProcessSectionRichTextVisual h-full min-h-75 w-full bg-stone-100/50 p-4 dark:bg-stone-900/50 *:m-0 [&_.media-block]:m-0 [&_img]:m-0"
|
|
410
410
|
/>
|
|
411
411
|
</div>
|
|
412
412
|
) : (
|
|
413
|
-
<div className="ProcessSectionDiagram07 flex min-h-
|
|
414
|
-
<span className="ProcessSectionDiagram08 inline-flex items-center gap-2 text-
|
|
415
|
-
<InlineLogoIcon className="ProcessSectionDiagram09 h-auto w-
|
|
416
|
-
|{' '}
|
|
413
|
+
<div className="ProcessSectionDiagram07 flex min-h-75 w-full bg-linear-to-br from-[#838383] to-[#8e887c] dark:from-[#838383] dark:to-[#8e887c] items-center justify-center">
|
|
414
|
+
<span className="ProcessSectionDiagram08 inline-flex items-center gap-2 text-xs uppercase tracking-[0.15em] text-stone-600 dark:text-stone-300">
|
|
415
|
+
<InlineLogoIcon className="ProcessSectionDiagram09 h-auto w-24 opacity-90" />|{' '}
|
|
417
416
|
</span>
|
|
418
417
|
</div>
|
|
419
418
|
)}
|
|
@@ -435,7 +434,7 @@ export const DDHGProcessSec: React.FC<DDHGProcessSecProps> = ({
|
|
|
435
434
|
diagramLabel = 'Process Flow Diagram',
|
|
436
435
|
diagramContent,
|
|
437
436
|
diagramVisualContent,
|
|
438
|
-
steps
|
|
437
|
+
steps,
|
|
439
438
|
}) => {
|
|
440
439
|
const processSteps = getSteps(steps)
|
|
441
440
|
const visualContent = diagramContent || diagramVisualContent
|
|
@@ -461,7 +460,7 @@ export const DDHGProcessSec: React.FC<DDHGProcessSecProps> = ({
|
|
|
461
460
|
<StaggerFadeUp
|
|
462
461
|
as="p"
|
|
463
462
|
delay={0.05}
|
|
464
|
-
className="ProcessSection04 eyebrowPrefix eyebrowEmphasis mb-2 origin-left
|
|
463
|
+
className="ProcessSection04 eyebrowPrefix eyebrowEmphasis mb-2 origin-left text-xs uppercase tracking-[0.2em] text-stone-400 dark:text-stone-400"
|
|
465
464
|
>
|
|
466
465
|
{eyebrowPrefix && (
|
|
467
466
|
<span className="ProcessSection05 eyebrowPrefix font-light">{eyebrowPrefix} </span>
|
|
@@ -503,37 +502,37 @@ export const DDHGProcessSec: React.FC<DDHGProcessSecProps> = ({
|
|
|
503
502
|
transition={{ duration: 0.9, delay: i * 0.1, ease: [0.22, 1, 0.36, 1] }}
|
|
504
503
|
>
|
|
505
504
|
<div className="ProcessSection13 flex gap-6">
|
|
506
|
-
<div className="ProcessSection14 flex
|
|
507
|
-
<div className="ProcessSection15 z-plane-1 flex h-14 w-14 items-center justify-center border border-
|
|
505
|
+
<div className="ProcessSection14 flex shrink-0 flex-col items-center">
|
|
506
|
+
<div className="ProcessSection15 bg-stone-200 dark:bg-zinc-900 z-plane-1 flex h-14 w-14 items-center justify-center rounded-md squircle border border-stone-100 dark:border-zinc-800">
|
|
508
507
|
<span className="ProcessSection16 text-lg font-semibold text-stone-700 dark:text-stone-200">
|
|
509
508
|
{step.num || String(i + 1).padStart(2, '0')}
|
|
510
509
|
</span>
|
|
511
510
|
</div>
|
|
512
511
|
{i < processSteps.length - 1 && (
|
|
513
512
|
<motion.div
|
|
514
|
-
className="ProcessSection17 mb-2 mt-2 w-px
|
|
513
|
+
className="ProcessSection17 mb-2 mt-2 w-px grow bg-indigo-500"
|
|
515
514
|
initial={{ scaleY: 0, opacity: 0 }}
|
|
516
515
|
whileInView={{ scaleY: 1, opacity: 1 }}
|
|
517
516
|
viewport={{ once: true, amount: 0.2 }}
|
|
518
517
|
transition={{
|
|
519
518
|
duration: 0.8,
|
|
520
519
|
delay: i * 0.1 + 0.2,
|
|
521
|
-
ease: [0.22, 1, 0.36, 1]
|
|
520
|
+
ease: [0.22, 1, 0.36, 1],
|
|
522
521
|
}}
|
|
523
522
|
style={{ minHeight: 40, transformOrigin: 'top' }}
|
|
524
523
|
/>
|
|
525
524
|
)}
|
|
526
525
|
</div>
|
|
527
526
|
|
|
528
|
-
<div className="ProcessSection18
|
|
529
|
-
<div className="ProcessSection19
|
|
527
|
+
<div className="ProcessSection18 grow pb-2">
|
|
528
|
+
<div className="ProcessSection19 bg-stone-200 dark:bg-zinc-900 rounded-md squircle border-border border p-5 transition-all duration-300 z-depth-hover hover:shadow-2xl hover:-translate-y-2 md:p-6">
|
|
530
529
|
{step.title && (
|
|
531
|
-
<
|
|
530
|
+
<h2 className="ProcessSection20 mb-2 text-2xl font-semibold text-indigo-700 dark:text-indigo-500 md:text-3xl">
|
|
532
531
|
{step.title}
|
|
533
|
-
</
|
|
532
|
+
</h2>
|
|
534
533
|
)}
|
|
535
534
|
{getStepDescription(step) && (
|
|
536
|
-
<p className="ProcessSection21 mb-4 text-
|
|
535
|
+
<p className="ProcessSection21 mb-4 text-base font-light leading-relaxed text-stone-700 dark:text-stone-200">
|
|
537
536
|
{getStepDescription(step)}
|
|
538
537
|
</p>
|
|
539
538
|
)}
|
|
@@ -545,8 +544,8 @@ export const DDHGProcessSec: React.FC<DDHGProcessSecProps> = ({
|
|
|
545
544
|
<span
|
|
546
545
|
key={substep.id || `${substep.label}-${subIndex}`}
|
|
547
546
|
className={cn(
|
|
548
|
-
'ProcessSection23 arch-edge-sm border border-
|
|
549
|
-
`ProcessSectionSubstep${i + 1}-${subIndex + 1}
|
|
547
|
+
'ProcessSection23 arch-edge-sm rounded-md squircle border border-stone-300 px-2 py-1 text-xs text-stone-600 dark:border-stone-700 dark:text-stone-300',
|
|
548
|
+
`ProcessSectionSubstep${i + 1}-${subIndex + 1}`,
|
|
550
549
|
)}
|
|
551
550
|
>
|
|
552
551
|
{substep.label}
|
|
@@ -6,7 +6,7 @@ import { cn } from '@/utilities/ui'
|
|
|
6
6
|
import {
|
|
7
7
|
ServiceDetailCard,
|
|
8
8
|
type ServiceDetailItem,
|
|
9
|
-
type ServiceDetailLayout
|
|
9
|
+
type ServiceDetailLayout,
|
|
10
10
|
} from './ServiceDetailCard'
|
|
11
11
|
|
|
12
12
|
export type DDHGServiceDetailsProps = {
|
|
@@ -35,8 +35,8 @@ const defaultServices: ServiceDetailItem[] = [
|
|
|
35
35
|
{ label: 'Brief development' },
|
|
36
36
|
{ label: 'Space audit' },
|
|
37
37
|
{ label: 'Stakeholder alignment' },
|
|
38
|
-
{ label: 'Design direction' }
|
|
39
|
-
]
|
|
38
|
+
{ label: 'Design direction' },
|
|
39
|
+
],
|
|
40
40
|
},
|
|
41
41
|
{
|
|
42
42
|
code: 'SVC-02',
|
|
@@ -49,8 +49,8 @@ const defaultServices: ServiceDetailItem[] = [
|
|
|
49
49
|
{ label: 'Concept strategy' },
|
|
50
50
|
{ label: 'Mood and material direction' },
|
|
51
51
|
{ label: 'Spatial planning' },
|
|
52
|
-
{ label: 'Preliminary visualisation' }
|
|
53
|
-
]
|
|
52
|
+
{ label: 'Preliminary visualisation' },
|
|
53
|
+
],
|
|
54
54
|
},
|
|
55
55
|
{
|
|
56
56
|
code: 'SVC-03',
|
|
@@ -63,9 +63,9 @@ const defaultServices: ServiceDetailItem[] = [
|
|
|
63
63
|
{ label: 'Interior detailing' },
|
|
64
64
|
{ label: 'Material schedules' },
|
|
65
65
|
{ label: 'Furniture direction' },
|
|
66
|
-
{ label: 'Lighting coordination' }
|
|
67
|
-
]
|
|
68
|
-
}
|
|
66
|
+
{ label: 'Lighting coordination' },
|
|
67
|
+
],
|
|
68
|
+
},
|
|
69
69
|
]
|
|
70
70
|
|
|
71
71
|
function getServices(services?: ServiceDetailItem[] | null) {
|
|
@@ -75,7 +75,7 @@ function getServices(services?: ServiceDetailItem[] | null) {
|
|
|
75
75
|
function getLayout(
|
|
76
76
|
service: ServiceDetailItem,
|
|
77
77
|
index: number,
|
|
78
|
-
layoutMode?: 'cycle' | 'manual' | null
|
|
78
|
+
layoutMode?: 'cycle' | 'manual' | null,
|
|
79
79
|
): ServiceDetailLayout {
|
|
80
80
|
if (layoutMode === 'manual' && service.layout && service.layout !== 'auto') return service.layout
|
|
81
81
|
return layoutCycle[index % layoutCycle.length]
|
|
@@ -100,7 +100,7 @@ export const DDHGServiceDetails: React.FC<DDHGServiceDetailsProps> = ({
|
|
|
100
100
|
eyebrowPrefix = 'detailed',
|
|
101
101
|
eyebrowEmphasis = 'breakdown',
|
|
102
102
|
layoutMode = 'cycle',
|
|
103
|
-
services
|
|
103
|
+
services,
|
|
104
104
|
}) => {
|
|
105
105
|
const serviceItems = useMemo(() => getServices(services), [services])
|
|
106
106
|
const [expanded, setExpanded] = useState<number | null>(null)
|
|
@@ -123,7 +123,7 @@ export const DDHGServiceDetails: React.FC<DDHGServiceDetailsProps> = ({
|
|
|
123
123
|
transition={{ duration: 0.9, ease: [0.22, 1, 0.36, 1] }}
|
|
124
124
|
>
|
|
125
125
|
{(eyebrowPrefix || eyebrowEmphasis) && (
|
|
126
|
-
<p className="ServiceDetails04 mb-2 text-
|
|
126
|
+
<p className="ServiceDetails04 mb-2 text-xs uppercase tracking-[0.2em] text-stone-600 dark:text-stone-200">
|
|
127
127
|
{eyebrowPrefix && <span className="font-light">{eyebrowPrefix} </span>}
|
|
128
128
|
{eyebrowEmphasis && <span className="font-medium">{eyebrowEmphasis}</span>}
|
|
129
129
|
</p>
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
import { AnimatePresence, motion } from 'framer-motion'
|
|
4
4
|
import { ChevronDown, ChevronUp, CircleDot } from 'lucide-react'
|
|
5
|
+
import Image from 'next/image'
|
|
5
6
|
import React from 'react'
|
|
6
|
-
import RichText from '@/components/RichText/index'
|
|
7
7
|
import { cn } from '@/utilities/ui'
|
|
8
8
|
|
|
9
9
|
export type ServiceDetailLayout = 'left' | 'right' | 'center' | 'split' | 'asym' | 'bleed'
|
|
@@ -161,12 +161,6 @@ type ServiceDetailCardProps = {
|
|
|
161
161
|
onToggle: () => void
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
-
function hasRichTextContent(value: unknown): boolean {
|
|
165
|
-
if (!value || typeof value !== 'object') return false
|
|
166
|
-
const root = (value as any)?.root
|
|
167
|
-
return Array.isArray(root?.children) && root.children.length > 0
|
|
168
|
-
}
|
|
169
|
-
|
|
170
164
|
function getDescription(service: ServiceDetailItem) {
|
|
171
165
|
return service.description || service.desc || ''
|
|
172
166
|
}
|
|
@@ -180,22 +174,15 @@ function getPoints(service: ServiceDetailItem) {
|
|
|
180
174
|
}
|
|
181
175
|
|
|
182
176
|
function VisualContent({ service }: { service: ServiceDetailItem }) {
|
|
183
|
-
const content = service.visualContent || service.mediaContent || null
|
|
184
|
-
if (hasRichTextContent(content)) {
|
|
185
|
-
return (
|
|
186
|
-
<div className="relative h-full min-h-[300px] w-full overflow-hidden bg-[#FAFAF8]">
|
|
187
|
-
<RichText
|
|
188
|
-
data={content}
|
|
189
|
-
enableGutter={false}
|
|
190
|
-
enableProse={false}
|
|
191
|
-
className="h-full min-h-[300px] w-full [&>*]:m-0 [&_.media-block]:m-0 [&_img]:m-0"
|
|
192
|
-
/>
|
|
193
|
-
</div>
|
|
194
|
-
)
|
|
195
|
-
}
|
|
196
177
|
return (
|
|
197
|
-
<div className="min-h-
|
|
198
|
-
<
|
|
178
|
+
<div className="relative h-full min-h-75 w-full overflow-hidden rounded-md squircle border border-stone-300/10 bg-stone-100/50 dark:border-stone-700/10 dark:bg-stone-900/50 hover:shadow-xl transition-all duration-300">
|
|
179
|
+
<Image
|
|
180
|
+
src="/media/placeholder-2-1920x1080.webp"
|
|
181
|
+
alt={`${service.title || 'Service detail'} visual`}
|
|
182
|
+
fill
|
|
183
|
+
className="object-cover"
|
|
184
|
+
sizes="(max-width: 768px) 100vw, 50vw"
|
|
185
|
+
/>
|
|
199
186
|
</div>
|
|
200
187
|
)
|
|
201
188
|
}
|
|
@@ -206,7 +193,7 @@ function ToggleButton({ isExpanded, onToggle }: { isExpanded: boolean; onToggle:
|
|
|
206
193
|
<button
|
|
207
194
|
type="button"
|
|
208
195
|
onClick={onToggle}
|
|
209
|
-
className="btn-outline
|
|
196
|
+
className="btn-outline inline-flex items-center gap-2 self-start rounded-md squircle border border-stone-300 bg-stone-100/50 px-4 py-2 text-base transition-all duration-300 hover:brightness-105 dark:border-stone-700/10 dark:bg-stone-900/50"
|
|
210
197
|
>
|
|
211
198
|
{isExpanded ? 'Close Details' : 'View Details'}
|
|
212
199
|
<Icon className="h-3.5 w-3.5" strokeWidth={1.8} />
|
|
@@ -225,7 +212,7 @@ function ExpandPanel({ isExpanded, children }: { isExpanded: boolean; children:
|
|
|
225
212
|
variants={{
|
|
226
213
|
hidden: {
|
|
227
214
|
height: 0,
|
|
228
|
-
opacity: 0
|
|
215
|
+
opacity: 0,
|
|
229
216
|
},
|
|
230
217
|
visible: {
|
|
231
218
|
height: 'auto',
|
|
@@ -234,8 +221,8 @@ function ExpandPanel({ isExpanded, children }: { isExpanded: boolean; children:
|
|
|
234
221
|
duration: 0.5,
|
|
235
222
|
ease: [0.22, 1, 0.36, 1],
|
|
236
223
|
staggerChildren: 0.08,
|
|
237
|
-
delayChildren: 0.1
|
|
238
|
-
}
|
|
224
|
+
delayChildren: 0.1,
|
|
225
|
+
},
|
|
239
226
|
},
|
|
240
227
|
exit: {
|
|
241
228
|
height: 0,
|
|
@@ -243,9 +230,9 @@ function ExpandPanel({ isExpanded, children }: { isExpanded: boolean; children:
|
|
|
243
230
|
transition: {
|
|
244
231
|
duration: 0.35,
|
|
245
232
|
staggerChildren: 0.05,
|
|
246
|
-
staggerDirection: -1
|
|
247
|
-
}
|
|
248
|
-
}
|
|
233
|
+
staggerDirection: -1,
|
|
234
|
+
},
|
|
235
|
+
},
|
|
249
236
|
}}
|
|
250
237
|
className="overflow-hidden"
|
|
251
238
|
>
|
|
@@ -254,20 +241,20 @@ function ExpandPanel({ isExpanded, children }: { isExpanded: boolean; children:
|
|
|
254
241
|
variants={{
|
|
255
242
|
hidden: {
|
|
256
243
|
opacity: 0,
|
|
257
|
-
y: 10
|
|
244
|
+
y: 10,
|
|
258
245
|
},
|
|
259
246
|
visible: {
|
|
260
247
|
opacity: 1,
|
|
261
248
|
y: 0,
|
|
262
249
|
transition: {
|
|
263
250
|
duration: 0.3,
|
|
264
|
-
ease: [0.22, 1, 0.36, 1]
|
|
265
|
-
}
|
|
251
|
+
ease: [0.22, 1, 0.36, 1],
|
|
252
|
+
},
|
|
266
253
|
},
|
|
267
254
|
exit: {
|
|
268
255
|
opacity: 0,
|
|
269
|
-
y: 6
|
|
270
|
-
}
|
|
256
|
+
y: 6,
|
|
257
|
+
},
|
|
271
258
|
}}
|
|
272
259
|
>
|
|
273
260
|
{child}
|
|
@@ -283,13 +270,13 @@ function DetailContent({
|
|
|
283
270
|
service,
|
|
284
271
|
index,
|
|
285
272
|
isExpanded,
|
|
286
|
-
onToggle
|
|
273
|
+
onToggle,
|
|
287
274
|
}: Omit<ServiceDetailCardProps, 'layout'>) {
|
|
288
275
|
const points = getPoints(service)
|
|
289
276
|
return (
|
|
290
277
|
<div className="flex h-full flex-col justify-center p-4 md:p-6">
|
|
291
278
|
{service.code && (
|
|
292
|
-
<span className="mb-3 block font-mono text-
|
|
279
|
+
<span className="mb-3 block font-mono text-xs tracking-[0.15em] text-stone-600 dark:text-stone-300">
|
|
293
280
|
{service.code}
|
|
294
281
|
</span>
|
|
295
282
|
)}
|
|
@@ -316,12 +303,12 @@ function DetailContent({
|
|
|
316
303
|
</div>
|
|
317
304
|
<ToggleButton isExpanded={isExpanded} onToggle={onToggle} />
|
|
318
305
|
<ExpandPanel isExpanded={isExpanded}>
|
|
319
|
-
<div className="mt-4 border-t border-
|
|
306
|
+
<div className="mt-4 border-t border-stone-300 dark:border-stone-700/10 pt-4">
|
|
320
307
|
<div className="flex flex-wrap gap-2">
|
|
321
308
|
{points.map((detail) => (
|
|
322
309
|
<span
|
|
323
310
|
key={detail}
|
|
324
|
-
className="arch-edge-sm border border-
|
|
311
|
+
className="arch-edge-sm rounded-md squircle border border-stone-300 px-3 py-1.5 text-xs text-stone-700 dark:border-stone-700/10 dark:text-stone-200"
|
|
325
312
|
>
|
|
326
313
|
{detail}
|
|
327
314
|
</span>
|
|
@@ -337,7 +324,7 @@ export function ServiceDetailCard(props: ServiceDetailCardProps) {
|
|
|
337
324
|
const { service, layout } = props
|
|
338
325
|
if (layout === 'center') {
|
|
339
326
|
return (
|
|
340
|
-
<div className="z-plane-2 chamfer-accent relative overflow-hidden">
|
|
327
|
+
<div className="z-plane-2 chamfer-accent relative overflow-hidden rounded-md squircle border border-stone-300 bg-stone-100/50 transition-all duration-300 dark:border-stone-700/10 dark:bg-stone-900/50">
|
|
341
328
|
<div className="pointer-events-none absolute inset-0 opacity-30">
|
|
342
329
|
<VisualContent service={service} />
|
|
343
330
|
</div>
|
|
@@ -350,8 +337,8 @@ export function ServiceDetailCard(props: ServiceDetailCardProps) {
|
|
|
350
337
|
|
|
351
338
|
if (layout === 'bleed') {
|
|
352
339
|
return (
|
|
353
|
-
<div className="z-plane-2 chamfer-accent relative overflow-hidden">
|
|
354
|
-
<div className="pointer-events-none absolute right-0 top-0 hidden h-full min-h-
|
|
340
|
+
<div className="z-plane-2 chamfer-accent relative overflow-hidden rounded-md squircle border border-stone-300 bg-stone-100/50 transition-all duration-300 dark:border-stone-700/10 dark:bg-stone-900/50">
|
|
341
|
+
<div className="pointer-events-none absolute right-0 top-0 hidden h-full min-h-75 w-1/2 opacity-30 lg:block">
|
|
355
342
|
<VisualContent service={service} />
|
|
356
343
|
</div>
|
|
357
344
|
<div className="relative max-w-2xl">
|
|
@@ -370,9 +357,7 @@ export function ServiceDetailCard(props: ServiceDetailCardProps) {
|
|
|
370
357
|
<div className="z-plane-2 chamfer-accent">
|
|
371
358
|
<div className={cn('grid grid-cols-1 gap-0', gridClass)}>
|
|
372
359
|
{visualFirst && (
|
|
373
|
-
<div
|
|
374
|
-
className={cn('flex min-h-[300px] items-center justify-center p-4 md:p-6', visualClass)}
|
|
375
|
-
>
|
|
360
|
+
<div className={cn('flex min-h-75 items-center justify-center p-4 md:p-6', visualClass)}>
|
|
376
361
|
<VisualContent service={service} />
|
|
377
362
|
</div>
|
|
378
363
|
)}
|
|
@@ -380,9 +365,7 @@ export function ServiceDetailCard(props: ServiceDetailCardProps) {
|
|
|
380
365
|
<DetailContent {...props} />
|
|
381
366
|
</div>
|
|
382
367
|
{!visualFirst && (
|
|
383
|
-
<div
|
|
384
|
-
className={cn('flex min-h-[300px] items-center justify-center p-4 md:p-6', visualClass)}
|
|
385
|
-
>
|
|
368
|
+
<div className={cn('flex min-h-75 items-center justify-center p-4 md:p-6', visualClass)}>
|
|
386
369
|
<VisualContent service={service} />
|
|
387
370
|
</div>
|
|
388
371
|
)}
|
|
@@ -24,7 +24,7 @@ const minHeightClassMap: Record<NonNullable<DDHGServiceHeroProps['minHeight']>,
|
|
|
24
24
|
screen: 'min-h-screen',
|
|
25
25
|
large: 'min-h-[70vh]',
|
|
26
26
|
medium: 'min-h-[56vh]',
|
|
27
|
-
compact: 'min-h-[42vh]'
|
|
27
|
+
compact: 'min-h-[42vh]',
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
let globalInstanceCounter = 0
|
|
@@ -32,7 +32,7 @@ let globalInstanceCounter = 0
|
|
|
32
32
|
function FadeUpOnInView({
|
|
33
33
|
children,
|
|
34
34
|
className = '',
|
|
35
|
-
delay = 0
|
|
35
|
+
delay = 0,
|
|
36
36
|
}: {
|
|
37
37
|
children: React.ReactNode
|
|
38
38
|
className?: string
|
|
@@ -54,7 +54,7 @@ function FadeUpOnInView({
|
|
|
54
54
|
node.style.transitionDelay = '0s'
|
|
55
55
|
}
|
|
56
56
|
},
|
|
57
|
-
{ threshold: 0.25 }
|
|
57
|
+
{ threshold: 0.25 },
|
|
58
58
|
)
|
|
59
59
|
observer.observe(node)
|
|
60
60
|
return () => observer.disconnect()
|
|
@@ -67,7 +67,7 @@ function FadeUpOnInView({
|
|
|
67
67
|
display: 'inline-block',
|
|
68
68
|
opacity: 0,
|
|
69
69
|
transform: 'translateY(24px)',
|
|
70
|
-
transition: 'opacity 700ms ease, transform 700ms ease'
|
|
70
|
+
transition: 'opacity 700ms ease, transform 700ms ease',
|
|
71
71
|
}}
|
|
72
72
|
>
|
|
73
73
|
{children}
|
|
@@ -78,7 +78,7 @@ function FadeUpOnInView({
|
|
|
78
78
|
function RevealText({
|
|
79
79
|
text,
|
|
80
80
|
className = '',
|
|
81
|
-
instanceIndex
|
|
81
|
+
instanceIndex,
|
|
82
82
|
}: {
|
|
83
83
|
text: string[]
|
|
84
84
|
className?: string
|
|
@@ -101,7 +101,7 @@ function RevealText({
|
|
|
101
101
|
setAnimationKey((key) => key + 1)
|
|
102
102
|
} else setIsVisible(false)
|
|
103
103
|
},
|
|
104
|
-
{ threshold: 0.3 }
|
|
104
|
+
{ threshold: 0.3 },
|
|
105
105
|
)
|
|
106
106
|
observer.observe(node)
|
|
107
107
|
return () => observer.disconnect()
|
|
@@ -117,7 +117,7 @@ function RevealText({
|
|
|
117
117
|
ref={textRef}
|
|
118
118
|
className={cn(
|
|
119
119
|
'inline-block h-auto bg-transparent text-left font-bold uppercase leading-none tracking-[1px]',
|
|
120
|
-
className
|
|
120
|
+
className,
|
|
121
121
|
)}
|
|
122
122
|
>
|
|
123
123
|
{words.map((word, wordIndex) => {
|
|
@@ -140,7 +140,7 @@ function RevealText({
|
|
|
140
140
|
animationName: isVisible ? 'ddhgServiceHeroReveal' : 'none',
|
|
141
141
|
animationDuration: '1s',
|
|
142
142
|
animationFillMode: 'forwards',
|
|
143
|
-
animationDelay: `${baseDelay + index * 0.05}s
|
|
143
|
+
animationDelay: `${baseDelay + index * 0.05}s`,
|
|
144
144
|
}}
|
|
145
145
|
>
|
|
146
146
|
{char}
|
|
@@ -169,7 +169,7 @@ export const DDHGServiceHero: React.FC<DDHGServiceHeroProps> = ({
|
|
|
169
169
|
description = 'From initial vision to final handover, our services span the full spectrum of interior architecture. Each engagement is shaped by the same principle: spaces should serve the people inside them.',
|
|
170
170
|
minHeight = 'large',
|
|
171
171
|
showDivider = true,
|
|
172
|
-
showScrollIndicator = true
|
|
172
|
+
showScrollIndicator = true,
|
|
173
173
|
}) => {
|
|
174
174
|
const minHeightClass = minHeightClassMap[minHeight || 'large']
|
|
175
175
|
return (
|
|
@@ -182,7 +182,7 @@ export const DDHGServiceHero: React.FC<DDHGServiceHeroProps> = ({
|
|
|
182
182
|
>
|
|
183
183
|
{customCSS && <style dangerouslySetInnerHTML={{ __html: customCSS }} />}
|
|
184
184
|
<motion.div
|
|
185
|
-
className="ServiceHeroCard relative z-10 mx-auto max-w-
|
|
185
|
+
className="ServiceHeroCard relative z-10 mx-auto w-full max-w-7xl overflow-clip rounded-md squircle bg-stone-100/50 p-6 dark:bg-stone-900/50 md:p-8"
|
|
186
186
|
initial={{ opacity: 0, y: 20 }}
|
|
187
187
|
whileInView={{ opacity: 1, y: 0 }}
|
|
188
188
|
viewport={{ once: true, amount: 0.35 }}
|