themes-coffee/seed/seed.json
Alex Dunmow 023bd23d96 feat(coffee): Wave A override contract — 49 builtin overrides, 7 page templates, persona blocks, seed
WO-TF-013. Bring the coffee theme up to the frozen OVERRIDE-CONTRACT:

- 49 mandatory builtin overrides in templates/overrides/coffee/ (chrome,
  marketing, primitives, commerce/local, blog family, auth surface,
  page-suggestions), each re-skinned in cafe/roastery chrome over the builtin
  data model. Legacy button/heading/image/text field reads updated to the new
  builtin contract (link/label/style, media/text).
- Signature moves: chalkboard menu panel (menu-list), hand-drawn doodle
  dividers, torn-paper edges, kraft-tag stamped buttons, circular roast stamps,
  hours "today" highlight. Semantic tokens only; CSS-first motion with
  prefers-reduced-motion fallbacks.
- 7 page templates: default, landing, article, full-width, blog-index, contact,
  auth.
- Blocks rework: deleted the five builtin-duplicating theme blocks (menu_board,
  hours_strip, location_card, footer, doodle_divider) — now overrides. Kept/added
  4 persona blocks: featured_pour, roast_profile, loyalty_card, brew_guide.
- 5 dual-mode presets (mode "both"), all 19 tokens, light and dark tuned.
- Bundled Fraunces / Work Sans / Caveat woff2 (OFL, latin subset, license
  recorded); fonts.json populated; all font-family via var(--font-*). Updated
  RECOMMENDED_FONTS.md, added RECOMMENDED_ICONS.md; required_icon_packs declared.
- Themed email-safe wrapper retained (tables, inline styles).
- Master pages rebuilt on builtin keys. Demo seed (demo:true): home, about,
  blog + 3 posts, contact (form + contact_submissions data table + row_inserted
  email-admins workflow), login. Cafe voice.

make (codeless build + verify) and check-safety both exit 0.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 10:57:54 +08:00

178 lines
15 KiB
JSON

{
"demo": true,
"settings": {
"merge": {
"site_title": "Ritual Coffee",
"site_description": "A neighbourhood cafe and small-batch roastery."
}
},
"data_tables": [
{
"key": "contact_submissions",
"name": "Contact Submissions",
"description": "Messages sent from the cafe contact form.",
"primary_key": "id",
"columns": [
{ "key": "name", "label": "Name", "type": "text", "required": true },
{ "key": "email", "label": "Email", "type": "email", "required": true },
{ "key": "reason", "label": "Reason", "type": "text", "required": false },
{ "key": "message", "label": "Message", "type": "text", "required": true }
]
}
],
"menu_items": [
{ "menu": "main", "label": "Home", "page_slug": "/", "sort_order": 0 },
{ "menu": "main", "label": "Menu", "url": "/#menu", "sort_order": 1 },
{ "menu": "main", "label": "About", "page_slug": "/about", "sort_order": 2 },
{ "menu": "main", "label": "Journal", "page_slug": "/blog", "sort_order": 3 },
{ "menu": "main", "label": "Visit", "page_slug": "/contact", "sort_order": 4 }
],
"pages": [
{
"slug": "/",
"title": "Ritual Coffee",
"template_key": "default",
"blocks": [
{ "block_key": "navbar", "title": "Navigation", "slot": "header", "sort_order": 0, "content": { "menuName": "main", "companyName": "Ritual Coffee", "ctaLabel": "Order ahead", "ctaUrl": "/contact" } },
{ "block_key": "hero", "title": "Hero", "slot": "main", "sort_order": 0, "content": { "template": "centered", "eyebrow": "Open from 7", "headline": "Coffee worth slowing down for", "subheadline": "We roast in small batches and pull every shot to order.", "ctaPrimary": { "text": "See the menu", "url": "/#menu" }, "ctaSecondary": { "text": "Find us", "url": "/contact" }, "minHeight": "50vh" } },
{ "block_key": "coffee:featured_pour", "title": "Featured Pour", "slot": "main", "sort_order": 1, "content": { "label": "This week", "origin": "Single origin", "name": "Guji Highlands", "tasting": "<p>Bright and floral. Notes of peach, jasmine and brown sugar.</p>", "price": "6.00", "currency": "$" } },
{ "block_key": "menu-list", "title": "Menu", "slot": "main", "sort_order": 2, "content": { "heading": "On the board", "intro": "Prices are for takeaway. Add fifty cents to dine in.", "currency": "$", "columns": 2, "sections": [
{ "title": "Espresso", "items": [
{ "name": "Espresso", "description": "Double shot", "price": "4.00" },
{ "name": "Flat white", "price": "5.00" },
{ "name": "Latte", "price": "5.50" },
{ "name": "Batch filter", "description": "Rotating single origin", "price": "5.00", "badges": [{ "label": "Filter" }] }
] },
{ "title": "Kitchen", "items": [
{ "name": "Butter croissant", "price": "5.50" },
{ "name": "Sourdough toast", "description": "With jam or honey", "price": "6.00" },
{ "name": "Bacon and egg roll", "price": "12.00" },
{ "name": "Granola bowl", "description": "Oats, yoghurt, seasonal fruit", "price": "11.00", "badges": [{ "label": "V" }] }
] }
] } },
{ "block_key": "hours-location", "title": "Hours", "slot": "main", "sort_order": 3, "content": { "heading": "Come and sit", "address": "12 Baker Lane\nNorthbridge", "phone": "08 1234 5678", "hours": [
{ "day": "Monday", "hours": "7:00 - 15:00" },
{ "day": "Tuesday", "hours": "7:00 - 15:00" },
{ "day": "Wednesday", "hours": "7:00 - 15:00" },
{ "day": "Thursday", "hours": "7:00 - 15:00" },
{ "day": "Friday", "hours": "7:00 - 16:00" },
{ "day": "Saturday", "hours": "8:00 - 16:00" },
{ "day": "Sunday", "closed": true }
] } },
{ "block_key": "footer", "title": "Footer", "slot": "footer", "sort_order": 0, "content": { "companyName": "Ritual Coffee", "tagline": "Small-batch coffee, baked fresh daily.", "address": "12 Baker Lane, Northbridge", "email": "hello@ritual.coffee", "copyright": "Ritual Coffee" } }
]
},
{
"slug": "/about",
"title": "About",
"template_key": "default",
"blocks": [
{ "block_key": "navbar", "title": "Navigation", "slot": "header", "sort_order": 0, "content": { "menuName": "main", "companyName": "Ritual Coffee", "ctaLabel": "Order ahead", "ctaUrl": "/contact" } },
{ "block_key": "hero", "title": "Hero", "slot": "main", "sort_order": 0, "content": { "template": "centered", "eyebrow": "Our story", "headline": "One roaster, one room", "subheadline": "We started on a single machine and never grew out of caring about it.", "minHeight": "auto" } },
{ "block_key": "rich-section", "title": "Story", "slot": "main", "sort_order": 1, "content": { "eyebrow": "Why we roast", "heading": "Fresh, not fast", "body": "<p>We roast twice a week and rest every batch before it hits the hopper. That means the coffee you drink was roasted days ago, not months.</p><p>Everything on the board is made in-house. The croissants are laminated overnight. The jam is cooked in small pots on the back bench.</p>", "mediaPosition": "right" } },
{ "block_key": "coffee:brew_guide", "title": "Brew Guide", "slot": "main", "sort_order": 2, "content": { "kicker": "Make it at home", "method": "V60 pour-over", "intro": "This is how we brew filter on the bar. Scale it up or down by the ratio.", "ratio": "1:16", "grind": "Medium-fine", "water": "300g", "temperature": "94C", "time": "3:00", "steps": [
{ "title": "Rinse and dose", "text": "Rinse the paper. Add 19g of coffee and level the bed." },
{ "title": "Bloom", "text": "Pour 45g of water. Wait 40 seconds." },
{ "title": "Pour in stages", "text": "Pour in slow circles to 300g by two minutes." },
{ "title": "Draw down", "text": "Let it finish by three minutes. Swirl and serve." }
] } },
{ "block_key": "team", "title": "Team", "slot": "main", "sort_order": 3, "content": { "heading": "Behind the bar", "members": [
{ "name": "Mara", "role": "Head roaster", "bio": "Runs the roaster and tastes every batch." },
{ "name": "Theo", "role": "Baker", "bio": "In before the birds. Owns the croissants." },
{ "name": "Priya", "role": "Barista", "bio": "Knows your order before you say it." }
] } },
{ "block_key": "footer", "title": "Footer", "slot": "footer", "sort_order": 0, "content": { "companyName": "Ritual Coffee", "tagline": "Small-batch coffee, baked fresh daily.", "email": "hello@ritual.coffee", "copyright": "Ritual Coffee" } }
]
},
{
"slug": "/blog",
"title": "Journal",
"template_key": "blog-index",
"blocks": [
{ "block_key": "navbar", "title": "Navigation", "slot": "header", "sort_order": 0, "content": { "menuName": "main", "companyName": "Ritual Coffee", "ctaLabel": "Order ahead", "ctaUrl": "/contact" } },
{ "block_key": "blog-hero", "title": "Journal Hero", "slot": "featured", "sort_order": 0, "content": { "title": "The Journal", "subtitle": "Notes from the roaster and the bar." } },
{ "block_key": "card", "title": "Post: Guji", "slot": "main", "sort_order": 0, "content": { "title": "Meet the Guji Highlands", "text": "Our new single origin is bright, floral and easy to love.", "link": "/blog/meet-the-guji-highlands", "linkLabel": "Read on" } },
{ "block_key": "card", "title": "Post: Roasting week", "slot": "main", "sort_order": 1, "content": { "title": "A week on the roaster", "text": "How we plan a roasting week and why we rest every batch.", "link": "/blog/a-week-on-the-roaster", "linkLabel": "Read on" } },
{ "block_key": "card", "title": "Post: Filter", "slot": "main", "sort_order": 2, "content": { "title": "How we brew filter", "text": "The recipe we use on the bar, step by step.", "link": "/blog/how-we-brew-filter", "linkLabel": "Read on" } },
{ "block_key": "footer", "title": "Footer", "slot": "footer", "sort_order": 0, "content": { "companyName": "Ritual Coffee", "tagline": "Small-batch coffee, baked fresh daily.", "email": "hello@ritual.coffee", "copyright": "Ritual Coffee" } }
]
},
{
"slug": "/blog/meet-the-guji-highlands",
"parent_slug": "/blog",
"title": "Meet the Guji Highlands",
"template_key": "article",
"blocks": [
{ "block_key": "navbar", "title": "Navigation", "slot": "header", "sort_order": 0, "content": { "menuName": "main", "companyName": "Ritual Coffee", "ctaLabel": "Order ahead", "ctaUrl": "/contact" } },
{ "block_key": "heading", "title": "Title", "slot": "main", "sort_order": 0, "content": { "level": 1, "text": "Meet the Guji Highlands" } },
{ "block_key": "text", "title": "Body", "slot": "main", "sort_order": 1, "content": { "text": "<p>Our new single origin comes from the Guji zone in southern Ethiopia. It is washed, which keeps it clean and bright.</p><p>We taste peach and jasmine up front, then a soft brown sugar finish. It works as espresso and shines as filter.</p><p>Come in this week and try it on the bar.</p>" } },
{ "block_key": "coffee:roast_profile", "title": "Roast Profile", "slot": "main", "sort_order": 2, "content": { "origin": "Single origin", "name": "Guji Highlands", "producer": "Smallholders, Guji zone", "roastLevel": "Medium", "notes": "<p>Peach, jasmine, brown sugar.</p>", "process": "Washed", "varietal": "Heirloom", "altitude": "1900-2100 masl" } },
{ "block_key": "footer", "title": "Footer", "slot": "footer", "sort_order": 0, "content": { "companyName": "Ritual Coffee", "tagline": "Small-batch coffee, baked fresh daily.", "email": "hello@ritual.coffee", "copyright": "Ritual Coffee" } }
]
},
{
"slug": "/blog/a-week-on-the-roaster",
"parent_slug": "/blog",
"title": "A week on the roaster",
"template_key": "article",
"blocks": [
{ "block_key": "navbar", "title": "Navigation", "slot": "header", "sort_order": 0, "content": { "menuName": "main", "companyName": "Ritual Coffee", "ctaLabel": "Order ahead", "ctaUrl": "/contact" } },
{ "block_key": "heading", "title": "Title", "slot": "main", "sort_order": 0, "content": { "level": 1, "text": "A week on the roaster" } },
{ "block_key": "text", "title": "Body", "slot": "main", "sort_order": 1, "content": { "text": "<p>We roast on Tuesdays and Fridays. Each batch is small, and we rest it before it goes on the bar.</p><p>Resting lets the coffee settle after roasting. Pulled too soon, it tastes sharp and gassy. Given a few days, it opens up.</p><p>That is why the date on the bag matters more than the date on the door.</p>" } },
{ "block_key": "footer", "title": "Footer", "slot": "footer", "sort_order": 0, "content": { "companyName": "Ritual Coffee", "tagline": "Small-batch coffee, baked fresh daily.", "email": "hello@ritual.coffee", "copyright": "Ritual Coffee" } }
]
},
{
"slug": "/blog/how-we-brew-filter",
"parent_slug": "/blog",
"title": "How we brew filter",
"template_key": "article",
"blocks": [
{ "block_key": "navbar", "title": "Navigation", "slot": "header", "sort_order": 0, "content": { "menuName": "main", "companyName": "Ritual Coffee", "ctaLabel": "Order ahead", "ctaUrl": "/contact" } },
{ "block_key": "heading", "title": "Title", "slot": "main", "sort_order": 0, "content": { "level": 1, "text": "How we brew filter" } },
{ "block_key": "text", "title": "Body", "slot": "main", "sort_order": 1, "content": { "text": "<p>Filter is the clearest way to taste a coffee. We keep the recipe simple so you can repeat it at home.</p><p>Weigh the coffee and the water. Keep the grind even. Pour in slow circles and give it room to draw down.</p>" } },
{ "block_key": "coffee:brew_guide", "title": "Brew Guide", "slot": "main", "sort_order": 2, "content": { "kicker": "The recipe", "method": "V60 pour-over", "ratio": "1:16", "grind": "Medium-fine", "water": "300g", "temperature": "94C", "time": "3:00", "steps": [
{ "title": "Rinse and dose", "text": "Rinse the paper. Add 19g and level the bed." },
{ "title": "Bloom", "text": "Pour 45g. Wait 40 seconds." },
{ "title": "Pour", "text": "Slow circles to 300g by two minutes." },
{ "title": "Finish", "text": "Draw down by three minutes. Serve." }
] } },
{ "block_key": "footer", "title": "Footer", "slot": "footer", "sort_order": 0, "content": { "companyName": "Ritual Coffee", "tagline": "Small-batch coffee, baked fresh daily.", "email": "hello@ritual.coffee", "copyright": "Ritual Coffee" } }
]
},
{
"slug": "/contact",
"title": "Visit",
"template_key": "contact",
"blocks": [
{ "block_key": "navbar", "title": "Navigation", "slot": "header", "sort_order": 0, "content": { "menuName": "main", "companyName": "Ritual Coffee", "ctaLabel": "Order ahead", "ctaUrl": "/contact" } },
{ "block_key": "hours-location", "title": "Hours", "slot": "main", "sort_order": 0, "content": { "heading": "Find us", "address": "12 Baker Lane\nNorthbridge", "phone": "08 1234 5678", "hours": [
{ "day": "Monday", "hours": "7:00 - 15:00" },
{ "day": "Tuesday", "hours": "7:00 - 15:00" },
{ "day": "Wednesday", "hours": "7:00 - 15:00" },
{ "day": "Thursday", "hours": "7:00 - 15:00" },
{ "day": "Friday", "hours": "7:00 - 16:00" },
{ "day": "Saturday", "hours": "8:00 - 16:00" },
{ "day": "Sunday", "closed": true }
] } },
{ "block_key": "contact-form", "title": "Contact Form", "slot": "main", "sort_order": 1, "content": { "heading": "Say hello", "description": "Booking a table for six or more? Send us a note and we will sort it.", "submitLabel": "Send message", "successMessage": "Thanks. We will get back to you soon.", "formConfig": { "targetTable": "contact_submissions" }, "fields": [
{ "name": "name", "label": "Name", "type": "text", "required": true, "width": "half" },
{ "name": "email", "label": "Email", "type": "email", "required": true, "width": "half" },
{ "name": "reason", "label": "Reason", "type": "text", "required": false, "width": "full" },
{ "name": "message", "label": "Message", "type": "textarea", "required": true, "width": "full" }
] } },
{ "block_key": "footer", "title": "Footer", "slot": "footer", "sort_order": 0, "content": { "companyName": "Ritual Coffee", "tagline": "Small-batch coffee, baked fresh daily.", "email": "hello@ritual.coffee", "copyright": "Ritual Coffee" } }
]
},
{
"slug": "/login",
"title": "Login",
"template_key": "auth",
"blocks": [
{ "block_key": "auth-form", "title": "Auth Form", "slot": "main", "sort_order": 0, "content": { "default_tab": "login", "show_social": false } },
{ "block_key": "text", "title": "Footer Note", "slot": "footer", "sort_order": 0, "content": { "text": "<p>Members get first pick of new roasts.</p>" } }
]
}
]
}