diff --git a/.claude/skills/publish/SKILL.md b/.claude/skills/publish/SKILL.md index 4ce6406..05b1eb9 100644 --- a/.claude/skills/publish/SKILL.md +++ b/.claude/skills/publish/SKILL.md @@ -11,7 +11,7 @@ Publish the project to all three targets: backup, dev remotes, and Chromatic. ### Step 2 — Push to backup (everything) -Push main directly to the `backup` remote (git.richie-snitch.online/richie/ParsonsFA). This is a private repo that receives the full repo including AI tooling, memory, and working docs. +Push main directly to the `backup` remote (git.tensordesign.com.au/richie/ParsonsFA). This is a private repo that receives the full repo including AI tooling, memory, and working docs. ```bash git push backup main @@ -50,23 +50,43 @@ git branch -D dev-clean **Important:** The `--force` is safe here because the stripped branch is always regenerated from main. Dev remotes never have unique commits. -### Step 4 — Deploy to Chromatic +### Step 4 — Sync assets to Gitea + +Push the `brandassets/` directory to the dedicated assets repo so Chromatic can load images via external URLs. ```bash -npm run chromatic +cd /tmp +rm -rf ParsonsAssets +git clone https://richie:151fdccacf11b6190d066a7e07f6f5310b2227dd@git.tensordesign.com.au/richie/ParsonsAssets.git +rsync -a --delete /brandassets/ /tmp/ParsonsAssets/ --exclude='.git' +cd /tmp/ParsonsAssets +git add -A +git diff --cached --quiet || git commit -m "Sync assets from main project" +git push origin main +cd +rm -rf /tmp/ParsonsAssets ``` -Run this in the background. Report the Storybook URL and build link when complete. +This step is idempotent — if nothing changed, no commit is created. Skip if you know no images were added or changed since last publish. -### Step 5 — Report +### Step 5 — Deploy to Chromatic + +```bash +STORYBOOK_ASSET_BASE=https://git.tensordesign.com.au/richie/ParsonsAssets/raw/branch/main npm run chromatic +``` + +The `STORYBOOK_ASSET_BASE` env var tells `assetUrl()` to resolve image paths from the Gitea assets repo instead of local static files. Run this in the background. Report the Storybook URL and build link when complete. + +### Step 6 — Report Summarise what was pushed: ``` Published to all targets: -- backup → git.richie-snitch.online/richie/ParsonsFA (full) -- fa-dev → git.richie-snitch.online/richie/Parsons (stripped) +- backup → git.tensordesign.com.au/richie/ParsonsFA (full) +- fa-dev → git.tensordesign.com.au/richie/Parsons (stripped) - sheffield → sheffield.sapiente.casa/richie/ParsonsFA (stripped) +- assets → git.tensordesign.com.au/richie/ParsonsAssets (synced) - Chromatic → [build link] ``` diff --git a/.gitignore b/.gitignore index a512242..fbf9e4e 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,9 @@ docs/reference/how-to-work-with-both-tools.md docs/reference/mcp-setup.md docs/reference/retroactive-review-plan.md +# Deploy scripts (contain credentials) +scripts/ + # Build logs build-storybook.log diff --git a/docs/memory/session-log.md b/docs/memory/session-log.md index 398c98b..3b102a4 100644 --- a/docs/memory/session-log.md +++ b/docs/memory/session-log.md @@ -26,6 +26,68 @@ Each entry follows this structure: ## Sessions +### Session 2026-04-13 — Chromatic image hosting + Gitea domain migration + +**Agent(s):** Claude Opus 4.6 (1M context) + +**Work completed:** +- **Gitea domain migration** — updated all remotes (backup, fa-dev) and references from `git.richie-snitch.online` to `git.tensordesign.com.au`. Updated publish skill and memory files. +- **Chromatic image hosting solution** — created `src/utils/assetUrl.ts` utility that resolves image paths via `STORYBOOK_ASSET_BASE` env var. When set (Chromatic builds), images load from Gitea ParsonsAssets repo. When empty (local dev), paths resolve via staticDirs as before. +- **Fixed path inconsistency** — story files used `/brandassets/images/...` which only worked locally via Vite root serving, not in builds. Changed to `/images/...` (correct for staticDirs) wrapped in `assetUrl()`. +- **Updated 4 files:** HomePage.tsx, HomePageV2.stories.tsx, HomePageV3.stories.tsx, HomePageV4.stories.tsx +- **Updated publish skill** — added Step 4 (sync assets to Gitea) and Step 5 (Chromatic with STORYBOOK_ASSET_BASE env var) +- **Created init script** — `scripts/init-assets-repo.sh` for one-time setup of ParsonsAssets repo on Gitea + +**Decisions made:** +- ParsonsAssets Gitea repo must be **public** so Chromatic clients can load images without auth +- `/brandlogo/` SVG paths left as-is — they're small, tracked in git, and work via staticDirs in builds +- Only `/brandassets/images/...` paths converted to `assetUrl()` — these are the large untracked binaries +- Scripts directory gitignored (contains embedded credentials) + +**Open questions:** +- User needs to create ParsonsAssets repo on Gitea and run `scripts/init-assets-repo.sh` (server not reachable from dev machine) + +**Next steps:** +- Create public ParsonsAssets repo on git.tensordesign.com.au +- Run init script to push 1.1GB of brand assets +- Test `/publish` end-to-end to verify Chromatic images render + +--- + +### Session 2026-04-12b — Homepage V3 redesign + FuneralFinder refinements + +**Agent(s):** Claude Opus 4.6 (1M context) + +**Work completed:** +- **HomePage V3 promoted to production** — story title changed from `Archive/HomePage V3` to `Pages/HomePage` +- **FuneralFinder V3 refinements:** responsive CTA (medium on mobile, large on desktop), button text "Search Local Providers" → "Search", "Free to use" bumped from captionSm to caption, tightened location pin-to-text gap +- **New section: "Why Use Funeral Arranger"** — text left + image right (people.png), overline + display3 heading + body copy +- **New section: "Three ways we can help you today"** — 3 feature cards with placeholder images, headings, descriptions, outlined CTA buttons +- **Section reorder:** partner logos carousel moved above Discover section, inherits overlap padding from FuneralFinder +- **Background colour scheme from Figma Make:** warm-grey alternating — `#f3efea` (darkest), `#fdfbf9` (lightest), `#f8f5f1` (mid), white sections with `#f3efea` borders +- **Overline headings** ("WHY USE FUNERAL ARRANGER", "WHAT YOU CAN DO HERE") styled in copper brand-600 +- **Card drop shadows** on three feature cards (shadow-md, removed border) +- **Heading consistency:** all section headings unified to display3 serif; "Why Use FA" was h3, FAQ was h2 — both fixed +- **SEO fixes:** h1 grammar ("funeral directors pricing" → "funeral director pricing"), logo section heading `

` → `

`, `aria-labelledby` on partner section +- **Section padding** increased from py 8/12 to 10/14 across all sections +- **Testimonials** left-aligned with consistent 560px max-width, centred block +- **"See more" button** added below FAQ accordion +- **FAQ heading** changed to "Frequently Asked Questions" +- **Logo section** changed to white bg, overline style heading, increased heading-to-logos gap +- **Figma capture** sent to Parsons Figma file (node 6049-25005) + +**Decisions made:** +- Page-level warm-grey backgrounds use direct hex values (#f3efea, #fdfbf9, #f8f5f1) rather than brand tokens — brand-100 (#f7ecdf) is too golden; the Figma tones are neutral-warm +- All section headings use display3 (Noto Serif SC) visually, rendered as semantic h2 tags +- Three feature card buttons are outlined, text-only (no arrows) + +**Next steps:** +- Replace feature card placeholder images with real screenshots/illustrations +- Wire up onClick handlers for feature card CTAs and FAQ "See more" when routing is in place +- Consider meta title/description for production deployment + +--- + ### Session 2026-04-12 — ComparisonPage refinements + new molecules **Agent(s):** Claude Opus 4.6 (1M context) diff --git a/src/components/pages/HomePage/HomePage.tsx b/src/components/pages/HomePage/HomePage.tsx index 954ff11..8059692 100644 --- a/src/components/pages/HomePage/HomePage.tsx +++ b/src/components/pages/HomePage/HomePage.tsx @@ -13,6 +13,7 @@ import type { SxProps, Theme } from '@mui/material/styles'; import { Typography } from '../../atoms/Typography'; import { Button } from '../../atoms/Button'; import { ProviderCardCompact } from '../../molecules/ProviderCardCompact'; +import { assetUrl } from '../../../utils/assetUrl'; import { Divider } from '../../atoms/Divider'; import { FuneralFinderV3, type FuneralFinderV3SearchParams } from '../../organisms/FuneralFinder'; @@ -638,7 +639,7 @@ export const HomePage = React.forwardRef( }} > Family planning together with care and confidence diff --git a/src/components/pages/HomePage/HomePageV2.stories.tsx b/src/components/pages/HomePage/HomePageV2.stories.tsx index cef686c..9dd8717 100644 --- a/src/components/pages/HomePage/HomePageV2.stories.tsx +++ b/src/components/pages/HomePage/HomePageV2.stories.tsx @@ -8,6 +8,7 @@ import { HomePage } from './HomePage'; import type { FeaturedProvider, TrustStat } from './HomePage'; import { Navigation } from '../../organisms/Navigation'; import { Footer } from '../../organisms/Footer'; +import { assetUrl } from '../../../utils/assetUrl'; // ─── Shared helpers ────────────────────────────────────────────────────────── @@ -231,7 +232,7 @@ export const Default: Story = { args: { navigation: nav, footer, - heroImageUrl: '/brandassets/images/heroes/parsonshero.png', + heroImageUrl: assetUrl('/images/heroes/parsonshero.png'), stats: trustStats, featuredProviders, onSelectFeaturedProvider: (id) => console.log('Featured provider:', id), diff --git a/src/components/pages/HomePage/HomePageV3.stories.tsx b/src/components/pages/HomePage/HomePageV3.stories.tsx index a570b0b..e1aa618 100644 --- a/src/components/pages/HomePage/HomePageV3.stories.tsx +++ b/src/components/pages/HomePage/HomePageV3.stories.tsx @@ -9,6 +9,7 @@ import type { FeaturedProvider, TrustStat, PartnerLogo } from './HomePage'; import React from 'react'; import { Navigation } from '../../organisms/Navigation'; import { Footer } from '../../organisms/Footer'; +import { assetUrl } from '../../../utils/assetUrl'; // ─── Shared helpers ────────────────────────────────────────────────────────── @@ -177,8 +178,8 @@ const featuredProviders: FeaturedProvider[] = [ name: 'H.Parsons Funeral Directors', location: 'Wollongong, NSW', verified: true, - imageUrl: '/brandassets/images/venues/hparsons-funeral-home-kiama/01.jpg', - logoUrl: '/brandassets/images/providers/hparsons-funeral-directors/logo.png', + imageUrl: assetUrl('/images/venues/hparsons-funeral-home-kiama/01.jpg'), + logoUrl: assetUrl('/images/providers/hparsons-funeral-directors/logo.png'), rating: 4.6, reviewCount: 7, startingPrice: 900, @@ -188,8 +189,8 @@ const featuredProviders: FeaturedProvider[] = [ name: 'Rankins Funerals', location: 'Wollongong, NSW', verified: true, - imageUrl: '/brandassets/images/venues/rankins-funeral-home-warrawong/01.jpg', - logoUrl: '/brandassets/images/providers/rankins-funerals/logo.png', + imageUrl: assetUrl('/images/venues/rankins-funeral-home-warrawong/01.jpg'), + logoUrl: assetUrl('/images/providers/rankins-funerals/logo.png'), rating: 4.8, reviewCount: 23, startingPrice: 1200, @@ -199,8 +200,8 @@ const featuredProviders: FeaturedProvider[] = [ name: 'Easy Funerals', location: 'Sydney, NSW', verified: true, - imageUrl: '/brandassets/images/venues/lakeside-memorial-park-chapel/01.jpg', - logoUrl: '/brandassets/images/providers/easy-funerals/logo.png', + imageUrl: assetUrl('/images/venues/lakeside-memorial-park-chapel/01.jpg'), + logoUrl: assetUrl('/images/providers/easy-funerals/logo.png'), rating: 4.5, reviewCount: 42, startingPrice: 850, @@ -209,30 +210,30 @@ const featuredProviders: FeaturedProvider[] = [ const partnerLogos: PartnerLogo[] = [ { - src: '/brandassets/images/providers/hparsons-funeral-directors/logo.png', + src: assetUrl('/images/providers/hparsons-funeral-directors/logo.png'), alt: 'H.Parsons Funeral Directors', }, - { src: '/brandassets/images/providers/rankins-funerals/logo.png', alt: 'Rankins Funerals' }, - { src: '/brandassets/images/providers/easy-funerals/logo.png', alt: 'Easy Funerals' }, - { src: '/brandassets/images/providers/lady-anne-funerals/logo.png', alt: 'Lady Anne Funerals' }, + { src: assetUrl('/images/providers/rankins-funerals/logo.png'), alt: 'Rankins Funerals' }, + { src: assetUrl('/images/providers/easy-funerals/logo.png'), alt: 'Easy Funerals' }, + { src: assetUrl('/images/providers/lady-anne-funerals/logo.png'), alt: 'Lady Anne Funerals' }, { - src: '/brandassets/images/providers/killick-family-funerals/logo.png', + src: assetUrl('/images/providers/killick-family-funerals/logo.png'), alt: 'Killick Family Funerals', }, { - src: '/brandassets/images/providers/kenneallys-funerals/logo.png', + src: assetUrl('/images/providers/kenneallys-funerals/logo.png'), alt: "Kenneally's Funerals", }, { - src: '/brandassets/images/providers/wollongong-city-funerals/logo.png', + src: assetUrl('/images/providers/wollongong-city-funerals/logo.png'), alt: 'Wollongong City Funerals', }, { - src: '/brandassets/images/providers/hparsons-funeral-directors-shoalhaven/logo.png', + src: assetUrl('/images/providers/hparsons-funeral-directors-shoalhaven/logo.png'), alt: 'H.Parsons Shoalhaven', }, { - src: '/brandassets/images/providers/mackay-family-funerals/logo.webp', + src: assetUrl('/images/providers/mackay-family-funerals/logo.webp'), alt: 'Mackay Family Funerals', }, ]; @@ -257,13 +258,13 @@ export const Default: Story = { args: { navigation: nav, footer, - heroImageUrl: '/brandassets/images/heroes/hero-3.png', + heroImageUrl: assetUrl('/images/heroes/hero-3.png'), heroHeading: 'Compare funeral director pricing near you and arrange with confidence', heroSubheading: 'Transparent pricing \u00B7 No hidden fees \u00B7 Arrange 24/7', stats: trustStats, featuredProviders, discoverMapSlot: React.createElement('img', { - src: '/brandassets/images/placeholder/map.png', + src: assetUrl('/images/placeholder/map.png'), alt: 'Map showing provider locations', style: { width: '100%', height: '100%', objectFit: 'cover' }, }), diff --git a/src/components/pages/HomePage/HomePageV4.stories.tsx b/src/components/pages/HomePage/HomePageV4.stories.tsx index 8118fe4..aac1374 100644 --- a/src/components/pages/HomePage/HomePageV4.stories.tsx +++ b/src/components/pages/HomePage/HomePageV4.stories.tsx @@ -10,6 +10,7 @@ import { FuneralFinderV4 } from '../../organisms/FuneralFinder/FuneralFinderV4'; import React from 'react'; import { Navigation } from '../../organisms/Navigation'; import { Footer } from '../../organisms/Footer'; +import { assetUrl } from '../../../utils/assetUrl'; // ─── Shared helpers ────────────────────────────────────────────────────────── @@ -178,8 +179,8 @@ const featuredProviders: FeaturedProvider[] = [ name: 'H.Parsons Funeral Directors', location: 'Wollongong, NSW', verified: true, - imageUrl: '/brandassets/images/venues/hparsons-funeral-home-kiama/01.jpg', - logoUrl: '/brandassets/images/providers/hparsons-funeral-directors/logo.png', + imageUrl: assetUrl('/images/venues/hparsons-funeral-home-kiama/01.jpg'), + logoUrl: assetUrl('/images/providers/hparsons-funeral-directors/logo.png'), rating: 4.6, reviewCount: 7, startingPrice: 900, @@ -189,8 +190,8 @@ const featuredProviders: FeaturedProvider[] = [ name: 'Rankins Funerals', location: 'Wollongong, NSW', verified: true, - imageUrl: '/brandassets/images/venues/rankins-funeral-home-warrawong/01.jpg', - logoUrl: '/brandassets/images/providers/rankins-funerals/logo.png', + imageUrl: assetUrl('/images/venues/rankins-funeral-home-warrawong/01.jpg'), + logoUrl: assetUrl('/images/providers/rankins-funerals/logo.png'), rating: 4.8, reviewCount: 23, startingPrice: 1200, @@ -200,8 +201,8 @@ const featuredProviders: FeaturedProvider[] = [ name: 'Easy Funerals', location: 'Sydney, NSW', verified: true, - imageUrl: '/brandassets/images/venues/lakeside-memorial-park-chapel/01.jpg', - logoUrl: '/brandassets/images/providers/easy-funerals/logo.png', + imageUrl: assetUrl('/images/venues/lakeside-memorial-park-chapel/01.jpg'), + logoUrl: assetUrl('/images/providers/easy-funerals/logo.png'), rating: 4.5, reviewCount: 42, startingPrice: 850, @@ -210,30 +211,30 @@ const featuredProviders: FeaturedProvider[] = [ const partnerLogos: PartnerLogo[] = [ { - src: '/brandassets/images/providers/hparsons-funeral-directors/logo.png', + src: assetUrl('/images/providers/hparsons-funeral-directors/logo.png'), alt: 'H.Parsons Funeral Directors', }, - { src: '/brandassets/images/providers/rankins-funerals/logo.png', alt: 'Rankins Funerals' }, - { src: '/brandassets/images/providers/easy-funerals/logo.png', alt: 'Easy Funerals' }, - { src: '/brandassets/images/providers/lady-anne-funerals/logo.png', alt: 'Lady Anne Funerals' }, + { src: assetUrl('/images/providers/rankins-funerals/logo.png'), alt: 'Rankins Funerals' }, + { src: assetUrl('/images/providers/easy-funerals/logo.png'), alt: 'Easy Funerals' }, + { src: assetUrl('/images/providers/lady-anne-funerals/logo.png'), alt: 'Lady Anne Funerals' }, { - src: '/brandassets/images/providers/killick-family-funerals/logo.png', + src: assetUrl('/images/providers/killick-family-funerals/logo.png'), alt: 'Killick Family Funerals', }, { - src: '/brandassets/images/providers/kenneallys-funerals/logo.png', + src: assetUrl('/images/providers/kenneallys-funerals/logo.png'), alt: "Kenneally's Funerals", }, { - src: '/brandassets/images/providers/wollongong-city-funerals/logo.png', + src: assetUrl('/images/providers/wollongong-city-funerals/logo.png'), alt: 'Wollongong City Funerals', }, { - src: '/brandassets/images/providers/hparsons-funeral-directors-shoalhaven/logo.png', + src: assetUrl('/images/providers/hparsons-funeral-directors-shoalhaven/logo.png'), alt: 'H.Parsons Shoalhaven', }, { - src: '/brandassets/images/providers/mackay-family-funerals/logo.webp', + src: assetUrl('/images/providers/mackay-family-funerals/logo.webp'), alt: 'Mackay Family Funerals', }, ]; @@ -258,7 +259,7 @@ export const Default: Story = { args: { navigation: nav, footer, - heroImageUrl: '/brandassets/images/heroes/hero-3.png', + heroImageUrl: assetUrl('/images/heroes/hero-3.png'), heroHeading: 'Compare funeral directors pricing near you and arrange with confidence', heroSubheading: 'Transparent pricing \u00B7 No hidden fees \u00B7 Arrange 24/7', finderSlot: React.createElement(FuneralFinderV4, { @@ -267,7 +268,7 @@ export const Default: Story = { stats: trustStats, featuredProviders, discoverMapSlot: React.createElement('img', { - src: '/brandassets/images/placeholder/map.png', + src: assetUrl('/images/placeholder/map.png'), alt: 'Map showing provider locations', style: { width: '100%', height: '100%', objectFit: 'cover' }, }), diff --git a/src/utils/assetUrl.ts b/src/utils/assetUrl.ts new file mode 100644 index 0000000..bf2ae7d --- /dev/null +++ b/src/utils/assetUrl.ts @@ -0,0 +1,10 @@ +/** + * Resolves a static asset path. In local dev the path is served by Storybook's + * staticDirs; when STORYBOOK_ASSET_BASE is set (e.g. Chromatic builds) it + * prepends the external host URL so images load from Gitea. + */ +export const assetUrl = (path: string): string => { + const base = + typeof import.meta !== 'undefined' ? (import.meta.env?.STORYBOOK_ASSET_BASE ?? '') : ''; + return `${base}${path}`; +};