diff --git a/apps/admin/src/components/page-builder/BannerForm.tsx b/apps/admin/src/components/page-builder/BannerForm.tsx
index 52550a6..960b91b 100644
--- a/apps/admin/src/components/page-builder/BannerForm.tsx
+++ b/apps/admin/src/components/page-builder/BannerForm.tsx
@@ -110,6 +110,8 @@ export default function BannerForm({
onChangeContentWidth={(w) => updatePayloadValue('contentWidth', w)}
textColorScheme={editingSection.payload?.textColorScheme}
onChangeTextColorScheme={(scheme) => updatePayloadValue('textColorScheme', scheme)}
+ titleSize={editingSection.payload?.titleSize}
+ onChangeTitleSize={(size) => updatePayloadValue('titleSize', size)}
/>
diff --git a/apps/admin/src/components/page-builder/ContentPositionPicker.tsx b/apps/admin/src/components/page-builder/ContentPositionPicker.tsx
index 06128cc..9dfd0ef 100644
--- a/apps/admin/src/components/page-builder/ContentPositionPicker.tsx
+++ b/apps/admin/src/components/page-builder/ContentPositionPicker.tsx
@@ -1,4 +1,4 @@
-import { Monitor, Smartphone, RotateCcw, Maximize2, Sun, Moon, Palette } from 'lucide-react';
+import { Monitor, Smartphone, RotateCcw, Maximize2, Sun, Moon, Palette, Type } from 'lucide-react';
export const GRID_POSITIONS = [
{ id: 'top-left', label: 'Top Left (บนซ้าย)', short: 'TL', icon: '↖' },
@@ -18,6 +18,13 @@ export const WIDTH_OPTIONS = [
{ id: 'compact', label: 'กรอบกระชับ (768px)', desc: 'กล่องกะทัดรัด max-w-3xl' },
] as const;
+export const TITLE_SIZE_OPTIONS = [
+ { id: 'sm', label: 'กะทัดรัด (Small / 44px)', desc: 'เหมาะกับข้อความยาว หรือภาพที่มีสินค้าเด่นด้านข้าง ไม่ชนสินค้า' },
+ { id: 'md', label: 'ปานกลาง (Medium / 60px)', desc: 'ขนาดมาตรฐานบทความ / Heading ชัดเจน ไม่ล้นจอ' },
+ { id: 'lg', label: 'ใหญ่ (Large / 76px)', desc: 'ขนาดโปรโมชัน เน้นตัวอักษรเด่นและสะดุดตา' },
+ { id: 'xl', label: 'ยักษ์ (Display / 96px)', desc: 'ขนาดดั้งเดิม (Display Huge) เหมาะกับคำสั้น 2-3 คำ' },
+] as const;
+
export const COLOR_SCHEME_OPTIONS = [
{
id: 'light',
@@ -45,6 +52,8 @@ export interface ContentPositionPickerProps {
onChangeContentWidth?: (width: string) => void;
textColorScheme?: 'light' | 'dark' | string;
onChangeTextColorScheme?: (scheme: 'light' | 'dark') => void;
+ titleSize?: 'sm' | 'md' | 'lg' | 'xl' | string;
+ onChangeTitleSize?: (size: string) => void;
title?: string;
subtitle?: string;
compact?: boolean;
@@ -60,6 +69,8 @@ export default function ContentPositionPicker({
onChangeContentWidth,
textColorScheme,
onChangeTextColorScheme,
+ titleSize,
+ onChangeTitleSize,
title = 'ตำแหน่งปุ่ม & เนื้อหา (Button & Content Position)',
subtitle = 'สามารถแยกตำแหน่งระหว่าง Desktop (PC) และ Mobile (มือถือ) ได้อิสระ',
compact = false,
@@ -255,6 +266,43 @@ export default function ContentPositionPicker({
)}
+
+ {/* Title Size / Heading Scale Preset Selection */}
+ {onChangeTitleSize && (
+
+
+
+
+ ขนาดตัวอักษรหัวข้อ (Title Font Size Preset)
+
+
+ {(titleSize || 'xl').toUpperCase()}
+
+
+
+ {TITLE_SIZE_OPTIONS.map((opt) => {
+ const isSelected = (titleSize || 'xl') === opt.id;
+ return (
+
+ );
+ })}
+
+
+ )}
);
}
diff --git a/apps/admin/src/components/page-builder/HeroArticleForm.tsx b/apps/admin/src/components/page-builder/HeroArticleForm.tsx
index d3505bd..ac1554d 100644
--- a/apps/admin/src/components/page-builder/HeroArticleForm.tsx
+++ b/apps/admin/src/components/page-builder/HeroArticleForm.tsx
@@ -72,6 +72,20 @@ export default function HeroArticleForm({
/>
+
+
+
+
+
updatePayloadValue('contentWidth', w)}
textColorScheme={editingSection.payload?.textColorScheme}
onChangeTextColorScheme={(scheme) => updatePayloadValue('textColorScheme', scheme)}
+ titleSize={editingSection.payload?.titleSize}
+ onChangeTitleSize={(size) => updatePayloadValue('titleSize', size)}
/>
diff --git a/apps/admin/src/components/page-builder/HeroV2Form.tsx b/apps/admin/src/components/page-builder/HeroV2Form.tsx
index e5042ee..fba2e5b 100644
--- a/apps/admin/src/components/page-builder/HeroV2Form.tsx
+++ b/apps/admin/src/components/page-builder/HeroV2Form.tsx
@@ -71,6 +71,20 @@ export default function HeroV2Form({
+
+
+
+
+
updatePayloadValue('contentWidth', w)}
textColorScheme={payload.textColorScheme}
onChangeTextColorScheme={(scheme) => updatePayloadValue('textColorScheme', scheme)}
+ titleSize={payload.titleSize}
+ onChangeTitleSize={(size) => updatePayloadValue('titleSize', size)}
/>
);
diff --git a/apps/backend/src/lib/productDetailSections.test.ts b/apps/backend/src/lib/productDetailSections.test.ts
index 2e4c420..d74d547 100644
--- a/apps/backend/src/lib/productDetailSections.test.ts
+++ b/apps/backend/src/lib/productDetailSections.test.ts
@@ -17,6 +17,10 @@ const validHeroCarouselPayload = {
subtitle: { th: "ข้อความรอง", en: "Supporting copy" },
buttonText: { th: "ดูสินค้า", en: "View product" },
focalPoint: { x: "50%", y: "45%" },
+ buttonPosition: "bottom-left",
+ contentWidth: "standard",
+ textColorScheme: "light",
+ titleSize: "xl",
},
],
autoplay: true,
diff --git a/apps/backend/src/routes/pages.ts b/apps/backend/src/routes/pages.ts
index ac7b1b4..b46ab84 100644
--- a/apps/backend/src/routes/pages.ts
+++ b/apps/backend/src/routes/pages.ts
@@ -1,6 +1,6 @@
import { Elysia, t } from "elysia";
import prisma from "../lib/prisma";
-// Trigger reload: support containerWidth, cardSize, and layout for PRODUCT_CAROUSEL and PRODUCTS
+// Trigger reload: support titleSize in HERO and HERO_VIDEO payloads
import {
LocalizedStringSchema,
HeroSectionPayloadSchema,
diff --git a/apps/mcp-server/section-toolkit.ts b/apps/mcp-server/section-toolkit.ts
index 8fb1f6a..47591f2 100644
--- a/apps/mcp-server/section-toolkit.ts
+++ b/apps/mcp-server/section-toolkit.ts
@@ -89,8 +89,8 @@ const PAGE_BLOCK_METADATA: Record = {
HERO: {
type: "HERO",
requiredFields: ["tagline", "title", "description", "imageUrl", "buttonText", "buttonLink"],
- optionalFields: ["focalPoint"],
- renderedFields: ["tagline", "title", "description", "imageUrl", "buttonText", "buttonLink", "focalPoint"],
+ optionalFields: ["focalPoint", "contentWidth", "textColorScheme", "buttonPosition", "mobileButtonPosition", "overlayStyle", "overlayOpacity", "titleSize"],
+ renderedFields: ["tagline", "title", "description", "imageUrl", "buttonText", "buttonLink", "focalPoint", "contentWidth", "textColorScheme", "buttonPosition", "mobileButtonPosition", "overlayStyle", "overlayOpacity", "titleSize"],
storedOnlyFields: [],
discoveryToolsNeeded: [],
warnings: ["Use an image URL from a host allowed by apps/website next.config.ts."],
@@ -669,8 +669,8 @@ const PAGE_BLOCK_METADATA: Record = {
HERO_V2: {
type: "HERO_V2",
requiredFields: ["title", "imageUrl"],
- optionalFields: ["tagline", "description", "contentAlignment", "showOrnament", "primaryButtonText", "primaryButtonLink", "secondaryButtonText", "secondaryButtonLink", "focalPoint"],
- renderedFields: ["tagline", "title", "description", "imageUrl", "contentAlignment", "showOrnament", "primaryButtonText", "primaryButtonLink", "secondaryButtonText", "secondaryButtonLink", "focalPoint"],
+ optionalFields: ["tagline", "description", "contentAlignment", "showOrnament", "primaryButtonText", "primaryButtonLink", "secondaryButtonText", "secondaryButtonLink", "focalPoint", "titleSize"],
+ renderedFields: ["tagline", "title", "description", "imageUrl", "contentAlignment", "showOrnament", "primaryButtonText", "primaryButtonLink", "secondaryButtonText", "secondaryButtonLink", "focalPoint", "titleSize"],
storedOnlyFields: [],
discoveryToolsNeeded: [],
warnings: ["contentAlignment must be left, center, or right. Use an image URL allowed by apps/website."],
diff --git a/apps/spa/src/components/DynamicHero.tsx b/apps/spa/src/components/DynamicHero.tsx
index a19cfe4..d2a1b06 100644
--- a/apps/spa/src/components/DynamicHero.tsx
+++ b/apps/spa/src/components/DynamicHero.tsx
@@ -151,6 +151,20 @@ export function getHeroContainerWidthClasses(contentWidth?: string) {
}
}
+export function getHeroTitleSizeClass(titleSize?: string): string {
+ switch (titleSize) {
+ case 'sm':
+ return 'ui-hero-title-sm';
+ case 'md':
+ return 'ui-hero-title-md';
+ case 'lg':
+ return 'ui-hero-title-lg';
+ case 'xl':
+ default:
+ return 'ui-hero-title-xl';
+ }
+}
+
export default function DynamicHero({ payload }: DynamicHeroProps) {
const { t, i18n } = useTranslation();
const lang = i18n.language;
@@ -240,6 +254,9 @@ export default function DynamicHero({ payload }: DynamicHeroProps) {
};
const containerClasses = getHeroContainerWidthClasses(contentWidth);
+ const titleSize = (payload as any).titleSize || 'xl';
+ const titleSizeClass = getHeroTitleSizeClass(titleSize);
+ const textWrapperWidthClass = titleSize === 'sm' || contentWidth === 'compact' ? 'max-w-xl' : titleSize === 'md' ? 'max-w-2xl' : 'max-w-3xl';
return (
@@ -258,14 +275,14 @@ export default function DynamicHero({ payload }: DynamicHeroProps) {
-
+
{tagline && (
{tagline}
)}
{title && (
-
+
{renderTitle(title)}
)}
diff --git a/apps/spa/src/components/DynamicHeroV2.tsx b/apps/spa/src/components/DynamicHeroV2.tsx
index f1fa506..25e3d47 100644
--- a/apps/spa/src/components/DynamicHeroV2.tsx
+++ b/apps/spa/src/components/DynamicHeroV2.tsx
@@ -2,6 +2,7 @@ import { Link } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { getLocalizedField } from '../utils/localization';
import { Sparkles, ChevronRight } from 'lucide-react';
+import { getHeroTitleSizeClass } from './DynamicHero';
interface DynamicHeroV2Props {
payload: Record;
@@ -68,7 +69,7 @@ export default function DynamicHeroV2({ payload }: DynamicHeroV2Props) {
)}
-
+
{renderTitle(title || '')}
diff --git a/apps/spa/src/components/DynamicHeroVideo.tsx b/apps/spa/src/components/DynamicHeroVideo.tsx
index e351d82..227985d 100644
--- a/apps/spa/src/components/DynamicHeroVideo.tsx
+++ b/apps/spa/src/components/DynamicHeroVideo.tsx
@@ -2,7 +2,7 @@ import { Link } from 'react-router-dom';
import type { HeroVideoSectionPayload } from '@homaroma/types';
import { useTranslation } from 'react-i18next';
import { getLocalizedField } from '../utils/localization';
-import { getHeroPositionClasses, getHeroContainerWidthClasses } from './DynamicHero';
+import { getHeroPositionClasses, getHeroContainerWidthClasses, getHeroTitleSizeClass } from './DynamicHero';
interface DynamicHeroVideoProps {
payload: HeroVideoSectionPayload;
@@ -98,6 +98,9 @@ export default function DynamicHeroVideo({ payload }: DynamicHeroVideoProps) {
const desktopPosition = (payload as any).buttonPosition || 'center';
const mobilePosition = (payload as any).mobileButtonPosition || desktopPosition;
const contentWidth = (payload as any).contentWidth || 'standard';
+ const titleSize = (payload as any).titleSize || 'xl';
+ const titleSizeClass = getHeroTitleSizeClass(titleSize);
+ const textWrapperWidthClass = titleSize === 'sm' || contentWidth === 'compact' ? 'max-w-xl' : titleSize === 'md' ? 'max-w-2xl' : 'max-w-3xl';
const { wrapperClasses, contentClasses, actionsClasses } = getHeroPositionClasses(mobilePosition, desktopPosition);
const containerClasses = getHeroContainerWidthClasses(contentWidth);
@@ -109,14 +112,14 @@ export default function DynamicHeroVideo({ payload }: DynamicHeroVideoProps) {
>
-
+
{tagline && (
{tagline}
)}
-
+
{renderTitle(title) || renderTitle(t('hero.defaultTitle'))}
diff --git a/apps/spa/src/index.css b/apps/spa/src/index.css
index f3cad84..d44f441 100644
--- a/apps/spa/src/index.css
+++ b/apps/spa/src/index.css
@@ -148,6 +148,22 @@
color: var(--color-pop-black);
}
+ .ui-hero-title-sm {
+ @apply !text-2xl sm:!text-3xl md:!text-4xl lg:!text-5xl;
+ }
+
+ .ui-hero-title-md {
+ @apply !text-3xl sm:!text-4xl md:!text-5xl lg:!text-6xl;
+ }
+
+ .ui-hero-title-lg {
+ @apply !text-4xl sm:!text-5xl md:!text-6xl lg:!text-7xl;
+ }
+
+ .ui-hero-title-xl {
+ @apply !text-5xl md:!text-7xl lg:!text-8xl;
+ }
+
.ui-hero-copy {
@apply mx-auto max-w-2xl pb-8 pt-4 text-lg font-light drop-shadow-md md:text-xl;
color: var(--color-pop-black);
diff --git a/apps/website/src/app/globals.css b/apps/website/src/app/globals.css
index bf77f42..3b3b1fb 100644
--- a/apps/website/src/app/globals.css
+++ b/apps/website/src/app/globals.css
@@ -451,6 +451,26 @@
filter: drop-shadow(0 4px 3px rgb(0 0 0 / 0.07)) drop-shadow(0 2px 2px rgb(0 0 0 / 0.06));
}
+ .ui-hero-title-sm {
+ font-size: 1.75rem !important;
+ line-height: 1.2 !important;
+ }
+
+ .ui-hero-title-md {
+ font-size: 2.25rem !important;
+ line-height: 1.2 !important;
+ }
+
+ .ui-hero-title-lg {
+ font-size: 2.75rem !important;
+ line-height: 1.15 !important;
+ }
+
+ .ui-hero-title-xl {
+ font-size: 3rem !important;
+ line-height: 1.25 !important;
+ }
+
.ui-hero-copy {
margin-inline: auto;
max-width: 42rem;
@@ -568,6 +588,26 @@
line-height: 1;
}
+ .ui-hero-title-sm {
+ font-size: 2.25rem !important;
+ line-height: 1.15 !important;
+ }
+
+ .ui-hero-title-md {
+ font-size: 3rem !important;
+ line-height: 1.15 !important;
+ }
+
+ .ui-hero-title-lg {
+ font-size: 3.75rem !important;
+ line-height: 1.1 !important;
+ }
+
+ .ui-hero-title-xl {
+ font-size: 4.5rem !important;
+ line-height: 1 !important;
+ }
+
.ui-hero-copy {
font-size: 1.25rem;
line-height: 1.75rem;
@@ -588,6 +628,26 @@
font-size: 6rem;
line-height: 1;
}
+
+ .ui-hero-title-sm {
+ font-size: 2.75rem !important;
+ line-height: 1.1 !important;
+ }
+
+ .ui-hero-title-md {
+ font-size: 3.75rem !important;
+ line-height: 1.05 !important;
+ }
+
+ .ui-hero-title-lg {
+ font-size: 4.75rem !important;
+ line-height: 1 !important;
+ }
+
+ .ui-hero-title-xl {
+ font-size: 6rem !important;
+ line-height: 1 !important;
+ }
}
.ui-panel {
diff --git a/apps/website/src/components/dynamic/DynamicPageRenderer.tsx b/apps/website/src/components/dynamic/DynamicPageRenderer.tsx
index fd4ac77..c30e0b9 100644
--- a/apps/website/src/components/dynamic/DynamicPageRenderer.tsx
+++ b/apps/website/src/components/dynamic/DynamicPageRenderer.tsx
@@ -273,6 +273,35 @@ function getHeroContainerWidthClasses(contentWidth?: string) {
}
}
+export function getHeroTitleSizeClass(titleSize?: unknown): string {
+ switch (titleSize) {
+ case 'sm':
+ return 'ui-hero-title-sm'
+ case 'md':
+ return 'ui-hero-title-md'
+ case 'lg':
+ return 'ui-hero-title-lg'
+ case 'xl':
+ default:
+ return 'ui-hero-title-xl'
+ }
+}
+
+export function getTailwindHeroTitleClass(titleSize?: unknown, defaultSize = 'xl'): string {
+ const size = (titleSize || defaultSize) as string
+ switch (size) {
+ case 'sm':
+ return 'text-2xl sm:text-3xl md:text-4xl'
+ case 'md':
+ return 'text-3xl sm:text-4xl md:text-5xl'
+ case 'lg':
+ return 'text-4xl sm:text-5xl md:text-6xl'
+ case 'xl':
+ default:
+ return 'text-4xl sm:text-5xl md:text-6xl lg:text-7xl'
+ }
+}
+
function HeroSection({ payload, lang }: { payload: Record, lang: string }) {
const { t } = useTranslation()
const i18nLang = useLang()
@@ -288,6 +317,9 @@ function HeroSection({ payload, lang }: { payload: Record, lang
const contentWidth = typeof payload.contentWidth === 'string' ? payload.contentWidth : 'standard'
const textColorScheme = typeof payload.textColorScheme === 'string' ? payload.textColorScheme : 'light'
const isDarkText = textColorScheme === 'dark'
+ const titleSize = typeof payload.titleSize === 'string' ? payload.titleSize : 'xl'
+ const titleSizeClass = getHeroTitleSizeClass(titleSize)
+ const textWrapperWidthClass = titleSize === 'sm' || contentWidth === 'compact' ? 'max-w-xl' : titleSize === 'md' ? 'max-w-2xl' : 'max-w-3xl'
const focalPoint = typeof payload.focalPoint === 'object' && payload.focalPoint ? (payload.focalPoint as { x: string, y: string }) : undefined
// If fields are explicitly defined as empty strings, respect them as empty
@@ -357,14 +389,14 @@ function HeroSection({ payload, lang }: { payload: Record, lang
{renderOverlay()}
-
+
{tagline && (
{tagline}
)}
{title && (
-
+
{renderAccentTitle(title, isDarkText ? 'text-brand-primary font-medium' : 'ui-accent-text font-medium')}
)}
@@ -607,14 +639,14 @@ function HeroVideoSection({ payload, lang }: { payload: Record,
-
+
{tagline && (
{tagline}
)}
{title && (
-
+
{renderAccentTitle(title, isDarkText ? 'text-brand-primary font-medium' : undefined)}
)}
@@ -1012,7 +1044,7 @@ function HeroV2Section({ payload, lang }: { payload: Record, la
)}
-
+
{renderAccentTitle(title || '', 'text-brand-primary')}
@@ -1271,8 +1303,12 @@ function BannerSection({ payload, lang }: { payload: Record, la
style={{ objectPosition: focalPoint ? `${focalPoint.x} ${focalPoint.y}` : undefined }}
/>
-
- {title &&
{title}
}
+
+ {title && (
+
+ {title}
+
+ )}
{description &&
{description}
}
{buttonText && (
@@ -2180,7 +2216,7 @@ function HeroArticleSection({ payload, lang }: { payload: Record
{category && {category}
}
- {title}
+ {title}
{subtitle && {subtitle}
}
{(author || date) && (
diff --git a/packages/types/index.ts b/packages/types/index.ts
index 6d4d8ec..afae778 100644
--- a/packages/types/index.ts
+++ b/packages/types/index.ts
@@ -652,6 +652,15 @@ export const DefaultTextColorSchemeSchema = (fallback: TextColorScheme = 'light'
.optional()
.transform((val) => (val ? (val as TextColorScheme) : fallback));
+export const TitleSizeSchema = z.enum(['sm', 'md', 'lg', 'xl']);
+export type TitleSize = z.infer;
+
+export const DefaultTitleSizeSchema = (fallback: TitleSize = 'xl') =>
+ z
+ .union([TitleSizeSchema, z.literal(''), z.null()])
+ .optional()
+ .transform((val) => (val ? (val as TitleSize) : fallback));
+
export const SectionPaddingLevelSchema = z.enum(['none', 'compact', 'normal', 'spacious']);
export type SectionPaddingLevel = z.infer;
@@ -674,6 +683,7 @@ export const HeroSectionPayloadSchema = z.object({
mobileButtonPosition: OptionalContentPositionSchema,
contentWidth: DefaultContentWidthSchema('standard'),
textColorScheme: DefaultTextColorSchemeSchema('light'),
+ titleSize: DefaultTitleSizeSchema('xl'),
overlayStyle: z.enum(['gradient', 'solid', 'none']).optional().default('gradient'),
overlayOpacity: z.number().min(0).max(100).optional(),
});
@@ -712,6 +722,7 @@ export const BannerSectionPayloadSchema = z.object({
mobileButtonPosition: OptionalContentPositionSchema,
contentWidth: DefaultContentWidthSchema('standard'),
textColorScheme: DefaultTextColorSchemeSchema('light'),
+ titleSize: DefaultTitleSizeSchema('xl'),
});
export type BannerSectionPayload = z.infer;
@@ -803,6 +814,7 @@ export const HeroVideoSectionPayloadSchema = z.object({
mobileButtonPosition: OptionalContentPositionSchema,
contentWidth: DefaultContentWidthSchema('standard'),
textColorScheme: DefaultTextColorSchemeSchema('light'),
+ titleSize: DefaultTitleSizeSchema('xl'),
});
export type HeroVideoSectionPayload = z.infer;
@@ -836,6 +848,7 @@ export const HeroCarouselSlideSchema = z.object({
mobileButtonPosition: OptionalContentPositionSchema,
contentWidth: DefaultContentWidthSchema('standard'),
textColorScheme: DefaultTextColorSchemeSchema('light'),
+ titleSize: DefaultTitleSizeSchema('xl'),
});
export type HeroCarouselSlide = z.infer;
@@ -889,6 +902,7 @@ export const HeroArticleSectionPayloadSchema = z.object({
imageUrl: z.string().optional(),
backgroundImageUrl: z.string().optional(),
overlayColor: z.string().optional(),
+ titleSize: DefaultTitleSizeSchema('xl'),
});
export type HeroArticleSectionPayload = z.infer;
@@ -1189,6 +1203,7 @@ export const HeroV2SectionPayloadSchema = z.object({
secondaryButtonText: LocalizedStringSchema.optional(),
secondaryButtonLink: z.string().optional(),
focalPoint: z.object({ x: z.string(), y: z.string() }).optional(),
+ titleSize: DefaultTitleSizeSchema('lg'),
});
export type HeroV2SectionPayload = z.infer;
@@ -1215,6 +1230,7 @@ export const HeroMinimalSectionPayloadSchema = z.object({
focalPoint: z.object({ x: z.string(), y: z.string() }).optional(),
contentAlignment: z.enum(['left', 'center', 'right']).optional().default('center'),
overlayOpacity: z.number().optional().default(20),
+ titleSize: DefaultTitleSizeSchema('lg'),
});
export type HeroMinimalSectionPayload = z.infer;
@@ -1225,6 +1241,7 @@ export const HeroSplitMinimalSectionPayloadSchema = z.object({
imagePosition: z.enum(['left', 'right']).optional().default('right'),
focalPoint: z.object({ x: z.string(), y: z.string() }).optional(),
backgroundColor: z.string().optional(),
+ titleSize: DefaultTitleSizeSchema('lg'),
});
export type HeroSplitMinimalSectionPayload = z.infer;
@@ -1236,6 +1253,7 @@ export const HeroVideoMinimalSectionPayloadSchema = z.object({
overlayOpacity: z.number().optional().default(25),
height: z.enum(['full', 'large', 'medium']).optional().default('large'),
focalPoint: z.object({ x: z.string(), y: z.string() }).optional(),
+ titleSize: DefaultTitleSizeSchema('lg'),
});
export type HeroVideoMinimalSectionPayload = z.infer;