diff --git a/master_pages.json b/master_pages.json index 9c998f7..3850916 100644 --- a/master_pages.json +++ b/master_pages.json @@ -5,7 +5,6 @@ "page_templates": ["default", "article", "blog-index", "contact"], "blocks": [ { "block_key": "navbar", "title": "Gilded Navigation", "content": { "menuName": "main", "logoType": "text", "logoText": { "text": "Maison Doré" } }, "slot": "header", "sort_order": 0 }, - { "block_key": "divider", "title": "Header Fan Divider", "content": { "variant": "ornament", "icon": "lucide:diamond" }, "slot": "header", "sort_order": 1 }, { "block_key": "slot", "title": "Main Content", "content": { "slotName": "main", "placeholder": "Page content" }, "slot": "main", "sort_order": 0 }, { "block_key": "footer", "title": "Site Footer", "content": { "layout": "centered", "companyName": "Maison Doré", "tagline": "A supper club in the grand manner." }, "slot": "footer", "sort_order": 0 } ] @@ -16,7 +15,6 @@ "page_templates": ["landing", "full-width"], "blocks": [ { "block_key": "navbar", "title": "Gilded Navigation", "content": { "menuName": "main", "logoType": "text", "logoText": { "text": "Maison Doré" } }, "slot": "marquee", "sort_order": 0 }, - { "block_key": "art-deco:reservation", "title": "Reservation Strip", "content": { "phone": "+1 555 0126", "openTable": "/contact", "hours": ["Dinner Tuesday to Sunday", "6pm to late"] }, "slot": "marquee", "sort_order": 1 }, { "block_key": "slot", "title": "Main Content", "content": { "slotName": "main" }, "slot": "main", "sort_order": 0 }, { "block_key": "divider", "title": "CTA Fan Divider", "content": { "variant": "ornament", "icon": "lucide:diamond" }, "slot": "cta", "sort_order": 0 }, { "block_key": "footer", "title": "Site Footer", "content": { "layout": "centered", "companyName": "Maison Doré", "tagline": "A supper club in the grand manner." }, "slot": "footer", "sort_order": 0 } diff --git a/preview.png b/preview.png index 454b6ea..946abf8 100644 Binary files a/preview.png and b/preview.png differ diff --git a/screenshots/01-home-light.png b/screenshots/01-home-light.png index 454b6ea..946abf8 100644 Binary files a/screenshots/01-home-light.png and b/screenshots/01-home-light.png differ diff --git a/screenshots/02-home-dark.png b/screenshots/02-home-dark.png index e41df25..82a0886 100644 Binary files a/screenshots/02-home-dark.png and b/screenshots/02-home-dark.png differ diff --git a/screenshots/03-about-light.png b/screenshots/03-about-light.png index 9c13e29..62440a1 100644 Binary files a/screenshots/03-about-light.png and b/screenshots/03-about-light.png differ diff --git a/screenshots/04-about-dark.png b/screenshots/04-about-dark.png index 13f4c8c..31b4088 100644 Binary files a/screenshots/04-about-dark.png and b/screenshots/04-about-dark.png differ diff --git a/screenshots/05-blog-the-gold-standard-light.png b/screenshots/05-blog-the-gold-standard-light.png index e40b875..5d7b94d 100644 Binary files a/screenshots/05-blog-the-gold-standard-light.png and b/screenshots/05-blog-the-gold-standard-light.png differ diff --git a/screenshots/06-blog-the-gold-standard-dark.png b/screenshots/06-blog-the-gold-standard-dark.png index ad7f2af..795e09b 100644 Binary files a/screenshots/06-blog-the-gold-standard-dark.png and b/screenshots/06-blog-the-gold-standard-dark.png differ diff --git a/seed/media/gold-room.svg b/seed/media/gold-room.svg new file mode 100644 index 0000000..be37a18 --- /dev/null +++ b/seed/media/gold-room.svg @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/seed/seed.json b/seed/seed.json index 19f63d3..e3856fc 100644 --- a/seed/seed.json +++ b/seed/seed.json @@ -6,6 +6,14 @@ "tagline": "A supper club in the grand manner." } }, + "media": [ + { + "id": "d3c0d3c0-a11d-4ec0-9000-000000000001", + "file": "media/gold-room.svg", + "alt": "Gilded Art Deco fan crest — the Gold Room at Maison Doré", + "folder": "Demo" + } + ], "data_tables": [ { "key": "contact_submissions", @@ -76,6 +84,7 @@ "content": { "eyebrow": "Private dining", "title": "The Gold Room", + "image": "d3c0d3c0-a11d-4ec0-9000-000000000001", "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", @@ -114,7 +123,7 @@ "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": "

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.

The point is restraint. One oyster, done right, sets the tone for the meal that follows.

" } } + { "block_key": "rich-text", "title": "Body", "slot": "main", "sort_order": 2, "content": { "html": "

The oyster came first, in 1926, and it has not left the menu since. Before the tables were dressed, before the band had a name, before the sign above the door had dried, the kitchen had settled on one dish to open the room. We serve it still on ice, one at a time, with a champagne mignonette and a single leaf of gold.

People ask why only one. The honest answer is that a supper club is a matter of tempo, and the first thing on the table sets it. A dozen oysters is generosity; one oyster, presented as though it were the only one in the house, is an argument about how the evening intends to proceed. Slowly. Deliberately. With attention paid.

The mignonette is older than the room. A cook we no longer have the name of set down the proportions on the back of a wine list: shallots cut fine enough to disappear, a good vinegar cut with a little champagne, cracked pepper, and nothing else that would announce itself. It has been copied and it has been improved upon, and every improvement has been quietly abandoned. We make it the way it was written.

The gold leaf is not decoration, whatever the photographs suggest. It is a signature — the way a house marks a dish as its own. A single flake, laid on with a dry brush at the pass, catches the low light of the room and tells you, without a word, where you are sitting. It tastes of nothing. That is the point of it.

Service is a small ceremony. The plate is carried in two hands, set down without a sound, and left alone. No pepper is offered. No lemon is brought unless it is asked for, and it is not encouraged. The oyster is not garnished at the table; the table is not the place for it. Everything that could be decided has been decided in the kitchen already.

We take the shells from a single bed on the cold side of the coast, from a grower who has sold to the house for three generations and who still telephones when the water turns. They arrive closed, heavy, and smelling of the sea. A shucker who has been with us longer than most of the room opens them to order, never in advance, because an oyster opened early is an oyster that has begun to forget itself.

The ice is shaved, not cubed, and banked so the shell sits level and spills nothing. A cook once suggested we set the oyster on rock salt for the look of it. The suggestion was heard and not taken. Salt draws the liquor out; ice keeps it in. The liquor is the dish.

What follows on the menu changes with the season and the mood of the kitchen — the consommé, the turbot, the crown of lamb, the soufflé ordered at the start. But the oyster does not change, because it is not a course so much as a promise. It says: we have thought about this. We will keep thinking about it, right through to the last pour.

Regulars have their rituals. One takes it with nothing but the mignonette and closes his eyes. One tips the shell and drinks the liquor first, then eats the oyster after, which the kitchen considers correct. One has ordered it every Friday for eleven years and has never once been offered a menu before it arrives.

That is the gold standard, and it has very little to do with the gold. It is the standard of doing one small thing exactly, every night, for a hundred years less six, and letting the rest of the meal follow from it. Come for dinner. Start with the oyster. Let the room take it from there.

" } } ] }, { @@ -124,7 +133,7 @@ "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": "

Doors open at six. The first cocktail arrives before the menu. Dinner runs five courses, unhurried, and the soufflé is ordered at the start.

The band plays after nine. Late suppers run until the last table is ready to leave.

" } } + { "block_key": "rich-text", "title": "Body", "slot": "main", "sort_order": 2, "content": { "html": "

Doors open at six. For the first hour the room belongs to the staff — cloths pressed, silver counted, candles trimmed to the same height along every table — and then the first guests arrive and it belongs to them until it is dark outside and dark again on the far side of midnight.

The first cocktail comes before the menu, always. It is a house rule old enough that no one remembers making it. A drink is put in your hand before a decision is asked of you, on the theory that no one should have to choose anything until they have been given a moment to arrive. The moment is the point of a supper club. Everything else is arranged around it.

Dinner runs five courses and is not to be hurried. The kitchen sends when the table is ready and not before, reads the pace of a room the way a good conductor reads an orchestra, and would rather hold a plate two minutes than land it on a conversation that has not finished. If you are in a hurry, the kitchen will know, and it will be sorry, and it will still not rush the turbot.

The soufflé is ordered at the start. This surprises first-timers and delights everyone else. A Grand Marnier soufflé cannot be summoned at the end of a meal on a whim; it must be begun while the oysters are still on ice, folded and set and watched, so that it arrives at the table risen and warm at the exact moment the last plate is cleared. To order it early is to plan your evening. We approve of planning your evening.

Between courses there is room to breathe. The cellar sends up a glass you did not order but should have. The maître d' passes and says nothing, which is its own kind of service. A regular two tables over lifts a glass to a regular she has never spoken to. The room does this on its own; we only set the conditions.

The band plays after nine. Before then the music is low and comes from nowhere in particular; after nine it comes from the corner and has names attached to it. The songs are old and the tempo is kind. No one is made to dance and a good many people do, in the narrow space between the bar and the last banquette, which was left narrow on purpose.

Late suppers begin at ten. The full menu closes and a shorter one opens — the oyster still, of course, and a plate of something warm, and whatever the kitchen has kept back for the hours when the room thins to the people who did not want to leave. These are the best hours. The staff will not tell you so, but they are.

Somewhere past midnight the pace changes again. The band puts down its instruments and picks up a glass. The kitchen sends out what it is eating itself. Conversations that started at separate tables have found their way to the bar. This is not on any menu and cannot be reserved.

We do not announce a closing time, because the club closes when the last table is ready to leave and not one minute sooner. The candles are replaced if they burn down. The cellar stays open. When the room is finally empty the staff sit where the guests sat, and that is a night at the club — begun with a drink you did not choose, ended at an hour no one agreed on, and worth every course in between.

" } } ] }, { @@ -134,7 +143,7 @@ "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": "

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.

Tell the sommelier what you are eating. The rest takes care of itself.

" } } + { "block_key": "rich-text", "title": "Body", "slot": "main", "sort_order": 2, "content": { "html": "

The list is long and the choices are few, by design. A cellar can be built two ways: wide, to have a little of everything, or deep, to have the right thing in quantity. We have always built ours deep. There are fewer names on our list than on most, and more bottles behind each one.

We pour champagne by the glass and mean it. Not one champagne — several, opened through the night so the glass in your hand was drawn from a bottle opened within the hour, never the morning. A supper club that will not open a fresh bottle for a single glass is not a supper club we would care to sit in.

The bench of burgundy is the pride of the room. It was begun by the first owner, who bought more than he could sell in the belief that a cellar is a promise to the future, and it has been added to every year since by people who took the promise seriously. Some of those bottles have been waiting under this floor longer than most of the staff have been alive.

We keep a small shelf of older bottles for the ones who ask. It is not printed. It is not offered. It exists for the guest who leans in and says, in effect, surprise me, and is prepared to be surprised at the price as well as the pour. The sommelier keeps the shelf in his head and brings it out for the right question.

The list favours the grower over the label. We would rather pour a careful wine from a name you have never heard than a famous one made carelessly, and we will tell you as much if you let us. A great many of our bottles come from families the house has bought from for decades, some of whom now send the grandchildren of the people who first shook hands on the arrangement.

Tell the sommelier what you are eating. This is the whole of the method and it is worth more than any list. He is not there to sell you the dear bottle; he is there to put the right glass beside the right plate, and the right glass is very often not the dear one. Trust it. The pairing is the point, and the pairing takes care of itself.

There is a house style to the pouring, too. Glasses are filled less than you might expect — enough to swirl, never enough to warm — and topped through the course so the wine keeps pace with the food. An empty glass is considered a small failure of attention. A glass filled to the brim is considered a larger one.

For the table that cannot decide, we keep a pairing that runs the length of the tasting menu, a glass to each course, chosen the same afternoon by whoever is on the floor that night. It is never written down and never twice the same. Order it and you are drinking the sommelier's evening, which is the best thing on the list and the one thing you cannot ask for by name.

What we pour and why is, in the end, a long answer to a short question, and the short answer is this: we buy carefully, we keep patiently, and we open generously. Come hungry, say what you are eating, and let the cellar do the rest. It has been doing it since 1926 and it has not been wrong often.

" } } ] }, { diff --git a/templates/overrides/art-deco/author-bio-hero.ninjatpl b/templates/overrides/art-deco/author-bio-hero.ninjatpl index 2798eae..5d6bf8e 100644 --- a/templates/overrides/art-deco/author-bio-hero.ninjatpl +++ b/templates/overrides/art-deco/author-bio-hero.ninjatpl @@ -12,10 +12,10 @@ {% if author.location %}{{ author.location }}{% endif %} {% if showSocial %}
-{% if author.website_url %}{% endif %} -{% if author.twitter_handle %}{% endif %} -{% if author.linkedin_url %}{% endif %} -{% if author.github_url %}{% endif %} +{% if author.website_url %}{% endif %} +{% if author.twitter_handle %}{% endif %} +{% if author.linkedin_url %}{% endif %} +{% if author.github_url %}{% endif %}
{% endif %} diff --git a/templates/overrides/art-deco/contact-card.ninjatpl b/templates/overrides/art-deco/contact-card.ninjatpl index 82831f8..eb7a311 100644 --- a/templates/overrides/art-deco/contact-card.ninjatpl +++ b/templates/overrides/art-deco/contact-card.ninjatpl @@ -5,7 +5,7 @@
{% for channel in channels %}
- {% if channel.icon %}{% endif %} + {% if channel.icon %}{% endif %}
{% if channel.label %}
{{ channel.label }}
{% endif %} {% if channel.value %}
{% if channel.link %}{{ channel.value }}{% else %}{{ channel.value }}{% endif %}
{% endif %} diff --git a/templates/overrides/art-deco/countdown.ninjatpl b/templates/overrides/art-deco/countdown.ninjatpl index 3727214..c3e68d0 100644 --- a/templates/overrides/art-deco/countdown.ninjatpl +++ b/templates/overrides/art-deco/countdown.ninjatpl @@ -11,7 +11,7 @@
diff --git a/templates/overrides/art-deco/cta.ninjatpl b/templates/overrides/art-deco/cta.ninjatpl index 8ad2c4a..bbf1bac 100644 --- a/templates/overrides/art-deco/cta.ninjatpl +++ b/templates/overrides/art-deco/cta.ninjatpl @@ -6,7 +6,7 @@ {% if text %}

{{ text }}

{% endif %}
- {% if primaryUrl and primaryLabel %}{{ primaryLabel }}{% endif %} + {% if primaryUrl and primaryLabel %}{{ primaryLabel }}{% endif %} {% if secondaryUrl and secondaryLabel %}{{ secondaryLabel }}{% endif %}
diff --git a/templates/overrides/art-deco/divider.ninjatpl b/templates/overrides/art-deco/divider.ninjatpl index 014bce5..6f7d6d6 100644 --- a/templates/overrides/art-deco/divider.ninjatpl +++ b/templates/overrides/art-deco/divider.ninjatpl @@ -3,7 +3,7 @@ {% if variant == "ornament" %} {% elif variant == "spacer-rule" %} diff --git a/templates/overrides/art-deco/event-list.ninjatpl b/templates/overrides/art-deco/event-list.ninjatpl index e0286d6..931b242 100644 --- a/templates/overrides/art-deco/event-list.ninjatpl +++ b/templates/overrides/art-deco/event-list.ninjatpl @@ -12,7 +12,7 @@

{{ event.title }}

{% if event.venue %}

{{ event.venue }}

{% endif %} {% if event.description %}

{{ event.description }}

{% endif %} - {% if event.link %}{{ event.linkLabel|default:"Details" }}{% endif %} + {% if event.link %}{{ event.linkLabel|default:"Details" }}{% endif %} {% endif %}{% endfor %} diff --git a/templates/overrides/art-deco/faq.ninjatpl b/templates/overrides/art-deco/faq.ninjatpl index 403888d..141c7e9 100644 --- a/templates/overrides/art-deco/faq.ninjatpl +++ b/templates/overrides/art-deco/faq.ninjatpl @@ -7,7 +7,7 @@
{{ item.question }} - +
{{ item.answer|safe }}
diff --git a/templates/overrides/art-deco/feature-grid.ninjatpl b/templates/overrides/art-deco/feature-grid.ninjatpl index e9d842c..be559b6 100644 --- a/templates/overrides/art-deco/feature-grid.ninjatpl +++ b/templates/overrides/art-deco/feature-grid.ninjatpl @@ -6,10 +6,10 @@
{% for item in items %}
- {% if item.icon %}
{% endif %} + {% if item.icon %}
{% endif %}

{% if item.linkUrl %}{{ item.title }}{% else %}{{ item.title }}{% endif %}

{% if item.text %}

{{ item.text }}

{% endif %} - {% if item.linkUrl and item.linkLabel %}{{ item.linkLabel }}{% endif %} + {% if item.linkUrl and item.linkLabel %}{{ item.linkLabel }}{% endif %}
{% endfor %}
diff --git a/templates/overrides/art-deco/hero.ninjatpl b/templates/overrides/art-deco/hero.ninjatpl index 2710637..c645259 100644 --- a/templates/overrides/art-deco/hero.ninjatpl +++ b/templates/overrides/art-deco/hero.ninjatpl @@ -1,8 +1,8 @@ {# hero override — folds in the old marquee_hero: sunburst overlay + stepped ziggurat framing, gold-foil Cinzel headline. Structure/fields/{% img %} calls preserved from builtin. Styled-text fields accept {text,color} or a bare string. #} -{% set eyebrowText = eyebrow.text|default:eyebrow %} -{% set headlineText = headline.text|default:headline %} -{% set subText = subheadline.text|default:subheadline %} -{% set descText = description.text|default:description %} +{% set eyebrowText = eyebrow|get:"text"|default:eyebrow %} +{% set headlineText = headline|get:"text"|default:headline %} +{% set subText = subheadline|get:"text"|default:subheadline %} +{% set descText = description|get:"text"|default:description %} {% set pText = ctaPrimary.text %} {% set pUrl = ctaPrimary.url %} {% set sText = ctaSecondary.text %} diff --git a/templates/overrides/art-deco/pricing.ninjatpl b/templates/overrides/art-deco/pricing.ninjatpl index 7cbff79..3c1c32e 100644 --- a/templates/overrides/art-deco/pricing.ninjatpl +++ b/templates/overrides/art-deco/pricing.ninjatpl @@ -14,7 +14,7 @@

{% if tier.description %}

{{ tier.description }}

{% endif %} {% if tier.features %}{% endif %} {% if tier.ctaUrl and tier.ctaLabel %}{% if tier.highlighted %}{{ tier.ctaLabel }}{% else %}{{ tier.ctaLabel }}{% endif %}{% endif %} diff --git a/templates/overrides/art-deco/quote.ninjatpl b/templates/overrides/art-deco/quote.ninjatpl index 0eb2ea3..51cf4cf 100644 --- a/templates/overrides/art-deco/quote.ninjatpl +++ b/templates/overrides/art-deco/quote.ninjatpl @@ -1,7 +1,7 @@ {# quote override — supper-club press pull-quote: large italic Cormorant flanked by gold sunburst crests. Fields mirror builtin: quote, style, align, cite, attribution, role. #} {% with style=style|default:"block" align=align|default:"left" %}
- {% if align == "center" %}{% endif %} + {% if align == "center" %}{% endif %} {{ quote|safe }} {% if attribution or role or cite %}
{% if attribution %}{{ attribution }}{% endif %}{% if role %}{{ role }}{% endif %}{% if cite %}Source{% endif %}
{% endif %}
diff --git a/templates/overrides/art-deco/rich-section.ninjatpl b/templates/overrides/art-deco/rich-section.ninjatpl index b071fa1..f00ed62 100644 --- a/templates/overrides/art-deco/rich-section.ninjatpl +++ b/templates/overrides/art-deco/rich-section.ninjatpl @@ -4,7 +4,7 @@ {% if eyebrow %}

{{ eyebrow }}

{% endif %} {% if heading %}

{{ heading }}

{% endif %} {% if body %}
{{ body|safe }}
{% endif %} - {% if ctaUrl and ctaLabel %}{{ ctaLabel }}{% endif %} + {% if ctaUrl and ctaLabel %}{{ ctaLabel }}{% endif %}
{% if media %}
{% img media alt=mediaAlt class="w-full h-auto object-cover" %}
{% endif %} diff --git a/templates/overrides/art-deco/sidebar-nav.ninjatpl b/templates/overrides/art-deco/sidebar-nav.ninjatpl index 3511d61..0e9a2d7 100644 --- a/templates/overrides/art-deco/sidebar-nav.ninjatpl +++ b/templates/overrides/art-deco/sidebar-nav.ninjatpl @@ -6,7 +6,7 @@ {% if title %}

{{ title }}

{% endif %} diff --git a/templates/overrides/art-deco/social-links.ninjatpl b/templates/overrides/art-deco/social-links.ninjatpl index 87dc729..0206e26 100644 --- a/templates/overrides/art-deco/social-links.ninjatpl +++ b/templates/overrides/art-deco/social-links.ninjatpl @@ -4,7 +4,7 @@ {% for link in links %}{% if link.url %}
  • - {% if link.network %}{% endif %} + {% if link.network %}{% endif %} {% if style == "stack" and link.label %}{{ link.label }}{% endif %}
  • diff --git a/templates/overrides/art-deco/team.ninjatpl b/templates/overrides/art-deco/team.ninjatpl index a48e305..13acb38 100644 --- a/templates/overrides/art-deco/team.ninjatpl +++ b/templates/overrides/art-deco/team.ninjatpl @@ -11,7 +11,7 @@ {% if member.role %}

    {{ member.role }}

    {% endif %} {% if member.bio %}

    {{ member.bio }}

    {% endif %} {% if member.socials %}
    - {% for social in member.socials %}{% if social.url %}{% endif %}{% endfor %} + {% for social in member.socials %}{% if social.url %}{% endif %}{% endfor %}
    {% endif %}
    diff --git a/templates/overrides/art-deco/testimonial.ninjatpl b/templates/overrides/art-deco/testimonial.ninjatpl index 75993a8..684f4aa 100644 --- a/templates/overrides/art-deco/testimonial.ninjatpl +++ b/templates/overrides/art-deco/testimonial.ninjatpl @@ -5,11 +5,11 @@ {% for q in quotes %}
    {% if q.rating %}
    - - - - - + + + + +
    {% endif %}
    {% if q.quote %}“{{ q.quote }}”{% endif %}
    diff --git a/templates/overrides/art-deco/timeline.ninjatpl b/templates/overrides/art-deco/timeline.ninjatpl index 8e605fd..ce88606 100644 --- a/templates/overrides/art-deco/timeline.ninjatpl +++ b/templates/overrides/art-deco/timeline.ninjatpl @@ -6,7 +6,7 @@ {% for step in steps %}
  • - {% if marker == "numbered" %}{{ forloop.counter }}{% elif marker == "dot" %}{% else %}{% endif %} + {% if marker == "numbered" %}{{ forloop.counter }}{% elif marker == "dot" %}{% else %}{% endif %}
    {% if step.label %}

    {{ step.label }}

    {% endif %}