On touchscreens, tapping a card fires :hover which changed flex from none to 1.3,
expanding the card mid-tap and shifting subsequent cards up — so the touch-up
registered on the wrong card. Fix: flex: none !important + transition: none on mobile.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
margin-top: auto collapses to 0 when the headline block fills the hero height
(e.g. long H1 word-wrap on small phones). Replace inline auto with .hero-mission
class: auto on desktop, clamp(40px, 6vh, 80px) on mobile for a guaranteed gap.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- ctaCards now merges Sanity data per-slot over defaults instead of all-or-nothing;
a partially-filled CMS (e.g. 2 cards) no longer hides the third card, and an
empty href in Sanity falls back to the correct default route
- Add overflow: visible to .cta-editorial on mobile so the third card isn't clipped
by the desktop overflow: hidden that wasn't being overridden
- Add pointer-events: none to the gradient overlay div so it can't intercept taps
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Mobile nav is ~104px tall (80px logo + 24px padding), desktop ~125px.
Set hero content padding to 120px mobile / 144px desktop.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Move donate button under H1 in reading path (was orphaned bottom-right, hidden on mobile)
- Hero height 63→70vh; responsive padding via CSS (88px/24px mobile, 96px/48px desktop)
- Type scale: eyebrow 12px/0.25em → 13px/0.2em; H1 margins snapped to 8px grid; blockquote 16px/1.6
- CTA cards on mobile: 200→280px height; force .cta-sub/.cta-more visible (were hover-only)
- Video body text capped at 620px (~65ch, was 680px/~85ch)
- Sponsors demoted to compact strip — removed large serif heading that outweighed CTAs
- Footer quick links: min-height 44px tap targets on mobile
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds homePage singleton document type (hero headline/mission, video section,
CTA cards, sponsors). Home page fetches from Sanity when configured and
falls back to the existing hardcoded values when not.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Astro didn't include the deleted public/studio/index.html in dist/client/
so the SSR route couldn't find it. Now we copy it from the studio build
stage to dist/studio-index.html after the Astro build — accessible to
the SSR route but invisible to the static file middleware.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Astro's static middleware was serving public/studio/index.html directly,
bypassing the [...path].ts route that rewrites /static/ to /studio/static/.
Deleting it makes all /studio requests go through the SSR rewrite.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sanity v3 basePath only affects the SPA router, not Vite's build output.
The built index.html hardcodes /static/ so we rewrite on the way out.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Without basePath the built studio references /static/*.js from the domain
root, but files live at /studio/static/*.js causing a blank page.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Lock file was generated with npm 11.x (Node 24 local) but node:20-alpine
has npm 10.x which enforces stricter lock file consistency. Using
npm install avoids the picomatch version conflict on CI.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
npm ci fails on alpine when lock file was generated on a different npm
version. --legacy-peer-deps handles the styled-components peer dep too.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
[...path] catches /studio itself (empty rest param), causing a redirect
loop. Now reads and returns index.html content for all /studio/* paths;
static assets are still served before this route fires.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Builds studio/ separately during Docker build and copies output to
public/studio/ so it is served as static files by the Astro Node adapter.
Catch-all route redirects deep studio links back to /studio for SPA routing.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Install @sanity/client + @portabletext/to-html
- studio/ — Sanity v3 project with post schema (title, slug, date, category,
summary, cover image with hotspot, Portable Text body). Run with
`cd studio && npm install && sanity dev` after setting SANITY_STUDIO_PROJECT_ID.
- src/lib/sanity.ts — typed client, GROQ queries, Portable Text → HTML conversion
- src/lib/news.ts — adds getArticles() / getArticle() async functions that prefer
Sanity when SANITY_PROJECT_ID is set; fall back to local markdown otherwise
- events/index.astro, events/[slug].astro, events/page/[page].astro — switch to
async getArticles()/getArticle(); [slug].astro drops getStaticPaths() in favour
of SSR request-time fetch with redirect-on-not-found
- .env.example — documents SANITY_PROJECT_ID / SANITY_DATASET / SANITY_API_TOKEN
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Astro wraps <script> tags as ES modules; inline onclick="fn()" only reaches
window globals. is:inline emits the script verbatim so all functions are global.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Without class="donate-overlay" the CSS display:none never applied,
leaving the fixed overlay covering the entire page on load and blocking
all clicks — making the page appear locked.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Cream (#F6F1E8) panel with slide-in/fade animation (no dark header bar)
- Eyebrow + Merriweather 900 title + subtitle header with circular close btn
- Running total dark green chip bar (updates live with mode/amount/Gift Aid)
- Full-label mode toggle: 'One-off donation' / 'Monthly donation', black active
- 2x2 amount chips with large Merriweather amount + impact text, black when selected
- 'Or another amount' inline row (£ prefix + right-aligned number input)
- Gift Aid block: custom visual checkbox, expandable name/address fields
- Pay step: Apple Pay / Google Pay / PayPal express buttons (→ JustGiving),
'Or pay with card' divider, full card form (email, card, expiry/CVC,
name, country/postcode), Direct Debit note (monthly only), lock-icon
Donate button, trust row (Stripe / cancel anytime / Charity SC007357)
- Done step: green checkmark, 'Thank you...' heading, gift summary, close
- Hero button: green pill uppercase 'DONATE →' (matching DonateButton)
- Yellow bar button: black pill uppercase 'DONATE NOW →'
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add vanilla JS donate modal with one-off/monthly toggle, amount chips,
custom input, impact text, Gift Aid checkbox, and JustGiving redirect
- Replace hero and yellow CTA bar JustGiving image links with styled
Donate buttons (heart icon) that open the modal
- Modal closes on overlay click or Escape key
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace placeholder one-liners with full first-person quotes from
the 2026 Horse Statements document for Breagha, Harley, Connolly,
Puzzle, and the Minis (Orris, Bru & Sam).
- Section heading updated to 'Meet the horses — In their own words.'
- Cards redesigned: taller photo (220px), green left-border quote
block in italic Merriweather, details in small caps green text
- Minis added as a group entry with shared card
- Memorial horses (Lady Suede, Wispa) moved to a separate
'Remembered fondly' subsection with grayscale treatment
- Updated details/ages/breeds to match the document
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace static output with @astrojs/node standalone adapter
so Nixpacks/Coolify can run the site as a Node server.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Rewrite volunteer-application.astro: 5-step multi-step form with
progress pills, choice cards, per-step validation, review step,
and fetch-based submission; matches new site design system
- Rewrite participant-application.astro: 5-step multi-step form
(Participant, Health & support, Activities, Consent, Review);
retains all original field names; 27 support question checkboxes
as interactive cards; callout box; guardian section on step 1
- Add volunteer-reference.astro: new non-public 5-step reference form
(noindex/nofollow); steps: The applicant, Your details, Relationship,
Assessment, Declaration; posts to /api/volunteer-reference
- Add functions/api/volunteer-reference.ts: Cloudflare Pages Function
mirroring volunteer-application pattern with Turnstile + Resend
- Add Ffordes sponsor logo to homepage; replace placeholder sponsor
boxes with full corporate sponsorship section (£750/annum) with
four benefit cards and CTAs
- Move ffordes_logo.png to public/sponsors/
- Remove all references to 'carriage driving' and 'free sessions'
across about.astro, index.astro, privacy.astro, support-us.astro,
and participant-application.astro
- facebook.astro: styled mock-post feed with like toggle, page header
card, sidebar, and embed note banner
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Desktop nav, mobile menu, footer social icons, and contact page
"Follow us" section all now include an Instagram icon linking to
https://www.instagram.com/HighlandGroupRDA.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
backdrop-filter on #site-nav creates a CSS containing block, causing
fixed inset-0 children to be clipped to the nav bar instead of the
viewport. Portal the menu to document.body on init to escape it.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Matches the same rgba(0,0,0,0.48) backdrop-filter treatment applied
to the Support Us cards for consistent text readability.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Added semi-opaque dark background (rgba 0,0,0,0.48) with blur(4px)
to the text panel on each editorial card so label, heading, body and
CTA are clearly legible regardless of the underlying image.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Removed fixed sm:h-[108px] height and top-only padding in favour of
symmetric py-3 sm:py-4, so the logo has equal space above and below
inside the dark scrolled bar. Also changed items-start to items-center
for proper vertical alignment.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Both absolutely-positioned elements were overlapping on viewports
≤767px. Extended hide breakpoint from 640px to 767px for the scroll
indicator and applied same breakpoint to the donate button. The
JustGiving button remains accessible via the intro strip below.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>