Files
gw-svelte/docs/v5.md
T

135 lines
6.8 KiB
Markdown
Raw Normal View History

2026-07-04 10:00:16 +12:00
# v5: Simplify the message on service pages
## Goal
Every service page should say one clear message, once, in a fixed order, using the
homepage's single visual language. No restated sections, no card-grid sprawl. Lead
with trust, show the emotional outcome, let the page breathe (PRODUCT.md principles).
The Tiny Gang page is the finished reference. The rest of this task is applying the
same treatment to the other two service pages.
## The problem we are fixing
The current `ServiceLandingPage.svelte` stacks ~10 sections that repeat each other:
hero, highlight collage, a 6-card benefit pager, an intro badge block, a decision
card, a pricing block with an extras grid, an areas card, a FAQ card, and a related
services grid. The same promise (matched groups, safe, free pickup) is said three or
four times in three or four different card styles. It reads as pages of text and
boxes, not one calm argument.
## The v5 rule
**Say it once, in order. One design system.**
Canonical section spine for every service page (this is the order):
1. **Hero** - what it is (shared `ServiceHero`: green copy left, photo right).
2. **What's different** - the 3-4 things that actually set this service apart.
3. **How it works** - the steps to get started, made explicit.
4. **Honest fit check** - who it suits, who it does not (two columns, one card).
5. **Proof** - `TestimonialsSection`.
6. **One deliberate image** - a real photo that breaks the text and carries meaning.
7. **Price** - even plan cards, plus a short row of promise notes.
8. **FAQ** - a calm ruled list, not stacked cards.
9. **Service area** - `ServiceAreaCoverage`: an Auckland hub with all suburbs as
tappable links. Robust on every screen (no pin map). Per-page stats, so puppy-visits
reads "in-home", not "pickup & drop-off".
10. **Book** - `BookingWizard`.
If a piece of content does not fit one of those ten slots, it is probably a repeat.
Cut it.
## Design rules (non-negotiable, taken from the Tiny Gang build)
- **Lists, not cards.** "What's different" is an icon + text list. "How it works" is
numbered items. Reserve real cards for pricing only. Never nest cards.
- **One heading grammar.** Every section opens with the same centered eyebrow + H2
(`.tg-eyebrow` + `.tg-h2`). No per-section badges, marks, or collages.
- **One token set.** Use the shared CSS variables (colours, radius, shadow, spacing).
No new gradients or per-section colour systems. Goodwalk green `#213021`, yellow
`#FFD100` for buttons only.
- **Pricing cards stay even.** Four equal cards in a row on desktop, 2-up at 980px,
1-up on mobile. Do not put images inside or beside the cards.
- **One image, deliberate.** A single full-width photo band between sections, with a
short keyword-bearing caption. It must mean something (the pack, the pickup, the
outcome), not decorate. See SEO rules below.
- **FAQ is a ruled list.** Hairline dividers between questions, no card chrome.
- **Copy: half it, then half it again.** Active voice. No em dashes. No heading that
restates the one above it.
## Image and SEO rules
- Use real Goodwalk photos from `static/images/` (keyword-rich filenames already).
- Register width + height in `src/lib/image-metadata.ts` so there is zero layout shift.
- Set explicit `width`, `height`, `loading="lazy"`, `decoding="async"` on every `<img>`.
- Alt text is a full, natural, location-aware sentence (e.g. "Four small Tiny Gang dogs
looking up together in the long grass at an Auckland park"), not "dogs".
- Keep the `FaqSection` schema (`emitSchema`) and the `Service` + `AggregateOffer`
structured data in `src/routes/[slug]/+page.svelte` intact.
## Reference implementation (copy this)
- Component: `src/lib/components/pages/ServiceClarityPage.svelte` (shared by all three
service pages, content-driven)
- Pricing variant: `src/lib/components/pages/PricingClarityPage.svelte`
- Coverage section: `src/lib/components/sections/ServiceAreaCoverage.svelte`
- Preview routes (noindex): `/variants/tiny-gang`, `/variants/solo-walks`,
`/variants/puppy-visits`, `/variants/our-pricing`
- Content: the `clarity` block in `pack-walks.ts`, `dog-walking.ts`, `puppy-visits.ts`
- Variant switcher (preview only): `src/lib/components/ui/VariantNav.svelte`, mounted in
`src/routes/+layout.svelte`
Read the header comment in `ServiceClarityPage.svelte` first. It states the philosophy
and the section order in one place.
## Status
Done (built, svelte-check clean, server-rendered):
- `ServiceClarityPage` generalised and content-driven; `ServicePageContent.clarity`
added in `src/lib/types.ts`. Old `TinyGangPage.svelte` deleted.
- `clarity` content written for pack-walks, dog-walking, puppy-visits. Tiny Gang renders
identically to before.
- Coverage spine slot added (`ServiceAreaCoverage`), with per-page stats so puppy-visits
reads "in-home" not "pickup & drop-off".
- Preview routes for all four variants, plus a global `VariantNav` to compare them.
## Live now
The clarity pages are the live pages. `src/routes/[slug]/+page.svelte` renders
`ServiceClarityPage` for pack-walks / dog-walking / puppy-visits and `PricingClarityPage`
for our-pricing. The old `ServiceLandingPage.svelte`, `PricingPage.svelte`, and
`ServiceAreaMap.svelte` have been deleted.
The `/variants/*` routes still exist as a sandbox (the minimal-footer test lives there),
but are **dev/localhost only**: `src/hooks.server.ts` returns 500 for the `/variants`
namespace off-localhost in production, and `VariantNav` is hidden the same way in
`+layout.svelte`. Verified on a real `node build`: public host → 500 for any
`/variants/*` and no `VariantNav`; localhost → variants load.
Footer note: the live pages keep the default footer. The `minimal` footer is still only
on the `/variants/*` pages, a separate decision from the page-design swap.
## Definition of done
- [x] One `ServiceClarityPage` component drives all three service pages.
- [x] Page-specific copy lives in content files, not the component.
- [x] All three pages follow the spine, say each point once, share one heading grammar
and one token set.
- [x] Pricing cards are even on every page. No image in the pricing block.
- [x] Exactly one deliberate, captioned, fully-SEO'd image band per service page.
- [x] FAQ is a ruled list. Schema preserved.
- [x] `npx svelte-check` clean (no new errors).
- [x] Live `[slug]` branches swapped to the clarity pages.
- [x] Old `ServiceLandingPage.svelte` / `PricingPage.svelte` / `ServiceAreaMap.svelte` deleted.
- [x] `/variants/*` blocked in production (500) and `VariantNav` hidden there.
- [ ] Decide whether to promote the `minimal` footer to the live pages.
## Do not
- Do not redesign the brand or introduce new colours, fonts, or gradients.
- Do not add card grids, badges, collages, or mobile pagers back in.
- Do not change wording on a page unless it is a repeat being removed or copy being
shortened. Keep the meaning.