Archived
A design pass: the type ladder from the logo, and one name per thing
TYPOGRAPHY, taken from the lockup and walked down to something you can read a paragraph in. "The Vine" in LeJour Script over COFFEEHOUSE + BAKERY in AdBhashitha is the whole brand voice, so: the script stays in the wordmark and nowhere else (it is unreadable at length); AdBhashitha carries h1–h4 and the price, and keeps the wordmark's 0.01em letter-spacing so a heading sits on the same rhythm as the logo above it; `eyebrow` and `label` are the hinge — sans, but letterspaced like the tagline — and then plain Raleway. Sizes are declared once in type.css instead of being re-chosen per template, and none of the type classes set a colour, because the same heading appears in sage on cream and in cream on sage. BUTTONS AND SURFACES have names now. `panel` is the white box that was "bg-white rounded-3xl shadow-xs" written out in nine places (which is how two of them end up with different corners); `panel-lift` is one that reacts. `pill` is one shape in four colourways, which exist because this site puts buttons on cream AND on sage and they cannot be the same colour on both. `chip`/`chip-on` are the products filter. RHYTHM: `section` (py-16 md:py-24) and `band` (py-14 md:py-20, tighter because a coloured strip is already doing the separating) replace nine hand-picked paddings. FOCUS: one visible ring for everything reachable by keyboard, as an outline rather than a shadow so it works on cream, on white and on the sage bands, at zero specificity so a utility can still win. Z-INDEX: written down in base.css, all two of it — 40 the sticky header, 30 the mobile panel, which is a child of the header and so can only ever sit under the bar. Everything else stacks in document order. The point of the comment is that a third layer doesn't get invented at 9999. DROPDOWNS: the admin's category selects were drawing the platform's own arrow in the platform's grey; they get the site's chevron and room for it. 53 tests green. Every class used across all nine pages — five public, four admin — resolves in the compiled stylesheet, so nothing here is styled by a name that doesn't exist. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
that is selling something, and the same treatment as the homepage hero — blurred photo, sage wash —
|
||||
carries the brand rather than inventing a new look for it.
|
||||
*/-->
|
||||
<section class="relative flex items-center py-14 md:py-20 bg-bakery-900 text-white overflow-hidden">
|
||||
<section class="band relative flex items-center bg-bakery-900 text-white overflow-hidden">
|
||||
<img th:src="${photos.of('gallery/Cakes.webp')}" alt=""
|
||||
class="absolute inset-0 w-full h-full object-cover blur-[3px] scale-110">
|
||||
<div class="absolute inset-0 bg-bakery-900/80"></div>
|
||||
@@ -16,9 +16,9 @@
|
||||
|
||||
<div class="relative container mx-auto px-4 w-full min-w-0">
|
||||
<div class="max-w-3xl mx-auto text-center">
|
||||
<p class="text-xs sm:text-sm uppercase tracking-[0.2em] text-bakery-200">Order ahead</p>
|
||||
<h1 class="mt-3 font-adbhashitha text-4xl md:text-5xl text-bakery-50">Goodie boxes & catering</h1>
|
||||
<p class="mt-5 text-base sm:text-lg text-bakery-100 text-balance leading-relaxed">
|
||||
<p class="eyebrow text-bakery-200">Order ahead</p>
|
||||
<h1 class="h1 mt-3 text-bakery-50">Goodie boxes & catering</h1>
|
||||
<p class="lede mt-5 text-bakery-100">
|
||||
Boxes for the office, packages for a party, and cakes and desserts for a wedding.
|
||||
</p>
|
||||
</div>
|
||||
@@ -55,7 +55,7 @@
|
||||
*/-->
|
||||
<section th:each="table : ${menu.packages}">
|
||||
<header class="max-w-2xl mx-auto text-center">
|
||||
<h2 class="font-adbhashitha text-3xl md:text-4xl text-bakery-900" th:text="${table.name}">Office boxes</h2>
|
||||
<h2 class="h2 text-bakery-900" th:text="${table.name}">Office boxes</h2>
|
||||
<p th:if="${table.blurb}" class="mt-3 text-bakery-700 leading-relaxed" th:text="${table.blurb}">
|
||||
Mini pastries for a morning meeting.
|
||||
</p>
|
||||
@@ -67,12 +67,11 @@
|
||||
: (${#lists.size(table.tiers) == 2} ? 'sm:grid-cols-2 max-w-3xl mx-auto'
|
||||
: 'sm:grid-cols-2 lg:grid-cols-3')">
|
||||
<article th:each="tier, t : ${table.tiers}"
|
||||
class="flex flex-col bg-white rounded-3xl shadow-xs p-6 md:p-8
|
||||
transition-shadow duration-300 hover:shadow-lg">
|
||||
<p class="text-xs uppercase tracking-[0.15em] text-bakery-600" th:text="${tier.label}">Small</p>
|
||||
<p th:if="${tier.price}" class="mt-2 font-adbhashitha text-4xl text-bakery-900" th:text="${tier.price}">$24</p>
|
||||
class="flex flex-col panel-lift p-6 md:p-8">
|
||||
<p class="label text-bakery-600" th:text="${tier.label}">Small</p>
|
||||
<p th:if="${tier.price}" class="price mt-2 text-bakery-900" th:text="${tier.price}">$24</p>
|
||||
<!--/* No price means "ask us" — say so rather than leaving a hole in the card. */-->
|
||||
<p th:unless="${tier.price}" class="mt-2 font-adbhashitha text-2xl text-bakery-700">Ask us</p>
|
||||
<p th:unless="${tier.price}" class="price mt-2 text-2xl text-bakery-700">Ask us</p>
|
||||
<!--/* "Small" doesn't tell anyone how many it feeds. A column whose heading is already a
|
||||
head count leaves this blank rather than saying it twice. */-->
|
||||
<p th:if="${tier.serves}" class="mt-1 text-sm text-bakery-600" th:text="${tier.serves}">About 6–8 people</p>
|
||||
@@ -107,14 +106,13 @@
|
||||
*/-->
|
||||
<div class="mt-8 max-w-2xl mx-auto text-center">
|
||||
<div th:if="${!#lists.isEmpty(table.notes)}">
|
||||
<h3 class="text-xs uppercase tracking-[0.15em] text-bakery-500 font-medium">Good to know</h3>
|
||||
<h3 class="label text-bakery-500">Good to know</h3>
|
||||
<ul class="mt-3 space-y-2 text-sm text-bakery-700">
|
||||
<li th:each="note : ${table.notes}" th:text="${note}">Everything is baked in sixes.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<a th:href="|/contact?about=${#uris.escapeQueryParam(table.name)}|"
|
||||
class="mt-6 inline-block border border-bakery-300 hover:bg-bakery-100 text-bakery-800
|
||||
px-7 py-3 rounded-full font-medium tracking-wide transition-colors"
|
||||
class="pill-outline mt-6"
|
||||
th:text="|Ask about ${#strings.toLowerCase(table.name)}|">Ask about office boxes</a>
|
||||
</div>
|
||||
</section>
|
||||
@@ -131,20 +129,20 @@
|
||||
|
||||
<!--/* The terms that apply whichever table you were reading, and the one real call to action. On sage,
|
||||
like the homepage's story band, so the page ends rather than trailing off. */-->
|
||||
<section class="bg-bakery-800 text-white py-16 md:py-20">
|
||||
<section class="section bg-bakery-800 text-white">
|
||||
<div class="container mx-auto px-4">
|
||||
<div class="max-w-2xl mx-auto text-center">
|
||||
<h2 class="font-adbhashitha text-2xl md:text-3xl">Before you order</h2>
|
||||
<h2 class="h3">Before you order</h2>
|
||||
<ul th:if="${!#lists.isEmpty(menu.notes)}" class="mt-6 space-y-3 text-bakery-100 leading-relaxed">
|
||||
<li th:each="note : ${menu.notes}" th:text="${note}">These are a guide rather than a menu.</li>
|
||||
</ul>
|
||||
<div class="mt-10 flex flex-col sm:flex-row gap-3 justify-center">
|
||||
<a href="/contact"
|
||||
class="bg-bakery-50 hover:bg-white text-bakery-900 px-8 py-3.5 rounded-full font-medium tracking-wide inline-block transition shadow-lg">
|
||||
class="pill-cream">
|
||||
Tell us what you need
|
||||
</a>
|
||||
<a href="tel:+13097010660"
|
||||
class="border border-bakery-200/60 hover:bg-bakery-50/10 text-bakery-50 px-8 py-3.5 rounded-full font-medium tracking-wide inline-block transition">
|
||||
class="pill-ghost">
|
||||
(309) 701-0660
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<div th:fragment="content" class="min-h-screen bg-bakery-50">
|
||||
|
||||
<header class="container mx-auto px-4 pt-14 pb-10 md:pt-20 md:pb-12 text-center">
|
||||
<h1 class="font-adbhashitha text-4xl md:text-5xl text-bakery-900">Contact us</h1>
|
||||
<h1 class="h1 text-bakery-900">Contact us</h1>
|
||||
<p class="mt-4 text-bakery-800 max-w-xl mx-auto leading-relaxed">
|
||||
Ask about a cake, a date, or an order for a crowd. We read everything that comes in.
|
||||
</p>
|
||||
@@ -17,8 +17,8 @@
|
||||
*/-->
|
||||
<div class="container mx-auto px-4 pb-16 md:pb-24">
|
||||
<div class="grid gap-8 lg:grid-cols-[1.4fr_1fr] max-w-5xl mx-auto items-start">
|
||||
<div class="bg-white p-8 md:p-10 rounded-3xl shadow-xs">
|
||||
<h2 class="font-adbhashitha text-2xl md:text-3xl text-bakery-900 mb-2">Get in touch</h2>
|
||||
<div class="panel p-8 md:p-10">
|
||||
<h2 class="h3 text-bakery-900 mb-2">Get in touch</h2>
|
||||
<p class="text-bakery-700 mb-8">
|
||||
Or call us: <a href="tel:+13097010660" class="underline underline-offset-4 hover:text-bakery-600">(309) 701-0660</a>
|
||||
</p>
|
||||
@@ -52,7 +52,7 @@
|
||||
</div>
|
||||
<div class="flex flex-col items-center gap-4">
|
||||
<button type="submit"
|
||||
class="px-8 py-3 bg-bakery-600 text-white rounded-full tracking-wide hover:bg-bakery-700 transition-colors">
|
||||
class="pill-sage">
|
||||
Send message
|
||||
</button>
|
||||
|
||||
@@ -71,18 +71,18 @@
|
||||
</div>
|
||||
|
||||
<aside class="space-y-6">
|
||||
<div class="bg-white p-6 md:p-8 rounded-3xl shadow-xs">
|
||||
<h2 class="font-adbhashitha text-xl text-bakery-900">Our hours</h2>
|
||||
<div class="panel p-6 md:p-8">
|
||||
<h2 class="h4 text-bakery-900">Our hours</h2>
|
||||
<div class="mt-4 text-bakery-800"
|
||||
th:replace="~{fragments/visit :: hours('text-bakery-800')}"></div>
|
||||
</div>
|
||||
<div class="bg-white p-6 md:p-8 rounded-3xl shadow-xs">
|
||||
<h2 class="font-adbhashitha text-xl text-bakery-900">Find us</h2>
|
||||
<div class="panel p-6 md:p-8">
|
||||
<h2 class="h4 text-bakery-900">Find us</h2>
|
||||
<div class="mt-4 text-bakery-800"
|
||||
th:replace="~{fragments/visit :: address('hover:text-bakery-600 underline underline-offset-4')}"></div>
|
||||
</div>
|
||||
<div class="rounded-3xl border border-bakery-200 p-6 md:p-8">
|
||||
<h2 class="font-adbhashitha text-xl text-bakery-900">Ordering for a crowd?</h2>
|
||||
<h2 class="h4 text-bakery-900">Ordering for a crowd?</h2>
|
||||
<p class="mt-2 text-sm text-bakery-700 leading-relaxed">
|
||||
Goodie boxes, party packages and wedding desserts have their own page, with sizes and prices.
|
||||
</p>
|
||||
|
||||
@@ -14,13 +14,13 @@
|
||||
<body>
|
||||
<div th:fragment="content" class="bg-bakery-50">
|
||||
<div class="container mx-auto px-4 py-24 md:py-32 text-center">
|
||||
<h1 class="font-adbhashitha text-4xl md:text-5xl text-bakery-900 mb-6">Something went wrong</h1>
|
||||
<h1 class="h1 text-bakery-900 mb-6">Something went wrong</h1>
|
||||
<p class="text-bakery-800 mb-10">
|
||||
That is our fault, not yours. Try again in a moment, or call us on
|
||||
<a href="tel:+13097010660" class="underline underline-offset-4">(309) 701-0660</a>.
|
||||
</p>
|
||||
<a href="/"
|
||||
class="bg-bakery-600 hover:bg-bakery-700 text-white px-8 py-3.5 rounded-full font-medium tracking-wide inline-block transition">
|
||||
class="pill-sage">
|
||||
Back home
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<body>
|
||||
<div th:fragment="content" class="bg-bakery-50">
|
||||
<div class="container mx-auto px-4 py-24 md:py-32 text-center">
|
||||
<h1 class="font-adbhashitha text-4xl md:text-5xl text-bakery-900 mb-6">
|
||||
<h1 class="h1 text-bakery-900 mb-6">
|
||||
We could not find that page
|
||||
</h1>
|
||||
<p class="text-bakery-800 mb-10">
|
||||
@@ -25,11 +25,11 @@
|
||||
</p>
|
||||
<div class="flex flex-col sm:flex-row gap-3 justify-center">
|
||||
<a href="/"
|
||||
class="bg-bakery-600 hover:bg-bakery-700 text-white px-8 py-3.5 rounded-full font-medium tracking-wide inline-block transition">
|
||||
class="pill-sage">
|
||||
Back home
|
||||
</a>
|
||||
<a href="/products"
|
||||
class="border border-bakery-300 hover:bg-bakery-100 text-bakery-700 px-8 py-3.5 rounded-full font-medium tracking-wide inline-block transition">
|
||||
class="pill-outline">
|
||||
See the menu
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 class="font-adbhashitha text-sm uppercase tracking-[0.18em] text-bakery-300 mb-4">Navigation</h3>
|
||||
<h3 class="label text-bakery-300 mb-4 font-adbhashitha">Navigation</h3>
|
||||
<ul class="space-y-2">
|
||||
<li><a href="/products" class="hover:text-white transition">Our Products</a></li>
|
||||
<li><a href="/catering" class="hover:text-white transition">Goodie Boxes & Catering</a></li>
|
||||
@@ -19,7 +19,7 @@
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 class="font-adbhashitha text-sm uppercase tracking-[0.18em] text-bakery-300 mb-4">Visit</h3>
|
||||
<h3 class="label text-bakery-300 mb-4 font-adbhashitha">Visit</h3>
|
||||
<div th:replace="~{fragments/visit :: address('hover:text-white transition')}"></div>
|
||||
<!--/* The hours are the thing people come to a bakery's site for, and the footer is on every
|
||||
page. */-->
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
<div th:replace="~{fragments/lockup :: small('text-bakery-700')}"></div>
|
||||
|
||||
<nav class="hidden md:flex items-center gap-8">
|
||||
<th:block th:replace="~{:: links('text-sm uppercase tracking-[0.15em] text-bakery-700 hover:text-bakery-900 transition')}"></th:block>
|
||||
<th:block th:replace="~{:: links('label text-bakery-700 hover:text-bakery-900 transition-colors')}"></th:block>
|
||||
</nav>
|
||||
|
||||
<details class="group md:hidden shrink-0">
|
||||
|
||||
@@ -4,16 +4,16 @@
|
||||
<div th:fragment="content" class="bg-bakery-50">
|
||||
|
||||
<!--/* The shop's own front, which is what the story is about. Same band as the catering page. */-->
|
||||
<section class="relative flex items-center py-14 md:py-20 bg-bakery-900 text-white overflow-hidden">
|
||||
<section class="band relative flex items-center bg-bakery-900 text-white overflow-hidden">
|
||||
<img th:src="${photos.of('gallery/Outside.webp')}" alt=""
|
||||
class="absolute inset-0 w-full h-full object-cover object-bottom blur-[3px] scale-110">
|
||||
<div class="absolute inset-0 bg-bakery-900/80"></div>
|
||||
<div class="absolute inset-0 bg-gradient-to-t from-bakery-900 via-bakery-800/60 to-bakery-900/80"></div>
|
||||
<div class="relative container mx-auto px-4 w-full min-w-0">
|
||||
<div class="max-w-3xl mx-auto text-center">
|
||||
<p class="text-xs sm:text-sm uppercase tracking-[0.2em] text-bakery-200">Since 2024</p>
|
||||
<h1 class="mt-3 font-adbhashitha text-4xl md:text-5xl text-bakery-50">Our story</h1>
|
||||
<p class="mt-5 text-base sm:text-lg text-bakery-100 text-balance leading-relaxed">
|
||||
<p class="eyebrow text-bakery-200">Since 2024</p>
|
||||
<h1 class="h1 mt-3 text-bakery-50">Our story</h1>
|
||||
<p class="lede mt-5 text-bakery-100">
|
||||
215 E Main Street, in the middle of downtown Princeville.
|
||||
</p>
|
||||
</div>
|
||||
@@ -25,7 +25,7 @@
|
||||
<div class="container mx-auto px-4 pb-16 md:pb-24">
|
||||
<div class="max-w-2xl mx-auto space-y-12">
|
||||
<section>
|
||||
<h2 class="font-adbhashitha text-2xl md:text-3xl text-bakery-900 mb-4">How it started</h2>
|
||||
<h2 class="h3 text-bakery-900 mb-4">How it started</h2>
|
||||
<p class="text-bakery-800 leading-relaxed">
|
||||
Morissa Bennett opened The Vine in 2024, at 215 E Main Street, in the middle of downtown
|
||||
Princeville. The plan was not complicated. Bake it ourselves, sell it ourselves, and keep
|
||||
@@ -34,7 +34,7 @@
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 class="font-adbhashitha text-2xl md:text-3xl text-bakery-900 mb-4">What we make</h2>
|
||||
<h2 class="h3 text-bakery-900 mb-4">What we make</h2>
|
||||
<p class="text-bakery-800 leading-relaxed">
|
||||
We opened with coffee and pastries. The menu kept growing. Now there are cinnamon rolls
|
||||
and caramel rolls, scones, cookie bars, macarons, brownies, and pies, plus sandwiches and
|
||||
@@ -43,7 +43,7 @@
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 class="font-adbhashitha text-2xl md:text-3xl text-bakery-900 mb-4">The cakes are the fun part</h2>
|
||||
<h2 class="h3 text-bakery-900 mb-4">The cakes are the fun part</h2>
|
||||
<p class="text-bakery-800 leading-relaxed">
|
||||
Cakes and decorated cookies are made to order, which means we mostly bake whatever
|
||||
Princeville is celebrating that week. We have done a tractor, a cow, a 76th birthday, a
|
||||
@@ -54,7 +54,7 @@
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2 class="font-adbhashitha text-2xl md:text-3xl text-bakery-900 mb-4">Around town</h2>
|
||||
<h2 class="h3 text-bakery-900 mb-4">Around town</h2>
|
||||
<p class="text-bakery-800 leading-relaxed">
|
||||
We turn out for Christmas in the Village every year and for other civic events, and the
|
||||
Princeville Civic Association counts us among the town's small businesses. Enjoy
|
||||
@@ -66,21 +66,21 @@
|
||||
</div>
|
||||
|
||||
<!--/* Somewhere to go after reading: the story is a preamble to an order. */-->
|
||||
<section class="bg-bakery-800 text-white py-16 md:py-20">
|
||||
<section class="section bg-bakery-800 text-white">
|
||||
<div class="container mx-auto px-4">
|
||||
<div class="max-w-2xl mx-auto text-center">
|
||||
<h2 class="font-adbhashitha text-2xl md:text-3xl">Come and see us</h2>
|
||||
<h2 class="h3">Come and see us</h2>
|
||||
<p class="mt-4 text-bakery-100 leading-relaxed">
|
||||
We open at 7:00am, Tuesday through Saturday. If you are after something for a date in the
|
||||
diary, it is worth asking early.
|
||||
</p>
|
||||
<div class="mt-8 flex flex-col sm:flex-row gap-3 justify-center">
|
||||
<a href="/products"
|
||||
class="bg-bakery-50 hover:bg-white text-bakery-900 px-8 py-3.5 rounded-full font-medium tracking-wide inline-block transition shadow-lg">
|
||||
class="pill-cream">
|
||||
See what we make
|
||||
</a>
|
||||
<a href="/contact"
|
||||
class="border border-bakery-200/60 hover:bg-bakery-50/10 text-bakery-50 px-8 py-3.5 rounded-full font-medium tracking-wide inline-block transition">
|
||||
class="pill-ghost">
|
||||
Get in touch
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -18,16 +18,16 @@
|
||||
<div class="relative container mx-auto px-4 w-full min-w-0">
|
||||
<div class="max-w-3xl mx-auto text-center">
|
||||
<div th:replace="~{fragments/lockup :: large('text-bakery-50 mb-10')}"></div>
|
||||
<p class="text-lg sm:text-xl text-bakery-100 mb-10 text-balance leading-relaxed">
|
||||
<p class="lede sm:text-xl text-bakery-100 mb-10">
|
||||
A coffeehouse and bakery in downtown Princeville, Illinois.
|
||||
</p>
|
||||
<div class="flex flex-col sm:flex-row gap-3 justify-center">
|
||||
<a href="/products"
|
||||
class="bg-bakery-50 hover:bg-white text-bakery-900 px-8 py-3.5 rounded-full font-medium tracking-wide inline-block transition shadow-lg">
|
||||
class="pill-cream">
|
||||
See the menu
|
||||
</a>
|
||||
<a href="#visit"
|
||||
class="border border-bakery-200/60 hover:bg-bakery-50/10 text-bakery-50 px-8 py-3.5 rounded-full font-medium tracking-wide inline-block transition">
|
||||
class="pill-ghost">
|
||||
Visit us
|
||||
</a>
|
||||
</div>
|
||||
@@ -36,28 +36,28 @@
|
||||
</section>
|
||||
|
||||
<!--/* What people come in for */-->
|
||||
<section class="py-16 md:py-24 bg-bakery-50">
|
||||
<section class="section bg-bakery-50">
|
||||
<div class="container mx-auto px-4">
|
||||
<h2 class="font-adbhashitha text-3xl md:text-4xl text-center text-bakery-900 mb-12">What people come in for</h2>
|
||||
<h2 class="h2 text-center text-bakery-900 mb-12">What people come in for</h2>
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-6 md:gap-8">
|
||||
<div th:each="item : ${ {'Cinnamon Rolls', 'Sugar Cookies', 'Cakes'} }"
|
||||
class="group text-center bg-white rounded-3xl overflow-hidden shadow-xs hover:shadow-lg hover:-translate-y-1 transition duration-300">
|
||||
class="group panel-lift overflow-hidden text-center hover:-translate-y-1">
|
||||
<div class="overflow-hidden">
|
||||
<!--/* The filenames carry the spaces in these names; SitePhotos encodes them. */-->
|
||||
<img th:src="${photos.of('gallery/' + item + '.webp')}" th:alt="${item}" width="600" height="400" loading="lazy"
|
||||
class="w-full h-56 object-cover transition-transform duration-500 group-hover:scale-105">
|
||||
</div>
|
||||
<h3 class="font-adbhashitha text-xl md:text-2xl text-bakery-800 py-6 tracking-wide" th:text="${item}">Cinnamon Rolls</h3>
|
||||
<h3 class="h4 md:text-2xl text-bakery-800 py-6" th:text="${item}">Cinnamon Rolls</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!--/* Our story */-->
|
||||
<section class="py-16 md:py-24 bg-bakery-800 text-white">
|
||||
<section class="section bg-bakery-800 text-white">
|
||||
<div class="container mx-auto px-4">
|
||||
<div class="max-w-3xl mx-auto text-center">
|
||||
<h2 class="font-adbhashitha text-3xl md:text-4xl mb-8" style="letter-spacing: 0.01em">Our story</h2>
|
||||
<h2 class="h2 mb-8" style="letter-spacing: 0.01em">Our story</h2>
|
||||
<p class="text-base md:text-lg text-bakery-100 mb-8 leading-relaxed">
|
||||
Morissa Bennett opened The Vine in 2024. We bake in our own kitchen on Main Street:
|
||||
cinnamon rolls, cookies, custom cakes, sandwiches, paninis, and coffee.
|
||||
@@ -74,20 +74,20 @@
|
||||
found it by reading the nav. Photo on one side, the offer on the other, and the three tables named so
|
||||
the link is worth following.
|
||||
*/-->
|
||||
<section class="py-16 md:py-24 bg-bakery-50">
|
||||
<section class="section bg-bakery-50">
|
||||
<div class="container mx-auto px-4">
|
||||
<div class="grid md:grid-cols-2 gap-8 md:gap-12 items-center max-w-5xl mx-auto">
|
||||
<img th:src="${photos.of('gallery/Sugar Cookies.webp')}" alt="Iced sugar cookies from The Vine"
|
||||
width="800" height="600" loading="lazy"
|
||||
class="w-full h-64 md:h-80 object-cover rounded-3xl shadow-xs">
|
||||
<div>
|
||||
<h2 class="font-adbhashitha text-3xl md:text-4xl text-bakery-900">Ordering for a crowd?</h2>
|
||||
<h2 class="h2 text-bakery-900">Ordering for a crowd?</h2>
|
||||
<p class="mt-4 text-bakery-800 leading-relaxed">
|
||||
Goodie boxes for the office, packages for a party, and cakes and desserts for a wedding —
|
||||
with prices, sizes and what each one includes, so you can see where to start.
|
||||
</p>
|
||||
<a href="/catering"
|
||||
class="mt-6 inline-block bg-bakery-600 hover:bg-bakery-700 text-white px-8 py-3.5 rounded-full font-medium tracking-wide transition">
|
||||
class="pill-sage mt-6">
|
||||
Goodie boxes & catering
|
||||
</a>
|
||||
</div>
|
||||
@@ -96,16 +96,16 @@
|
||||
</section>
|
||||
|
||||
<!--/* Visit us */-->
|
||||
<section id="visit" class="py-16 md:py-24 bg-bakery-50 scroll-mt-24">
|
||||
<section id="visit" class="section bg-bakery-50 scroll-mt-24">
|
||||
<div class="container mx-auto px-4">
|
||||
<h2 class="font-adbhashitha text-3xl md:text-4xl text-center text-bakery-900 mb-12">Visit us</h2>
|
||||
<h2 class="h2 text-center text-bakery-900 mb-12">Visit us</h2>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-8 md:gap-12 max-w-4xl mx-auto">
|
||||
<div class="bg-white rounded-3xl p-6 md:p-8">
|
||||
<h2 class="font-adbhashitha text-2xl md:text-3xl text-bakery-900 mb-6">Our hours</h2>
|
||||
<div class="panel p-6 md:p-8">
|
||||
<h2 class="h3 text-bakery-900 mb-6">Our hours</h2>
|
||||
<div th:replace="~{fragments/visit :: hours('text-bakery-800')}"></div>
|
||||
</div>
|
||||
<div class="bg-white rounded-3xl p-6 md:p-8">
|
||||
<h2 class="font-adbhashitha text-2xl md:text-3xl text-bakery-900 mb-6">Find us</h2>
|
||||
<div class="panel p-6 md:p-8">
|
||||
<h2 class="h3 text-bakery-900 mb-6">Find us</h2>
|
||||
<div class="text-bakery-800"
|
||||
th:replace="~{fragments/visit :: address('hover:text-bakery-600 underline underline-offset-4')}"></div>
|
||||
</div>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<div th:fragment="content" class="min-h-screen bg-bakery-50">
|
||||
|
||||
<header class="container mx-auto px-4 pt-14 pb-10 md:pt-20 md:pb-12 text-center">
|
||||
<h1 class="font-adbhashitha text-4xl md:text-5xl text-bakery-900">Our products</h1>
|
||||
<h1 class="h1 text-bakery-900">Our products</h1>
|
||||
<p class="mt-4 text-bakery-800 max-w-2xl mx-auto leading-relaxed">
|
||||
What comes out of the kitchen on Main Street. Cakes and decorated cookies are made to order, so
|
||||
most of what follows started as somebody describing what they wanted.
|
||||
@@ -23,10 +23,7 @@
|
||||
th:href="${category == 'All' ? '/products' : '/products?category=' + #uris.escapeQueryParam(category)}"
|
||||
th:text="${category}"
|
||||
th:aria-current="${category == selected ? 'page' : null}"
|
||||
th:class="'px-6 py-2 rounded-full border text-sm uppercase tracking-[0.12em] transition-colors '
|
||||
+ (${category == selected}
|
||||
? 'bg-bakery-600 text-white border-bakery-600'
|
||||
: 'bg-white border-bakery-300 text-bakery-700 hover:bg-bakery-100')">All</a>
|
||||
th:class="${category == selected} ? 'chip-on' : 'chip'">All</a>
|
||||
</div>
|
||||
|
||||
<!--/* Deliberately unanimated, as before: filtering used to run a layout reflow plus an enter/exit
|
||||
@@ -34,13 +31,13 @@
|
||||
responding. The only motion left is the shadow on hover. */-->
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||
<div th:each="product : ${products}"
|
||||
class="group bg-white rounded-3xl overflow-hidden shadow-xs transition-shadow duration-300 hover:shadow-lg">
|
||||
class="group panel-lift overflow-hidden">
|
||||
<div class="relative w-full overflow-hidden">
|
||||
<div th:replace="~{:: gallery(${product})}"></div>
|
||||
</div>
|
||||
<div class="p-6 text-center">
|
||||
<h3 class="font-adbhashitha text-xl text-bakery-900 mb-2 tracking-wide" th:text="${product.name}">Name</h3>
|
||||
<span class="text-xs uppercase tracking-[0.15em] text-bakery-600" th:text="${product.category}">Category</span>
|
||||
<h3 class="h4 text-bakery-900 mb-2" th:text="${product.name}">Name</h3>
|
||||
<span class="label text-bakery-600" th:text="${product.category}">Category</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -52,21 +49,21 @@
|
||||
</div>
|
||||
|
||||
<!--/* A catalogue with no way to order from it is a gallery. */-->
|
||||
<section class="bg-bakery-800 text-white py-16 md:py-20">
|
||||
<section class="section bg-bakery-800 text-white">
|
||||
<div class="container mx-auto px-4">
|
||||
<div class="max-w-2xl mx-auto text-center">
|
||||
<h2 class="font-adbhashitha text-2xl md:text-3xl">Want one of these, or something else?</h2>
|
||||
<h2 class="h3">Want one of these, or something else?</h2>
|
||||
<p class="mt-4 text-bakery-100 leading-relaxed">
|
||||
Cakes and decorated cookies are made to order. Tell us the date and roughly what you have in
|
||||
mind — a tractor, a retirement, the class of 1964 — and we will work from there.
|
||||
</p>
|
||||
<div class="mt-8 flex flex-col sm:flex-row gap-3 justify-center">
|
||||
<a href="/contact"
|
||||
class="bg-bakery-50 hover:bg-white text-bakery-900 px-8 py-3.5 rounded-full font-medium tracking-wide inline-block transition shadow-lg">
|
||||
class="pill-cream">
|
||||
Ask about an order
|
||||
</a>
|
||||
<a href="/catering"
|
||||
class="border border-bakery-200/60 hover:bg-bakery-50/10 text-bakery-50 px-8 py-3.5 rounded-full font-medium tracking-wide inline-block transition">
|
||||
class="pill-ghost">
|
||||
Ordering for a crowd
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -38,3 +38,39 @@ body {
|
||||
background-color: var(--color-bakery-300);
|
||||
color: var(--color-bakery-900);
|
||||
}
|
||||
|
||||
/*
|
||||
* FOCUS. One visible ring for everything you can reach with a keyboard, as an outline rather than a
|
||||
* shadow so it shows up on cream, on white and on the sage bands without needing three variants.
|
||||
* :where() keeps its specificity at zero, so a utility can still override it.
|
||||
*/
|
||||
:where(a, button, summary, input, select, textarea, [tabindex]):focus-visible {
|
||||
outline: 2px solid var(--color-bakery-500);
|
||||
outline-offset: 3px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
/*
|
||||
* THE Z-INDEX SCALE, in full. Two layers is all this site has, and writing them down is what stops a
|
||||
* third being invented at 9999:
|
||||
*
|
||||
* 40 the sticky header
|
||||
* 30 the mobile menu panel, which is a child of the header and therefore already inside its stacking
|
||||
* context — it can only ever sit under the bar, which is exactly where it belongs
|
||||
*
|
||||
* Everything else stacks in document order: the hero's tint sits over its photo because it comes after
|
||||
* it, and the product-card arrows sit over the photos for the same reason.
|
||||
*/
|
||||
|
||||
/*
|
||||
* A native select still gets its own arrow from the platform, in the platform's colour. This is the one
|
||||
* control the admin uses that we don't draw ourselves, so it gets the site's chevron instead.
|
||||
*/
|
||||
select.field {
|
||||
appearance: none;
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%234a5740' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
|
||||
background-repeat: no-repeat;
|
||||
background-position: right 0.6rem center;
|
||||
background-size: 1.1rem;
|
||||
padding-right: 2.4rem;
|
||||
}
|
||||
|
||||
@@ -58,3 +58,67 @@ summary {
|
||||
summary::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/*
|
||||
* SURFACES. Every white box on the site was "bg-white rounded-3xl shadow-xs" written out again, which is
|
||||
* how two of them end up with different corners. `panel` is that box; `panel-lift` is one you can click
|
||||
* or hover, and it lifts.
|
||||
*/
|
||||
@utility panel {
|
||||
@apply bg-white rounded-3xl shadow-xs;
|
||||
}
|
||||
|
||||
@utility panel-lift {
|
||||
@apply panel transition duration-300 hover:shadow-lg;
|
||||
}
|
||||
|
||||
/*
|
||||
* BUTTONS. One shape — a full pill, generous, letterspaced — in four colourways, because the site puts
|
||||
* buttons on cream and on sage and they cannot be the same colour on both.
|
||||
*
|
||||
* pill-sage filled, on a light background pill-outline quiet, on a light background
|
||||
* pill-cream filled, on a sage background pill-ghost quiet, on a sage background
|
||||
*/
|
||||
@utility pill {
|
||||
@apply inline-flex items-center justify-center gap-2 rounded-full
|
||||
px-8 py-3.5 font-medium tracking-wide transition-colors;
|
||||
}
|
||||
|
||||
@utility pill-sage {
|
||||
@apply pill bg-bakery-600 text-white hover:bg-bakery-700;
|
||||
}
|
||||
|
||||
@utility pill-cream {
|
||||
@apply pill bg-bakery-50 text-bakery-900 hover:bg-white shadow-lg;
|
||||
}
|
||||
|
||||
@utility pill-outline {
|
||||
@apply pill border border-bakery-300 text-bakery-800 hover:bg-bakery-100;
|
||||
}
|
||||
|
||||
@utility pill-ghost {
|
||||
@apply pill border border-bakery-200/60 text-bakery-50 hover:bg-bakery-50/10;
|
||||
}
|
||||
|
||||
/* Smaller, for a filter row rather than a call to action. */
|
||||
@utility chip {
|
||||
@apply inline-flex items-center rounded-full border px-6 py-2 label
|
||||
bg-white border-bakery-300 text-bakery-700 transition-colors hover:bg-bakery-100;
|
||||
}
|
||||
|
||||
@utility chip-on {
|
||||
@apply chip bg-bakery-600 border-bakery-600 text-white hover:bg-bakery-600;
|
||||
}
|
||||
|
||||
/*
|
||||
* RHYTHM. Two vertical sizes, so the page has a beat instead of nine hand-picked paddings: `section` for
|
||||
* a block of content, `band` for a photographic or coloured strip, which sits tighter because its
|
||||
* background is already doing the separating.
|
||||
*/
|
||||
@utility section {
|
||||
@apply py-16 md:py-24;
|
||||
}
|
||||
|
||||
@utility band {
|
||||
@apply py-14 md:py-20;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
@import "./theme.css";
|
||||
@import "./base.css";
|
||||
@import "./type.css";
|
||||
@import "./components.css";
|
||||
@import "./admin.css";
|
||||
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* The typographic ladder, taken from the logo and walked down to something you can read a paragraph in.
|
||||
*
|
||||
* The lockup is the brand's whole voice: "The Vine" in LeJour Script over COFFEEHOUSE + BAKERY in
|
||||
* AdBhashitha, letterspaced. Everything below is that idea, made progressively more readable:
|
||||
*
|
||||
* 1. .wordmark LeJour Script the name, and nothing else. A script face is unreadable at length,
|
||||
* so it never leaves the lockup.
|
||||
* 2. .h1 .h2 .h3 AdBhashitha the lockup's second font, carrying every heading. It keeps the
|
||||
* wordmark's 0.01em letter-spacing so a heading sits on the same
|
||||
* rhythm as the logo above it.
|
||||
* 3. .eyebrow Raleway, caps the hinge: sans, but letterspaced like the lockup's tagline. Used
|
||||
* .label above a heading and on small labels, it carries the brand into
|
||||
* places a display face would be shouting.
|
||||
* 4. .lede, body Raleway plain, and left alone.
|
||||
*
|
||||
* Sizes are declared here rather than in the templates so a heading is a decision made once. None of
|
||||
* these set a colour: the same heading appears in sage on cream and in cream on sage, and a class that
|
||||
* decided that would be fought with a utility every time.
|
||||
*/
|
||||
|
||||
@utility wordmark {
|
||||
font-family: var(--font-lejour);
|
||||
letter-spacing: 0.01em;
|
||||
}
|
||||
|
||||
@utility h1 {
|
||||
@apply font-adbhashitha text-4xl md:text-5xl leading-tight text-balance;
|
||||
letter-spacing: 0.01em;
|
||||
}
|
||||
|
||||
@utility h2 {
|
||||
@apply font-adbhashitha text-3xl md:text-4xl leading-tight text-balance;
|
||||
letter-spacing: 0.01em;
|
||||
}
|
||||
|
||||
@utility h3 {
|
||||
@apply font-adbhashitha text-2xl md:text-3xl leading-snug;
|
||||
letter-spacing: 0.01em;
|
||||
}
|
||||
|
||||
@utility h4 {
|
||||
@apply font-adbhashitha text-xl leading-snug;
|
||||
letter-spacing: 0.01em;
|
||||
}
|
||||
|
||||
/* Above a heading, or as a section's own small heading. */
|
||||
@utility eyebrow {
|
||||
@apply text-xs sm:text-sm uppercase font-medium;
|
||||
letter-spacing: 0.2em;
|
||||
}
|
||||
|
||||
/* Smaller, tighter: a column heading, a "good to know", a category chip. */
|
||||
@utility label {
|
||||
@apply text-xs uppercase font-medium;
|
||||
letter-spacing: 0.15em;
|
||||
}
|
||||
|
||||
/* The sentence under a page title. One size up from body, and balanced so it doesn't leave an orphan. */
|
||||
@utility lede {
|
||||
@apply text-base sm:text-lg leading-relaxed text-balance;
|
||||
}
|
||||
|
||||
/*
|
||||
* A price. The display face at a size nothing else uses, because on a catering card the number is the
|
||||
* thing the eye should land on after the size.
|
||||
*/
|
||||
@utility price {
|
||||
@apply font-adbhashitha text-4xl leading-none;
|
||||
letter-spacing: 0.01em;
|
||||
}
|
||||
Reference in New Issue
Block a user