From cff39e87c2d160203cc43f634250426262770231 Mon Sep 17 00:00:00 2001 From: austin Date: Sun, 26 Jul 2026 19:33:06 -0500 Subject: [PATCH] Say where you are, let the keyboard past, and give the story pictures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit THE NAV NEVER SAID WHICH PAGE YOU WERE ON. A four-page site gets away with that right up until somebody clicks Catering, lands on a page of prices, and cannot tell whether the click worked. The current page now carries aria-current for a screen reader and a sage rule under the word for everyone else — a rule rather than a darker colour, because the nav is already sage on cream and darkening it reads as a hover. The list is generated from one array now instead of four hand-written anchors, which is what makes the marking possible at all. THE KEYBOARD HAD NO WAY PAST THE NAV. Every page begins with a skip link — off-screen until it has focus, then a real button in the corner, which is the half of that pattern everyone forgets. THE STORY WAS FOUR BLOCKS OF TEXT. It has photographs between the sections now, captioned in small caps, and an opening paragraph set with a drop cap in the display face. Once, on that page: a drop cap on every page would be a costume rather than a voice. 60 tests. Two new ones, both on things that fail silently rather than loudly: the active link (a wrong model attribute would mark nothing, which looks exactly like a page with no active link) and the skip link's target existing. --- .../resources/templates/fragments/header.html | 17 ++++++---- .../resources/templates/fragments/page.html | 5 ++- src/main/resources/templates/history.html | 18 +++++++++- src/main/styles/components.css | 34 +++++++++++++++++++ .../itsthevine/web/SiteControllerTest.java | 18 ++++++++++ 5 files changed, 84 insertions(+), 8 deletions(-) diff --git a/src/main/resources/templates/fragments/header.html b/src/main/resources/templates/fragments/header.html index 4fe0403..31e04fe 100644 --- a/src/main/resources/templates/fragments/header.html +++ b/src/main/resources/templates/fragments/header.html @@ -55,13 +55,18 @@ - + - Our Products - Catering - Our Story - Contact + Our Products diff --git a/src/main/resources/templates/fragments/page.html b/src/main/resources/templates/fragments/page.html index f6351ba..28cb33b 100644 --- a/src/main/resources/templates/fragments/page.html +++ b/src/main/resources/templates/fragments/page.html @@ -15,8 +15,11 @@
+ +
-
+
diff --git a/src/main/resources/templates/history.html b/src/main/resources/templates/history.html index c0fcac6..dbfed4e 100644 --- a/src/main/resources/templates/history.html +++ b/src/main/resources/templates/history.html @@ -26,7 +26,7 @@

How it started

-

+

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 enough tables that nobody feels rushed out the door. @@ -42,6 +42,14 @@

+
+ Cinnamon rolls, iced, on the counter at The Vine +
The cinnamon rolls, most mornings
+
+

The cakes are the fun part

@@ -53,6 +61,14 @@

+
+ A decorated cake made to order at The Vine +
Made to order, whatever the week is celebrating
+
+

Around town

diff --git a/src/main/styles/components.css b/src/main/styles/components.css index 058712a..a1fc1e4 100644 --- a/src/main/styles/components.css +++ b/src/main/styles/components.css @@ -200,3 +200,37 @@ @utility band { @apply py-14 md:py-20; } + +/* + * THE PAGE YOU ARE ON, in the nav. A rule under the word rather than a colour change: the nav is already + * sage on cream, and darkening it further reads as a hover, not as "you are here". + */ +@utility is-here { + @apply text-bakery-900; + text-decoration: underline; + text-decoration-color: var(--color-bakery-500); + text-decoration-thickness: 2px; + text-underline-offset: 8px; +} + +/* + * The keyboard's way past the nav. Off-screen until focused, then a normal-looking button in the corner — + * the pattern only works if it becomes visible, which is the half everyone forgets. + */ +@utility skip-link { + @apply sr-only; + &:focus { + @apply not-sr-only fixed left-4 top-4 z-50 pill-sage; + } +} + +/* + * An opening paragraph set like a printed one. Used once, on the story — a drop cap on every page would + * be a costume rather than a voice. + */ +@utility opening-para { + &::first-letter { + @apply font-adbhashitha text-6xl text-bakery-700 float-left mr-3 mt-1; + line-height: 0.75; + } +} diff --git a/src/test/java/com/itsthevine/web/SiteControllerTest.java b/src/test/java/com/itsthevine/web/SiteControllerTest.java index 78880be..8f0fd7f 100644 --- a/src/test/java/com/itsthevine/web/SiteControllerTest.java +++ b/src/test/java/com/itsthevine/web/SiteControllerTest.java @@ -123,6 +123,24 @@ class SiteControllerTest { mvc.perform(get("/products")).andExpect(content().string(containsString("href=\"/catering\""))); } + @Test + void theNavMarksThePageYouAreOn() throws Exception { + // Generated from the path the controller set, so a wrong model attribute would mark nothing at + // all — and nothing at all looks exactly like a page that simply has no active link. + mvc.perform(get("/catering")) + .andExpect(content().string(containsString("href=\"/catering\" aria-current=\"page\""))); + mvc.perform(get("/products")) + .andExpect(content().string(containsString("href=\"/products\" aria-current=\"page\""))) + .andExpect(content().string(not(containsString("href=\"/catering\" aria-current")))); + } + + @Test + void everyPageOffersTheKeyboardAWayPastTheNav() throws Exception { + mvc.perform(get("/")) + .andExpect(content().string(containsString("href=\"#content\""))) + .andExpect(content().string(containsString("id=\"content\""))); + } + @Test void aCateringButtonStartsTheEnquiryOffAboutThatTable() throws Exception { mvc.perform(get("/contact").param("about", "Weddings"))