-
Mid-Year Secret Sale
-
Get up to 30% off on premium scent reed diffusers.
-
- Shop Sale
-
+
+
+
+
Special Promotion
+
Get discount on our reed diffusers.
+
Buy Now
)
},
- // 6. CATEGORIES
+
+ // ==========================================
+ // MINIMAL & LUXURY (Category: minimal)
+ // ==========================================
+ {
+ type: 'HERO_MINIMAL',
+ category: 'minimal',
+ badge: 'new',
+ description: 'Quiet Luxury full-width centered typography hero with adjustable overlay darkness.',
+ fieldsSpec: {
+ required: ['imageUrl', 'title'],
+ optional: ['tagline', 'contentAlignment', 'overlayOpacity'],
+ description: 'แบนเนอร์สไตล์ Quiet Luxury ตัวอักษรเรียบหรูตรงกลาง ปรับความมืดของ Overlay ได้'
+ },
+ payload: {
+ imageUrl: 'https://images.unsplash.com/photo-1608571423902-eed4a5ad8108?auto=format&fit=crop&w=1200&q=80',
+ tagline: { th: 'สารสกัดจากพฤกษศาสตร์ธรรมชาติ', en: 'AUTUMN EQUINOX · BOTANICAL ESSENCE' },
+ title: { th: 'กลิ่นอายของผืนดินชุ่มน้ำและไม้ซีดาร์ [sanctuary]', en: 'The scent of damp earth and cedar [sanctuary]' },
+ contentAlignment: 'center',
+ overlayOpacity: 25
+ },
+ renderPreview: () => (
+
+
+
+
+ AUTUMN EQUINOX · BOTANICAL ESSENCE
+
The scent of damp earth and cedar [sanctuary]
+
+
+ )
+ },
+ {
+ type: 'HERO_SPLIT_MINIMAL',
+ category: 'minimal',
+ badge: 'new',
+ description: 'Minimalist split layout hero with pure typography on one side and curated imagery on the other.',
+ fieldsSpec: {
+ required: ['imageUrl', 'title'],
+ optional: ['subtitle', 'imagePosition', 'backgroundColor'],
+ description: 'แบนเนอร์แบบสองฝั่งสไตล์มินิมอล เน้นการจัดวางตัวอักษรแบบโมเดิร์น'
+ },
+ payload: {
+ imageUrl: 'https://images.unsplash.com/photo-1547887537-6158d64c35b3?auto=format&fit=crop&w=800&q=80',
+ title: { th: 'รังสรรค์ด้วยความเงียบสงบ เพื่อช่วงเวลาอันผ่อนคลาย', en: 'Formulated in silence, crafted for quiet moments.' },
+ subtitle: { th: 'สกัดจากพฤกษศาสตร์เทือกเขาแอลป์ออร์แกนิก', en: 'Certified organic extraction from alpine botanicals.' },
+ imagePosition: 'right',
+ backgroundColor: '#161917'
+ },
+ renderPreview: (isMobile) => (
+
+
+
Formulated in silence, crafted for quiet moments.
+
Certified organic extraction from alpine botanicals.
+
+
+
+
+
+ )
+ },
+ {
+ type: 'HERO_VIDEO_MINIMAL',
+ category: 'minimal',
+ badge: 'new',
+ description: 'Atmospheric silent video hero showcasing nature and serene motion.',
+ fieldsSpec: {
+ required: ['videoUrl'],
+ optional: ['tagline', 'title', 'posterImageUrl', 'height', 'overlayOpacity'],
+ description: 'วิดีโอแบนเนอร์สไตล์เงียบสงบ ไร้ปุ่มรบกวนสายตา'
+ },
+ payload: {
+ videoUrl: 'https://cdn.coverr.co/videos/coverr-essential-oils-and-diffuser-5374/1080p.mp4',
+ posterImageUrl: 'https://images.unsplash.com/photo-1608571423902-eed4a5ad8108?auto=format&fit=crop&w=1200&q=80',
+ tagline: { th: 'งานศิลปะแห่งชีวิต', en: 'LIVING ARTWORK' },
+ title: { th: 'หายใจอย่างมีสติ', en: 'Breathe with Intention' },
+ height: 'large',
+ overlayOpacity: 25
+ },
+ renderPreview: () => (
+
+
+
+
+ LIVING ARTWORK
+
Breathe with Intention
+
+
+ )
+ },
+ {
+ type: 'BANNER_MINIMAL',
+ category: 'minimal',
+ badge: 'new',
+ description: 'Quiet luxury typographic banner with concise headline and destination link.',
+ fieldsSpec: {
+ required: ['title'],
+ optional: ['subtitle', 'linkUrl', 'backgroundColor', 'textColor'],
+ description: 'แบนเนอร์ข้อความสไตล์โมเดิร์นคลาสสิก'
+ },
+ payload: {
+ title: { th: 'สารสกัดพฤกษศาสตร์บริสุทธิ์ 100% เก็บเกี่ยวด้วยความเคารพธรรมชาติ', en: '100% pure botanical distillates, harvested with intention.' },
+ subtitle: { th: 'ส่งฟรีแบบคาร์บอนสุทธิเป็นศูนย์ ทุกคำสั่งซื้อตั้งแต่ ฿1,500', en: 'Free carbon-neutral delivery on all orders over ฿1,500' },
+ linkUrl: '/shop',
+ backgroundColor: '#1A1E1C',
+ textColor: '#EDEBE6'
+ },
+ renderPreview: () => (
+
+
100% pure botanical distillates, harvested with intention.
+
Free carbon-neutral delivery on all orders over ฿1,500
+
+ )
+ },
+ {
+ type: 'ANNOUNCEMENT_BAR_MINIMAL',
+ category: 'minimal',
+ badge: 'new',
+ description: 'Minimalist scrolling announcements ticker with dot separators.',
+ fieldsSpec: {
+ required: ['slides'],
+ optional: ['backgroundColor', 'textColor', 'speed'],
+ description: 'แถบข้อความวิ่งด้านบนแบบมินิมอล'
+ },
+ payload: {
+ slides: [
+ 'COMPLIMENTARY BOTANICAL SAMPLE WITH EVERY ORDER',
+ 'HAND-POURED IN SMALL BATCHES'
+ ],
+ backgroundColor: '#0F1713',
+ textColor: '#DCE6E0',
+ speed: 4000
+ },
+ renderPreview: () => (
+
+ COMPLIMENTARY BOTANICAL SAMPLE WITH EVERY ORDER · HAND-POURED IN SMALL BATCHES
+
+ )
+ },
+ {
+ type: 'USP_MINIMAL',
+ category: 'minimal',
+ badge: 'new',
+ description: 'Horizontal brand commitments and USP ticker with dot/pipe delimiters.',
+ fieldsSpec: {
+ required: ['items'],
+ optional: ['separator', 'backgroundColor', 'textColor'],
+ description: 'แถบข้อความการันตีจุดเด่น คั่นด้วยจุดหรือเส้น'
+ },
+ payload: {
+ items: ['Ethically Sourced', 'Zero Synthetics', 'Hand-Poured', 'Cruelty-Free'],
+ separator: 'dot',
+ backgroundColor: '#141816',
+ textColor: '#C8D1CC'
+ },
+ renderPreview: () => (
+
+ Ethically Sourced
+
+ Zero Synthetics
+
+ Hand-Poured
+
+ Cruelty-Free
+
+ )
+ },
+
+ // ==========================================
+ // PRODUCTS & SHOP (Category: products)
+ // ==========================================
{
type: 'CATEGORIES',
category: 'products',
description: 'Visual category grid showcase to guide users to specific collections.',
+ fieldsSpec: {
+ required: [],
+ optional: ['title', 'subtitle', 'categoryIds'],
+ description: 'กริดหมวดหมู่สินค้า ดึงข้อมูลจากฐานข้อมูลอัตโนมัติหรือเลือกตาม ID'
+ },
payload: {
- title: 'Shop by Collection',
- subtitle: 'Choose your preferred sensory style',
+ title: { th: 'เลือกชมตามคอลเลกชัน', en: 'Shop by Collection' },
+ subtitle: { th: 'เลือกสไตล์กลิ่นหอมที่คุณหลงใหล', en: 'Choose your preferred sensory style' },
categoryIds: [1, 2, 3]
},
- renderPreview: () => (
+ renderPreview: (isMobile) => (
-
-
Shop by Collection
+
+
Shop by Collection
Choose your preferred sensory style
-
- {[
- { name: 'Essential Oils', img: 'https://images.unsplash.com/photo-1608571423902-eed4a5ad8108?auto=format&fit=crop&w=200&q=80' },
- { name: 'Reed Diffusers', img: 'https://images.unsplash.com/photo-1547887537-6158d64c35b3?auto=format&fit=crop&w=200&q=80' },
- { name: 'Room Sprays', img: 'https://images.unsplash.com/photo-1612817288484-6f916006741a?auto=format&fit=crop&w=200&q=80' }
- ].map((cat, i) => (
-
-
-
-
{cat.name}
+
+ {['Essential Oils', 'Reed Diffusers', 'Room Sprays'].map((cat, idx) => (
+
+
+
+
{cat}
))}
)
},
- // 7. PRODUCTS
{
type: 'PRODUCTS',
category: 'products',
- description: 'Showcase grid or carousel for featured products, brand items, or a customized list with Quick Shop option.',
- payload: {
- title: 'Our Best Sellers',
- subtitle: 'Hand-picked organic favorites',
- type: 'featured',
- limit: 3,
- layout: 'grid',
- enableQuickShop: true
+ description: 'Showcase grid or carousel for featured products, brand items, or a customized list.',
+ fieldsSpec: {
+ required: ['type'],
+ optional: ['title', 'subtitle', 'categoryId', 'brandId', 'productIds', 'limit'],
+ description: 'กริดแสดงสินค้า รองรับโหมด Featured, Scent, Brand หรือ Custom ID'
},
- renderPreview: () => (
+ payload: {
+ title: { th: 'สินค้าขายดีประจำเดือน', en: 'Best Sellers' },
+ subtitle: { th: 'คัดสรรกลิ่นยอดนิยมจากลูกค้าของเรา', en: 'Our customer favorite products' },
+ type: 'featured',
+ limit: 3
+ },
+ renderPreview: (isMobile) => (
-
-
Our Best Sellers
-
Hand-picked organic favorites
+
+
Best Sellers
+
Our customer favorite products
-
+
{[
- { name: 'Ozone Ambient Blend', price: '฿850', img: 'https://images.unsplash.com/photo-1608571423902-eed4a5ad8108?auto=format&fit=crop&w=200&q=80' },
- { name: 'Lavender Sanctuary Diffuser', price: '฿1,290', img: 'https://images.unsplash.com/photo-1547887537-6158d64c35b3?auto=format&fit=crop&w=200&q=80' },
- { name: 'Citrus Zest Room Mist', price: '฿450', img: 'https://images.unsplash.com/photo-1612817288484-6f916006741a?auto=format&fit=crop&w=200&q=80' }
- ].map((prod, i) => (
-
-
-
-
-
-
{prod.name}
-
{prod.price}
+ { name: 'Pure Lavender Essence', price: '฿890' },
+ { name: 'Cedarwood Atmosphere', price: '฿1,250' },
+ { name: 'Citrus Dawn Diffuser', price: '฿1,490' }
+ ].map((p, idx) => (
+
+
+
+
+
+ {p.name}
+ {p.price}
-
- Quick Add
-
))}
)
},
- // 8. PRODUCT_CAROUSEL
{
type: 'PRODUCT_CAROUSEL',
category: 'products',
description: 'Swipeable horizontal card carousel displaying specific product collections.',
+ fieldsSpec: {
+ required: [],
+ optional: ['title', 'description', 'collectionId', 'limit', 'showPrice', 'showAddToCart'],
+ description: 'สไลด์การ์ดสินค้าแนวนอน เลื่อนดูสินค้าในคอลเลกชันได้อย่างสะดวก'
+ },
payload: {
- title: 'Featured Collection',
- description: 'Selected scents for wellness journeys.',
- collectionId: 'wellness-campaign',
- limit: 5,
+ title: { th: 'คอลเลกชันพิเศษ', en: 'Featured Collection' },
+ description: { th: 'สินค้าคัดสรรพิเศษสำหรับแคมเปญนี้', en: 'Hand-picked products for this campaign.' },
+ limit: 6,
showPrice: true,
showAddToCart: true
},
renderPreview: () => (
-
-
-
Featured Collection
-
Selected scents for wellness journeys
-
-
Slide next →
+
+
Featured Collection
+ View All →
-
- {[
- { name: 'Ozone Ambient', price: '฿850', img: 'https://images.unsplash.com/photo-1608571423902-eed4a5ad8108?auto=format&fit=crop&w=150&q=80' },
- { name: 'Lavender Sanctuary', price: '฿1,290', img: 'https://images.unsplash.com/photo-1547887537-6158d64c35b3?auto=format&fit=crop&w=150&q=80' },
- { name: 'Citrus Zest Mist', price: '฿450', img: 'https://images.unsplash.com/photo-1612817288484-6f916006741a?auto=format&fit=crop&w=150&q=80' },
- { name: 'Eucalyptus Mint', price: '฿890', img: 'https://images.unsplash.com/photo-1540555700478-4be289fbecef?auto=format&fit=crop&w=150&q=80' }
- ].map((prod, i) => (
-
-
-
-
-
-
{prod.name}
-
{prod.price}
+
+ {[1, 2, 3, 4].map((i) => (
+
+
+
+
Botanical Diffuser #{i}
+
฿1,200
))}
)
},
- // 9. RELATED_PRODUCTS
+ {
+ type: 'PRODUCT_LAYOUT',
+ category: 'products',
+ badge: 'new',
+ description: 'Full product detail page layout template including media gallery, buy box, specs tabs, and reviews.',
+ fieldsSpec: {
+ required: [],
+ optional: ['showBreadcrumbs', 'enableStickyBuyBox', 'defaultTab'],
+ description: 'เทมเพลตมาตรฐานสำหรับหน้ารายละเอียดสินค้า ประกอบด้วยแกลเลอรี ป้ายราคา ตัวเลือกกลิ่น และรีวิว'
+ },
+ payload: {
+ showBreadcrumbs: true,
+ enableStickyBuyBox: true,
+ defaultTab: 'description'
+ },
+ renderPreview: (isMobile) => (
+
+
+
+
+
+
Signature Series
+
Ozone & Wild Mint Reed Diffuser
+
฿1,850
+
Clean, crisp, oceanic botanical diffuser blending spearmint with maritime pine.
+
Add To Cart
+
+
+ )
+ },
{
type: 'RELATED_PRODUCTS',
category: 'products',
description: 'Dynamic block recommending items from the same category for the product page layout.',
+ fieldsSpec: {
+ required: [],
+ optional: ['title', 'showHeading', 'showViewAllLink'],
+ description: 'บล็อกแนะนำสินค้าที่เกี่ยวข้องจากหมวดหมู่เดียวกัน'
+ },
payload: {
- title: 'You May Also Like',
+ title: { th: 'สินค้าที่คุณอาจชอบ', en: 'Related Products' },
showHeading: true,
showViewAllLink: true
},
renderPreview: () => (
-
-
You May Also Like
-
View All
+
+
Related Products
+ View all
-
-
-
-
+
+ {[1, 2, 3].map((i) => (
+
+
-
-
Ozone Ambient Blend
-
฿850
-
-
-
-
-
-
-
-
Lavender sanctuary
-
฿1,290
-
-
+ ))}
)
},
- // 10. EDITORIAL_TILE
+
+ // ==========================================
+ // STORY & EDITORIAL (Category: editorial)
+ // ==========================================
{
type: 'EDITORIAL_TILE',
category: 'editorial',
- description: 'Stunning editorial grid block presenting storytelling text alongside a curated campaign photo.',
- payload: {
- title: 'Moodboard [IRL]',
- description: 'An expressive mix of texture, shape and movement. Deconstructed details, utilitarian elements and fluid tailoring come together in looks that feel personal.',
- imageUrl: 'https://images.unsplash.com/photo-1515886657613-9f3515b0c78f?auto=format&fit=crop&w=800&q=80',
- imagePosition: 'left',
- imageAspectRatio: 'tall',
- buttonText: 'Shop the looks',
- buttonLink: '/shop',
- backgroundColor: '#1E293B',
- textColor: '#FFFFFF'
+ badge: 'updated',
+ description: 'Stunning editorial grid block presenting storytelling text alongside a curated campaign photo with adjustable aspect ratio.',
+ fieldsSpec: {
+ required: ['title', 'description', 'imageUrl', 'imagePosition'],
+ optional: ['imageAspectRatio', 'buttonText', 'buttonLink', 'backgroundColor', 'textColor'],
+ description: 'บล็อกเล่าเรื่องสไตล์นิตยสาร รองรับสัดส่วนภาพ landscape, wide, square, portrait, tall'
},
- renderPreview: () => (
-
-
-
+ payload: {
+ title: { th: 'รังสรรค์ด้วยความหลงใหลในประสาทสัมผัส', en: 'Crafted with [Sensory Passion]' },
+ description: { th: 'ทุกสูตรคือการคารวะต่อพฤกษศาสตร์ธรรมชาติ เพื่อมอบความสงบให้ทุกวันของคุณ', en: 'Every formulation is a tribute to pure botanical essences, hand-blended to capture nature’s quiet intelligence.' },
+ imageUrl: 'https://images.unsplash.com/photo-1608571423902-eed4a5ad8108?auto=format&fit=crop&w=800&q=80',
+ imagePosition: 'left',
+ imageAspectRatio: 'landscape',
+ buttonText: { th: 'อ่านเรื่องราวของเรา', en: 'Read Our Story' },
+ buttonLink: '/about',
+ backgroundColor: '#FDFDF9',
+ textColor: '#1F3D2D'
+ },
+ renderPreview: (isMobile) => (
+
+
+
-
-
Crafted with [Sensory Passion]
-
- Every formulation at HomAroma is a tribute to pure botanical essences, hand-blended to capture nature’s quiet intelligence.
-
-
- Read Our Story
-
+
+
Crafted with [Sensory Passion]
+
Every formulation is a tribute to pure botanical essences, hand-blended to capture nature’s quiet intelligence.
+
Read Our Story →
)
},
- // 10.5 FEATURED_TILES
{
type: 'FEATURED_TILES',
category: 'editorial',
- description: 'Side-by-side campaign grid featuring square or tall images with centered titles and outline CTA buttons (Jo Malone aesthetic).',
+ badge: 'updated',
+ description: 'Side-by-side campaign grid featuring square or landscape images with dual-level links (Jo Malone aesthetic).',
+ fieldsSpec: {
+ required: ['tiles'],
+ optional: ['title', 'subtitle', 'headerAlign', 'showHeading', 'columns', 'containerWidth', 'paddingTop', 'paddingBottom', 'sectionPadding', 'layoutPreset', 'imageAspectRatio', 'textAlign', 'imageRounded', 'buttonStyle', 'backgroundColor', 'textColor'],
+ description: 'บล็อกการ์ดภาพคู่แบบ Jo Malone รองรับ headerAlign: left/center/right/none, containerWidth: standard/wide/full, paddingTop/paddingBottom: none/compact/normal/spacious, layoutPreset: editorial/cards/banner, imageAspectRatio: landscape/wide/square/portrait, ข้อความลิงก์สองระดับ'
+ },
payload: {
- title: 'Summer Campaign',
+ title: { th: 'แคมเปญเด่นประจำฤดูกาล', en: 'Featured Campaigns' },
+ headerAlign: 'left',
+ showHeading: true,
columns: 2,
- backgroundColor: '#FDFDF9',
- textColor: '#1F3D2D',
+ containerWidth: 'wide',
+ paddingTop: 'compact',
+ paddingBottom: 'normal',
+ layoutPreset: 'editorial',
+ imageAspectRatio: 'landscape',
+ textAlign: 'left',
+ imageRounded: '2xl',
+ buttonStyle: 'link',
tiles: [
{
- title: 'Here Comes The Sun',
- description: '',
- imageUrl: 'https://images.unsplash.com/photo-1608571423902-eed4a5ad8108?auto=format&fit=crop&w=600&q=80',
- buttonText: 'Shop Beach Blossom',
+ title: { th: 'วันหยุดแสนสะอาดสดชื่น', en: 'Weekend Clean' },
+ description: { th: 'สัมผัสความอบอุ่นของแสงแดดยามเช้า', en: 'Embrace the crisp morning sun' },
+ imageUrl: 'https://images.unsplash.com/photo-1608571423902-eed4a5ad8108?auto=format&fit=crop&w=800&q=80',
+ imageAspectRatio: 'landscape',
+ buttonText: { th: 'เลือกซื้อชุดพักผ่อน →', en: 'Shop Relaxed Sets →' },
buttonLink: '/shop'
},
{
- title: 'The Scent Of A New Adventure',
- description: '',
- imageUrl: 'https://images.unsplash.com/photo-1547887537-6158d64c35b3?auto=format&fit=crop&w=600&q=80',
- buttonText: 'Be The First To Know',
+ title: { th: 'ความสบายที่นุ่มนวล', en: 'Soft Casual' },
+ description: { th: 'กลิ่นหอมผ่อนคลายตลอดทั้งวัน', en: 'Relaxing ambient notes for all day' },
+ imageUrl: 'https://images.unsplash.com/photo-1547887537-6158d64c35b3?auto=format&fit=crop&w=800&q=80',
+ imageAspectRatio: 'landscape',
+ buttonText: { th: 'เลือกซื้อคอลเลกชันหญิง →', en: 'Shop Women →' },
buttonLink: '/shop'
}
]
},
- renderPreview: () => (
-
-
-
-
-
-
Here Comes The Sun
-
- Shop Beach Blossom
-
+ renderPreview: (isMobile) => (
+
+
+
Featured Campaigns
-
-
-
-
-
The Scent Of A New Adventure
-
- Be The First To Know
-
+
+ {[
+ { title: 'Weekend Clean', link: 'Shop Relaxed Sets →', img: 'https://images.unsplash.com/photo-1608571423902-eed4a5ad8108?auto=format&fit=crop&w=600&q=80' },
+ { title: 'Soft Casual', link: 'Shop Women →', img: 'https://images.unsplash.com/photo-1547887537-6158d64c35b3?auto=format&fit=crop&w=600&q=80' }
+ ].map((t, idx) => (
+
+
+
+
+
+
{t.title}
+ {t.link}
+
+
+ ))}
)
},
- // 11. EDITORIAL_CAROUSEL
{
type: 'EDITORIAL_CAROUSEL',
category: 'editorial',
description: 'Stories and values slider displaying image slideshows side-by-side with localized editorial statements.',
+ fieldsSpec: {
+ required: ['slides'],
+ optional: ['title'],
+ description: 'สไลด์เล่าเรื่องราวคุณค่าของแบรนด์'
+ },
payload: {
- title: 'The Wellness Philosophy',
+ title: { th: 'ปรัชญาแห่งสุขภาวะ', en: 'The Wellness [Philosophy]' },
slides: [
{
category: 'Heritage',
- title: 'Rooted in Nature',
- description: 'Our ingredients are sustainably sourced from organic growers who share our respect for ecological balance.',
- imageUrl: 'https://images.unsplash.com/photo-1608571423902-eed4a5ad8108?auto=format&fit=crop&w=400&q=80',
- buttonText: 'Discover Sourcing',
+ title: { th: 'หยั่งรากในธรรมชาติ', en: 'Rooted in Nature' },
+ description: { th: 'วัตถุดิบทั้งหมดมาจากผู้ปลูกเกษตรอินทรีย์ที่ยั่งยืน', en: 'Our ingredients are sustainably sourced from organic growers who share our respect for ecological balance.' },
+ imageUrl: 'https://images.unsplash.com/photo-1547887537-6158d64c35b3?auto=format&fit=crop&w=800&q=80',
+ buttonText: { th: 'ค้นพบแหล่งกำเนิด', en: 'Discover Sourcing' },
buttonLink: '/sourcing'
}
]
},
renderPreview: () => (
-
-
The Wellness Philosophy
-
-
-
-
-
-
Heritage
-
Rooted in Nature
-
Our ingredients are sustainably sourced from organic growers who share our respect for ecological balance.
-
Discover Sourcing →
-
-
+
+
Heritage
+
Rooted in Nature
+
Our ingredients are sustainably sourced from organic growers who share our respect for ecological balance.
)
},
- // 12. SCENT_NOTES_BREAKDOWN
{
type: 'SCENT_NOTES_BREAKDOWN',
category: 'editorial',
description: 'Fragrance profile breakdowns containing Top, Heart/Middle, and Base notes lists.',
+ fieldsSpec: {
+ required: [],
+ optional: ['title', 'description', 'topNotes', 'heartNotes', 'middleNotes', 'baseNotes'],
+ description: 'โครงสร้างจำแนกระดับกลิ่นหอม แสดงโน้ต Top, Heart, Base'
+ },
payload: {
- title: 'Scent Signature Breakdown',
- description: 'Detailed analysis of fragrance volatility levels.',
- topNotes: ['Italian Bergamot', 'Citrus Peel'],
- heartNotes: ['Jasmine Absolute', 'French Lavender'],
- baseNotes: ['Sandalwood', 'Clean Musk']
+ title: { th: 'โครงสร้างกลิ่นหอม', en: 'Scent Notes Breakdown' },
+ description: { th: 'การเดินทางของกลิ่นหอมตลอด 3 ระดับสัมผัส', en: 'The fragrance evolution across three olfactory layers.' },
+ topNotes: ['Citrus', 'Green Tea', 'Bergamot'],
+ heartNotes: ['White Jasmine', 'Damask Rose'],
+ baseNotes: ['White Musk', 'Cedarwood', 'Amber']
},
renderPreview: () => (
-
-
-
Scent Signature Breakdown
-
Detailed analysis of fragrance volatility levels
-
-
-
-
Top
-
Italian Bergamot, Citrus Peel
+
+
Scent Notes
+
+
+ Top
+ Bergamot, Citrus
-
-
Heart
-
Jasmine Absolute, French Lavender
+
+ Heart
+ Jasmine, Rose
-
-
Base
-
Sandalwood, Clean Musk
+
+ Base
+ Cedar, Amber
)
},
- // 13. QUOTE_CALLOUT
{
type: 'QUOTE_CALLOUT',
category: 'editorial',
description: 'Elegant text banner presenting callout quotations, ideal for customer testimonials.',
+ fieldsSpec: {
+ required: ['quote'],
+ optional: ['author', 'role'],
+ description: 'กล่องโควทคำคมพรีเมียม สำหรับคำนิยมหรือสโลแกน'
+ },
payload: {
- quote: 'Fragrance is the invisible, unforgettable fashion accessory.',
- author: 'Coco Chanel',
- role: 'Fashion Designer'
+ quote: { th: 'กลิ่นหอมคือเครื่องประดับที่มองไม่เห็น แต่ยากจะลืมเลือน', en: 'Fragrance is the invisible, unforgettable accessory.' },
+ author: 'Founder',
+ role: 'HomAroma Atelier'
},
renderPreview: () => (
-
-
“
-
- "Fragrance is the invisible, unforgettable fashion accessory."
-
-
- — Coco Chanel | Fashion Designer
-
+
+
+
"Fragrance is the invisible, unforgettable accessory."
+
— Founder, HomAroma Atelier
)
},
- // 14. TEXT
{
- type: 'TEXT',
+ type: 'USP_BAR',
category: 'editorial',
- description: 'Plain text component for headers, centered paragraphs, or brand catchphrases.',
+ description: 'Unique Selling Proposition Bar highlighting product perks (Icons & Labels).',
+ fieldsSpec: {
+ required: ['items'],
+ optional: [],
+ description: 'แถบแสดงจุดเด่น 4 ช่องพร้อมไอคอน'
+ },
payload: {
- title: 'Natural & Ecological Policy',
- content: 'We use 100% natural, botanically derived ingredients in all formulations. Cruelty-free.',
- textAlign: 'center'
+ items: [
+ { title: '100% Pure', description: 'Botanical extracts' },
+ { title: 'Free Shipping', description: 'Over ฿1,500' },
+ { title: 'Eco Friendly', description: 'Zero carbon footprint' }
+ ]
},
renderPreview: () => (
-
-
Natural & Ecological Policy
-
- We use 100% natural, botanically derived ingredients in all formulations. Cruelty-free.
-
+
+
100% Pure
+
Free Shipping
+
Eco Friendly
)
},
- // 15. RICH_TEXT
- {
- type: 'RICH_TEXT',
- category: 'editorial',
- description: 'Styled markdown block designed for longer stories or HTML embedding.',
- payload: {
- title: 'Corporate Social Responsibility',
- content: '
Our commitments extend beyond scent creation. HomAroma proudly partners with rural farming families in Northern Thailand to source organic lemongrass oil.
Sustainable development goals Fair-trade wages '
- },
- renderPreview: () => (
-
-
Corporate Social Responsibility
-
-
Our commitments extend beyond scent creation. HomAroma proudly partners with rural farming families in Northern Thailand to source organic lemongrass oil.
-
- Sustainable development goals
- Fair-trade wages
-
-
-
- )
- },
- // 16. HERO_ARTICLE
+
+ // ==========================================
+ // ARTICLE ELEMENTS (Category: articles)
+ // ==========================================
{
type: 'HERO_ARTICLE',
category: 'articles',
description: 'Editorial article header with background blur, date, author name, and title overlays.',
+ fieldsSpec: {
+ required: ['title', 'imageUrl'],
+ optional: ['subtitle', 'author', 'category', 'publishDate', 'overlayColor'],
+ description: 'ส่วนหัวบทความสไตล์นิตยสาร'
+ },
payload: {
- title: 'Fragrance & Mindfulness Journey',
- subtitle: 'How ambient scent transforms focus and breathing cycles.',
- author: 'Dr. Aromatherapist',
- category: 'Insights',
- publishDate: '2026-07-27',
- imageUrl: 'https://images.unsplash.com/photo-1547887537-6158d64c35b3?auto=format&fit=crop&w=600&q=80'
+ title: { th: 'เรื่องราวของกลิ่นหอมและการผ่อนคลาย', en: 'Scent Guide [Article]' },
+ subtitle: { th: 'ค้นพบความลับเบื้องหลังน้ำมันหอมระเหย', en: 'Discover the story behind each fragrance.' },
+ author: 'Aromatherapist',
+ category: 'Story',
+ publishDate: '2026-01-01',
+ imageUrl: 'https://images.unsplash.com/photo-1608571423902-eed4a5ad8108?auto=format&fit=crop&w=1200&q=80'
},
renderPreview: () => (
-
-
-
- Insights
- •
- 2026-07-27
-
-
Fragrance & Mindfulness Journey
-
How ambient scent transforms focus and breathing cycles.
-
Written by Dr. Aromatherapist
+
+
+
+ Story · 2026-01-01
+
Scent Guide [Article]
)
},
- // 17. ARTICLE_HEADER
{
type: 'ARTICLE_HEADER',
category: 'articles',
description: 'Introductory page header for standard text articles.',
+ fieldsSpec: {
+ required: ['title'],
+ optional: ['subtitle'],
+ description: 'ส่วนหัวบทความมาตรฐาน'
+ },
payload: {
- title: 'The Chemistry of Volatility',
- subtitle: 'Understanding high, middle, and low evaporation rates of pure aromatherapy elements.'
+ title: { th: 'บทความแนะนำ', en: 'Article Title' },
+ subtitle: { th: 'คำนำสั้นๆ สำหรับบทความนี้', en: 'A concise introduction to the story.' }
},
renderPreview: () => (
-
-
The Chemistry of Volatility
-
Understanding high, middle, and low evaporation rates of pure aromatherapy elements.
+
+
Article Title
+
A concise introduction to the story.
)
},
- // 18. ARTICLE_MEDIA
{
type: 'ARTICLE_MEDIA',
category: 'articles',
description: 'Article paragraph paired with a side image (left/right alignment).',
+ fieldsSpec: {
+ required: ['body'],
+ optional: ['heading', 'imageUrl', 'imagePosition', 'width'],
+ description: 'ย่อหน้าบทความคู่กับภาพประกอบ'
+ },
payload: {
- heading: 'Sourcing Lavender Extract',
- body: 'Our lavender is harvested at dawn in Provence when oil concentrations are highest, then steam-distilled locally within 4 hours.',
- imagePosition: 'right',
- imageUrl: 'https://images.unsplash.com/photo-1547887537-6158d64c35b3?auto=format&fit=crop&w=100&q=80'
+ heading: { th: 'หัวข้อย่อย', en: 'Article Section' },
+ body: { th: 'เนื้อหาย่อหน้าบทความ...', en: 'Write one focused paragraph here with botanical insights.' },
+ imagePosition: 'right'
},
renderPreview: () => (
-
-
-
Sourcing Lavender Extract
-
- Our lavender is harvested at dawn in Provence when oil concentrations are highest, then steam-distilled locally within 4 hours.
-
-
-
-
+
+
+
Article Section
+
Write one focused paragraph here with botanical insights.
+
)
},
- // 19. ARTICLE_GALLERY
{
type: 'ARTICLE_GALLERY',
category: 'articles',
description: 'Photo collection grids to show off multiple illustrations or steps.',
+ fieldsSpec: {
+ required: ['images'],
+ optional: ['layout'],
+ description: 'แกลเลอรีรูปภาพหลายรูปในบทความ'
+ },
payload: {
layout: 'grid',
images: [
- { imageUrl: 'https://images.unsplash.com/photo-1608571423902-eed4a5ad8108?auto=format&fit=crop&w=200&q=80' },
- { imageUrl: 'https://images.unsplash.com/photo-1547887537-6158d64c35b3?auto=format&fit=crop&w=200&q=80' }
+ { imageUrl: 'https://images.unsplash.com/photo-1608571423902-eed4a5ad8108?auto=format&fit=crop&w=400&q=80', alt: 'One' },
+ { imageUrl: 'https://images.unsplash.com/photo-1547887537-6158d64c35b3?auto=format&fit=crop&w=400&q=80', alt: 'Two' }
]
},
renderPreview: () => (
-
-
-
-
-
-
-
+
)
},
- // 20. ARTICLE_FACTS
{
type: 'ARTICLE_FACTS',
category: 'articles',
description: 'Quick summaries or key takeaway bullets for editorial pieces.',
+ fieldsSpec: {
+ required: ['items'],
+ optional: ['title'],
+ description: 'กล่องสรุปข้อเท็จจริงสำคัญ'
+ },
payload: {
- title: 'Key Scent Benefits',
+ title: { th: 'ประเด็นสำคัญ', en: 'Key Facts' },
items: [
- { title: 'Relaxation', description: 'Proven scent to lower blood pressure and cortisol levels.' },
- { title: 'Focus Boost', description: 'Peppermint elements trigger sensory wakefulness.' }
+ { title: '100% Organic', description: 'Certified by ECOCERT' },
+ { title: 'Zero Additives', description: 'Pure unadulterated oil' }
]
},
renderPreview: () => (
-
-
- Key Scent Benefits
-
-
-
- Relaxation: Proven scent to lower blood pressure and cortisol levels.
-
-
- Focus Boost: Peppermint elements trigger sensory wakefulness.
-
+
+
Key Facts
+
+
• 100% Organic: Certified by ECOCERT
+
• Zero Additives: Pure unadulterated oil
)
},
- // 21. ARTICLE_VIDEO
{
type: 'ARTICLE_VIDEO',
category: 'articles',
description: 'Embedded video player wrapper for articles.',
+ fieldsSpec: {
+ required: ['videoUrl'],
+ optional: ['aspectRatio'],
+ description: 'ตัวเล่นวิดีโอฝังในบทความ'
+ },
payload: {
- videoUrl: 'https://www.youtube.com/watch?v=mock',
+ videoUrl: 'https://www.youtube.com/watch?v=VIDEO_ID',
aspectRatio: '16:9'
},
renderPreview: () => (
-
-
-
-
Watch Youtube Video Preview
+
)
},
- // 22. ARTICLE_REFERENCES
{
type: 'ARTICLE_REFERENCES',
category: 'articles',
description: 'Citation list or scientific reference cards.',
+ fieldsSpec: {
+ required: ['items'],
+ optional: ['title'],
+ description: 'รายการเอกสารอ้างอิง'
+ },
payload: {
- title: 'Study Sources',
- items: [
- { title: 'Journal of Aromatherapy Research (Vol. 12)', link: 'https://example.com' },
- { title: 'Clinical Scent Testing & Sleep Induction (2024)', link: 'https://example.com' }
- ]
+ title: { th: 'เอกสารอ้างอิง', en: 'References' },
+ items: [{ title: 'International Aromatherapy Journal 2026' }]
},
renderPreview: () => (
-
-
Study Sources
-
+
+ References
+ [1] International Aromatherapy Journal 2026
)
},
- // 23. ARTICLE_TABLE
{
type: 'ARTICLE_TABLE',
category: 'articles',
description: 'Comparison table displaying technical parameters or specs.',
+ fieldsSpec: {
+ required: ['columns', 'rows'],
+ optional: ['title'],
+ description: 'ตารางเปรียบเทียบข้อมูล'
+ },
payload: {
- title: 'Volatility Comparison',
- columns: ['Fragrance Type', 'Top Note Evaporation', 'Average Life'],
- rows: [
- { label: 'Essential Oil', cells: ['High (Fast)', '4-6 hours'] },
- { label: 'Carrier Blend', cells: ['Low (Slow)', '24-48 hours'] }
- ]
+ title: { th: 'เปรียบเทียบคุณสมบัติ', en: 'Technical Comparison' },
+ columns: ['Property', 'Value'],
+ rows: [{ label: 'Extraction', cells: ['Steam Distillation', 'Cold Pressed'] }]
},
renderPreview: () => (
-
-
-
-
- Fragrance Type
- Top Note Evaporation
- Average Life
-
-
-
-
- Essential Oil
- High (Fast)
- 4-6 hours
-
-
- Carrier Blend
- Low (Slow)
- 24-48 hours
-
-
-
+
+
+ Property Value
+
+
+ Extraction Steam Distillation
+
)
},
- // 24. ARTICLE_DOWNLOAD
{
type: 'ARTICLE_DOWNLOAD',
category: 'articles',
description: 'File attachments download cards (PDF guides, catalogues).',
+ fieldsSpec: {
+ required: ['files'],
+ optional: ['title'],
+ description: 'กล่องดาวน์โหลดไฟล์แนบ'
+ },
payload: {
- title: 'Available Resources',
- files: [
- { title: 'Organic Certification PDF', fileType: 'PDF', url: '#' },
- { title: 'Aromatherapy Scent Catalogue', fileType: 'PDF', url: '#' }
- ]
+ title: { th: 'ดาวน์โหลดเอกสาร', en: 'Downloads' },
+ files: [{ title: 'Botanical Guide 2026', url: 'https://example.com/guide.pdf', fileType: 'PDF' }]
},
renderPreview: () => (
-
-
Available Resources
-
- {[
- { title: 'Organic Certification PDF', size: '2.4 MB' },
- { title: 'Scent Catalogue', size: '4.8 MB' }
- ].map((f, i) => (
-
-
-
{f.title}
-
{f.size} • PDF
-
-
-
-
-
- ))}
+
+
+
+ Botanical Guide 2026 (PDF)
+
Download
)
},
- // 25. ARTICLE_CTA
{
type: 'ARTICLE_CTA',
category: 'articles',
description: 'Call-to-action blocks prompting next-step user clicks.',
+ fieldsSpec: {
+ required: ['title', 'primaryText', 'primaryLink'],
+ optional: ['alignment'],
+ description: 'บล็อกกระตุ้นการตัดสินใจปิดท้ายบทความ'
+ },
payload: {
- title: 'Ready to start your wellness journey?',
- primaryText: 'Explore Collection',
- primaryLink: '/shop',
- alignment: 'center'
+ title: { th: 'ต้องการข้อมูลเพิ่มเติม?', en: 'Need more information?' },
+ primaryText: { th: 'ติดต่อเรา', en: 'Contact Us' },
+ primaryLink: '/contact'
},
renderPreview: () => (
-
-
Ready to start your wellness journey?
-
- Explore Collection
-
+
+
Need more information?
+ Contact Us
)
},
- // 26. NEWSLETTER
+
+ // ==========================================
+ // FORMS & INFO (Category: forms)
+ // ==========================================
{
type: 'NEWSLETTER',
category: 'forms',
description: 'Email subscription block to attract newsletter sign-ups.',
+ fieldsSpec: {
+ required: ['title'],
+ optional: ['description', 'buttonText', 'placeholderText', 'showPrivacyCheckbox', 'privacyText'],
+ description: 'ฟอร์มรับสมัครจดหมายข่าวพร้อมกล่องยอมรับนโยบาย'
+ },
payload: {
- title: 'Begin Your Wellness Journey',
- description: 'Subscribe to receive 10% off your first purchase and exclusive updates.',
- buttonText: 'Subscribe',
- placeholderText: 'Enter your email address',
- showPrivacyCheckbox: true,
- privacyText: 'I agree to the privacy policy.'
+ title: { th: 'เริ่มต้นการเดินทางแห่งสุขภาวะ', en: 'Begin Your Wellness Journey' },
+ description: { th: 'รับส่วนลด 10% สำหรับคำสั่งซื้อแรก', en: 'Subscribe to receive 10% off your first purchase.' },
+ buttonText: { th: 'สมัครรับข่าวสาร', en: 'Subscribe' },
+ placeholderText: 'Enter your email address'
},
renderPreview: () => (
-
-
-
Begin Your Wellness Journey
-
Subscribe to receive 10% off your first purchase and exclusive updates.
-
+
)
},
- // 27. ACCORDION
{
type: 'ACCORDION',
category: 'forms',
description: 'Question-answer accordions for FAQs, divided by custom categories.',
+ fieldsSpec: {
+ required: ['categories'],
+ optional: ['title'],
+ description: 'แถบพับคำถามที่พบบ่อย (FAQs) แยกหมวดหมู่'
+ },
payload: {
- title: 'Frequently Asked Questions',
+ title: { th: 'คำถามที่พบบ่อย', en: 'Frequently Asked Questions' },
categories: [
{
- name: 'General Policy',
- icon: 'HelpCircle',
+ name: { th: 'ทั่วไป', en: 'General' },
questions: [
- { q: 'How long do Reed Diffusers last?', a: 'Normally, they evaporate gradually over 4 to 6 weeks depending on temperature levels.' },
- { q: 'Are essential oils safe for pets?', a: 'Some oils are toxic to dogs/cats. Please consult a veterinarian before diffusing.' }
+ {
+ q: { th: 'สินค้าเป็นออร์แกนิก 100% หรือไม่?', en: 'Are all products 100% organic?' },
+ a: { th: 'ใช่วัตถุดิบทั้งหมดผ่านการรับรองมาตรฐานสากล', en: 'Yes, all extracts are certified organic.' }
+ }
]
}
]
},
renderPreview: () => (
-
-
- Frequently Asked Questions (General Policy)
-
-
- {[
- { q: 'How long do Reed Diffusers last?', a: 'Normally, they evaporate gradually over 4 to 6 weeks depending on temperature levels.' },
- { q: 'Are essential oils safe for pets?', a: 'Some oils are toxic to dogs/cats. Please consult a veterinarian before diffusing.' }
- ].map((faq, i) => (
-
-
- {faq.q}
-
-
-
{faq.a}
-
- ))}
+
+
FAQs
+
+ Are all products 100% organic?
+
)
},
- // 28. CONTACT_INFO
{
type: 'CONTACT_INFO',
category: 'forms',
description: 'Beautiful information box showing address, telephone, and social details.',
+ fieldsSpec: {
+ required: ['title'],
+ optional: ['address', 'email', 'line', 'hours'],
+ description: 'กล่องข้อมูลติดต่อร้านค้า'
+ },
payload: {
- title: 'Contact Details',
- address: '123 Sukhumvit Rd, Bangkok, Thailand',
- email: 'hello@homaroma.com',
+ title: { th: 'ติดต่อเรา', en: 'Contact Us' },
+ address: '123 Sukhumvit Road, Bangkok',
+ email: 'hello@homaroma.shop',
line: '@homaroma',
- hours: 'Mon-Fri: 9AM - 6PM'
+ hours: 'Mon-Fri 9AM-6PM'
},
renderPreview: () => (
-
-
Contact Details
-
-
-
- 123 Sukhumvit Rd, Bangkok
-
-
-
- hello@homaroma.com
-
-
-
-
- Mon-Fri: 9AM - 6PM
-
-
+
+
Bangkok, Thailand
+
hello@homaroma.shop
)
},
- // 29. CONTACT_FORM
{
type: 'CONTACT_FORM',
category: 'forms',
description: 'General support email inquiry contact form.',
+ fieldsSpec: {
+ required: ['title'],
+ optional: ['subtitle'],
+ description: 'ฟอร์มส่งข้อความติดต่อสอบถาม'
+ },
payload: {
- title: 'Get In Touch',
- subtitle: 'We would love to hear from you.'
+ title: { th: 'ส่งข้อความหาเรา', en: 'Get In Touch' },
+ subtitle: { th: 'เรายินดีตอบทุกคำถามของคุณ', en: 'We would love to hear from you.' }
},
renderPreview: () => (
-
-
-
Get In Touch
-
We would love to hear from you.
-
-
-
-
-
-
- Send Message
-
-
+
+
Get In Touch
+
+ Send
+
+ )
+ },
+
+ // ==========================================
+ // LAYOUT & CUSTOM (Category: layout)
+ // ==========================================
+ {
+ type: 'TEXT',
+ category: 'layout',
+ description: 'Plain text component for headers, centered paragraphs, or brand catchphrases.',
+ fieldsSpec: {
+ required: ['content'],
+ optional: ['title', 'textAlign'],
+ description: 'บล็อกข้อความตัวอักษรเรียบง่าย'
+ },
+ payload: {
+ title: { th: 'คำมั่นสัญญาของเรา', en: 'Our Commitment' },
+ content: { th: 'เรามุ่งมั่นคัดสรรเฉพาะสิ่งที่ดีที่สุดเพื่อคุณ', en: 'We only use 100% natural and sustainably sourced botanicals.' },
+ textAlign: 'center'
+ },
+ renderPreview: () => (
+
+
Our Commitment
+
We only use 100% natural and sustainably sourced botanicals.
+
+ )
+ },
+ {
+ type: 'RICH_TEXT',
+ category: 'layout',
+ description: 'Styled markdown block designed for longer stories or HTML embedding.',
+ fieldsSpec: {
+ required: ['content'],
+ optional: ['title'],
+ description: 'บล็อกข้อความจัดรูปแบบ HTML หรือ Markdown'
+ },
+ payload: {
+ title: { th: 'เรื่องราวของแบรนด์', en: 'Brand Story' },
+ content: { th: '
เรื่องราวความเป็นมาของแบรนด์...
', en: '
Tell the authentic story of your botanical journey here.
' }
+ },
+ renderPreview: () => (
+
+
Brand Story
+
Tell the authentic story of your botanical journey here.
+
+ )
+ },
+ {
+ type: 'DIVIDER',
+ category: 'layout',
+ badge: 'new',
+ description: 'Section separation line with configurable style, thickness, spacing, color, and container width.',
+ fieldsSpec: {
+ required: [],
+ optional: ['width', 'style', 'thickness', 'spacing', 'color'],
+ description: 'เส้นคั่นปรับ style (solid/dashed/dotted), width (full/container), spacing (sm/md/lg) และสีได้'
+ },
+ payload: {
+ width: 'container',
+ style: 'solid',
+ thickness: 1,
+ spacing: 'md',
+ color: '#334155'
+ },
+ renderPreview: () => (
+
+ )
+ },
+ {
+ type: 'CUSTOM',
+ category: 'layout',
+ badge: 'new',
+ description: 'Dynamic extensible white-label block supporting custom components and flexible props.',
+ fieldsSpec: {
+ required: ['componentId'],
+ optional: ['props'],
+ description: 'บล็อกส่วนขยายสำหรับเพิ่ม Component พิเศษเฉพาะแบรนด์ เช่น BakeryCategories'
+ },
+ payload: {
+ componentId: 'BakeryCategories',
+ props: {
+ title: { th: 'หมวดหมู่เบเกอรี่', en: 'Bakery Categories' },
+ subtitle: { th: 'เลือกซื้อขนมอบตามหมวดหมู่ที่คุณชอบ', en: 'Explore fresh-baked favorites by collection.' },
+ layout: 'horizontal'
+ }
+ },
+ renderPreview: () => (
+
+
Custom Component: BakeryCategories
+
Explore fresh-baked favorites by collection.
)
}
@@ -1035,25 +1342,52 @@ export default function CmsMockupPage() {
- {/* Search Input Bar */}
-
-
-
setSearchQuery(e.target.value)}
- className="w-full bg-night-900/80 border border-white/10 text-white rounded-2xl pl-10 pr-9 py-2.5 text-xs focus:outline-none focus:border-cyan-glow/50 focus:ring-1 focus:ring-cyan-glow/50 transition-all placeholder:text-slate-500"
- />
- {searchQuery && (
+ {/* Global Controls & Search */}
+
+ {/* Device Preview Switcher */}
+
setSearchQuery('')}
- className="absolute right-3 top-1/2 -translate-y-1/2 text-slate-400 hover:text-white p-0.5 rounded-full hover:bg-white/10 transition-colors cursor-pointer"
+ onClick={() => setGlobalMobileView(false)}
+ className={`px-3 py-1.5 rounded-xl text-xs font-bold flex items-center gap-1.5 transition-all cursor-pointer ${
+ !globalMobileView ? 'bg-cyan-glow text-night-900 shadow-md' : 'text-slate-400 hover:text-white'
+ }`}
>
-
+
+ {t('cmsMockup.desktopView', 'Desktop')}
- )}
+ setGlobalMobileView(true)}
+ className={`px-3 py-1.5 rounded-xl text-xs font-bold flex items-center gap-1.5 transition-all cursor-pointer ${
+ globalMobileView ? 'bg-cyan-glow text-night-900 shadow-md' : 'text-slate-400 hover:text-white'
+ }`}
+ >
+
+ {t('cmsMockup.mobileView', 'Mobile (375px)')}
+
+
+
+ {/* Search Input */}
+
+
+ setSearchQuery(e.target.value)}
+ className="w-full bg-night-900/80 border border-white/10 text-white rounded-2xl pl-10 pr-9 py-2 text-xs focus:outline-none focus:border-cyan-glow/50 focus:ring-1 focus:ring-cyan-glow/50 transition-all placeholder:text-slate-500"
+ />
+ {searchQuery && (
+ setSearchQuery('')}
+ className="absolute right-3 top-1/2 -translate-y-1/2 text-slate-400 hover:text-white p-0.5 rounded-full hover:bg-white/10 transition-colors cursor-pointer"
+ >
+
+
+ )}
+
@@ -1065,7 +1399,7 @@ export default function CmsMockupPage() {
key={cat.id}
type="button"
onClick={() => setActiveCategory(cat.id)}
- className={`px-5 py-2 text-xs font-bold transition-all rounded-xl whitespace-nowrap cursor-pointer ${
+ className={`px-4 py-2 text-xs font-bold transition-all rounded-xl whitespace-nowrap cursor-pointer ${
activeCategory === cat.id
? 'bg-cyan-glow text-night-900 shadow-lg shadow-cyan-glow/20'
: 'text-slate-400 hover:text-white hover:bg-white/5'
@@ -1111,11 +1445,12 @@ export default function CmsMockupPage() {
{filteredBlocks.map((block) => {
const localizedDesc = t(`cmsMockup.blocks.${block.type}`, block.description);
const localizedCategory = t(`cmsMockup.categories.${block.category}`, block.category);
+ const isMobile = isBlockMobile(block.type);
return (
{/* Block Header Info */}
@@ -1127,12 +1462,54 @@ export default function CmsMockupPage() {
{localizedCategory}
+ {block.badge && (
+
+ {block.badge === 'new' ? '✨ NEW' : '⚡ UPDATED'}
+
+ )}
{localizedDesc}
{/* Action buttons */}
-
+
+ {/* Copy LLM Prompt Button */}
+ copyLlmPrompt(block)}
+ className={`px-3 py-1.5 rounded-xl border text-[10px] font-bold uppercase tracking-wider transition-all flex items-center gap-1.5 cursor-pointer ${
+ copiedPromptType === block.type
+ ? 'bg-purple-500/20 border-purple-500/40 text-purple-300 shadow-md'
+ : 'bg-purple-900/20 border-purple-500/20 hover:bg-purple-900/40 text-purple-200'
+ }`}
+ >
+ {copiedPromptType === block.type ? : }
+ {copiedPromptType === block.type
+ ? t('cmsMockup.llmPromptCopied', 'Prompt Copied')
+ : t('cmsMockup.copyLlmPrompt', 'Copy LLM Prompt')}
+
+
+ {/* View Schema Spec Button */}
+ setShowSpecFor(showSpecFor === block.type ? null : block.type)}
+ className={`px-3 py-1.5 rounded-xl border text-[10px] font-bold uppercase tracking-wider transition-all flex items-center gap-1.5 cursor-pointer ${
+ showSpecFor === block.type
+ ? 'bg-sky-500/20 text-sky-300 border-sky-500/40'
+ : 'bg-white/5 hover:bg-white/10 text-slate-300 border-white/10'
+ }`}
+ >
+
+ {showSpecFor === block.type
+ ? t('cmsMockup.hideSchema', 'Hide Spec')
+ : t('cmsMockup.schemaSpec', 'Schema Spec')}
+
+
+ {/* View JSON Payload Button */}
setShowJsonFor(showJsonFor === block.type ? null : block.type)}
@@ -1145,6 +1522,8 @@ export default function CmsMockupPage() {
? t('cmsMockup.hidePayload', 'Hide Payload')
: t('cmsMockup.viewPayload', 'View Payload')}
+
+ {/* Copy JSON Payload Button */}
copyPayload(block.type, block.payload)}
@@ -1160,17 +1539,66 @@ export default function CmsMockupPage() {
+ {/* Schema Spec Box */}
+ {showSpecFor === block.type && (
+
+
+
+ {block.type} Schema Specification
+
+
{block.fieldsSpec.description}
+
+
+
Required Fields
+
+ {block.fieldsSpec.required.length > 0 ? (
+ block.fieldsSpec.required.map((f) => (
+ {f}
+ ))
+ ) : (
+ None (all fields optional)
+ )}
+
+
+
+
Optional Fields
+
+ {block.fieldsSpec.optional.map((f) => (
+ {f}
+ ))}
+
+
+
+
+ )}
+
{/* JSON Code view */}
{showJsonFor === block.type && (
-
+
{JSON.stringify(block.payload, null, 2)}
)}
- {/* Live Visual Preview Frame */}
-
-
- {block.renderPreview()}
+ {/* Live Visual Preview Frame with Responsive Toggle */}
+
+
+ Preview:
+ toggleBlockMobile(block.type)}
+ className={`text-[10px] font-bold px-2 py-0.5 rounded-lg border transition-colors flex items-center gap-1 cursor-pointer ${
+ isMobile ? 'bg-cyan-glow/20 text-cyan-glow border-cyan-glow/30' : 'bg-white/5 text-slate-400 border-white/10 hover:text-white'
+ }`}
+ >
+ {isMobile ? : }
+ {isMobile ? 'Mobile 375px' : 'Desktop'}
+
+
+
+
+
+ {block.renderPreview(isMobile)}
+
diff --git a/apps/backend/src/routes/pages.ts b/apps/backend/src/routes/pages.ts
index 0519646..94b8dff 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 landscape and wide aspect ratios for FEATURED_TILES and EDITORIAL_TILE
+// Trigger reload: support paddingTop, paddingBottom, and sectionPadding for FEATURED_TILES
import {
LocalizedStringSchema,
HeroSectionPayloadSchema,
diff --git a/apps/mcp-server/section-toolkit.ts b/apps/mcp-server/section-toolkit.ts
index 8211d6e..8fb1f6a 100644
--- a/apps/mcp-server/section-toolkit.ts
+++ b/apps/mcp-server/section-toolkit.ts
@@ -199,8 +199,8 @@ const PAGE_BLOCK_METADATA: Record
= {
FEATURED_TILES: {
type: "FEATURED_TILES",
requiredFields: ["tiles[].title", "tiles[].imageUrl"],
- optionalFields: ["title", "subtitle", "columns", "backgroundColor", "textColor", "tiles[].description", "tiles[].buttonText", "tiles[].buttonLink", "tiles[].imageAspectRatio"],
- renderedFields: ["title", "subtitle", "columns", "backgroundColor", "textColor", "tiles[].title", "tiles[].description", "tiles[].imageUrl", "tiles[].buttonText", "tiles[].buttonLink", "tiles[].imageAspectRatio"],
+ optionalFields: ["title", "subtitle", "headerAlign", "showHeading", "columns", "containerWidth", "paddingTop", "paddingBottom", "sectionPadding", "layoutPreset", "textAlign", "ctaStyle", "imageRounded", "backgroundColor", "textColor", "tiles[].description", "tiles[].buttonText", "tiles[].buttonLink", "tiles[].imageAspectRatio"],
+ renderedFields: ["title", "subtitle", "headerAlign", "showHeading", "columns", "containerWidth", "paddingTop", "paddingBottom", "sectionPadding", "layoutPreset", "textAlign", "ctaStyle", "imageRounded", "backgroundColor", "textColor", "tiles[].title", "tiles[].description", "tiles[].imageUrl", "tiles[].buttonText", "tiles[].buttonLink", "tiles[].imageAspectRatio"],
storedOnlyFields: [],
discoveryToolsNeeded: [],
warnings: ["columns should be 2, 3, or 4."],
diff --git a/apps/spa/src/components/DynamicFeaturedTiles.tsx b/apps/spa/src/components/DynamicFeaturedTiles.tsx
index 0cf03e9..bf82d05 100644
--- a/apps/spa/src/components/DynamicFeaturedTiles.tsx
+++ b/apps/spa/src/components/DynamicFeaturedTiles.tsx
@@ -71,6 +71,47 @@ export default function DynamicFeaturedTiles({ payload }: DynamicFeaturedTilesPr
}
};
+ const containerWidth = payload.containerWidth || 'standard';
+
+ const getContainerWidthClass = (width: string) => {
+ switch (width) {
+ case 'full':
+ return 'w-full max-w-none';
+ case 'wide':
+ return 'w-full max-w-[1600px] mx-auto';
+ case 'standard':
+ default:
+ return 'ui-section-inner';
+ }
+ };
+
+ const headerAlign = payload.headerAlign || (layoutPreset === 'editorial' ? 'left' : 'center');
+ const showHeading = payload.showHeading !== false && headerAlign !== 'none';
+
+ const getHeaderAlignClass = (align: string) => {
+ switch (align) {
+ case 'left':
+ return 'text-left mr-auto items-start';
+ case 'right':
+ return 'text-right ml-auto items-end';
+ case 'center':
+ default:
+ return 'text-center mx-auto items-center';
+ }
+ };
+
+ const getAccentLineClass = (align: string) => {
+ switch (align) {
+ case 'left':
+ return 'mr-auto';
+ case 'right':
+ return 'ml-auto';
+ case 'center':
+ default:
+ return 'mx-auto';
+ }
+ };
+
const isLeftAlign = textAlign === 'left';
const isRightAlign = textAlign === 'right';
const alignContainerClass = isLeftAlign
@@ -79,15 +120,46 @@ export default function DynamicFeaturedTiles({ payload }: DynamicFeaturedTilesPr
? 'items-end text-right'
: 'items-center text-center';
+ const padTop = payload.paddingTop || payload.sectionPadding || 'normal';
+ const padBottom = payload.paddingBottom || payload.sectionPadding || 'normal';
+
+ const getPaddingTopClass = (pad: string) => {
+ switch (pad) {
+ case 'none':
+ return 'pt-0';
+ case 'compact':
+ return 'pt-6 md:pt-10';
+ case 'spacious':
+ return 'pt-20 md:pt-28';
+ case 'normal':
+ default:
+ return 'pt-10 md:pt-16';
+ }
+ };
+
+ const getPaddingBottomClass = (pad: string) => {
+ switch (pad) {
+ case 'none':
+ return 'pb-0';
+ case 'compact':
+ return 'pb-6 md:pb-10';
+ case 'spacious':
+ return 'pb-20 md:pb-28';
+ case 'normal':
+ default:
+ return 'pb-10 md:pb-16';
+ }
+ };
+
return (
-
+
{/* Optional Section Header */}
- {(sectionTitle || sectionSubtitle) && (
-
+ {showHeading && (sectionTitle || sectionSubtitle) && (
+
{sectionTitle && (
{sectionTitle}
@@ -98,7 +170,7 @@ export default function DynamicFeaturedTiles({ payload }: DynamicFeaturedTilesPr
{sectionSubtitle}
)}
-
+
)}
diff --git a/apps/website/src/components/dynamic/DynamicPageRenderer.tsx b/apps/website/src/components/dynamic/DynamicPageRenderer.tsx
index 43a8a24..b868435 100644
--- a/apps/website/src/components/dynamic/DynamicPageRenderer.tsx
+++ b/apps/website/src/components/dynamic/DynamicPageRenderer.tsx
@@ -1710,6 +1710,19 @@ function FeaturedTilesSection({ payload, lang }: { payload: Record
{
+ switch (width) {
+ case 'full':
+ return 'w-full max-w-none'
+ case 'wide':
+ return 'w-full max-w-[1600px] mx-auto'
+ case 'standard':
+ default:
+ return 'w-full max-w-7xl mx-auto'
+ }
+ }
const getColsClass = (cols: number) => {
switch (cols) {
@@ -1760,6 +1773,35 @@ function FeaturedTilesSection({ payload, lang }: { payload: Record {
+ switch (align) {
+ case 'left':
+ return 'text-left mr-auto items-start'
+ case 'right':
+ return 'text-right ml-auto items-end'
+ case 'center':
+ default:
+ return 'text-center mx-auto items-center'
+ }
+ }
+
+ const getAccentLineClass = (align: string) => {
+ switch (align) {
+ case 'left':
+ return 'mr-auto'
+ case 'right':
+ return 'ml-auto'
+ case 'center':
+ default:
+ return 'mx-auto'
+ }
+ }
+
const isLeftAlign = textAlign === 'left'
const isRightAlign = textAlign === 'right'
const alignContainerClass = isLeftAlign
@@ -1768,18 +1810,57 @@ function FeaturedTilesSection({ payload, lang }: { payload: Record {
+ switch (pad) {
+ case 'none':
+ return 'pt-0'
+ case 'compact':
+ return 'pt-6 md:pt-10'
+ case 'spacious':
+ return 'pt-20 md:pt-28'
+ case 'normal':
+ default:
+ return 'pt-10 md:pt-16'
+ }
+ }
+
+ const getPaddingBottomClass = (pad: string) => {
+ switch (pad) {
+ case 'none':
+ return 'pb-0'
+ case 'compact':
+ return 'pb-6 md:pb-10'
+ case 'spacious':
+ return 'pb-20 md:pb-28'
+ case 'normal':
+ default:
+ return 'pb-10 md:pb-16'
+ }
+ }
+
return (
-
-
- {(title || subtitle) && (
-
+
+
+ {showHeading && (title || subtitle) && (
+
{title && (
{renderAccentTitle(title)}
)}
{subtitle &&
{subtitle}
}
-
+
)}
diff --git a/packages/types/index.ts b/packages/types/index.ts
index 20ebca6..fb9f382 100644
--- a/packages/types/index.ts
+++ b/packages/types/index.ts
@@ -729,10 +729,16 @@ export const FeaturedTilesSectionPayloadSchema = z.object({
subtitle: LocalizedStringSchema.optional(),
columns: z.number().optional().default(2),
layoutPreset: z.enum(['editorial', 'spotlight', 'custom']).optional(),
+ headerAlign: z.enum(['left', 'center', 'right', 'none']).optional().default('center'),
+ showHeading: z.boolean().optional().default(true),
textAlign: z.enum(['left', 'center', 'right']).optional(),
ctaStyle: z.enum(['arrow_link', 'pill_button', 'solid_button', 'none']).optional(),
imageAspectRatio: z.enum(['landscape', 'wide', 'square', 'portrait', 'tall', 'auto']).optional(),
imageRounded: z.enum(['none', 'sm', 'md', 'xl', '2xl', '3xl', 'full']).optional(),
+ containerWidth: z.enum(['standard', 'wide', 'full']).optional().default('standard'),
+ paddingTop: z.enum(['none', 'compact', 'normal', 'spacious']).optional(),
+ paddingBottom: z.enum(['none', 'compact', 'normal', 'spacious']).optional(),
+ sectionPadding: z.enum(['none', 'compact', 'normal', 'spacious']).optional().default('normal'),
backgroundColor: z.string().optional(),
textColor: z.string().optional(),
tiles: z.array(z.object({