Sample Source-Showcase-E2 (TEMPLATE): source-code page on the index magazine system: slim cover banner, About, Project Structure, code walkthrough with copyable navy-barred code blocks, CTA. Reuse by editing only the PROJECT block at the top of the script.
\n\n\n"
}
]
},
{
"heading": "Bilingual Course Data: CATALOG Structure",
"body": "Six set menus, each with a bilingual description, 8 to 10 courses (each with bilingual name + bilingual description), auspicious highlights, and dietary options. privateRoomAllowed + exclusiveVipRoom drive the booking-form seating selector.",
"files": [
{
"label": "index.html: CATALOG sample (10-pax Set B, the signature)",
"code": "{\n id: '10b',\n name: 'ๅๆ Lucky Star Signature Set B',\n nameEn: 'Lucky Star Signature Set B',\n pax: 10, price: 1288, perPax: 129, courses: 10, tier: 'signature',\n image: 'images/menus/10-pax-set-b.jpeg',\n description: 'Signature flagship โ Lobster yee sang ยท cheese-baked lobster ยท suckling pig ยท bird\\'s nest finale. VIP Room INCLUDED.',\n courseList: [\n {\n name: '้พ่พ้ฒ้ฑผๆ็',\n nameEn: 'Lobster & Abalone Yee Sang',\n desc: 'Sliced fresh Boston lobster and South African abalone with gold-leaf crackers. โญ Signature.',\n descZh: 'ๆณขๅฃซ้กฟ้พ่พๅบ่บซ้ ๅ้้ฒ้ฑผ่็๏ผ้็ฎ่็๏ผโญ ๆ็ๆ็ใ',\n auspicious: 'ๆญฅๆญฅ้ซๅ โ rising fortune'\n }\n // ... 9 more courses with bilingual desc/descZh\n ],\n auspiciousHighlights: [\n { symbol: '้พ่พ', meaning: 'strength' },\n { symbol: '็็ช', meaning: 'longevity' },\n { symbol: 'ไนณ็ช', meaning: 'peace & unity' }\n ],\n dietaryOptions: ['none','noPork','noBeef','pescatarian','vegetarian','noShellfish'],\n privateRoomAllowed: false, // 10b is exclusively in VIP Room\n privateRoomSurcharge: 0,\n exclusiveVipRoom: true // reserveTable rejects vipRoom for any other set\n}"
}
]
}
],
"cta": "Want an agent-ready, zero-cost booking page like this built for your own festival or venue? Let's scope it."
};
/* ===================== END EDIT BLOCK ===================== */
const pref = (u) => /^https?:|^mailto:|^tel:/.test(u || '') ? u : (SITE + (u || ''));
const esc = (s) => String(s).replace(/&/g,'&').replace(//g,'>');
const rich = (s) => esc(s).replace(/<(\/?(?:b|code))>/g, '<$1>');
// raw code store for copy buttons
const RAW = [];
function codeBlock(label, codeStr, extraClass){
const idx = RAW.push(codeStr) - 1;
const rendered = esc(codeStr).split('\n')
.map(line => /^\s*#/.test(line) ? `${line}` : line).join('\n');
return `