@roottale/cms-renderer-next 0.41.1 → 0.42.0

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 (60) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/dist/before-after-client.d.ts +15 -0
  3. package/dist/before-after-client.js +8 -0
  4. package/dist/before-after-client.js.map +1 -0
  5. package/dist/chunk-4LQPZDXZ.js +75 -0
  6. package/dist/chunk-4LQPZDXZ.js.map +1 -0
  7. package/dist/chunk-6GQCFFHU.js +540 -0
  8. package/dist/chunk-6GQCFFHU.js.map +1 -0
  9. package/dist/chunk-F3G6RVIR.js +220 -0
  10. package/dist/chunk-F3G6RVIR.js.map +1 -0
  11. package/dist/chunk-H46JUIHZ.js +79 -0
  12. package/dist/chunk-H46JUIHZ.js.map +1 -0
  13. package/dist/chunk-K62RR4UQ.js +53 -0
  14. package/dist/chunk-K62RR4UQ.js.map +1 -0
  15. package/dist/chunk-NUUTTSGT.js +916 -0
  16. package/dist/chunk-NUUTTSGT.js.map +1 -0
  17. package/dist/chunk-RSNUZ4BF.js +3378 -0
  18. package/dist/chunk-RSNUZ4BF.js.map +1 -0
  19. package/dist/chunk-U5AKACPN.js +113 -0
  20. package/dist/chunk-U5AKACPN.js.map +1 -0
  21. package/dist/chunk-WWS43XCT.js +206 -0
  22. package/dist/chunk-WWS43XCT.js.map +1 -0
  23. package/dist/cms-public.css +164 -51
  24. package/dist/concerns-client.d.ts +12 -0
  25. package/dist/concerns-client.js +8 -0
  26. package/dist/concerns-client.js.map +1 -0
  27. package/dist/expertise-client.d.ts +10 -0
  28. package/dist/expertise-client.js +8 -0
  29. package/dist/expertise-client.js.map +1 -0
  30. package/dist/hero-carousel-client.d.ts +36 -0
  31. package/dist/hero-carousel-client.js +8 -0
  32. package/dist/hero-carousel-client.js.map +1 -0
  33. package/dist/routes.d.ts +51 -5
  34. package/dist/routes.js +109 -62
  35. package/dist/routes.js.map +1 -1
  36. package/dist/seo-checks.d.ts +87 -0
  37. package/dist/seo-checks.js +27 -0
  38. package/dist/seo-checks.js.map +1 -0
  39. package/dist/server.d.ts +51 -2
  40. package/dist/server.js +8 -2
  41. package/dist/site-config-DgYGGwu1.d.ts +3910 -0
  42. package/dist/spaces-client.d.ts +10 -0
  43. package/dist/spaces-client.js +8 -0
  44. package/dist/spaces-client.js.map +1 -0
  45. package/dist/templates.css +3246 -194
  46. package/dist/templates.d.ts +20 -1028
  47. package/dist/templates.js +70 -2
  48. package/dist/templates.js.map +1 -1
  49. package/dist/{theme-css-vars-BiyHBsJG.d.ts → theme-css-vars-CD3jcEkp.d.ts} +2 -2
  50. package/dist/ui-react-motion-client.d.ts +73 -0
  51. package/dist/ui-react-motion-client.js +14 -0
  52. package/dist/ui-react-motion-client.js.map +1 -0
  53. package/dist/validate.d.ts +15 -1
  54. package/dist/validate.js +806 -17
  55. package/dist/validate.js.map +1 -1
  56. package/package.json +18 -6
  57. package/dist/chunk-GOHP7RWD.js +0 -1647
  58. package/dist/chunk-GOHP7RWD.js.map +0 -1
  59. package/dist/chunk-IOYBEH6E.js +0 -271
  60. package/dist/chunk-IOYBEH6E.js.map +0 -1
@@ -1,1030 +1,14 @@
1
- import { z } from 'zod';
2
- export { R as RootTaleCssVars, t as themeToCssVars } from './theme-css-vars-BiyHBsJG.js';
1
+ import { C as ConcernsSection, E as ExpertiseSection, S as SpacesSection, B as BeforeAfterSection, a as ContactSection, b as CtaBannerSection, F as FaqSection, c as FooterSection, H as HeroSection, d as HoursSection, P as PricingSection, e as ProcessSection, R as RichTextSection, f as ServicesSection, T as TeamSection, g as TestimonialsSection, h as TrustSection, i as SiteConfig, j as SiteConfigInput } from './site-config-DgYGGwu1.js';
2
+ export { k as BUILTIN_SECTION_SCHEMAS, l as BUILTIN_SECTION_TYPES, m as BeforeAfterSectionSchema, n as BlogListSection, o as BlogListSectionSchema, p as ConcernsSectionSchema, q as ContactSectionSchema, r as CtaBannerSectionSchema, s as CustomSection, t as CustomSectionSchema, u as ExpertiseSectionSchema, v as FaqSectionSchema, w as FooterSectionSchema, x as HeroSectionSchema, y as HoursSectionSchema, L as LeadFormSection, z as LeadFormSectionSchema, N as NavItem, A as NavItemSchema, D as PricingSectionSchema, G as ProcessSectionSchema, I as RichTextSectionSchema, J as SECTION_VARIANTS, K as Section, M as SectionCta, O as SectionInput, Q as SectionSchema, U as ServicesSectionSchema, V as SiteConfigSchema, W as SpacesSectionSchema, X as TeamSectionSchema, Y as TestimonialsSectionSchema, Z as TrustSectionSchema, _ as defineSiteConfig, $ as parseSiteConfig } from './site-config-DgYGGwu1.js';
3
+ export { R as RootTaleCssVars, t as themeToCssVars } from './theme-css-vars-CD3jcEkp.js';
3
4
  import { ReactElement, CSSProperties, ReactNode } from 'react';
5
+ import 'zod';
4
6
  import '@roottale/cms-client/server';
7
+ import '@roottale/ui-react/theme';
5
8
 
6
- /**
7
- * `@roottale/cms-renderer-next/templates` — canonical `SiteConfig` 스키마.
8
- *
9
- * ADR-0040 P2 + P0.5 RFC §① (`roottale-docs/docs/services/external-site-blockification.md`).
10
- *
11
- * 설계 원칙 (codex consult #1 반영):
12
- * - **계약 = `section type + variant + renderer registry`.** tier 는 스키마 필드가
13
- * 아니라 문서/거버넌스용 성숙도 메타데이터.
14
- * - **100% serializable** — 함수/JSX 금지 (Astro parity + admin preview 동일 경로).
15
- * escape hatch 는 config 안 함수가 아니라 `customSections` registry
16
- * (`SiteRenderer` 에 빌드 시 type→컴포넌트 주입).
17
- * - CMS-bound 섹션(`blog-list`/`lead-form`)은 `RootTaleBlogList`/`RootTaleLeadForm`
18
- * 으로 위임 — templates 는 cms-renderer 코어를 단방향 의존 (RFC §②).
19
- *
20
- * RFC §① 대비 구현 정정:
21
- * - `site.url` 은 optional — 스타터/외부 사이트가 `SITE_URL` env 로 런타임 해석하는
22
- * 기존 패턴(P4 스타터)과 충돌하므로 config 강제 대신 env fallback 허용.
23
- * - 빌트인에 `rich-text` 추가 (P4 스타터 기 운영 섹션 — "동일 패턴" 군).
24
- * allow: SIZE_OK — canonical SectionSchema registry이며 W1-2 계약이 이 파일 수정을 요구한다.
25
- */
26
-
27
- declare const NavItemSchema: z.ZodObject<{
28
- label: z.ZodString;
29
- href: z.ZodString;
30
- children: z.ZodOptional<z.ZodArray<z.ZodObject<{
31
- label: z.ZodString;
32
- href: z.ZodString;
33
- }, "strip", z.ZodTypeAny, {
34
- href: string;
35
- label: string;
36
- }, {
37
- href: string;
38
- label: string;
39
- }>, "many">>;
40
- }, "strip", z.ZodTypeAny, {
41
- href: string;
42
- label: string;
43
- children?: {
44
- href: string;
45
- label: string;
46
- }[] | undefined;
47
- }, {
48
- href: string;
49
- label: string;
50
- children?: {
51
- href: string;
52
- label: string;
53
- }[] | undefined;
54
- }>;
55
- type NavItem = z.infer<typeof NavItemSchema>;
56
- declare const CtaSchema: z.ZodObject<{
57
- label: z.ZodString;
58
- href: z.ZodString;
59
- }, "strip", z.ZodTypeAny, {
60
- href: string;
61
- label: string;
62
- }, {
63
- href: string;
64
- label: string;
65
- }>;
66
- type SectionCta = z.infer<typeof CtaSchema>;
67
- declare const HeroSectionSchema: z.ZodObject<{
68
- id: z.ZodOptional<z.ZodString>;
69
- theme: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
70
- } & {
71
- type: z.ZodLiteral<"hero">;
72
- variant: z.ZodDefault<z.ZodEnum<["split", "image", "minimal"]>>;
73
- props: z.ZodObject<{
74
- eyebrow: z.ZodOptional<z.ZodString>;
75
- /** `\n` 으로 줄바꿈. */
76
- title: z.ZodString;
77
- description: z.ZodOptional<z.ZodString>;
78
- imageSrc: z.ZodOptional<z.ZodString>;
79
- imageAlt: z.ZodOptional<z.ZodString>;
80
- cta: z.ZodOptional<z.ZodObject<{
81
- label: z.ZodString;
82
- href: z.ZodString;
83
- }, "strip", z.ZodTypeAny, {
84
- href: string;
85
- label: string;
86
- }, {
87
- href: string;
88
- label: string;
89
- }>>;
90
- }, "strip", z.ZodTypeAny, {
91
- title: string;
92
- description?: string | undefined;
93
- eyebrow?: string | undefined;
94
- imageSrc?: string | undefined;
95
- imageAlt?: string | undefined;
96
- cta?: {
97
- href: string;
98
- label: string;
99
- } | undefined;
100
- }, {
101
- title: string;
102
- description?: string | undefined;
103
- eyebrow?: string | undefined;
104
- imageSrc?: string | undefined;
105
- imageAlt?: string | undefined;
106
- cta?: {
107
- href: string;
108
- label: string;
109
- } | undefined;
110
- }>;
111
- }, "strip", z.ZodTypeAny, {
112
- type: "hero";
113
- variant: "image" | "split" | "minimal";
114
- props: {
115
- title: string;
116
- description?: string | undefined;
117
- eyebrow?: string | undefined;
118
- imageSrc?: string | undefined;
119
- imageAlt?: string | undefined;
120
- cta?: {
121
- href: string;
122
- label: string;
123
- } | undefined;
124
- };
125
- theme?: Record<string, string> | undefined;
126
- id?: string | undefined;
127
- }, {
128
- type: "hero";
129
- props: {
130
- title: string;
131
- description?: string | undefined;
132
- eyebrow?: string | undefined;
133
- imageSrc?: string | undefined;
134
- imageAlt?: string | undefined;
135
- cta?: {
136
- href: string;
137
- label: string;
138
- } | undefined;
139
- };
140
- theme?: Record<string, string> | undefined;
141
- id?: string | undefined;
142
- variant?: "image" | "split" | "minimal" | undefined;
143
- }>;
144
- declare const RichTextSectionSchema: z.ZodObject<{
145
- id: z.ZodOptional<z.ZodString>;
146
- variant: z.ZodOptional<z.ZodString>;
147
- theme: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
148
- } & {
149
- type: z.ZodLiteral<"rich-text">;
150
- props: z.ZodObject<{
151
- heading: z.ZodOptional<z.ZodString>;
152
- /** `\n\n` 으로 문단 분리. */
153
- body: z.ZodString;
154
- }, "strip", z.ZodTypeAny, {
155
- body: string;
156
- heading?: string | undefined;
157
- }, {
158
- body: string;
159
- heading?: string | undefined;
160
- }>;
161
- }, "strip", z.ZodTypeAny, {
162
- type: "rich-text";
163
- props: {
164
- body: string;
165
- heading?: string | undefined;
166
- };
167
- theme?: Record<string, string> | undefined;
168
- id?: string | undefined;
169
- variant?: string | undefined;
170
- }, {
171
- type: "rich-text";
172
- props: {
173
- body: string;
174
- heading?: string | undefined;
175
- };
176
- theme?: Record<string, string> | undefined;
177
- id?: string | undefined;
178
- variant?: string | undefined;
179
- }>;
180
- declare const ServicesSectionSchema: z.ZodObject<{
181
- id: z.ZodOptional<z.ZodString>;
182
- theme: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
183
- } & {
184
- type: z.ZodLiteral<"services">;
185
- variant: z.ZodDefault<z.ZodEnum<["grid", "list"]>>;
186
- props: z.ZodObject<{
187
- heading: z.ZodOptional<z.ZodString>;
188
- description: z.ZodOptional<z.ZodString>;
189
- items: z.ZodArray<z.ZodObject<{
190
- title: z.ZodString;
191
- description: z.ZodOptional<z.ZodString>;
192
- href: z.ZodOptional<z.ZodString>;
193
- }, "strip", z.ZodTypeAny, {
194
- title: string;
195
- href?: string | undefined;
196
- description?: string | undefined;
197
- }, {
198
- title: string;
199
- href?: string | undefined;
200
- description?: string | undefined;
201
- }>, "many">;
202
- }, "strip", z.ZodTypeAny, {
203
- items: {
204
- title: string;
205
- href?: string | undefined;
206
- description?: string | undefined;
207
- }[];
208
- heading?: string | undefined;
209
- description?: string | undefined;
210
- }, {
211
- items: {
212
- title: string;
213
- href?: string | undefined;
214
- description?: string | undefined;
215
- }[];
216
- heading?: string | undefined;
217
- description?: string | undefined;
218
- }>;
219
- }, "strip", z.ZodTypeAny, {
220
- type: "services";
221
- variant: "grid" | "list";
222
- props: {
223
- items: {
224
- title: string;
225
- href?: string | undefined;
226
- description?: string | undefined;
227
- }[];
228
- heading?: string | undefined;
229
- description?: string | undefined;
230
- };
231
- theme?: Record<string, string> | undefined;
232
- id?: string | undefined;
233
- }, {
234
- type: "services";
235
- props: {
236
- items: {
237
- title: string;
238
- href?: string | undefined;
239
- description?: string | undefined;
240
- }[];
241
- heading?: string | undefined;
242
- description?: string | undefined;
243
- };
244
- theme?: Record<string, string> | undefined;
245
- id?: string | undefined;
246
- variant?: "grid" | "list" | undefined;
247
- }>;
248
- declare const FaqSectionSchema: z.ZodObject<{
249
- id: z.ZodOptional<z.ZodString>;
250
- variant: z.ZodOptional<z.ZodString>;
251
- theme: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
252
- } & {
253
- type: z.ZodLiteral<"faq">;
254
- props: z.ZodObject<{
255
- heading: z.ZodOptional<z.ZodString>;
256
- items: z.ZodArray<z.ZodObject<{
257
- question: z.ZodString;
258
- answer: z.ZodString;
259
- }, "strip", z.ZodTypeAny, {
260
- question: string;
261
- answer: string;
262
- }, {
263
- question: string;
264
- answer: string;
265
- }>, "many">;
266
- /** FAQPage JSON-LD 주입 (기본 true — SEO 3 pillars). 페이지에 FAQ 섹션이 여럿이면 하나만 true 로. */
267
- jsonLd: z.ZodDefault<z.ZodBoolean>;
268
- }, "strip", z.ZodTypeAny, {
269
- items: {
270
- question: string;
271
- answer: string;
272
- }[];
273
- jsonLd: boolean;
274
- heading?: string | undefined;
275
- }, {
276
- items: {
277
- question: string;
278
- answer: string;
279
- }[];
280
- heading?: string | undefined;
281
- jsonLd?: boolean | undefined;
282
- }>;
283
- }, "strip", z.ZodTypeAny, {
284
- type: "faq";
285
- props: {
286
- items: {
287
- question: string;
288
- answer: string;
289
- }[];
290
- jsonLd: boolean;
291
- heading?: string | undefined;
292
- };
293
- theme?: Record<string, string> | undefined;
294
- id?: string | undefined;
295
- variant?: string | undefined;
296
- }, {
297
- type: "faq";
298
- props: {
299
- items: {
300
- question: string;
301
- answer: string;
302
- }[];
303
- heading?: string | undefined;
304
- jsonLd?: boolean | undefined;
305
- };
306
- theme?: Record<string, string> | undefined;
307
- id?: string | undefined;
308
- variant?: string | undefined;
309
- }>;
310
- declare const CtaBannerSectionSchema: z.ZodObject<{
311
- id: z.ZodOptional<z.ZodString>;
312
- variant: z.ZodOptional<z.ZodString>;
313
- theme: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
314
- } & {
315
- type: z.ZodLiteral<"cta-banner">;
316
- props: z.ZodObject<{
317
- title: z.ZodString;
318
- description: z.ZodOptional<z.ZodString>;
319
- cta: z.ZodOptional<z.ZodObject<{
320
- label: z.ZodString;
321
- href: z.ZodString;
322
- }, "strip", z.ZodTypeAny, {
323
- href: string;
324
- label: string;
325
- }, {
326
- href: string;
327
- label: string;
328
- }>>;
329
- }, "strip", z.ZodTypeAny, {
330
- title: string;
331
- description?: string | undefined;
332
- cta?: {
333
- href: string;
334
- label: string;
335
- } | undefined;
336
- }, {
337
- title: string;
338
- description?: string | undefined;
339
- cta?: {
340
- href: string;
341
- label: string;
342
- } | undefined;
343
- }>;
344
- }, "strip", z.ZodTypeAny, {
345
- type: "cta-banner";
346
- props: {
347
- title: string;
348
- description?: string | undefined;
349
- cta?: {
350
- href: string;
351
- label: string;
352
- } | undefined;
353
- };
354
- theme?: Record<string, string> | undefined;
355
- id?: string | undefined;
356
- variant?: string | undefined;
357
- }, {
358
- type: "cta-banner";
359
- props: {
360
- title: string;
361
- description?: string | undefined;
362
- cta?: {
363
- href: string;
364
- label: string;
365
- } | undefined;
366
- };
367
- theme?: Record<string, string> | undefined;
368
- id?: string | undefined;
369
- variant?: string | undefined;
370
- }>;
371
- /** → `RootTaleBlogList` 위임 (cms-bound). */
372
- declare const BlogListSectionSchema: z.ZodObject<{
373
- id: z.ZodOptional<z.ZodString>;
374
- variant: z.ZodOptional<z.ZodString>;
375
- theme: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
376
- } & {
377
- type: z.ZodLiteral<"blog-list">;
378
- props: z.ZodObject<{
379
- heading: z.ZodOptional<z.ZodString>;
380
- limit: z.ZodOptional<z.ZodNumber>;
381
- /** 포스트 링크 베이스. 기본 `/blog`. */
382
- blogBasePath: z.ZodOptional<z.ZodString>;
383
- emptyMessage: z.ZodOptional<z.ZodString>;
384
- }, "strip", z.ZodTypeAny, {
385
- limit?: number | undefined;
386
- emptyMessage?: string | undefined;
387
- heading?: string | undefined;
388
- blogBasePath?: string | undefined;
389
- }, {
390
- limit?: number | undefined;
391
- emptyMessage?: string | undefined;
392
- heading?: string | undefined;
393
- blogBasePath?: string | undefined;
394
- }>;
395
- }, "strip", z.ZodTypeAny, {
396
- type: "blog-list";
397
- props: {
398
- limit?: number | undefined;
399
- emptyMessage?: string | undefined;
400
- heading?: string | undefined;
401
- blogBasePath?: string | undefined;
402
- };
403
- theme?: Record<string, string> | undefined;
404
- id?: string | undefined;
405
- variant?: string | undefined;
406
- }, {
407
- type: "blog-list";
408
- props: {
409
- limit?: number | undefined;
410
- emptyMessage?: string | undefined;
411
- heading?: string | undefined;
412
- blogBasePath?: string | undefined;
413
- };
414
- theme?: Record<string, string> | undefined;
415
- id?: string | undefined;
416
- variant?: string | undefined;
417
- }>;
418
- /** → `RootTaleLeadForm` 위임 (cms-bound). */
419
- declare const LeadFormSectionSchema: z.ZodObject<{
420
- id: z.ZodOptional<z.ZodString>;
421
- variant: z.ZodOptional<z.ZodString>;
422
- theme: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
423
- } & {
424
- type: z.ZodLiteral<"lead-form">;
425
- props: z.ZodObject<{
426
- /** 사이트 자체 server 엔드포인트 (예: `/api/inquiry`). intake API 직접 지정 금지. */
427
- action: z.ZodString;
428
- vertical: z.ZodOptional<z.ZodEnum<["consulting", "medical", "tax", "legal"]>>;
429
- heading: z.ZodOptional<z.ZodString>;
430
- description: z.ZodOptional<z.ZodString>;
431
- submitLabel: z.ZodOptional<z.ZodString>;
432
- }, "strip", z.ZodTypeAny, {
433
- action: string;
434
- vertical?: "consulting" | "medical" | "tax" | "legal" | undefined;
435
- heading?: string | undefined;
436
- description?: string | undefined;
437
- submitLabel?: string | undefined;
438
- }, {
439
- action: string;
440
- vertical?: "consulting" | "medical" | "tax" | "legal" | undefined;
441
- heading?: string | undefined;
442
- description?: string | undefined;
443
- submitLabel?: string | undefined;
444
- }>;
445
- }, "strip", z.ZodTypeAny, {
446
- type: "lead-form";
447
- props: {
448
- action: string;
449
- vertical?: "consulting" | "medical" | "tax" | "legal" | undefined;
450
- heading?: string | undefined;
451
- description?: string | undefined;
452
- submitLabel?: string | undefined;
453
- };
454
- theme?: Record<string, string> | undefined;
455
- id?: string | undefined;
456
- variant?: string | undefined;
457
- }, {
458
- type: "lead-form";
459
- props: {
460
- action: string;
461
- vertical?: "consulting" | "medical" | "tax" | "legal" | undefined;
462
- heading?: string | undefined;
463
- description?: string | undefined;
464
- submitLabel?: string | undefined;
465
- };
466
- theme?: Record<string, string> | undefined;
467
- id?: string | undefined;
468
- variant?: string | undefined;
469
- }>;
470
- declare const TrustSectionSchema: z.ZodEffects<z.ZodObject<{
471
- id: z.ZodOptional<z.ZodString>;
472
- theme: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
473
- } & {
474
- type: z.ZodLiteral<"trust">;
475
- variant: z.ZodDefault<z.ZodEnum<["stat-band", "logo-cloud", "feature-grid"]>>;
476
- props: z.ZodObject<{
477
- heading: z.ZodOptional<z.ZodString>;
478
- metrics: z.ZodOptional<z.ZodArray<z.ZodObject<{
479
- value: z.ZodString;
480
- unit: z.ZodOptional<z.ZodString>;
481
- label: z.ZodString;
482
- source: z.ZodOptional<z.ZodString>;
483
- }, "strip", z.ZodTypeAny, {
484
- value: string;
485
- label: string;
486
- unit?: string | undefined;
487
- source?: string | undefined;
488
- }, {
489
- value: string;
490
- label: string;
491
- unit?: string | undefined;
492
- source?: string | undefined;
493
- }>, "many">>;
494
- credentials: z.ZodOptional<z.ZodArray<z.ZodObject<{
495
- name: z.ZodString;
496
- issuer: z.ZodOptional<z.ZodString>;
497
- kind: z.ZodOptional<z.ZodEnum<["license", "education", "association"]>>;
498
- image: z.ZodOptional<z.ZodString>;
499
- }, "strip", z.ZodTypeAny, {
500
- name: string;
501
- image?: string | undefined;
502
- issuer?: string | undefined;
503
- kind?: "license" | "education" | "association" | undefined;
504
- }, {
505
- name: string;
506
- image?: string | undefined;
507
- issuer?: string | undefined;
508
- kind?: "license" | "education" | "association" | undefined;
509
- }>, "many">>;
510
- logos: z.ZodOptional<z.ZodArray<z.ZodObject<{
511
- src: z.ZodString;
512
- alt: z.ZodString;
513
- href: z.ZodOptional<z.ZodString>;
514
- }, "strip", z.ZodTypeAny, {
515
- src: string;
516
- alt: string;
517
- href?: string | undefined;
518
- }, {
519
- src: string;
520
- alt: string;
521
- href?: string | undefined;
522
- }>, "many">>;
523
- disclaimer: z.ZodOptional<z.ZodString>;
524
- }, "strip", z.ZodTypeAny, {
525
- heading?: string | undefined;
526
- metrics?: {
527
- value: string;
528
- label: string;
529
- unit?: string | undefined;
530
- source?: string | undefined;
531
- }[] | undefined;
532
- credentials?: {
533
- name: string;
534
- image?: string | undefined;
535
- issuer?: string | undefined;
536
- kind?: "license" | "education" | "association" | undefined;
537
- }[] | undefined;
538
- logos?: {
539
- src: string;
540
- alt: string;
541
- href?: string | undefined;
542
- }[] | undefined;
543
- disclaimer?: string | undefined;
544
- }, {
545
- heading?: string | undefined;
546
- metrics?: {
547
- value: string;
548
- label: string;
549
- unit?: string | undefined;
550
- source?: string | undefined;
551
- }[] | undefined;
552
- credentials?: {
553
- name: string;
554
- image?: string | undefined;
555
- issuer?: string | undefined;
556
- kind?: "license" | "education" | "association" | undefined;
557
- }[] | undefined;
558
- logos?: {
559
- src: string;
560
- alt: string;
561
- href?: string | undefined;
562
- }[] | undefined;
563
- disclaimer?: string | undefined;
564
- }>;
565
- }, "strip", z.ZodTypeAny, {
566
- type: "trust";
567
- variant: "stat-band" | "logo-cloud" | "feature-grid";
568
- props: {
569
- heading?: string | undefined;
570
- metrics?: {
571
- value: string;
572
- label: string;
573
- unit?: string | undefined;
574
- source?: string | undefined;
575
- }[] | undefined;
576
- credentials?: {
577
- name: string;
578
- image?: string | undefined;
579
- issuer?: string | undefined;
580
- kind?: "license" | "education" | "association" | undefined;
581
- }[] | undefined;
582
- logos?: {
583
- src: string;
584
- alt: string;
585
- href?: string | undefined;
586
- }[] | undefined;
587
- disclaimer?: string | undefined;
588
- };
589
- theme?: Record<string, string> | undefined;
590
- id?: string | undefined;
591
- }, {
592
- type: "trust";
593
- props: {
594
- heading?: string | undefined;
595
- metrics?: {
596
- value: string;
597
- label: string;
598
- unit?: string | undefined;
599
- source?: string | undefined;
600
- }[] | undefined;
601
- credentials?: {
602
- name: string;
603
- image?: string | undefined;
604
- issuer?: string | undefined;
605
- kind?: "license" | "education" | "association" | undefined;
606
- }[] | undefined;
607
- logos?: {
608
- src: string;
609
- alt: string;
610
- href?: string | undefined;
611
- }[] | undefined;
612
- disclaimer?: string | undefined;
613
- };
614
- theme?: Record<string, string> | undefined;
615
- id?: string | undefined;
616
- variant?: "stat-band" | "logo-cloud" | "feature-grid" | undefined;
617
- }>, {
618
- type: "trust";
619
- variant: "stat-band" | "logo-cloud" | "feature-grid";
620
- props: {
621
- heading?: string | undefined;
622
- metrics?: {
623
- value: string;
624
- label: string;
625
- unit?: string | undefined;
626
- source?: string | undefined;
627
- }[] | undefined;
628
- credentials?: {
629
- name: string;
630
- image?: string | undefined;
631
- issuer?: string | undefined;
632
- kind?: "license" | "education" | "association" | undefined;
633
- }[] | undefined;
634
- logos?: {
635
- src: string;
636
- alt: string;
637
- href?: string | undefined;
638
- }[] | undefined;
639
- disclaimer?: string | undefined;
640
- };
641
- theme?: Record<string, string> | undefined;
642
- id?: string | undefined;
643
- }, {
644
- type: "trust";
645
- props: {
646
- heading?: string | undefined;
647
- metrics?: {
648
- value: string;
649
- label: string;
650
- unit?: string | undefined;
651
- source?: string | undefined;
652
- }[] | undefined;
653
- credentials?: {
654
- name: string;
655
- image?: string | undefined;
656
- issuer?: string | undefined;
657
- kind?: "license" | "education" | "association" | undefined;
658
- }[] | undefined;
659
- logos?: {
660
- src: string;
661
- alt: string;
662
- href?: string | undefined;
663
- }[] | undefined;
664
- disclaimer?: string | undefined;
665
- };
666
- theme?: Record<string, string> | undefined;
667
- id?: string | undefined;
668
- variant?: "stat-band" | "logo-cloud" | "feature-grid" | undefined;
669
- }>;
670
- declare const ContactSectionSchema: z.ZodObject<{
671
- id: z.ZodOptional<z.ZodString>;
672
- theme: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
673
- } & {
674
- type: z.ZodLiteral<"contact">;
675
- variant: z.ZodDefault<z.ZodEnum<["form-map-5050", "split"]>>;
676
- props: z.ZodObject<{
677
- heading: z.ZodOptional<z.ZodString>;
678
- form: z.ZodObject<{
679
- enabled: z.ZodBoolean;
680
- vertical: z.ZodOptional<z.ZodEnum<["medical", "tax", "legal", "consulting"]>>;
681
- }, "strip", z.ZodTypeAny, {
682
- enabled: boolean;
683
- vertical?: "consulting" | "medical" | "tax" | "legal" | undefined;
684
- }, {
685
- enabled: boolean;
686
- vertical?: "consulting" | "medical" | "tax" | "legal" | undefined;
687
- }>;
688
- phone: z.ZodOptional<z.ZodString>;
689
- address: z.ZodOptional<z.ZodString>;
690
- hours: z.ZodOptional<z.ZodArray<z.ZodObject<{
691
- day: z.ZodString;
692
- open: z.ZodString;
693
- close: z.ZodString;
694
- note: z.ZodOptional<z.ZodString>;
695
- }, "strip", z.ZodTypeAny, {
696
- open: string;
697
- day: string;
698
- close: string;
699
- note?: string | undefined;
700
- }, {
701
- open: string;
702
- day: string;
703
- close: string;
704
- note?: string | undefined;
705
- }>, "many">>;
706
- mapEmbedUrl: z.ZodOptional<z.ZodString>;
707
- }, "strip", z.ZodTypeAny, {
708
- form: {
709
- enabled: boolean;
710
- vertical?: "consulting" | "medical" | "tax" | "legal" | undefined;
711
- };
712
- heading?: string | undefined;
713
- phone?: string | undefined;
714
- address?: string | undefined;
715
- hours?: {
716
- open: string;
717
- day: string;
718
- close: string;
719
- note?: string | undefined;
720
- }[] | undefined;
721
- mapEmbedUrl?: string | undefined;
722
- }, {
723
- form: {
724
- enabled: boolean;
725
- vertical?: "consulting" | "medical" | "tax" | "legal" | undefined;
726
- };
727
- heading?: string | undefined;
728
- phone?: string | undefined;
729
- address?: string | undefined;
730
- hours?: {
731
- open: string;
732
- day: string;
733
- close: string;
734
- note?: string | undefined;
735
- }[] | undefined;
736
- mapEmbedUrl?: string | undefined;
737
- }>;
738
- }, "strip", z.ZodTypeAny, {
739
- type: "contact";
740
- variant: "split" | "form-map-5050";
741
- props: {
742
- form: {
743
- enabled: boolean;
744
- vertical?: "consulting" | "medical" | "tax" | "legal" | undefined;
745
- };
746
- heading?: string | undefined;
747
- phone?: string | undefined;
748
- address?: string | undefined;
749
- hours?: {
750
- open: string;
751
- day: string;
752
- close: string;
753
- note?: string | undefined;
754
- }[] | undefined;
755
- mapEmbedUrl?: string | undefined;
756
- };
757
- theme?: Record<string, string> | undefined;
758
- id?: string | undefined;
759
- }, {
760
- type: "contact";
761
- props: {
762
- form: {
763
- enabled: boolean;
764
- vertical?: "consulting" | "medical" | "tax" | "legal" | undefined;
765
- };
766
- heading?: string | undefined;
767
- phone?: string | undefined;
768
- address?: string | undefined;
769
- hours?: {
770
- open: string;
771
- day: string;
772
- close: string;
773
- note?: string | undefined;
774
- }[] | undefined;
775
- mapEmbedUrl?: string | undefined;
776
- };
777
- theme?: Record<string, string> | undefined;
778
- id?: string | undefined;
779
- variant?: "split" | "form-map-5050" | undefined;
780
- }>;
781
- /** customSections 용 fallback — `type` 자유, props 는 직렬화만 강제. */
782
- declare const CustomSectionSchema: z.ZodObject<{
783
- /** 안정적 anchor·dedup·preview 매핑용. 페이지 내 유일. */
784
- id: z.ZodOptional<z.ZodString>;
785
- /** 빌트인 또는 customSections registry 키. kebab-case. */
786
- type: z.ZodString;
787
- /** 같은 type 의 비주얼 변형. 빌트인 type 은 enum 으로 좁힘. */
788
- variant: z.ZodOptional<z.ZodString>;
789
- /** 섹션 스코프 토큰 override (`--rt-*` CSS 변수 → 값). */
790
- theme: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
791
- /** 섹션별 직렬화 props. */
792
- props: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodType<unknown, z.ZodTypeDef, unknown>>>;
793
- }, "strip", z.ZodTypeAny, {
794
- type: string;
795
- props: Record<string, unknown>;
796
- theme?: Record<string, string> | undefined;
797
- id?: string | undefined;
798
- variant?: string | undefined;
799
- }, {
800
- type: string;
801
- theme?: Record<string, string> | undefined;
802
- id?: string | undefined;
803
- variant?: string | undefined;
804
- props?: Record<string, unknown> | undefined;
805
- }>;
806
- declare const BUILTIN_SECTION_SCHEMAS: Record<string, z.ZodTypeAny>;
807
- /** 빌트인 type 목록 (renderer registry 와 1:1). */
808
- declare const BUILTIN_SECTION_TYPES: readonly string[];
809
- type HeroSection = z.output<typeof HeroSectionSchema>;
810
- type RichTextSection = z.output<typeof RichTextSectionSchema>;
811
- type ServicesSection = z.output<typeof ServicesSectionSchema>;
812
- type FaqSection = z.output<typeof FaqSectionSchema>;
813
- type CtaBannerSection = z.output<typeof CtaBannerSectionSchema>;
814
- type BlogListSection = z.output<typeof BlogListSectionSchema>;
815
- type LeadFormSection = z.output<typeof LeadFormSectionSchema>;
816
- type TrustSection = z.output<typeof TrustSectionSchema>;
817
- type ContactSection = z.output<typeof ContactSectionSchema>;
818
- type CustomSection = z.output<typeof CustomSectionSchema>;
819
- /** 파싱 결과 섹션 (defaults 적용 후). */
820
- type Section = HeroSection | RichTextSection | ServicesSection | FaqSection | CtaBannerSection | BlogListSection | LeadFormSection | TrustSection | ContactSection | CustomSection;
821
- /** config 작성용 섹션 (defaults 생략 가능). `site.config.ts` 에서 이 타입 사용. */
822
- type SectionInput = z.input<typeof HeroSectionSchema> | z.input<typeof RichTextSectionSchema> | z.input<typeof ServicesSectionSchema> | z.input<typeof FaqSectionSchema> | z.input<typeof CtaBannerSectionSchema> | z.input<typeof BlogListSectionSchema> | z.input<typeof LeadFormSectionSchema> | z.input<typeof TrustSectionSchema> | z.input<typeof ContactSectionSchema> | z.input<typeof CustomSectionSchema>;
823
- /**
824
- * 섹션 스키마 — 빌트인 type 이면 해당 스키마로 *강제* 검증 (union fallthrough 로
825
- * 빌트인 오타이핑이 CustomSection 으로 조용히 통과하는 것을 차단), 미지 type 은
826
- * CustomSection 으로 통과 (렌더러가 customSections registry 로 해석).
827
- */
828
- declare const SectionSchema: z.ZodType<Section, z.ZodTypeDef, SectionInput>;
829
- declare const SiteConfigSchema: z.ZodObject<{
830
- site: z.ZodObject<{
831
- /** canonical origin. 생략 시 소비측이 `SITE_URL` env 등으로 해석. */
832
- url: z.ZodOptional<z.ZodString>;
833
- title: z.ZodString;
834
- description: z.ZodOptional<z.ZodString>;
835
- locale: z.ZodDefault<z.ZodString>;
836
- og: z.ZodOptional<z.ZodObject<{
837
- image: z.ZodOptional<z.ZodString>;
838
- }, "strip", z.ZodTypeAny, {
839
- image?: string | undefined;
840
- }, {
841
- image?: string | undefined;
842
- }>>;
843
- }, "strip", z.ZodTypeAny, {
844
- title: string;
845
- locale: string;
846
- description?: string | undefined;
847
- url?: string | undefined;
848
- og?: {
849
- image?: string | undefined;
850
- } | undefined;
851
- }, {
852
- title: string;
853
- description?: string | undefined;
854
- url?: string | undefined;
855
- og?: {
856
- image?: string | undefined;
857
- } | undefined;
858
- locale?: string | undefined;
859
- }>;
860
- /**
861
- * 콘텐츠 스트림 분리 (ADR-0060). 비우면 단일 /blog(레거시 동작). 선언 순서 =
862
- * 라우팅 우선순위. `routes.ts` 팩토리에 `collections` 로 전달해 sitemap/feed/
863
- * 아카이브를 스트림별로 파생.
864
- */
865
- collections: z.ZodDefault<z.ZodArray<z.ZodObject<{
866
- /** 안정 식별자 (라우트/가드/파생 키). */
867
- key: z.ZodString;
868
- /** 작성자 카드·nav 라벨. */
869
- label: z.ZodString;
870
- /** 라우트 base path (예: "/notice" | "/blog"). 앞 슬래시 포함. */
871
- basePath: z.ZodString;
872
- /** 레이아웃 레지스트리 키 (board=게시판, grid=카드 그리드, …). 미지 키는 렌더러 fallback. */
873
- layout: z.ZodDefault<z.ZodString>;
874
- /** 이 스트림에 속하는 category slug 들. */
875
- categories: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
876
- /** RSS 피드 포함. */
877
- feed: z.ZodDefault<z.ZodBoolean>;
878
- /** `${basePath}/categories/{slug}` 아카이브 생성. */
879
- archives: z.ZodDefault<z.ZodBoolean>;
880
- /** 글별 동적 OG. */
881
- og: z.ZodDefault<z.ZodBoolean>;
882
- /** 작성 UX: 하위 카테고리 1개 필수(미선택 발행 차단). */
883
- requireSubcategory: z.ZodDefault<z.ZodBoolean>;
884
- /** 작성 UX: 상단고정 토글 노출. */
885
- pinning: z.ZodDefault<z.ZodBoolean>;
886
- /** nav/카드 아이콘 키 (선택). */
887
- icon: z.ZodOptional<z.ZodString>;
888
- }, "strip", z.ZodTypeAny, {
889
- layout: string;
890
- categories: string[];
891
- label: string;
892
- key: string;
893
- basePath: string;
894
- feed: boolean;
895
- archives: boolean;
896
- og: boolean;
897
- requireSubcategory: boolean;
898
- pinning: boolean;
899
- icon?: string | undefined;
900
- }, {
901
- label: string;
902
- key: string;
903
- basePath: string;
904
- layout?: string | undefined;
905
- icon?: string | undefined;
906
- categories?: string[] | undefined;
907
- feed?: boolean | undefined;
908
- archives?: boolean | undefined;
909
- og?: boolean | undefined;
910
- requireSubcategory?: boolean | undefined;
911
- pinning?: boolean | undefined;
912
- }>, "many">>;
913
- /** 사이트 전역 토큰 override (`--rt-*` CSS 변수 → 값). 비우면 admin /design SSoT. */
914
- theme: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
915
- nav: z.ZodDefault<z.ZodArray<z.ZodObject<{
916
- label: z.ZodString;
917
- href: z.ZodString;
918
- children: z.ZodOptional<z.ZodArray<z.ZodObject<{
919
- label: z.ZodString;
920
- href: z.ZodString;
921
- }, "strip", z.ZodTypeAny, {
922
- href: string;
923
- label: string;
924
- }, {
925
- href: string;
926
- label: string;
927
- }>, "many">>;
928
- }, "strip", z.ZodTypeAny, {
929
- href: string;
930
- label: string;
931
- children?: {
932
- href: string;
933
- label: string;
934
- }[] | undefined;
935
- }, {
936
- href: string;
937
- label: string;
938
- children?: {
939
- href: string;
940
- label: string;
941
- }[] | undefined;
942
- }>, "many">>;
943
- /** path("/", "/services", …) → 섹션 배열. */
944
- pages: z.ZodRecord<z.ZodString, z.ZodArray<z.ZodType<Section, z.ZodTypeDef, SectionInput>, "many">>;
945
- }, "strip", z.ZodTypeAny, {
946
- collections: {
947
- layout: string;
948
- categories: string[];
949
- label: string;
950
- key: string;
951
- basePath: string;
952
- feed: boolean;
953
- archives: boolean;
954
- og: boolean;
955
- requireSubcategory: boolean;
956
- pinning: boolean;
957
- icon?: string | undefined;
958
- }[];
959
- theme: Record<string, string>;
960
- nav: {
961
- href: string;
962
- label: string;
963
- children?: {
964
- href: string;
965
- label: string;
966
- }[] | undefined;
967
- }[];
968
- site: {
969
- title: string;
970
- locale: string;
971
- description?: string | undefined;
972
- url?: string | undefined;
973
- og?: {
974
- image?: string | undefined;
975
- } | undefined;
976
- };
977
- pages: Record<string, Section[]>;
978
- }, {
979
- site: {
980
- title: string;
981
- description?: string | undefined;
982
- url?: string | undefined;
983
- og?: {
984
- image?: string | undefined;
985
- } | undefined;
986
- locale?: string | undefined;
987
- };
988
- pages: Record<string, SectionInput[]>;
989
- collections?: {
990
- label: string;
991
- key: string;
992
- basePath: string;
993
- layout?: string | undefined;
994
- icon?: string | undefined;
995
- categories?: string[] | undefined;
996
- feed?: boolean | undefined;
997
- archives?: boolean | undefined;
998
- og?: boolean | undefined;
999
- requireSubcategory?: boolean | undefined;
1000
- pinning?: boolean | undefined;
1001
- }[] | undefined;
1002
- theme?: Record<string, string> | undefined;
1003
- nav?: {
1004
- href: string;
1005
- label: string;
1006
- children?: {
1007
- href: string;
1008
- label: string;
1009
- }[] | undefined;
1010
- }[] | undefined;
1011
- }>;
1012
- type SiteConfig = z.output<typeof SiteConfigSchema>;
1013
- /** config 작성용 (defaults 생략 가능). */
1014
- type SiteConfigInput = Omit<z.input<typeof SiteConfigSchema>, "pages"> & {
1015
- pages: Record<string, SectionInput[]>;
1016
- };
1017
- /** config 검증 + defaults 적용. 실패 시 ZodError throw (빌드 타임 fail-fast 용). */
1018
- declare function parseSiteConfig(input: unknown): SiteConfig;
1019
- /**
1020
- * `site.config.ts` 작성 헬퍼 — 타입 추론 + 즉시 검증.
1021
- *
1022
- * ```ts
1023
- * import { defineSiteConfig } from "@roottale/cms-renderer-next/templates";
1024
- * export default defineSiteConfig({ site: { title: "…" }, pages: { "/": [ … ] } });
1025
- * ```
1026
- */
1027
- declare function defineSiteConfig(input: SiteConfigInput): SiteConfig;
9
+ declare function TemplateExpertise(section: ExpertiseSection): ReactElement;
10
+ declare function TemplateSpaces(section: SpacesSection): ReactElement;
11
+ declare function TemplateConcerns(section: ConcernsSection): ReactElement;
1028
12
 
1029
13
  /**
1030
14
  * 빌트인 섹션 템플릿 — MUI-free, 0 JS RSC (ADR-0040 P2).
@@ -1041,18 +25,26 @@ declare function defineSiteConfig(input: SiteConfigInput): SiteConfig;
1041
25
 
1042
26
  /** 섹션 `theme`(--rt-* 변수 override)를 inline style 로. */
1043
27
  declare function sectionThemeStyle(theme: Record<string, string> | undefined): CSSProperties | undefined;
1044
- /** 빌트인 `hero`. variant: split(기본) / image / minimal. */
28
+ /** 빌트인 `hero`. variant: split(기본) / image / minimal / carousel. */
1045
29
  declare function TemplateHero(section: HeroSection): ReactElement;
1046
30
  /** 빌트인 `rich-text`. 문단은 `\n\n` 분리. */
1047
31
  declare function TemplateRichText(section: RichTextSection): ReactElement;
1048
- /** 빌트인 `services`. variant: grid(기본) / list. */
32
+ /** 빌트인 `services`. variant: grid(기본) / list / index-rows / split-featured. */
1049
33
  declare function TemplateServices(section: ServicesSection): ReactElement;
34
+ declare function TemplateFooter(section: FooterSection): ReactElement;
1050
35
  /** 빌트인 `faq`. `<details>` 0 JS + FAQPage JSON-LD (기본 on). */
1051
36
  declare function TemplateFaq(section: FaqSection): ReactElement;
1052
- /** 빌트인 `cta-banner`. */
37
+ /** 빌트인 `cta-banner`. variant: default(기본) / photo-overlay. */
1053
38
  declare function TemplateCtaBanner(section: CtaBannerSection): ReactElement;
1054
39
  declare function TemplateTrust(section: TrustSection): ReactElement;
40
+ /** 빌트인 `testimonials`(C11). variant: editorial-quote(기본) / quote-rail. */
41
+ declare function TemplateTestimonials(section: TestimonialsSection): ReactElement;
42
+ declare function TemplateTeam(section: TeamSection): ReactElement;
1055
43
  declare function TemplateContact(section: ContactSection): ReactElement;
44
+ declare function TemplateHours(section: HoursSection): ReactElement;
45
+ declare function TemplatePricing(section: PricingSection): ReactElement;
46
+ declare function TemplateProcess(section: ProcessSection): ReactElement;
47
+ declare function TemplateBeforeAfter(section: BeforeAfterSection): ReactElement;
1056
48
 
1057
49
  /**
1058
50
  * `SiteRenderer` — `SiteConfig.pages[path]` 섹션 배열을 registry 로 렌더.
@@ -1111,4 +103,4 @@ interface SiteRendererProps {
1111
103
  */
1112
104
  declare function SiteRenderer(props: SiteRendererProps): ReactElement;
1113
105
 
1114
- export { BUILTIN_SECTION_SCHEMAS, BUILTIN_SECTION_TYPES, type BlogListSection, BlogListSectionSchema, type ContactSection, ContactSectionSchema, type CtaBannerSection, CtaBannerSectionSchema, type CustomSection, CustomSectionSchema, type FaqSection, FaqSectionSchema, type HeroSection, HeroSectionSchema, type LeadFormSection, LeadFormSectionSchema, type NavItem, NavItemSchema, type RichTextSection, RichTextSectionSchema, type Section, type SectionComponent, type SectionCta, type SectionInput, SectionSchema, type ServicesSection, ServicesSectionSchema, type SiteConfig, type SiteConfigInput, SiteConfigSchema, SiteRenderer, type SiteRendererProps, TemplateContact, TemplateCtaBanner, TemplateFaq, TemplateHero, TemplateRichText, TemplateServices, TemplateTrust, type TrustSection, TrustSectionSchema, defineSiteConfig, parseSiteConfig, sectionThemeStyle };
106
+ export { BeforeAfterSection, ConcernsSection, ContactSection, CtaBannerSection, ExpertiseSection, FaqSection, FooterSection, HeroSection, HoursSection, PricingSection, ProcessSection, RichTextSection, type SectionComponent, ServicesSection, SiteConfig, SiteConfigInput, SiteRenderer, type SiteRendererProps, SpacesSection, TeamSection, TemplateBeforeAfter, TemplateConcerns, TemplateContact, TemplateCtaBanner, TemplateExpertise, TemplateFaq, TemplateFooter, TemplateHero, TemplateHours, TemplatePricing, TemplateProcess, TemplateRichText, TemplateServices, TemplateSpaces, TemplateTeam, TemplateTestimonials, TemplateTrust, TestimonialsSection, TrustSection, sectionThemeStyle };