WO-TF-011: dress the fine-dining / supper-club persona (gilded symmetry,
ziggurat frames, sunbursts, hairline gold rules; champagne/ivory light,
gold-on-lacquer dark) against the frozen Wave-0 builtin schemas.
Overrides (templates/overrides/art-deco/): all 49 mandatory builtin keys,
each re-skinned from the builtin default with every content field, provider
field, custom tag ({% img %}/{% button %}/{% form %}/{% signup_form %}/
{% auth_form %} wiring) and JS (navbar drawer, gallery lightbox, countdown,
stats count-up, video/audio facade, announcement dismiss) preserved verbatim.
Auth trio reproduces the untouchable /api/auth/* endpoints and field names;
captcha widget injected from _captcha_widget. manifest.yaml declares all 49.
Page templates: added blog-index, contact, auth (now 7 total) in Deco chrome.
Blocks rework (spec D5): footer/hero(marquee)/gallery/divider/pull-quote theme
blocks deleted — folded into overrides of the builtin keys. Kept persona
furniture reservation + menu; added private_dining + chef_signature (4 blocks).
Presets: 4 dual-mode (mode "both"), all 19 tokens, light AND dark tuned.
Fonts: bundle Cinzel + Cormorant Garamond (OFL) as Latin woff2 subsets in
assets/fonts/ (license recorded in OFL.txt); all font-family via var().
Email wrapper themed. required_icon_packs=["lucide"] + RECOMMENDED_ICONS.md.
Seed (demo): home/about/blog(3 posts)/contact/login pages in supper-club voice;
contact-form targets seeded contact_submissions data table; row_inserted
workflow emails admins.
Verified: ninja plugin build (codeless), verify, archive-check, and
check-safety all exit 0. Visual quality UNVERIFIED until Wave B.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
201 lines
10 KiB
JSON
201 lines
10 KiB
JSON
{
|
|
"demo": true,
|
|
"settings": {
|
|
"merge": {
|
|
"companyName": "Maison Doré",
|
|
"tagline": "A supper club in the grand manner."
|
|
}
|
|
},
|
|
"data_tables": [
|
|
{
|
|
"key": "contact_submissions",
|
|
"name": "Reservation Enquiries",
|
|
"description": "Seeded contact-form submissions for the Maison Doré demo. A submission becomes a row here and emails the site admins.",
|
|
"columns": [
|
|
{ "key": "name", "label": "Name", "type": "text", "required": true },
|
|
{ "key": "email", "label": "Email", "type": "email", "required": true },
|
|
{ "key": "party", "label": "Party size", "type": "text", "required": false },
|
|
{ "key": "message", "label": "Message", "type": "text", "required": true }
|
|
]
|
|
}
|
|
],
|
|
"pages": [
|
|
{
|
|
"slug": "/",
|
|
"title": "Maison Doré",
|
|
"template_key": "landing",
|
|
"blocks": [
|
|
{
|
|
"block_key": "hero",
|
|
"title": "Hero",
|
|
"slot": "main",
|
|
"sort_order": 1,
|
|
"content": {
|
|
"template": "centered",
|
|
"eyebrow": "Established 1926",
|
|
"headline": "Maison Doré",
|
|
"subheadline": "A supper club in the grand manner.",
|
|
"description": "Dinner and late suppers, served under gilded ceilings. A short tasting menu, a long cellar, and a room built for the evening.",
|
|
"ctaPrimary": { "text": "Reserve a table", "url": "/contact" },
|
|
"ctaSecondary": { "text": "Read the menu", "url": "#tasting" }
|
|
}
|
|
},
|
|
{
|
|
"block_key": "art-deco:chef_signature",
|
|
"title": "Chef's Signature",
|
|
"slot": "main",
|
|
"sort_order": 2,
|
|
"content": {
|
|
"eyebrow": "Chef's signature",
|
|
"dish": "Gold-leaf oyster, champagne mignonette",
|
|
"note": "The dish that opened the room in 1926. We still serve it the same way, on ice, one at a time.",
|
|
"chef": "Elise Marchand, Head Chef"
|
|
}
|
|
},
|
|
{
|
|
"block_key": "art-deco:menu",
|
|
"title": "Tasting Menu",
|
|
"slot": "main",
|
|
"sort_order": 3,
|
|
"content": {
|
|
"title": "Chef's Tasting",
|
|
"courses": [
|
|
{ "name": "Oysters, champagne mignonette", "description": "Half a dozen, on ice.", "price": "$32" },
|
|
{ "name": "Consommé doré", "description": "Clarified beef broth, tarragon, gold leaf.", "price": "$24" },
|
|
{ "name": "Turbot, beurre blanc", "description": "Line-caught, roasted on the bone.", "price": "$58" },
|
|
{ "name": "Crown of lamb", "description": "Herbs, salt-baked roots, jus.", "price": "$62" },
|
|
{ "name": "Grand Marnier soufflé", "description": "To finish. Order at the start.", "price": "$28" }
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"block_key": "art-deco:private_dining",
|
|
"title": "Private Dining",
|
|
"slot": "main",
|
|
"sort_order": 4,
|
|
"content": {
|
|
"eyebrow": "Private dining",
|
|
"title": "The Gold Room",
|
|
"description": "A room of your own behind the main floor. One long table, a dedicated maître d', and the full cellar. We write the menu with you.",
|
|
"seats": "Seats 2 to 14",
|
|
"minimum": "From $2,400",
|
|
"enquireLabel": "Enquire",
|
|
"enquireUrl": "/contact",
|
|
"mediaPosition": "left"
|
|
}
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"slug": "/about",
|
|
"title": "The House",
|
|
"template_key": "default",
|
|
"blocks": [
|
|
{ "block_key": "heading", "title": "Heading", "slot": "main", "sort_order": 1, "content": { "text": "The House", "level": 1 } },
|
|
{ "block_key": "rich-text", "title": "Story", "slot": "main", "sort_order": 2, "content": { "html": "<p>Maison Doré opened on a narrow street in 1926 and has kept its hours ever since. We take reservations for dinner and hold a few tables back for late suppers.</p><p>The kitchen runs a short tasting menu that changes with the season. The cellar runs long. The room stays the same, which is the point.</p>" } },
|
|
{ "block_key": "divider", "title": "Divider", "slot": "main", "sort_order": 3, "content": { "variant": "ornament", "icon": "lucide:diamond" } },
|
|
{ "block_key": "quote", "title": "Quote", "slot": "main", "sort_order": 4, "content": { "style": "block", "align": "center", "quote": "Come for dinner, stay for the last pour.", "attribution": "The House" } }
|
|
]
|
|
},
|
|
{
|
|
"slug": "/blog",
|
|
"title": "From the Floor",
|
|
"template_key": "blog-index",
|
|
"blocks": [
|
|
{ "block_key": "card", "title": "Post: Gold Standard", "slot": "main", "sort_order": 1, "content": { "layout": "vertical", "title": "The gold standard", "text": "<p>Why one oyster, served one at a time, still opens every table.</p>", "link": "/blog/the-gold-standard", "linkLabel": "Read on" } },
|
|
{ "block_key": "card", "title": "Post: A Night", "slot": "main", "sort_order": 2, "content": { "layout": "vertical", "title": "A night at the club", "text": "<p>From the first cocktail to the last soufflé. How an evening unfolds.</p>", "link": "/blog/a-night-at-the-club", "linkLabel": "Read on" } },
|
|
{ "block_key": "card", "title": "Post: Cellar", "slot": "main", "sort_order": 3, "content": { "layout": "vertical", "title": "Notes from the cellar", "text": "<p>What we pour and why. A short walk through the list.</p>", "link": "/blog/notes-from-the-cellar", "linkLabel": "Read on" } }
|
|
]
|
|
},
|
|
{
|
|
"slug": "/blog/the-gold-standard",
|
|
"title": "The gold standard",
|
|
"template_key": "article",
|
|
"parent_slug": "/blog",
|
|
"blocks": [
|
|
{ "block_key": "heading", "title": "Title", "slot": "main", "sort_order": 1, "content": { "text": "The gold standard", "level": 1 } },
|
|
{ "block_key": "rich-text", "title": "Body", "slot": "main", "sort_order": 2, "content": { "html": "<p>The oyster came first, in 1926, and it has not left the menu since. We serve it on ice, one at a time, with a champagne mignonette and a single leaf of gold.</p><p>The point is restraint. One oyster, done right, sets the tone for the meal that follows.</p>" } }
|
|
]
|
|
},
|
|
{
|
|
"slug": "/blog/a-night-at-the-club",
|
|
"title": "A night at the club",
|
|
"template_key": "article",
|
|
"parent_slug": "/blog",
|
|
"blocks": [
|
|
{ "block_key": "heading", "title": "Title", "slot": "main", "sort_order": 1, "content": { "text": "A night at the club", "level": 1 } },
|
|
{ "block_key": "rich-text", "title": "Body", "slot": "main", "sort_order": 2, "content": { "html": "<p>Doors open at six. The first cocktail arrives before the menu. Dinner runs five courses, unhurried, and the soufflé is ordered at the start.</p><p>The band plays after nine. Late suppers run until the last table is ready to leave.</p>" } }
|
|
]
|
|
},
|
|
{
|
|
"slug": "/blog/notes-from-the-cellar",
|
|
"title": "Notes from the cellar",
|
|
"template_key": "article",
|
|
"parent_slug": "/blog",
|
|
"blocks": [
|
|
{ "block_key": "heading", "title": "Title", "slot": "main", "sort_order": 1, "content": { "text": "Notes from the cellar", "level": 1 } },
|
|
{ "block_key": "rich-text", "title": "Body", "slot": "main", "sort_order": 2, "content": { "html": "<p>The list is long and the choices are few, by design. We pour champagne by the glass, keep a deep bench of burgundy, and hold a small shelf of older bottles for the ones who ask.</p><p>Tell the sommelier what you are eating. The rest takes care of itself.</p>" } }
|
|
]
|
|
},
|
|
{
|
|
"slug": "/contact",
|
|
"title": "Reservations",
|
|
"template_key": "contact",
|
|
"blocks": [
|
|
{
|
|
"block_key": "contact-form",
|
|
"title": "Reservation Enquiry",
|
|
"slot": "main",
|
|
"sort_order": 1,
|
|
"content": {
|
|
"heading": "Request a table",
|
|
"description": "Tell us the date, the hour and the party. We will confirm by email.",
|
|
"submitLabel": "Request a table",
|
|
"successMessage": "Thank you. Your table request has been received. We will confirm by email.",
|
|
"fields": [
|
|
{ "name": "name", "label": "Your name", "type": "text", "required": true, "width": "half" },
|
|
{ "name": "email", "label": "Email", "type": "email", "required": true, "width": "half" },
|
|
{ "name": "party", "label": "Party size", "type": "text", "required": false, "width": "half" },
|
|
{ "name": "message", "label": "Date, time and any notes", "type": "textarea", "required": true, "width": "full" }
|
|
],
|
|
"formConfig": { "enabled": true, "captchaEnabled": false, "targetTable": "contact_submissions" }
|
|
}
|
|
},
|
|
{
|
|
"block_key": "hours-location",
|
|
"title": "Hours & Location",
|
|
"slot": "aside",
|
|
"sort_order": 1,
|
|
"content": {
|
|
"heading": "Hours",
|
|
"hours": [
|
|
{ "day": "Tuesday to Thursday", "hours": "6pm to late" },
|
|
{ "day": "Friday to Saturday", "hours": "5pm to late" },
|
|
{ "day": "Sunday", "hours": "5pm to 10pm" },
|
|
{ "day": "Monday", "closed": true }
|
|
],
|
|
"specialHoursNote": "Late suppers from 10pm, Friday and Saturday.",
|
|
"address": "12 Gilt Lane\nThe Old Quarter",
|
|
"phone": "+1 555 0126"
|
|
}
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"slug": "/login",
|
|
"title": "Members",
|
|
"template_key": "auth",
|
|
"blocks": [
|
|
{ "block_key": "auth-form", "title": "Sign in", "slot": "main", "sort_order": 1, "content": { "default_tab": "login", "show_social": false } },
|
|
{ "block_key": "text", "title": "Foot", "slot": "footer", "sort_order": 1, "content": { "text": "<p>Members book priority tables and private-room dates.</p>" } }
|
|
]
|
|
}
|
|
],
|
|
"menu_items": [
|
|
{ "menu": "main", "label": "Home", "page_slug": "/", "sort_order": 1 },
|
|
{ "menu": "main", "label": "The House", "page_slug": "/about", "sort_order": 2 },
|
|
{ "menu": "main", "label": "From the Floor", "page_slug": "/blog", "sort_order": 3 },
|
|
{ "menu": "main", "label": "Reservations", "page_slug": "/contact", "sort_order": 4 }
|
|
]
|
|
}
|