Archived
Everything on the shared names — the copy-paste is gone
The ported markup was written a page at a time, so the same thing was said several ways. Counted before touching anything: nine variants of the page gutter, seven max-widths, six link styles, two definitions of an input, and one stray shadow. Now: `container` (which already centres and pads), `measure`/`measure-wide`, `link`/`link-plain`/ `link-on-dark`, one `field`, `photo`, `page-head`. Nothing in a template writes `bg-white rounded-… shadow-…` or `underline underline-offset-4` any more — 119 uses of `panel`, 82 of `label`, 52 of `panel-lift`, 17 of `link`. TWO REAL FIXES FELL OUT OF IT, not just tidying: - Every section said `container mx-auto px-4`: `mx-auto` twice, and a px-4 that beat the responsive padding inside `container`. The gutter was 16px at every width, including on a 27-inch screen. Removing the copy-paste restores sm:px-6 lg:px-8, which is most of why the pages now breathe. - The public form and the admin had grown two different inputs — cream vs white, ring-2 vs ring-1, py-2.5 vs py-2, and different text sizes. There is one `field` now, and the same focus ring as everything else. The admin uses the same names where they are the same thing (`link`, `field`, `h4`, `--radius-*`) and keeps its own denser buttons, because it is a tool and not a shop front. 53 tests green. Every class used across all nine pages resolves in the compiled stylesheet — that check is what makes a sweep this size safe to do with a script. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
@@ -38,8 +38,22 @@ wordmark's 0.01em letter-spacing so a heading sits on the same rhythm as the log
|
||||
read a paragraph of. None of the type classes set a colour — the same heading appears in sage on cream and
|
||||
cream on sage.
|
||||
|
||||
Write those class names in templates rather than the utilities behind them: a button is `pill-sage`, and
|
||||
the four colourways exist because the site puts buttons on cream *and* on sage.
|
||||
Write those class names in templates rather than the utilities behind them. The full vocabulary:
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| surfaces | `panel`, `panel-lift`, `panel-head`, `panel-mark`, `photo` |
|
||||
| buttons | `pill-sage`, `pill-cream`, `pill-outline`, `pill-ghost`, `chip`/`chip-on` |
|
||||
| links | `link`, `link-plain`, `link-on-dark` |
|
||||
| type | `h1`–`h4`, `price`, `eyebrow`, `label`, `lede`, `wordmark` |
|
||||
| layout | `container`, `measure`, `measure-wide`, `section`, `band`, `page-head` |
|
||||
| forms | `field` — one input for the public form and the admin |
|
||||
|
||||
Four colourways of one button exist because the site puts buttons on cream *and* on sage. Corners come
|
||||
from `--radius-panel` (12px) and `--radius-field` (8px), so "how round is a card" is one decision.
|
||||
|
||||
If you find yourself writing `bg-white rounded-… shadow-…` or `underline underline-offset-4` in a
|
||||
template, there is already a name for it.
|
||||
|
||||
### Why server-rendered
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
<div class="flex-1 min-w-60">
|
||||
<a th:href="@{/admin/catering/tables/{id}(id=${table.id})}"
|
||||
class="font-adbhashitha text-lg text-bakery-900 underline underline-offset-4"
|
||||
class="link h4 text-bakery-900"
|
||||
th:text="${table.name}">Office</a>
|
||||
<p class="text-sm text-bakery-600">
|
||||
<span th:text="|${#lists.size(table.tiers)} column${#lists.size(table.tiers) == 1 ? '' : 's'}|">3 columns</span>,
|
||||
|
||||
@@ -26,8 +26,8 @@
|
||||
<div>
|
||||
<h1 class="font-lejour text-4xl text-bakery-700">The Vine</h1>
|
||||
<nav class="mt-1 flex flex-wrap gap-4 text-sm">
|
||||
<a href="/admin" class="text-bakery-700 underline underline-offset-4 hover:text-bakery-900">The catalogue</a>
|
||||
<a href="/admin/catering" class="text-bakery-700 underline underline-offset-4 hover:text-bakery-900">Goodie boxes & catering</a>
|
||||
<a href="/admin" class="link">The catalogue</a>
|
||||
<a href="/admin/catering" class="link">Goodie boxes & catering</a>
|
||||
</nav>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<div class="card">
|
||||
<div class="flex flex-wrap items-baseline justify-between gap-2">
|
||||
<h2 class="card-heading">This table</h2>
|
||||
<a href="/admin/catering" class="text-sm text-bakery-700 underline underline-offset-4">All tables</a>
|
||||
<a href="/admin/catering" class="link text-sm">All tables</a>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 grid gap-2 sm:grid-cols-[14rem_1fr]">
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<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="relative container w-full min-w-0">
|
||||
<div class="max-w-3xl mx-auto text-center">
|
||||
<p class="eyebrow text-bakery-200">Order ahead</p>
|
||||
<h1 class="h1 mt-3 text-bakery-50">Goodie boxes & catering</h1>
|
||||
@@ -26,9 +26,9 @@
|
||||
</section>
|
||||
|
||||
<div class="bg-bakery-50">
|
||||
<div class="container mx-auto px-4 pt-14 pb-16 md:pt-16 md:pb-24">
|
||||
<div class="container pt-14 pb-16 md:pt-16 md:pb-24">
|
||||
|
||||
<p class="max-w-2xl mx-auto text-center text-bakery-800 leading-relaxed">
|
||||
<p class="measure text-center text-bakery-800 leading-relaxed">
|
||||
Every one of these is a starting point. Tell us the date, the number of people and what you had in
|
||||
mind, and we will bake to it.
|
||||
</p>
|
||||
@@ -54,7 +54,7 @@
|
||||
alignment the aggregate guarantees.
|
||||
*/-->
|
||||
<section th:each="table : ${menu.packages}">
|
||||
<header class="max-w-2xl mx-auto text-center">
|
||||
<header class="measure text-center">
|
||||
<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.
|
||||
@@ -109,7 +109,7 @@
|
||||
three cards led to the same place, since an enquiry is about the table rather than the size,
|
||||
and the label read "Ask about the 15–20 people" on the tables whose sizes are headcounts.
|
||||
*/-->
|
||||
<div class="mt-8 max-w-2xl mx-auto text-center">
|
||||
<div class="mt-8 measure text-center">
|
||||
<div th:if="${!#lists.isEmpty(table.notes)}">
|
||||
<h3 class="label text-bakery-500">Good to know</h3>
|
||||
<ul class="mt-3 space-y-2 text-sm text-bakery-700">
|
||||
@@ -125,7 +125,7 @@
|
||||
<!--/* Only shows if every table has been emptied out in the admin. Better than a bare heading. */-->
|
||||
<p th:if="${#lists.isEmpty(menu.packages)}" class="text-center text-bakery-800">
|
||||
Our catering list is being updated. Call us on
|
||||
<a href="tel:+13097010660" class="underline underline-offset-4">(309) 701-0660</a> and we will
|
||||
<a href="tel:+13097010660" class="link-plain">(309) 701-0660</a> and we will
|
||||
talk it through.
|
||||
</p>
|
||||
</div>
|
||||
@@ -135,8 +135,8 @@
|
||||
<!--/* 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="section bg-bakery-800 text-white">
|
||||
<div class="container mx-auto px-4">
|
||||
<div class="max-w-2xl mx-auto text-center">
|
||||
<div class="container">
|
||||
<div class="measure text-center">
|
||||
<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>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<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">
|
||||
<header class="page-head">
|
||||
<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.
|
||||
@@ -15,12 +15,12 @@
|
||||
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="container pb-16 md:pb-24">
|
||||
<div class="grid gap-8 lg:grid-cols-[1.4fr_1fr] measure-wide 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>
|
||||
Or call us: <a href="tel:+13097010660" class="link-plain">(309) 701-0660</a>
|
||||
</p>
|
||||
|
||||
<!--/*
|
||||
@@ -38,17 +38,17 @@
|
||||
<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-field focus:outline-none focus:ring-2 focus:ring-bakery-500 focus:border-bakery-500">
|
||||
class="field">
|
||||
</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-field focus:outline-none focus:ring-2 focus:ring-bakery-500 focus:border-bakery-500">
|
||||
class="field">
|
||||
</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-field focus:outline-none focus:ring-2 focus:ring-bakery-500 focus:border-bakery-500"></textarea>
|
||||
class="field"></textarea>
|
||||
</div>
|
||||
<div class="flex flex-col items-center gap-4">
|
||||
<button type="submit"
|
||||
@@ -60,7 +60,7 @@
|
||||
<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>.
|
||||
<a href="tel:+13097010660" class="link-plain">(309) 701-0660</a>.
|
||||
</p>
|
||||
</div>
|
||||
</form>
|
||||
@@ -79,15 +79,14 @@
|
||||
<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>
|
||||
th:replace="~{fragments/visit :: address('link-plain')}"></div>
|
||||
</div>
|
||||
<div class="rounded-panel 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">
|
||||
<a href="/catering" class="link mt-4 inline-block font-medium">
|
||||
Goodie boxes & catering
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -13,11 +13,11 @@
|
||||
'/', ~{::content})}">
|
||||
<body>
|
||||
<div th:fragment="content" class="bg-bakery-50">
|
||||
<div class="container mx-auto px-4 py-24 md:py-32 text-center">
|
||||
<div class="container py-24 md:py-32 text-center">
|
||||
<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>.
|
||||
<a href="tel:+13097010660" class="link-plain">(309) 701-0660</a>.
|
||||
</p>
|
||||
<a href="/"
|
||||
class="pill-sage">
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
'/', ~{::content})}">
|
||||
<body>
|
||||
<div th:fragment="content" class="bg-bakery-50">
|
||||
<div class="container mx-auto px-4 py-24 md:py-32 text-center">
|
||||
<div class="container py-24 md:py-32 text-center">
|
||||
<h1 class="h1 text-bakery-900 mb-6">
|
||||
We could not find that page
|
||||
</h1>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<body>
|
||||
<footer th:fragment="footer" class="bg-bakery-900 text-bakery-100">
|
||||
<div class="container mx-auto px-4 py-14">
|
||||
<div class="container py-14">
|
||||
<div class="grid grid-cols-1 md:grid-cols-4 gap-10">
|
||||
<div class="col-span-1 md:col-span-2 flex items-start">
|
||||
<div th:replace="~{fragments/lockup :: small('text-bakery-50')}"></div>
|
||||
@@ -11,16 +11,16 @@
|
||||
<div>
|
||||
<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>
|
||||
<li><a href="/history" class="hover:text-white transition">Our Story</a></li>
|
||||
<li><a href="/contact" class="hover:text-white transition">Contact</a></li>
|
||||
<li><a href="/products" class="hover:text-white transition-colors">Our Products</a></li>
|
||||
<li><a href="/catering" class="hover:text-white transition-colors">Goodie Boxes & Catering</a></li>
|
||||
<li><a href="/history" class="hover:text-white transition-colors">Our Story</a></li>
|
||||
<li><a href="/contact" class="hover:text-white transition-colors">Contact</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 class="label text-bakery-300 mb-4 font-adbhashitha">Visit</h3>
|
||||
<div th:replace="~{fragments/visit :: address('hover:text-white transition')}"></div>
|
||||
<div th:replace="~{fragments/visit :: address('link-on-dark')}"></div>
|
||||
<!--/* The hours are the thing people come to a bakery's site for, and the footer is on every
|
||||
page. */-->
|
||||
<div class="mt-4 text-sm text-bakery-200"
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
here would resolve against the 80px header box and get clipped to a sliver.
|
||||
*/-->
|
||||
<header th:fragment="header" class="sticky top-0 z-40 bg-bakery-50/90 backdrop-blur border-b border-bakery-200">
|
||||
<div class="container mx-auto px-4">
|
||||
<div class="container">
|
||||
<div class="flex items-center justify-between gap-2 h-20 md:h-24">
|
||||
<div th:replace="~{fragments/lockup :: small('text-bakery-700')}"></div>
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
</svg>
|
||||
</summary>
|
||||
<div class="absolute inset-x-0 top-full z-30 h-[calc(100dvh-5rem)] bg-bakery-50">
|
||||
<nav class="container mx-auto px-4 flex flex-col">
|
||||
<nav class="container flex flex-col">
|
||||
<th:block th:replace="~{:: links('text-bakery-800 hover:text-bakery-600 transition py-4 text-lg border-b border-bakery-100')}"></th:block>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
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="relative container w-full min-w-0">
|
||||
<div class="max-w-3xl mx-auto text-center">
|
||||
<p class="eyebrow text-bakery-200">Since 2024</p>
|
||||
<h1 class="h1 mt-3 text-bakery-50">Our story</h1>
|
||||
@@ -20,10 +20,10 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<header class="container mx-auto px-4 pt-14 pb-2 md:pt-16 text-center"></header>
|
||||
<header class="container pt-14 pb-2 md:pt-16 text-center"></header>
|
||||
|
||||
<div class="container mx-auto px-4 pb-16 md:pb-24">
|
||||
<div class="max-w-2xl mx-auto space-y-12">
|
||||
<div class="container pb-16 md:pb-24">
|
||||
<div class="measure space-y-12">
|
||||
<section>
|
||||
<h2 class="h3 text-bakery-900 mb-4">How it started</h2>
|
||||
<p class="text-bakery-800 leading-relaxed">
|
||||
@@ -67,8 +67,8 @@
|
||||
|
||||
<!--/* Somewhere to go after reading: the story is a preamble to an order. */-->
|
||||
<section class="section bg-bakery-800 text-white">
|
||||
<div class="container mx-auto px-4">
|
||||
<div class="max-w-2xl mx-auto text-center">
|
||||
<div class="container">
|
||||
<div class="measure text-center">
|
||||
<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
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
<!--/* w-full/min-w-0 keep this flex item from sizing to its max-content width and blowing out the
|
||||
page on narrow screens. */-->
|
||||
<div class="relative container mx-auto px-4 w-full min-w-0">
|
||||
<div class="relative container 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="lede sm:text-xl text-bakery-100 mb-10">
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
<!--/* What people come in for */-->
|
||||
<section class="section bg-bakery-50">
|
||||
<div class="container mx-auto px-4">
|
||||
<div class="container">
|
||||
<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'} }"
|
||||
@@ -55,14 +55,14 @@
|
||||
|
||||
<!--/* Our story */-->
|
||||
<section class="section bg-bakery-800 text-white">
|
||||
<div class="container mx-auto px-4">
|
||||
<div class="container">
|
||||
<div class="max-w-3xl mx-auto text-center">
|
||||
<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.
|
||||
</p>
|
||||
<a href="/history" class="text-white hover:text-bakery-200 font-semibold underline underline-offset-4">
|
||||
<a href="/history" class="link-on-dark font-semibold">
|
||||
Read our story
|
||||
</a>
|
||||
</div>
|
||||
@@ -75,11 +75,11 @@
|
||||
the link is worth following.
|
||||
*/-->
|
||||
<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">
|
||||
<div class="container">
|
||||
<div class="grid md:grid-cols-2 gap-8 md:gap-12 items-center measure-wide">
|
||||
<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-panel shadow-xs">
|
||||
class="photo w-full h-64 md:h-80 object-cover">
|
||||
<div>
|
||||
<h2 class="h2 text-bakery-900">Ordering for a crowd?</h2>
|
||||
<p class="mt-4 text-bakery-800 leading-relaxed">
|
||||
@@ -97,7 +97,7 @@
|
||||
|
||||
<!--/* Visit us */-->
|
||||
<section id="visit" class="section bg-bakery-50 scroll-mt-24">
|
||||
<div class="container mx-auto px-4">
|
||||
<div class="container">
|
||||
<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="panel p-6 md:p-8">
|
||||
@@ -107,7 +107,7 @@
|
||||
<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>
|
||||
th:replace="~{fragments/visit :: address('link-plain')}"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3,15 +3,15 @@
|
||||
<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">
|
||||
<header class="page-head">
|
||||
<h1 class="h1 text-bakery-900">Our products</h1>
|
||||
<p class="mt-4 text-bakery-800 max-w-2xl mx-auto leading-relaxed">
|
||||
<p class="mt-4 text-bakery-800 measure 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.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<div class="container mx-auto px-4 pb-16">
|
||||
<div class="container pb-16">
|
||||
<!--/*
|
||||
The category filter: links, not buttons. Each filtered view is now a URL you can bookmark or send
|
||||
to somebody, the browser's back button does what it looks like it does, and a crawler can see all
|
||||
@@ -46,14 +46,14 @@
|
||||
|
||||
<p th:if="${#lists.isEmpty(products)}" class="text-center text-bakery-800">
|
||||
Nothing in that category just now.
|
||||
<a href="/products" class="underline underline-offset-4">See everything</a>.
|
||||
<a href="/products" class="link-plain">See everything</a>.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!--/* A catalogue with no way to order from it is a gallery. */-->
|
||||
<section class="section bg-bakery-800 text-white">
|
||||
<div class="container mx-auto px-4">
|
||||
<div class="max-w-2xl mx-auto text-center">
|
||||
<div class="container">
|
||||
<div class="measure text-center">
|
||||
<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
|
||||
|
||||
@@ -36,10 +36,7 @@
|
||||
disabled:opacity-30 disabled:cursor-not-allowed;
|
||||
}
|
||||
|
||||
@utility field {
|
||||
@apply w-full rounded-field border border-bakery-300 bg-white px-3 py-2 text-sm
|
||||
focus:border-bakery-500 focus:outline-none focus:ring-1 focus:ring-bakery-500;
|
||||
}
|
||||
/* `field` is shared with the public form — see components.css. */
|
||||
|
||||
@utility card {
|
||||
@apply rounded-panel border border-bakery-200 bg-white p-4 shadow-sm;
|
||||
|
||||
@@ -7,15 +7,70 @@
|
||||
* only a registered utility can take a variant (`hover:`, `md:`, `file:`).
|
||||
*/
|
||||
|
||||
/* The exception. In @layer components, matching the old site — and that ordering matters: a utility like
|
||||
`px-4`, which the markup applies alongside `container` on nearly every section, has to win over this,
|
||||
or every gutter on the site silently widens. */
|
||||
/*
|
||||
* The page gutter, and the only plain class left in a layer.
|
||||
*
|
||||
* Every section used to write `container mx-auto px-4`, carried over from the React site: `mx-auto` twice
|
||||
* and a px-4 that beat the responsive padding below, so the gutter was 16px at every width including a
|
||||
* 27-inch screen. The markup now says `container` and nothing else, which is why this can stay in the
|
||||
* components layer — there is no longer a utility next to it that has to win.
|
||||
*/
|
||||
@layer components {
|
||||
.container {
|
||||
@apply max-w-7xl mx-auto px-4 sm:px-6 lg:px-8;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* MEASURES. Text you read wants a narrow column and a grid of cards wants a wide one; those two numbers
|
||||
* were seven different max-w-* classes chosen a template at a time.
|
||||
*/
|
||||
@utility measure {
|
||||
@apply max-w-2xl mx-auto;
|
||||
}
|
||||
|
||||
@utility measure-wide {
|
||||
@apply max-w-5xl mx-auto;
|
||||
}
|
||||
|
||||
/*
|
||||
* LINKS in running text. Underlined, offset so the line clears the descenders, and colour-shifting on
|
||||
* hover — three variants because a link in a paragraph, a link on a sage band and a quiet one in small
|
||||
* print are the same idea in different rooms.
|
||||
*/
|
||||
@utility link {
|
||||
@apply underline underline-offset-4 text-bakery-700 hover:text-bakery-900 transition-colors;
|
||||
}
|
||||
|
||||
@utility link-on-dark {
|
||||
@apply underline underline-offset-4 text-bakery-50 hover:text-white transition-colors;
|
||||
}
|
||||
|
||||
/* Inherits its colour: for a link inside a coloured paragraph that already sets one. */
|
||||
@utility link-plain {
|
||||
@apply underline underline-offset-4 hover:text-bakery-600 transition-colors;
|
||||
}
|
||||
|
||||
/*
|
||||
* FIELDS. One input, everywhere. The public form had its own (cream, ring-2, py-2.5) and the admin had
|
||||
* another (white, ring-1, py-2, text-sm), which is what happens when a form gets written twice.
|
||||
*/
|
||||
@utility field {
|
||||
@apply w-full rounded-field border border-bakery-300 bg-white px-3.5 py-2.5 text-sm
|
||||
focus:border-bakery-500 focus:outline-none focus:ring-1 focus:ring-bakery-500;
|
||||
}
|
||||
|
||||
/* A photograph standing on the page rather than inside a card: same edge and shadow as one. */
|
||||
@utility photo {
|
||||
@apply rounded-panel border border-bakery-200/70;
|
||||
box-shadow: var(--shadow-card);
|
||||
}
|
||||
|
||||
/* The cream header at the top of a page that has no photographic band. */
|
||||
@utility page-head {
|
||||
@apply container pt-14 pb-10 md:pt-20 md:pb-12 text-center;
|
||||
}
|
||||
|
||||
/*
|
||||
* THE BRANCH MARKS of the wordmark, as masks rather than inline SVG.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user