Next.js image optimizer blocks internal Docker URLs due to SSRF
protection (private IP resolution). Instead, proxy assets through
/api/assets/[id] which fetches from internal Directus URL server-side.
This bypasses both Cloudflare Access and SSRF protection since the
<Image> src is a same-origin path, not an external URL.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
NEXT_PUBLIC_ vars need to be set both at build time (client bundle)
AND at runtime (server-side rendering in standalone mode).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Directus CMS is behind Cloudflare Access, which blocks the Next.js
image optimizer from fetching assets. Route image requests through the
internal Docker network (http://katheryn-cms:8055) instead.
- Add NEXT_PUBLIC_DIRECTUS_ASSET_URL/TOKEN env vars for client components
- Use DIRECTUS_INTERNAL_URL for server-side Directus API calls
- Convert store detail page from client to server component (data
fetching now happens server-side, not in browser)
- Add internal Docker hostname to Next.js remotePatterns
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add @paypal/react-paypal-js, nodemailer, @types/nodemailer to package.json
- Add Order and OrderItem TypeScript interfaces to directus.ts
- These were part of the checkout implementation but missed in the initial commit
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Migrated from /root/.katheryn_credentials to the new organized
/opt/secrets/ directory structure. Symlinks ensure backward compat.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Use env_file referencing /root/.katheryn_credentials for all secrets
- Remove inline secrets from environment block (PayPal, SMTP, store token)
- Add directus_katheryn-internal network for internal CMS access
- Add container security: read_only, cap_drop ALL, no-new-privileges
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Create shipping.ts with flat-rate tiers: UK £10, Europe £25, International £40
- Integrate shipping cost into PayPal order breakdown (item_total + shipping)
- Add server-side shipping calculation in order creation API (prevents tampering)
- Update checkout page to show real-time shipping cost based on country selection
- Add subtotal/shipping/total breakdown to order confirmation page
- Add order confirmation emails via SMTP (customer + Katheryn notification)
- Include shipping breakdown in email templates
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add removeLeadingImage() to strip the first image from content when it matches
the featured image, preventing duplication on blog post pages
- Handles figure wraps, linked images, and standalone img tags
- Featured image now appears only once (in the header), not repeated in content
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add convertCaptionShortcodes() to transform [caption]...[/caption] into
<figure class="wp-caption"> with <figcaption>
- Handle both plain images and linked images (wrapped in <a> tags)
- Add CSS styling for figure captions in prose content
- All 17 posts with captions now display properly
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add decodeExcerptEntities() to handle —, …, smart quotes, etc.
- Add removeShortcodes() to strip [caption] and other WordPress shortcodes
- Regenerate blog-posts.json and pages.json with cleaned excerpts
Fixes issue where [caption] tags and raw HTML entities appeared in blog listings.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Embeds the Breaking The Silence film (https://youtu.be/hpzvEQs9vEk)
in a dedicated video section on the page.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Passionate Presence Centre page with Living Awake series
- Add Consulting page with approach and testimonials
- Add 1-to-1 Sessions page with session types and areas of focus
- Update navigation to link to new pages
- Add images for all three pages
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Homepage, events, and store pages now use force-dynamic
- This ensures fresh data is fetched at runtime
- Fixes build-time Directus fetch failures
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Import getAssetUrl function for Directus asset URLs
- Update homepage events section to display thumbnail images
- Images link to events page and show hover effect
- Fallback gracefully when no image is available
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add auth token to asset URLs for proper image access
- Map Directus artwork fields (name->title, price_gbp/usd->price, notes->description)
- Add currency field (GBP/USD) based on available price
- Fetch upcoming events dynamically on homepage
- Prefer artworks with images for featured display
- Add proper error handling for artwork lookups
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Switch from fill+object-cover (crops to aspect ratio) to explicit
width/height so book covers display at their natural proportions.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Cynthia's portrait photo as a circular image above her name
- Restyle TOC entries with hover background, arrow reveal on hover,
and subtle transition to make poems feel more clickable
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Organize 87 poems into 3 thematic sections:
I. At the Threshold (mortality, hospice, accompaniment)
II. The Country of Memory (family, childhood, remembrance)
III. Wild Things, Still Breathing (nature, prayer, presence)
- Create shared data module (src/data/poems.ts) with all poem content
- Add book-format table of contents on homepage
- Add sequential prev/next navigation between poems
- Add section breadcrumbs on poem pages
- Create About page with enriched biography and photos
- Reframe essay as Afterword with proper navigation
- Include both books: Meeting in the Margins + Mortal Beings
- Download 3 photos of Cynthia and Meeting in the Margins cover
- Add book-specific CSS (TOC entries, separators, poem nav)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Moved cynthia-poetry-website into katheryn-website repo as sibling to
frontend. Added actual Mortal Beings book cover image replacing the
placeholder text. Also includes new backlog tasks for newsletter setup
and artwork processing.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Keep social links, logo, and copyright in footer.
Newsletter signup is already available in /subscribe page.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add external link to cynthia-staging.jeffemmett.com
- Support external links in both desktop and mobile nav
- Opens in new tab with proper rel attributes
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add full-screen portrait hero with testimonial quote overlay
- Add social icons on hero section
- Add scroll indicator animation
- Add YouTube video background for In Your Own Skin section
- Add book section with Amazon embed
- Add Amazon images domain to Next.js config
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add full biographical content from Squarespace export
- Include artist statement and teacher bio sections
- Add media banner and major projects showcase
- Use Squarespace CDN images for portraits
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Parse Squarespace WordPress XML export and extract all blog posts
- Create blog listing page with posts grouped by year
- Create individual blog post pages with full content
- Add social sharing, prev/next navigation, related posts
- Configure Next.js for Squarespace CDN images
- Add Tailwind typography plugin for prose styling
- Include 357 artwork thumbnails from Airtable
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>