Archived
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.
100 lines
5.0 KiB
HTML
100 lines
5.0 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en" xmlns:th="http://www.thymeleaf.org" th:replace="~{fragments/page :: page(${title}, ${description}, ${path}, ~{::content})}">
|
|
<body>
|
|
<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="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>
|
|
</header>
|
|
|
|
<!--/*
|
|
The form, and beside it the things somebody on this page is usually actually after: when we are open,
|
|
where we are, and the phone number. They were on the homepage and in the footer but not here, which
|
|
made this page a form and nothing else.
|
|
*/-->
|
|
<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="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>
|
|
|
|
<!--/*
|
|
A plain form post. The enquiry is validated, written down and mailed by the server, which then
|
|
renders this page again with the outcome — no fetch, no JSON, and nothing to go wrong between
|
|
pressing the button and the enquiry being recorded.
|
|
|
|
Spring Security's CSRF token is added to any th:action form automatically, which is what keeps
|
|
this working on a deployment that has an identity provider configured (there, an unaccompanied
|
|
POST is rejected).
|
|
*/-->
|
|
<!--/* th:unless, not th:if="${!sent}": the attribute is absent on a GET, and SpEL cannot negate
|
|
a null. */-->
|
|
<form th:action="@{/contact}" method="post" th:unless="${sent}">
|
|
<div class="mb-4">
|
|
<label class="block text-sm font-medium text-bakery-800 mb-2" for="name">Name</label>
|
|
<input type="text" id="name" name="name" th:value="${name}" required
|
|
class="w-full px-4 py-2.5 bg-bakery-50 border border-bakery-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-bakery-500 focus:border-bakery-500">
|
|
</div>
|
|
<div class="mb-4">
|
|
<label class="block text-sm font-medium text-bakery-800 mb-2" for="email">Email</label>
|
|
<input type="email" id="email" name="email" th:value="${email}" required
|
|
class="w-full px-4 py-2.5 bg-bakery-50 border border-bakery-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-bakery-500 focus:border-bakery-500">
|
|
</div>
|
|
<div class="mb-4">
|
|
<label class="block text-sm font-medium text-bakery-800 mb-2" for="message">Message</label>
|
|
<textarea id="message" name="message" rows="5" required th:text="${message}"
|
|
class="w-full px-4 py-2.5 bg-bakery-50 border border-bakery-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-bakery-500 focus:border-bakery-500"></textarea>
|
|
</div>
|
|
<div class="flex flex-col items-center gap-4">
|
|
<button type="submit"
|
|
class="pill-sage">
|
|
Send message
|
|
</button>
|
|
|
|
<!--/* Never claim a success we did not get: say what happened and give them the phone number. */-->
|
|
<p th:if="${error}" role="alert" class="text-center text-red-700">
|
|
<span th:text="${error}">Could not send the message.</span>
|
|
Please call us on
|
|
<a href="tel:+13097010660" class="underline underline-offset-4">(309) 701-0660</a>.
|
|
</p>
|
|
</div>
|
|
</form>
|
|
|
|
<p th:if="${sent}" role="status" class="text-bakery-700">
|
|
Thanks. Your message is on its way, and we will get back to you.
|
|
</p>
|
|
</div>
|
|
|
|
<aside class="space-y-6">
|
|
<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="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="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>
|
|
<a href="/catering" class="mt-4 inline-block text-bakery-700 hover:text-bakery-900 font-medium
|
|
underline underline-offset-4 transition-colors">
|
|
Goodie boxes & catering
|
|
</a>
|
|
</div>
|
|
</aside>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|